D8385: hgk: remove a "b" used on a kwargs expansion, the keys are strs
spectral created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D8385 AFFECTED FILES hgext/hgk.py CHANGE DETAILS diff --git a/hgext/hgk.py b/hgext/hgk.py --- a/hgext/hgk.py +++ b/hgext/hgk.py @@ -358,7 +358,7 @@ ) def revlist(ui, repo, *revs, **opts): """print revisions""" -if opts[b'header']: +if opts['header']: full = b"commit" else: full = None To: spectral, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: Moving patches traffic to a another list?
> On Apr 5, 2020, at 19:38, Pierre-Yves David > wrote: > > A couple of day ago, you asked on IRC for help on how to create a new list. > It looks like the `newlist` utility is meant for that. A small blog post give > some more details here: > > http://data.agaric.com/create-mailman-list-through-command-line > > And the utility seems to have a manpage > > http://manpages.ubuntu.com/manpages/bionic/man8/newlist.8.html > > Does this matches what we have installed ? That was a huge help! Okay, I think I've done the right thing. Can you go check? Also, I have an admin password here for list moderation. Do you want that so you can mod through the initial phab messages etc? I'm also happy to temporarily make you a phab admin to set the right knobs...I'm assuming we can't ansible-ize that? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
mercurial@44667: new changeset (1 on stable)
New changeset (1 on stable) in mercurial: https://www.mercurial-scm.org/repo/hg/rev/b561f3a68e41 changeset: 44667:b561f3a68e41 branch: stable tag: tip parent: 44650:3f29c5edac8e user:Pierre-Yves David date:Mon Apr 06 00:24:57 2020 +0200 summary: discovery: avoid wrongly saying there are nothing to pull -- Repository URL: https://www.mercurial-scm.org/repo/hg ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D8384: rust-chg: silence warning about dated coding style
yuja created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D8384 AFFECTED FILES rust/chg/src/message.rs rust/chg/src/runcommand.rs CHANGE DETAILS diff --git a/rust/chg/src/runcommand.rs b/rust/chg/src/runcommand.rs --- a/rust/chg/src/runcommand.rs +++ b/rust/chg/src/runcommand.rs @@ -37,7 +37,7 @@ Finished, } -type CommandPoll = io::Result<(AsyncS<(Client, H, i32), CommandState>)>; +type CommandPoll = io::Result, H, i32), CommandState>>; /// Future resolves to `(exit_code, client)`. #[must_use = "futures do nothing unless polled"] diff --git a/rust/chg/src/message.rs b/rust/chg/src/message.rs --- a/rust/chg/src/message.rs +++ b/rust/chg/src/message.rs @@ -152,7 +152,7 @@ fn new_parse_error(error: E) -> io::Error where -E: Into>, +E: Into>, { io::Error::new(io::ErrorKind::InvalidData, error) } To: yuja, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D8382: rust-chg: send client side umask to server
yuja created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This is equivalent to forwardumask() of hgclient.c. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D8382 AFFECTED FILES rust/chg/src/clientext.rs rust/chg/src/locator.rs rust/chg/src/main.rs rust/chg/src/procutil.rs CHANGE DETAILS diff --git a/rust/chg/src/procutil.rs b/rust/chg/src/procutil.rs --- a/rust/chg/src/procutil.rs +++ b/rust/chg/src/procutil.rs @@ -25,6 +25,19 @@ unsafe { libc::geteuid() } } +/// Returns the umask of the current process. +/// +/// # Safety +/// +/// This is unsafe because the umask value is temporarily changed, and +/// the change can be observed from the other threads. Don't call this in +/// multi-threaded context. +pub unsafe fn get_umask() -> u32 { +let mask = libc::umask(0); +libc::umask(mask); +mask +} + /// Changes the given fd to blocking mode. pub fn set_blocking_fd(fd: RawFd) -> io::Result<()> { let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) }; diff --git a/rust/chg/src/main.rs b/rust/chg/src/main.rs --- a/rust/chg/src/main.rs +++ b/rust/chg/src/main.rs @@ -73,6 +73,7 @@ } fn run() -> io::Result { +let umask = unsafe { procutil::get_umask() }; // not thread safe let mut loc = Locator::prepare_from_env()?; loc.set_early_args(locator::collect_early_args(env::args_os().skip(1))); let handler = ChgUiHandler::new(); @@ -80,6 +81,7 @@ let fut = loc .connect() .and_then(|(_, client)| client.attach_io(io::stdin(), io::stdout(), io::stderr())) +.and_then(move |client| client.set_umask(umask)) .and_then(|client| { let pid = client.server_spec().process_id.unwrap(); let pgid = client.server_spec().process_group_id; diff --git a/rust/chg/src/locator.rs b/rust/chg/src/locator.rs --- a/rust/chg/src/locator.rs +++ b/rust/chg/src/locator.rs @@ -24,8 +24,14 @@ use super::message::{Instruction, ServerSpec}; use super::procutil; -const REQUIRED_SERVER_CAPABILITIES: &[&str] = -&["attachio", "chdir", "runcommand", "setenv", "validate"]; +const REQUIRED_SERVER_CAPABILITIES: &[&str] = &[ +"attachio", +"chdir", +"runcommand", +"setenv", +"setumask2", +"validate", +]; /// Helper to connect to and spawn a server process. #[derive(Clone, Debug)] diff --git a/rust/chg/src/clientext.rs b/rust/chg/src/clientext.rs --- a/rust/chg/src/clientext.rs +++ b/rust/chg/src/clientext.rs @@ -5,9 +5,10 @@ //! cHg extensions to command server client. -use bytes::Bytes; +use bytes::{BufMut, Bytes, BytesMut}; use std::ffi::OsStr; use std::io; +use std::mem; use std::os::unix::ffi::OsStrExt; use std::os::unix::io::AsRawFd; use std::path::Path; @@ -41,6 +42,9 @@ I: IntoIterator, P: AsRef; +/// Changes the umask of the server process. +fn set_umask(self, mask: u32) -> OneShotRequest; + /// Runs the specified Mercurial command with cHg extension. fn run_command_chg(self, handler: H, args: I) -> ChgRunCommand where @@ -90,6 +94,12 @@ OneShotRequest::start_with_args(self, b"setenv", message::pack_env_vars_os(vars)) } +fn set_umask(self, mask: u32) -> OneShotRequest { +let mut args = BytesMut::with_capacity(mem::size_of_val(&mask)); +args.put_u32_be(mask); +OneShotRequest::start_with_args(self, b"setumask2", args) +} + fn run_command_chg(self, handler: H, args: I) -> ChgRunCommand where I: IntoIterator, To: yuja, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D8383: rust-chg: update name of the server process
yuja created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This is a copy of updateprocname() of hgclient.c. At this point, rust-chg is basically functional. I did dogfooding for a couple of weeks in 2018. There are a few remaining tasks: a. loop detection by CHGINTERNALMARK b. forward unsupported commands (notably serve -d) to real hg c. better handling of early server exception d. modernize codebase (2018 edition, impl trait, async/await) For (d), we'll probably want to switch to async-std, but I'm thinking of upgrading to Tokio 0.2 as an intermediate step since process API isn't ported to async-std yet. I'm pretty sure future migration to async-std will be painless compared to the mass rewrite from futures-0.1 to 0.3. https://github.com/async-rs/async-std/issues/22 REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D8383 AFFECTED FILES rust/chg/src/clientext.rs rust/chg/src/locator.rs CHANGE DETAILS diff --git a/rust/chg/src/locator.rs b/rust/chg/src/locator.rs --- a/rust/chg/src/locator.rs +++ b/rust/chg/src/locator.rs @@ -196,6 +196,17 @@ Ok((loc, client)) }) .and_then(|(loc, client)| { +// It's purely optional, and the server might not support this command. +if client.server_spec().capabilities.contains("setprocname") { +let fut = client +.set_process_name(format!("chg[worker/{}]", loc.process_id)) +.map(|client| (loc, client)); +Either::A(fut) +} else { +Either::B(future::ok((loc, client))) +} +}) +.and_then(|(loc, client)| { client .set_current_dir(&loc.current_dir) .map(|client| (loc, client)) diff --git a/rust/chg/src/clientext.rs b/rust/chg/src/clientext.rs --- a/rust/chg/src/clientext.rs +++ b/rust/chg/src/clientext.rs @@ -42,6 +42,11 @@ I: IntoIterator, P: AsRef; +/// Changes the process title of the server. +fn set_process_name(self, name: P) -> OneShotRequest +where +P: AsRef; + /// Changes the umask of the server process. fn set_umask(self, mask: u32) -> OneShotRequest; @@ -94,6 +99,13 @@ OneShotRequest::start_with_args(self, b"setenv", message::pack_env_vars_os(vars)) } +fn set_process_name(self, name: P) -> OneShotRequest +where +P: AsRef, +{ +OneShotRequest::start_with_args(self, b"setprocname", name.as_ref().as_bytes()) +} + fn set_umask(self, mask: u32) -> OneShotRequest { let mut args = BytesMut::with_capacity(mem::size_of_val(&mask)); args.put_u32_be(mask); To: yuja, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D8381: rust-chg: add config validation and process returned instructions
yuja created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This is the reimplementation of runinstructions() and main() in chg.c. In Rust version, we only pass in early arguments to the server as the locator doesn't know the full arguments. This should be fine since these arguments are just passed in to _earlyparseopts() and _parseconfig(), which means the server doesn't need full arguments. Another difference is the handling of the "exit " instruction. In Rust version, we can simply reuse the connection instead of "exit(code)" as the command error isn't displayed yet. That's because the client-side stdio is not attached until the connection is validated. This behavior is cleaner than C, but it also means that the early server exception wouldn't be propagated to client because stderr isn't attached. So we might have to reconsider when to attach/detach the server stdio. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D8381 AFFECTED FILES rust/chg/src/locator.rs CHANGE DETAILS diff --git a/rust/chg/src/locator.rs b/rust/chg/src/locator.rs --- a/rust/chg/src/locator.rs +++ b/rust/chg/src/locator.rs @@ -21,10 +21,11 @@ use tokio_timer; use super::clientext::ChgClientExt; -use super::message::ServerSpec; +use super::message::{Instruction, ServerSpec}; use super::procutil; -const REQUIRED_SERVER_CAPABILITIES: &[&str] = &["attachio", "chdir", "runcommand", "setenv"]; +const REQUIRED_SERVER_CAPABILITIES: &[&str] = +&["attachio", "chdir", "runcommand", "setenv", "validate"]; /// Helper to connect to and spawn a server process. #[derive(Clone, Debug)] @@ -35,6 +36,7 @@ env_vars: Vec<(OsString, OsString)>, process_id: u32, base_sock_path: PathBuf, +redirect_sock_path: Option, timeout: Duration, } @@ -51,6 +53,7 @@ env_vars: env::vars_os().collect(), process_id: process::id(), base_sock_path: prepare_server_socket_path()?, +redirect_sock_path: None, timeout: default_timeout(), }) } @@ -77,16 +80,110 @@ /// /// The server process will be spawned if not running. pub fn connect(self) -> impl Future { -self.try_connect() +future::loop_fn((self, 0), |(loc, cnt)| { +if cnt < 10 { +let fut = loc +.try_connect() +.and_then(|(loc, client)| { +client +.validate(&loc.hg_early_args) +.map(|(client, instructions)| (loc, client, instructions)) +}) +.and_then(move |(loc, client, instructions)| { +loc.run_instructions(client, instructions, cnt) +}); +Either::A(fut) +} else { +let msg = format!( +concat!( +"too many redirections.\n", +"Please make sure {:?} is not a wrapper which ", +"changes sensitive environment variables ", +"before executing hg. If you have to use a ", +"wrapper, wrap chg instead of hg.", +), +loc.hg_command +); +Either::B(future::err(io::Error::new(io::ErrorKind::Other, msg))) +} +}) +} + +/// Runs instructions received from the server. +fn run_instructions( +mut self, +client: UnixClient, +instructions: Vec, +cnt: usize, +) -> io::Result> { +let mut reconnect = false; +for inst in instructions { +debug!("instruction: {:?}", inst); +match inst { +Instruction::Exit(_) => { +// Just returns the current connection to run the +// unparsable command and report the error +return Ok(Loop::Break((self, client))); +} +Instruction::Reconnect => { +reconnect = true; +} +Instruction::Redirect(path) => { +if path.parent() != self.base_sock_path.parent() { +let msg = format!( +"insecure redirect instruction from server: {}", +path.display() +); +return Err(io::Error::new(io::ErrorKind::InvalidData, msg)); +} +self.redirect_sock_path = Some(path); +reconnect = true; +} +Instruction::Unlink(path) => { +if path.parent() != self.base_sock_path.parent() { +let msg = format!( +"insec
D8380: rust-chg: collect server flags from command arguments
yuja created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This is the reimplementation of testsensitiveflag() and setcmdserverargs() of chg.c. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D8380 AFFECTED FILES rust/chg/src/locator.rs rust/chg/src/main.rs CHANGE DETAILS diff --git a/rust/chg/src/main.rs b/rust/chg/src/main.rs --- a/rust/chg/src/main.rs +++ b/rust/chg/src/main.rs @@ -9,7 +9,7 @@ extern crate tokio; extern crate tokio_hglib; -use chg::locator::Locator; +use chg::locator::{self, Locator}; use chg::procutil; use chg::{ChgClientExt, ChgUiHandler}; use futures::sync::oneshot; @@ -73,7 +73,8 @@ } fn run() -> io::Result { -let loc = Locator::prepare_from_env()?; +let mut loc = Locator::prepare_from_env()?; +loc.set_early_args(locator::collect_early_args(env::args_os().skip(1))); let handler = ChgUiHandler::new(); let (result_tx, result_rx) = oneshot::channel(); let fut = loc diff --git a/rust/chg/src/locator.rs b/rust/chg/src/locator.rs --- a/rust/chg/src/locator.rs +++ b/rust/chg/src/locator.rs @@ -30,6 +30,7 @@ #[derive(Clone, Debug)] pub struct Locator { hg_command: OsString, +hg_early_args: Vec, current_dir: PathBuf, env_vars: Vec<(OsString, OsString)>, process_id: u32, @@ -45,6 +46,7 @@ pub fn prepare_from_env() -> io::Result { Ok(Locator { hg_command: default_hg_command(), +hg_early_args: Vec::new(), current_dir: env::current_dir()?, env_vars: env::vars_os().collect(), process_id: process::id(), @@ -62,6 +64,15 @@ OsString::from_vec(buf).into() } +/// Specifies the arguments to be passed to the server at start. +pub fn set_early_args(&mut self, args: I) +where +I: IntoIterator, +P: AsRef, +{ +self.hg_early_args = args.into_iter().map(|a| a.as_ref().to_owned()).collect(); +} + /// Connects to the server. /// /// The server process will be spawned if not running. @@ -109,6 +120,7 @@ .arg(&sock_path) .arg("--daemon-postexec") .arg("chdir:/") +.args(&self.hg_early_args) .current_dir(&self.current_dir) .env_clear() .envs(self.env_vars.iter().cloned()) @@ -275,3 +287,100 @@ Err(io::Error::new(io::ErrorKind::Other, msg)) } } + +/// Collects arguments which need to be passed to the server at start. +pub fn collect_early_args(args: I) -> Vec +where +I: IntoIterator, +P: AsRef, +{ +let mut args_iter = args.into_iter(); +let mut early_args = Vec::new(); +while let Some(arg) = args_iter.next() { +let argb = arg.as_ref().as_bytes(); +if argb == b"--" { +break; +} else if argb.starts_with(b"--") { +let mut split = argb[2..].splitn(2, |&c| c == b'='); +match split.next().unwrap() { +b"traceback" => { +if split.next().is_none() { +early_args.push(arg.as_ref().to_owned()); +} +} +b"config" | b"cwd" | b"repo" | b"repository" => { +if split.next().is_some() { +// --= +early_args.push(arg.as_ref().to_owned()); +} else { +// -- +args_iter.next().map(|val| { +early_args.push(arg.as_ref().to_owned()); +early_args.push(val.as_ref().to_owned()); +}); +} +} +_ => {} +} +} else if argb.starts_with(b"-R") { +if argb.len() > 2 { +// -R +early_args.push(arg.as_ref().to_owned()); +} else { +// -R +args_iter.next().map(|val| { +early_args.push(arg.as_ref().to_owned()); +early_args.push(val.as_ref().to_owned()); +}); +} +} +} + +early_args +} + +#[cfg(test)] +mod tests { +use super::*; + +#[test] +fn collect_early_args_some() { +assert!(collect_early_args(&[] as &[&OsStr]).is_empty()); +assert!(collect_early_args(&["log"]).is_empty()); +assert_eq!( +collect_early_args(&["log", "-Ra", "foo"]), +os_string_vec_from(&[b"-Ra"]) +); +assert_eq!( +collect_early_args(&["log", "-R", "repo", "", "--traceback", "a"]), +os_string_vec_from(&[b"-R", b"repo", b"--traceback"]) +); +assert_eq!( +collect_early_args(&["log", "--config", "diff.git=1", "-q"]), +os_string_vec_from(&[b"--config", b"diff.git=1"]) +)
D8379: rust-chg: add interface to run "validate" request
yuja created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D8379 AFFECTED FILES rust/chg/src/clientext.rs CHANGE DETAILS diff --git a/rust/chg/src/clientext.rs b/rust/chg/src/clientext.rs --- a/rust/chg/src/clientext.rs +++ b/rust/chg/src/clientext.rs @@ -5,15 +5,17 @@ //! cHg extensions to command server client. +use bytes::Bytes; use std::ffi::OsStr; +use std::io; use std::os::unix::ffi::OsStrExt; use std::os::unix::io::AsRawFd; use std::path::Path; -use tokio_hglib::protocol::OneShotRequest; +use tokio_hglib::protocol::{OneShotQuery, OneShotRequest}; use tokio_hglib::{Client, Connection}; use super::attachio::AttachIo; -use super::message; +use super::message::{self, Instruction}; use super::runcommand::ChgRunCommand; use super::uihandler::SystemHandler; @@ -45,6 +47,19 @@ I: IntoIterator, P: AsRef, H: SystemHandler; + +/// Validates if the server can run Mercurial commands with the expected +/// configuration. +/// +/// The `args` should contain early command arguments such as `--config` +/// and `-R`. +/// +/// Client-side environment must be sent prior to this request, by +/// `set_current_dir()` and `set_env_vars_os()`. +fn validate(self, args: I) -> OneShotQuery io::Result>> +where +I: IntoIterator, +P: AsRef; } impl ChgClientExt for Client @@ -83,4 +98,17 @@ { ChgRunCommand::with_client(self, handler, message::pack_args_os(args)) } + +fn validate(self, args: I) -> OneShotQuery io::Result>> +where +I: IntoIterator, +P: AsRef, +{ +OneShotQuery::start_with_args( +self, +b"validate", +message::pack_args_os(args), +message::parse_instructions, +) +} } To: yuja, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D8378: rust-chg: add helper to parse instructions sent from server
yuja created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY This is well structured version of runinstructions() of chg.c. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D8378 AFFECTED FILES rust/chg/src/message.rs CHANGE DETAILS diff --git a/rust/chg/src/message.rs b/rust/chg/src/message.rs --- a/rust/chg/src/message.rs +++ b/rust/chg/src/message.rs @@ -10,6 +10,7 @@ use std::ffi::{OsStr, OsString}; use std::io; use std::os::unix::ffi::OsStrExt; +use std::path::PathBuf; pub use tokio_hglib::message::*; // re-exports @@ -67,6 +68,42 @@ } } +/// Client-side instruction requested by the server. +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum Instruction { +Exit(i32), +Reconnect, +Redirect(PathBuf), +Unlink(PathBuf), +} + +/// Parses validation result into instructions. +pub fn parse_instructions(data: Bytes) -> io::Result> { +let mut instructions = Vec::new(); +for l in data.split(|&c| c == b'\0') { +if l.is_empty() { +continue; +} +let mut s = l.splitn(2, |&c| c == b' '); +let inst = match (s.next().unwrap(), s.next()) { +(b"exit", Some(arg)) => decode_latin1(arg) +.parse() +.map(Instruction::Exit) +.map_err(|_| new_parse_error(format!("invalid exit code: {:?}", arg)))?, +(b"reconnect", None) => Instruction::Reconnect, +(b"redirect", Some(arg)) => { +Instruction::Redirect(OsStr::from_bytes(arg).to_owned().into()) +} +(b"unlink", Some(arg)) => Instruction::Unlink(OsStr::from_bytes(arg).to_owned().into()), +_ => { +return Err(new_parse_error(format!("unknown command: {:?}", l))); +} +}; +instructions.push(inst); +} +Ok(instructions) +} + // allocate large buffer as environment variables can be quite long const INITIAL_PACKED_ENV_VARS_CAPACITY: usize = 4096; @@ -168,6 +205,50 @@ } #[test] +fn parse_instructions_good() { +let src = [ +b"exit 123".as_ref(), +b"reconnect".as_ref(), +b"redirect /whatever".as_ref(), +b"unlink /someother".as_ref(), +] +.join(&0); +let insts = vec![ +Instruction::Exit(123), +Instruction::Reconnect, +Instruction::Redirect(path_buf_from(b"/whatever")), +Instruction::Unlink(path_buf_from(b"/someother")), +]; +assert_eq!(parse_instructions(Bytes::from(src)).unwrap(), insts); +} + +#[test] +fn parse_instructions_empty() { +assert_eq!(parse_instructions(Bytes::new()).unwrap(), vec![]); +assert_eq!( +parse_instructions(Bytes::from_static(b"\0")).unwrap(), +vec![] +); +} + +#[test] +fn parse_instructions_malformed_exit_code() { +assert!(parse_instructions(Bytes::from_static(b"exit foo")).is_err()); +} + +#[test] +fn parse_instructions_missing_argument() { +assert!(parse_instructions(Bytes::from_static(b"exit")).is_err()); +assert!(parse_instructions(Bytes::from_static(b"redirect")).is_err()); +assert!(parse_instructions(Bytes::from_static(b"unlink")).is_err()); +} + +#[test] +fn parse_instructions_unknown_command() { +assert!(parse_instructions(Bytes::from_static(b"quit 0")).is_err()); +} + +#[test] fn pack_env_vars_os_good() { assert_eq!( pack_env_vars_os(vec![] as Vec<(OsString, OsString)>), @@ -229,4 +310,8 @@ fn os_string_pair_from(k: &[u8], v: &[u8]) -> (OsString, OsString) { (os_string_from(k), os_string_from(v)) } + +fn path_buf_from(s: &[u8]) -> PathBuf { +os_string_from(s).into() +} } To: yuja, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH STABLE V2] discovery: avoid wrongly saying there are nothing to pull
On Mon, 06 Apr 2020 01:33:28 +0200, Pierre-Yves David wrote: > # HG changeset patch > # User Pierre-Yves David > # Date 1586125497 -7200 > # Mon Apr 06 00:24:57 2020 +0200 > # Branch stable > # Node ID 2d761788a0f24e85d6d7e2784a72fa13ccf5217b > # Parent 3f29c5edac8e4a663f062960f65bba7bc8a26536 > # EXP-Topic pull-shadow > # Available At https://foss.heptapod.net/octobus/mercurial-devel/ > # hg pull https://foss.heptapod.net/octobus/mercurial-devel/ -r > 2d761788a0f2 > discovery: avoid wrongly saying there are nothing to pull Sounds good, queued, thanks. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH STABLE] discovery: avoid wrongly saying there are nothing to pull
This one left with unwanted change, disregard it in favor on v2 On 4/6/20 1:32 AM, Pierre-Yves David wrote: # HG changeset patch # User Pierre-Yves David # Date 1586125497 -7200 # Mon Apr 06 00:24:57 2020 +0200 # Branch stable # Node ID e58f537d4c33b4d203b867eca11a1e19ae65e4b9 # Parent 3f29c5edac8e4a663f062960f65bba7bc8a26536 # EXP-Topic pull-shadow # Available At https://foss.heptapod.net/octobus/mercurial-devel/ # hg pull https://foss.heptapod.net/octobus/mercurial-devel/ -r e58f537d4c33 discovery: avoid wrongly saying there are nothing to pull We can be in a situation where a revision passed through `hg pull --rev REV`. For example the server could be during heads advertisement, to hide some pull request. Or obsolete/hidden content could be explicitly pulled. So in this case the lookup associated to `REV` returned successfully, but the normal discovery will find all advertised heads already known locally. This flip a special boolean `anyinc` that will prevent any fetch attempt, preventing `REV` to be pulled over. We add three line of code to detect this case and make sure a pull actually happens. My main target is to make some third party extensions happy (I expect the associated test to move upstream with the extension). However this fix already make some of the `infinitepush` test happier. diff --git a/mercurial/discovery.py b/mercurial/discovery.py --- a/mercurial/discovery.py +++ b/mercurial/discovery.py @@ -67,6 +67,10 @@ def findcommonincoming(repo, remote, hea ancestorsof=ancestorsof, ) common, anyinc, srvheads = res +if heads and not anyinc: +# server could be lying on the advertised heads +has_node = repo.changelog.hasnode +anyinc = any(not has_node(n) for n in heads) return (list(common), anyinc, heads or list(srvheads)) diff --git a/tests/test-infinitepush-ci.t b/tests/test-infinitepush-ci.t --- a/tests/test-infinitepush-ci.t +++ b/tests/test-infinitepush-ci.t @@ -249,12 +249,12 @@ XXX: we should show better message when $ hg pull -r b4e4bce660512ad3e71189e14588a70ac8e31fef pulling from ssh://user@dummy/repo searching for changes - no changes found adding changesets adding manifests adding file changes added 4 changesets with 4 changes to 4 files new changesets eaba929e866c:b4e4bce66051 + (run 'hg update' to get a working copy) $ hg glog o 5:b4e4bce66051 added e | public diff --git a/tests/test-infinitepush.t b/tests/test-infinitepush.t --- a/tests/test-infinitepush.t +++ b/tests/test-infinitepush.t @@ -165,3 +165,36 @@ Make sure phase on the client is public. (run 'hg heads .' to see heads, 'hg merge' to merge) $ hg log -r scratch/scratchontopofpublic -T '{phase}' draft (no-eol) + + + $ cd .. + +Try pulling explicite rev from a vanillia fresh clone + +(similar to something done with client3, but without the extension this time) + + $ hg clone ssh://user@dummy/repo client4 + requesting all changes + adding changesets + adding manifests + adding file changes + added 2 changesets with 2 changes to 2 files + new changesets 67145f466344:a79b6597f322 + updating to branch default + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + + $ cd client4 + $ cat << EOF >> .hg/hgrc + > [extensions] + > infinitepush=! + > EOF + $ hg pull -r `cat ../testpullbycommithash1` + pulling from ssh://user@dummy/repo + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files (+1 heads) + new changesets 33910bfe6ffe (1 drafts) + (run 'hg heads' to see heads, 'hg merge' to merge) + $ cd .. -- Pierre-Yves David ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel