strip: do now include internal changeset in the strip backup
See inline comment for details.
--- a/mercurial/repair.py Wed Mar 08 11:00:30 2023 +0100
+++ b/mercurial/repair.py Fri Mar 10 07:10:19 2023 +0100
@@ -351,8 +351,14 @@
vfs = repo.vfs
unfi = repo.unfiltered()
to_node = unfi.changelog.node
+ # internal changeset are internal implementation details that should not
+ # leave the repository and not be exposed to the users. In addition feature
+ # using them requires to be resistant to strip. See test case for more
+ # details.
all_backup = unfi.revs(
- b"(%ln)::(%ld)", stripbases, unfi.changelog.headrevs()
+ b"(%ln)::(%ld) and not _internal()",
+ stripbases,
+ unfi.changelog.headrevs(),
)
if not all_backup:
return None
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-bundle-phase-internal.t Fri Mar 10 07:10:19 2023 +0100
@@ -0,0 +1,236 @@
+=====================================================
+test behavior of the `internal` phase around bundling
+=====================================================
+
+Long story short, internal changeset are internal implementation details and
+they should never leave the repository. Hence, they should never be in a
+bundle.
+
+Setup
+=====
+
+ $ cat << EOF >> $HGRCPATH
+ > [ui]
+ > logtemplate="{node|short} [{phase}] {desc|firstline}"
+ > EOF
+
+
+ $ hg init reference-repo --config format.use-internal-phase=yes
+ $ cd reference-repo
+ $ echo a > a
+ $ hg add a
+ $ hg commit -m "a"
+ $ echo b > b
+ $ hg add b
+ $ hg commit -m "b"
+ $ echo b > c
+ $ hg add c
+ $ hg commit -m "c"
+ $ hg log -G
+ @ 07f0cc02c068 [draft] c
+ |
+ o d2ae7f538514 [draft] b
+ |
+ o cb9a9f314b8b [draft] a
+
+ $ hg up ".^"
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+
+do a shelve
+
+ $ touch a_file.txt
+ $ hg shelve -A
+ adding a_file.txt
+ shelved as default
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ hg log -G --hidden
+ o 2ec3cf310d86 [internal] changes to: b
+ |
+ | o 07f0cc02c068 [draft] c
+ |/
+ @ d2ae7f538514 [draft] b
+ |
+ o cb9a9f314b8b [draft] a
+
+ $ shelved_node=`hg log --rev tip --hidden -T '{node|short}'`
+
+add more changeset above it
+
+ $ hg up 'desc(a)'
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ echo d > d
+ $ hg add d
+ $ hg commit -m "d"
+ created new head
+ $ echo d > e
+ $ hg add e
+ $ hg commit -m "e"
+ $ hg up null
+ 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
+ $ hg log -G
+ o 636bc07920e3 [draft] e
+ |
+ o 980f7dc84c29 [draft] d
+ |
+ | o 07f0cc02c068 [draft] c
+ | |
+ | o d2ae7f538514 [draft] b
+ |/
+ o cb9a9f314b8b [draft] a
+
+ $ hg log -G --hidden
+ o 636bc07920e3 [draft] e
+ |
+ o 980f7dc84c29 [draft] d
+ |
+ | o 2ec3cf310d86 [internal] changes to: b
+ | |
+ | | o 07f0cc02c068 [draft] c
+ | |/
+ | o d2ae7f538514 [draft] b
+ |/
+ o cb9a9f314b8b [draft] a
+
+ $ cd ..
+
+backup bundle from strip
+========================
+
+strip an ancestors of the internal changeset
+--------------------------------------------
+
+ $ cp -ar reference-repo strip-ancestor
+ $ cd strip-ancestor
+
+The internal change is stripped, yet it should be skipped from the backup bundle.
+
+ $ hg log -G
+ o 636bc07920e3 [draft] e
+ |
+ o 980f7dc84c29 [draft] d
+ |
+ | o 07f0cc02c068 [draft] c
+ | |
+ | o d2ae7f538514 [draft] b
+ |/
+ o cb9a9f314b8b [draft] a
+
+ $ hg debugstrip 'desc(b)'
+ saved backup bundle to $TESTTMP/strip-ancestor/.hg/strip-backup/d2ae7f538514-59bd8bc3-backup.hg
+
+The change should be either gone or hidden
+
+ $ hg log -G
+ o 636bc07920e3 [draft] e
+ |
+ o 980f7dc84c29 [draft] d
+ |
+ o cb9a9f314b8b [draft] a
+
+
+The backup should not include it (as people tend to manipulate these directly)
+
+ $ ls -1 .hg/strip-backup/
+ d2ae7f538514-59bd8bc3-backup.hg
+ $ hg debugbundle .hg/strip-backup/*.hg
+ Stream params: {Compression: BZ}
+ changegroup -- {nbchanges: 2, version: 03} (mandatory: True)
+ d2ae7f538514cd87c17547b0de4cea71fe1af9fb
+ 07f0cc02c06869c81ebf33867edef30554020c0d
+ cache:rev-branch-cache -- {} (mandatory: False)
+ phase-heads -- {} (mandatory: True)
+ 07f0cc02c06869c81ebf33867edef30554020c0d draft
+
+Shelve should still work
+
+ $ hg unshelve
+ unshelving change 'default'
+ rebasing shelved changes
+ $ hg status
+ A a_file.txt
+
+ $ cd ..
+
+strip an unrelated changeset with a lower revnum
+------------------------------------------------
+
+ $ cp -ar reference-repo strip-unrelated
+ $ cd strip-unrelated
+
+The internal change is not directly stripped, but it is affected by the strip
+and it is in the "temporary backup" zone. The zone that needs to be put in a
+temporary bundle while we affect data under it.
+
+ $ hg debugstrip 'desc(c)'
+ saved backup bundle to $TESTTMP/strip-unrelated/.hg/strip-backup/07f0cc02c068-8fd0515f-backup.hg
+
+The change should be either gone or hidden
+
+ $ hg log -G
+ o 636bc07920e3 [draft] e
+ |
+ o 980f7dc84c29 [draft] d
+ |
+ | o d2ae7f538514 [draft] b
+ |/
+ o cb9a9f314b8b [draft] a
+
+The backup should not include it (as people tend to manipulate these directly)
+
+ $ ls -1 .hg/strip-backup/
+ 07f0cc02c068-8fd0515f-backup.hg
+ $ hg debugbundle .hg/strip-backup/*.hg
+ Stream params: {Compression: BZ}
+ changegroup -- {nbchanges: 1, version: 03} (mandatory: True)
+ 07f0cc02c06869c81ebf33867edef30554020c0d
+ cache:rev-branch-cache -- {} (mandatory: False)
+ phase-heads -- {} (mandatory: True)
+ 07f0cc02c06869c81ebf33867edef30554020c0d draft
+
+Shelve should still work
+
+ $ hg unshelve
+ unshelving change 'default'
+ rebasing shelved changes
+ $ hg status
+ A a_file.txt
+
+ $ cd ..
+
+explicitly strip the internal changeset
+---------------------------------------
+
+ $ cp -ar reference-repo strip-explicit
+ $ cd strip-explicit
+
+The internal change is directly selected for stripping.
+
+ $ hg debugstrip --hidden $shelved_node
+
+The change should be gone
+
+ $ hg log -G --hidden
+ o 636bc07920e3 [draft] e
+ |
+ o 980f7dc84c29 [draft] d
+ |
+ | o 07f0cc02c068 [draft] c
+ | |
+ | o d2ae7f538514 [draft] b
+ |/
+ o cb9a9f314b8b [draft] a
+
+
+We don't need to backup anything
+
+ $ ls -1 .hg/strip-backup/
+
+Shelve should still work
+
+ $ hg unshelve
+ unshelving change 'default'
+ rebasing shelved changes
+ $ hg status
+ A a_file.txt
+
+ $ cd ..