[Updated] D11764: rhg: add support for narrow clones and sparse checkouts
aalekseyev (Arseniy Alekseyev)
phabricator at mercurial-scm.org
Mon Nov 29 17:40:31 UTC 2021
aalekseyev updated this revision to Diff 31195.
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D11764?vs=31080&id=31195
BRANCH
default
CHANGES SINCE LAST ACTION
https://phab.mercurial-scm.org/D11764/new/
REVISION DETAIL
https://phab.mercurial-scm.org/D11764
AFFECTED FILES
rust/hg-core/src/repo.rs
rust/hg-core/src/requirements.rs
rust/rhg/src/commands/files.rs
rust/rhg/src/commands/status.rs
rust/rhg/src/main.rs
tests/test-rhg-sparse-narrow.t
CHANGE DETAILS
diff --git a/tests/test-rhg-sparse-narrow.t b/tests/test-rhg-sparse-narrow.t
new file mode 100644
--- /dev/null
+++ b/tests/test-rhg-sparse-narrow.t
@@ -0,0 +1,120 @@
+#require rhg
+
+ $ NO_FALLBACK="env RHG_ON_UNSUPPORTED=abort"
+
+Rhg works well when sparse working copy is enabled.
+
+ $ cd "$TESTTMP"
+ $ hg init repo-sparse
+ $ cd repo-sparse
+ $ cat > .hg/hgrc <<EOF
+ > [extensions]
+ > sparse=
+ > EOF
+
+ $ echo a > show
+ $ echo x > hide
+ $ mkdir dir1 dir2
+ $ echo x > dir1/x
+ $ echo y > dir1/y
+ $ echo z > dir2/z
+
+ $ hg ci -Aqm 'initial'
+ $ hg debugsparse --include 'show'
+ $ ls -A
+ .hg
+ show
+
+ $ tip=$(hg log -r . --template '{node}')
+ $ $NO_FALLBACK rhg files -r "$tip"
+ dir1/x
+ dir1/y
+ dir2/z
+ hide
+ show
+ $ $NO_FALLBACK rhg files
+ show
+
+ $ $NO_FALLBACK rhg cat -r "$tip" hide
+ x
+
+ $ cd ..
+
+We support most things when narrow is enabled, too, with a couple of caveats.
+
+ $ . "$TESTDIR/narrow-library.sh"
+ $ real_hg=$RHG_FALLBACK_EXECUTABLE
+
+ $ cat >> $HGRCPATH <<EOF
+ > [extensions]
+ > narrow=
+ > EOF
+
+ $ hg clone --narrow ./repo-sparse repo-narrow --include dir1
+ requesting all changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 2 changes to 2 files
+ new changesets 6d714a4a2998
+ updating to branch default
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+ $ cd repo-narrow
+
+ $ $NO_FALLBACK rhg cat -r "$tip" dir1/x
+ x
+ $ "$real_hg" cat -r "$tip" dir1/x
+ x
+
+TODO: bad error message
+
+ $ $NO_FALLBACK rhg cat -r "$tip" hide
+ abort: invalid revision identifier: 6d714a4a2998cbfd0620db44da58b749f6565d63
+ [255]
+ $ "$real_hg" cat -r "$tip" hide
+ [1]
+
+A naive implementation of [rhg files] leaks the paths that are supposed to be
+hidden by narrow, so we just fall back to hg.
+
+ $ $NO_FALLBACK rhg files -r "$tip"
+ unsupported feature: rhg files -r <rev> is not supported in narrow clones
+ [252]
+ $ "$real_hg" files -r "$tip"
+ dir1/x
+ dir1/y
+
+Hg status needs to do some filtering based on narrow spec, so we don't
+support it in rhg for narrow clones yet.
+
+ $ mkdir dir2
+ $ touch dir2/q
+ $ "$real_hg" status
+ $ $NO_FALLBACK rhg --config rhg.status=true status
+ unsupported feature: rhg status is not supported for sparse checkouts or narrow clones yet
+ [252]
+
+Adding "orphaned" index files:
+
+ $ (cd ..; cp {repo-sparse,repo-narrow}/.hg/store/data/hide.i)
+ $ (cd ..; mkdir repo-narrow/.hg/store/data/dir2; cp {repo-sparse,repo-narrow}/.hg/store/data/dir2/z.i)
+ $ "$real_hg" verify
+ checking changesets
+ checking manifests
+ crosschecking files in changesets and manifests
+ checking files
+ checked 1 changesets with 2 changes to 2 files
+
+ $ "$real_hg" files -r "$tip"
+ dir1/x
+ dir1/y
+
+# TODO: even though [hg files] hides the orphaned dir2/z, [hg cat] still shows it.
+# rhg has the same issue, but at least it's not specific to rhg.
+# This is despite [hg verify] succeeding above.
+
+ $ $NO_FALLBACK rhg cat -r "$tip" dir2/z
+ z
+ $ "$real_hg" cat -r "$tip" dir2/z
+ z
diff --git a/rust/rhg/src/main.rs b/rust/rhg/src/main.rs
--- a/rust/rhg/src/main.rs
+++ b/rust/rhg/src/main.rs
@@ -588,7 +588,8 @@
}
}
-const SUPPORTED_EXTENSIONS: &[&[u8]] = &[b"blackbox", b"share"];
+const SUPPORTED_EXTENSIONS: &[&[u8]] =
+ &[b"blackbox", b"share", b"sparse", b"narrow"];
fn check_extensions(config: &Config) -> Result<(), CommandError> {
let enabled = config.get_section_keys(b"extensions");
diff --git a/rust/rhg/src/commands/status.rs b/rust/rhg/src/commands/status.rs
--- a/rust/rhg/src/commands/status.rs
+++ b/rust/rhg/src/commands/status.rs
@@ -174,6 +174,13 @@
};
let repo = invocation.repo?;
+
+ if repo.has_sparse() || repo.has_narrow() {
+ return Err(CommandError::unsupported(
+ "rhg status is not supported for sparse checkouts or narrow clones yet"
+ ));
+ }
+
let mut dmap = repo.dirstate_map_mut()?;
let options = StatusOptions {
diff --git a/rust/rhg/src/commands/files.rs b/rust/rhg/src/commands/files.rs
--- a/rust/rhg/src/commands/files.rs
+++ b/rust/rhg/src/commands/files.rs
@@ -39,10 +39,38 @@
let rev = invocation.subcommand_args.value_of("rev");
let repo = invocation.repo?;
+
+ // It seems better if this check is removed: this would correspond to
+ // automatically enabling the extension if the repo requires it.
+ // However we need this check to be in sync with vanilla hg so hg tests
+ // pass.
+ if repo.has_sparse()
+ && invocation.config.get(b"extensions", b"sparse").is_none()
+ {
+ return Err(CommandError::unsupported(
+ "repo is using sparse, but sparse extension is not enabled",
+ ));
+ }
+
if let Some(rev) = rev {
+ if repo.has_narrow() {
+ return Err(CommandError::unsupported(
+ "rhg files -r <rev> is not supported in narrow clones",
+ ));
+ }
let files = list_rev_tracked_files(repo, rev).map_err(|e| (e, rev))?;
display_files(invocation.ui, repo, files.iter())
} else {
+ // The dirstate always reflects the sparse narrowspec, so if
+ // we only have sparse without narrow all is fine.
+ // If we have narrow, then [hg files] needs to check if
+ // the store narrowspec is in sync with the one of the dirstate,
+ // so we can't support that without explicit code.
+ if repo.has_narrow() {
+ return Err(CommandError::unsupported(
+ "rhg files is not supported in narrow clones",
+ ));
+ }
let distate = Dirstate::new(repo)?;
let files = distate.tracked_files()?;
display_files(invocation.ui, repo, files)
diff --git a/rust/hg-core/src/requirements.rs b/rust/hg-core/src/requirements.rs
--- a/rust/hg-core/src/requirements.rs
+++ b/rust/hg-core/src/requirements.rs
@@ -88,6 +88,10 @@
// When it starts writing to the repository, it’ll need to either keep the
// persistent nodemap up to date or remove this entry:
NODEMAP_REQUIREMENT,
+ // Not all commands support `sparse` and `narrow`. The commands that do
+ // not should opt out by checking `has_sparse` and `has_narrow`.
+ SPARSE_REQUIREMENT,
+ NARROW_REQUIREMENT,
];
// Copied from mercurial/requirements.py:
diff --git a/rust/hg-core/src/repo.rs b/rust/hg-core/src/repo.rs
--- a/rust/hg-core/src/repo.rs
+++ b/rust/hg-core/src/repo.rs
@@ -248,6 +248,14 @@
.contains(requirements::DIRSTATE_V2_REQUIREMENT)
}
+ pub fn has_sparse(&self) -> bool {
+ self.requirements.contains(requirements::SPARSE_REQUIREMENT)
+ }
+
+ pub fn has_narrow(&self) -> bool {
+ self.requirements.contains(requirements::NARROW_REQUIREMENT)
+ }
+
fn dirstate_file_contents(&self) -> Result<Vec<u8>, HgError> {
Ok(self
.hg_vfs()
To: aalekseyev, #hg-reviewers, Alphare
Cc: Alphare, mercurial-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurial-scm.org/pipermail/mercurial-patches/attachments/20211129/963590cc/attachment-0002.html>
More information about the Mercurial-patches
mailing list