From aa580a47d812cb399cb43d42868b0ba2acfa4465 Mon Sep 17 00:00:00 2001 From: Muir Manders Date: Thu, 12 May 2022 16:52:14 -0700 Subject: [PATCH] nativeclone: support non-eden working copies Summary: Hook the Rust clone code in to the working copy init. I tweaked the arg checking to not require "--noupdate". As you can see in test-hgrc.t, we no longer use a user friendly template when writing the repo's .hg/hgrc. Also visible in test-hgrc.t, I this fixes a regression in the handling of "%" in repo URLs. Reviewed By: quark-zju Differential Revision: D35985475 fbshipit-source-id: d10a9589fb941d9fc0888ad0aba1f4e11ba47794 --- eden/scm/lib/hgcommands/src/commands/clone.rs | 63 ++++++++++++------- eden/scm/tests/test-hgrc.t | 17 +---- eden/scm/tests/test-offline-commit.t | 2 +- eden/scm/tests/test-rust-clone.t | 15 ----- 4 files changed, 46 insertions(+), 51 deletions(-) diff --git a/eden/scm/lib/hgcommands/src/commands/clone.rs b/eden/scm/lib/hgcommands/src/commands/clone.rs index 26c9b150ac..759e7eb41b 100644 --- a/eden/scm/lib/hgcommands/src/commands/clone.rs +++ b/eden/scm/lib/hgcommands/src/commands/clone.rs @@ -6,6 +6,7 @@ */ use std::fs; +use std::io::Write; use std::path::Path; use std::path::PathBuf; @@ -16,6 +17,7 @@ use cliparser::define_flags; use edenapi::Builder; use repo::constants::HG_PATH; use repo::repo::Repo; +use types::HgId; use super::ConfigSet; use super::Result; @@ -50,7 +52,7 @@ define_flags! { git: bool, /// enable a sparse profile - enable_profile: String, + enable_profile: Option, /// files to include in a sparse profile include: String, @@ -69,21 +71,19 @@ define_flags! { pub fn run( mut clone_opts: CloneOpts, global_opts: HgGlobalOpts, - _io: &IO, + io: &IO, mut config: ConfigSet, ) -> Result { if !config.get_or_default::("clone", "use-rust")? { return Err(errors::FallbackToPython.into()); } - if !clone_opts.noupdate - || !clone_opts.updaterev.is_empty() + if !clone_opts.updaterev.is_empty() || !clone_opts.rev.is_empty() || clone_opts.pull || clone_opts.stream || !clone_opts.shallow || clone_opts.git - || !clone_opts.enable_profile.is_empty() || !clone_opts.include.is_empty() || !clone_opts.exclude.is_empty() { @@ -109,7 +109,6 @@ pub fn run( return Err(errors::FallbackToPython.into()); } - let source = clone_opts.source; // This gets the reponame from the --configfile config. // TODO: Parse the reponame from the source so the configfile isn't needed let reponame = match config.get_opt::("remotefilelog", "reponame")? { @@ -138,25 +137,33 @@ pub fn run( ); } - if let Err(e) = clone_metadata(global_opts, config, source, &destination) { - let removal_dir = if dest_preexists { - destination.join(HG_PATH) - } else { - destination - }; - fs::remove_dir_all(removal_dir)?; - return Err(e); + match clone_metadata(io, &clone_opts, global_opts, config, &destination) { + Ok((mut repo, target)) => { + if let Some(target) = target { + clone::init_working_copy(&mut repo, target, clone_opts.enable_profile.clone())?; + } + } + Err(e) => { + let removal_dir = if dest_preexists { + destination.join(HG_PATH) + } else { + destination + }; + fs::remove_dir_all(removal_dir)?; + return Err(e); + } } Ok(0) } fn clone_metadata( + io: &IO, + clone_opts: &CloneOpts, global_opts: HgGlobalOpts, mut config: ConfigSet, - source: String, destination: &Path, -) -> Result { +) -> Result<(Repo, Option)> { tracing::trace!("performing rust clone"); tracing::debug!(target: "rust_clone", rust_clone="true"); @@ -165,7 +172,7 @@ fn clone_metadata( .into_iter() .map(|file| format!("%include {}\n", file)) .collect::(); - hgrc_content.push_str(format!("\n[paths]\ndefault = {}\n", source).as_str()); + hgrc_content.push_str(format!("\n[paths]\ndefault = {}\n", clone_opts.source).as_str()); let mut repo = Repo::init(&destination, &mut config, Some(hgrc_content))?; @@ -178,7 +185,7 @@ fn clone_metadata( let commits = repo.dag_commits()?; let config = repo.config(); - let bookmarks: Vec = match config.get_opt("remotenames", "selectivepulldefault")? { + let bookmark_names: Vec = match config.get_opt("remotenames", "selectivepulldefault")? { Some(bms) => bms, None => { return Err( @@ -188,18 +195,32 @@ fn clone_metadata( }; tracing::trace!("fetching lazy commit data and bookmarks"); - exchange::clone( + let bookmark_ids = exchange::clone( edenapi, &mut metalog.write(), &mut commits.write(), - bookmarks, + bookmark_names.clone(), )?; ::fail::fail_point!("run::clone", |_| { Err(errors::Abort("Injected clone failure".to_string().into()).into()) }); - Ok(0) + if !clone_opts.noupdate { + if let Some(default_bm) = bookmark_names.first() { + if let Some(target) = bookmark_ids.get(default_bm) { + return Ok((repo, Some(target.clone()))); + } else if !global_opts.quiet { + write!( + io.error(), + "Server has no '{}' bookmark - skipping checkout.\n", + default_bm + )?; + } + } + } + + Ok((repo, None)) } pub fn name() -> &'static str { diff --git a/eden/scm/tests/test-hgrc.t b/eden/scm/tests/test-hgrc.t index 5aebcf09d6..b639a50767 100644 --- a/eden/scm/tests/test-hgrc.t +++ b/eden/scm/tests/test-hgrc.t @@ -35,24 +35,13 @@ Issue1199: Can't use '%' in hgrc (eg url encoded username) $ newclientrepo "foo%bar" $ newclientrepo foobar test:foo%bar_server $ cat .hg/hgrc - # example repository config (see 'hg help config' for more info) + [paths] - default = test:foo%EF%BF%BDr_server - - # path aliases to other clones of this repo in URLs or filesystem paths - # (see 'hg help config.paths' for more info) - # - # default:pushurl = ssh://jdoe@example.net/hg/jdoes-fork - # my-fork = ssh://jdoe@example.net/hg/jdoes-fork - # my-clone = /home/jdoe/jdoes-clone - - [ui] - # name and email (local to this repository, optional), e.g. - # username = Jane Doe + default = test:foo%bar_server $ hg paths default = test:foo%EF%BF%BDr_server $ hg showconfig paths - paths.default=test:foo%EF%BF%BDr_server + paths.default=test:foo%bar_server $ hg showconfig bundle bundle.mainreporoot=$TESTTMP/foobar $ cd .. diff --git a/eden/scm/tests/test-offline-commit.t b/eden/scm/tests/test-offline-commit.t index 5fda744571..6b59f4fc76 100644 --- a/eden/scm/tests/test-offline-commit.t +++ b/eden/scm/tests/test-offline-commit.t @@ -30,7 +30,7 @@ Commit and edit on top of B: DEBUG dag::protocol: resolve names [112478962961147124edd43549aedd1a335e44bf] remotely DEBUG dag::protocol: resolve ids [2] remotely DEBUG checkout::prefetch: children of 112478962961147124edd43549aedd1a335e44bf: ['26805aba1e600a82e93661149f2313866a221a7b'] - DEBUG dag::protocol: resolve ids [0] remotely + DEBUG dag::protocol: resolve ids [3] remotely $ touch B1 $ LOG=dag::protocol=debug hg commit -Am B1 B1 diff --git a/eden/scm/tests/test-rust-clone.t b/eden/scm/tests/test-rust-clone.t index 5a19b090f4..f272330bd5 100644 --- a/eden/scm/tests/test-rust-clone.t +++ b/eden/scm/tests/test-rust-clone.t @@ -29,15 +29,6 @@ test rust clone Test that nonsupported options fallback to python: - $ cd $TESTTMP - $ hg clone test:e1 $TESTTMP/update-clone - fetching lazy changelog - populating main commit graph - tip commit: 9bc730a19041f9ec7cb33c626e811aa233efb18c - fetching selected remote bookmarks - updating to branch default - 5 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cd $TESTTMP $ hg clone -U -r $D test:e1 $TESTTMP/rev-clone fetching lazy changelog @@ -48,12 +39,6 @@ Test that nonsupported options fallback to python: $ git init -q git-source $ hg clone --git "$TESTTMP/git-source" $TESTTMP/git-clone - $ hg clone -U --enable-profile test_profile test:e1 $TESTTMP/sparse-clone --config extensions.sparse= - fetching lazy changelog - populating main commit graph - tip commit: 9bc730a19041f9ec7cb33c626e811aa233efb18c - fetching selected remote bookmarks - Test rust clone $ hg clone -U test:e1 $TESTTMP/rust-clone --config remotenames.selectivepulldefault='master, stable' TRACE hgcommands::commands::clone: performing rust clone