Mercurial > hg
view tests/test-subrepo.t @ 49087:bfc117647c71
rust-revlog: move check for nodemap requirement to caller
It's good for both making `Revlog` testable and reusable to have it
not depend on the higher-level `Repo` type. This patch is one step in
towards that. Additionally, this change in particular gives the
callers more control over when to use a nodemap.
Differential Revision: https://phab.mercurial-scm.org/D12546
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Tue, 12 Apr 2022 11:40:37 -0700 |
parents | 6b1049d71c3e |
children |
line wrap: on
line source
Let commit recurse into subrepos by default to match pre-2.0 behavior: $ echo "[ui]" >> $HGRCPATH $ echo "commitsubrepos = Yes" >> $HGRCPATH $ hg init t $ cd t first revision, no sub $ echo a > a $ hg ci -Am0 adding a add first sub $ echo s = s > .hgsub $ hg add .hgsub $ hg init s $ echo a > s/a Issue2232: committing a subrepo without .hgsub $ hg ci -mbad s abort: can't commit subrepos without .hgsub [255] $ hg -R s add s/a $ hg files -S .hgsub a s/a `hg files` respects ui.relative-paths BROKEN: shows subrepo paths relative to the subrepo $ hg files -S --config ui.relative-paths=no .hgsub a s/a $ hg -R s ci -Ams0 $ hg sum parent: 0:f7b1eb17ad24 tip 0 branch: default commit: 1 added, 1 subrepos update: (current) phases: 1 draft $ hg ci -m1 test handling .hgsubstate "added" explicitly. $ hg parents --template '{node}\n{files}\n' 7cf8cfea66e410e8e3336508dfeec07b3192de51 .hgsub .hgsubstate $ hg rollback -q $ hg add .hgsubstate $ hg ci -m1 $ hg parents --template '{node}\n{files}\n' 7cf8cfea66e410e8e3336508dfeec07b3192de51 .hgsub .hgsubstate Subrepopath which overlaps with filepath, does not change warnings in remove() $ mkdir snot $ touch snot/file $ hg remove -S snot/file not removing snot/file: file is untracked [1] $ hg cat snot/filenot snot/filenot: no such file in rev 7cf8cfea66e4 [1] $ rm -r snot Revert subrepo and test subrepo fileset keyword: $ echo b > s/a $ hg revert --dry-run "set:subrepo('glob:s*')" reverting subrepo s reverting s/a $ cat s/a b $ hg revert "set:subrepo('glob:s*')" reverting subrepo s reverting s/a $ cat s/a a $ rm s/a.orig Revert subrepo with no backup. The "reverting s/a" line is gone since we're really running 'hg update' in the subrepo: $ echo b > s/a $ hg revert --no-backup s reverting subrepo s Issue2022: update -C $ echo b > s/a $ hg sum parent: 1:7cf8cfea66e4 tip 1 branch: default commit: 1 subrepos update: (current) phases: 2 draft $ hg co -C 1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg sum parent: 1:7cf8cfea66e4 tip 1 branch: default commit: (clean) update: (current) phases: 2 draft commands that require a clean repo should respect subrepos $ echo b >> s/a $ hg backout tip abort: uncommitted changes in subrepository "s" [255] $ hg revert -C -R s s/a add sub sub $ echo ss = ss > s/.hgsub $ hg init s/ss $ echo a > s/ss/a $ hg -R s add s/.hgsub $ hg -R s/ss add s/ss/a $ hg sum parent: 1:7cf8cfea66e4 tip 1 branch: default commit: 1 subrepos update: (current) phases: 2 draft $ hg ci -m2 committing subrepository s committing subrepository s/ss $ hg sum parent: 2:df30734270ae tip 2 branch: default commit: (clean) update: (current) phases: 3 draft test handling .hgsubstate "modified" explicitly. $ hg parents --template '{node}\n{files}\n' df30734270ae757feb35e643b7018e818e78a9aa .hgsubstate $ hg rollback -q $ hg status -A .hgsubstate M .hgsubstate $ hg ci -m2 $ hg parents --template '{node}\n{files}\n' df30734270ae757feb35e643b7018e818e78a9aa .hgsubstate bump sub rev (and check it is ignored by ui.commitsubrepos) $ echo b > s/a $ hg -R s ci -ms1 $ hg --config ui.commitsubrepos=no ci -m3 leave sub dirty (and check ui.commitsubrepos=no aborts the commit) $ echo c > s/a $ hg --config ui.commitsubrepos=no ci -m4 abort: uncommitted changes in subrepository "s" (use --subrepos for recursive commit) [255] $ hg id f6affe3fbfaa+ tip $ hg -R s ci -mc $ hg id f6affe3fbfaa+ tip $ echo d > s/a $ hg ci -m4 committing subrepository s $ hg tip -R s changeset: 4:02dcf1d70411 tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: 4 check caching $ hg co 0 0 files updated, 0 files merged, 2 files removed, 0 files unresolved $ hg debugsub restore $ hg co 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg debugsub path s source s revision 02dcf1d704118aee3ee306ccfa1910850d5b05ef new branch for merge tests $ hg co 1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo t = t >> .hgsub $ hg init t $ echo t > t/t $ hg -R t add t adding t/t 5 $ hg ci -m5 # add sub committing subrepository t created new head $ echo t2 > t/t 6 $ hg st -R s $ hg ci -m6 # change sub committing subrepository t $ hg debugsub path s source s revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 path t source t revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad $ echo t3 > t/t 7 $ hg ci -m7 # change sub again for conflict test committing subrepository t $ hg rm .hgsub 8 $ hg ci -m8 # remove sub test handling .hgsubstate "removed" explicitly. $ hg parents --template '{node}\n{files}\n' 96615c1dad2dc8e3796d7332c77ce69156f7b78e .hgsub .hgsubstate $ hg rollback -q $ hg remove .hgsubstate $ hg ci -m8 $ hg parents --template '{node}\n{files}\n' 96615c1dad2dc8e3796d7332c77ce69156f7b78e .hgsub .hgsubstate merge tests $ hg co -C 3 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg merge 5 # test adding 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg debugsub path s source s revision fc627a69481fcbe5f1135069e8a3881c023e4cf5 path t source t revision 60ca1237c19474e7a3978b0dc1ca4e6f36d51382 $ hg ci -m9 created new head $ hg merge 6 --debug # test change resolving manifests branchmerge: True, force: False, partial: False ancestor: 1f14a2e2d3ec, local: f0d2028bf86d+, remote: 1831e14459c4 starting 4 threads for background file closing (?) .hgsubstate: versions differ -> m subrepo merge f0d2028bf86d+ 1831e14459c4 1f14a2e2d3ec subrepo t: other changed, get t:6747d179aa9a688023c4b0cad32e4c92bb7f34ad:hg getting subrepo t resolving manifests branchmerge: False, force: False, partial: False ancestor: 60ca1237c194, local: 60ca1237c194+, remote: 6747d179aa9a t: remote is newer -> g getting t 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg debugsub path s source s revision fc627a69481fcbe5f1135069e8a3881c023e4cf5 path t source t revision 6747d179aa9a688023c4b0cad32e4c92bb7f34ad $ echo conflict > t/t $ hg ci -m10 committing subrepository t $ HGMERGE=internal:merge hg merge --debug 7 # test conflict resolving manifests branchmerge: True, force: False, partial: False ancestor: 1831e14459c4, local: e45c8b14af55+, remote: f94576341bcf starting 4 threads for background file closing (?) .hgsubstate: versions differ -> m subrepo merge e45c8b14af55+ f94576341bcf 1831e14459c4 subrepo t: both sides changed subrepository t diverged (local revision: 20a0db6fbf6c, remote revision: 7af322bc1198) starting 4 threads for background file closing (?) you can (m)erge, keep (l)ocal [working copy] or keep (r)emote [merge rev]. what do you want to do? m merging subrepository "t" resolving manifests branchmerge: True, force: False, partial: False ancestor: 6747d179aa9a, local: 20a0db6fbf6c+, remote: 7af322bc1198 starting 4 threads for background file closing (?) preserving t for resolve of t t: versions differ -> m picked tool ':merge' for t (binary False symlink False changedelete False) merging t my t@20a0db6fbf6c+ other t@7af322bc1198 ancestor t@6747d179aa9a warning: conflicts while merging t! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon subrepo t: merge with t:7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4:hg 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) should conflict $ cat t/t <<<<<<< local: 20a0db6fbf6c - test: 10 conflict ======= t3 >>>>>>> other: 7af322bc1198 - test: 7 11: remove subrepo t $ hg co -C 5 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg revert -r 4 .hgsub # remove t $ hg ci -m11 created new head $ hg debugsub path s source s revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 local removed, remote changed, keep changed $ hg merge 6 remote [merge rev] changed subrepository t which local [working copy] removed use (c)hanged version or (d)elete? c 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) BROKEN: should include subrepo t $ hg debugsub path s source s revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 $ cat .hgsubstate e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s 6747d179aa9a688023c4b0cad32e4c92bb7f34ad t $ hg ci -m 'local removed, remote changed, keep changed' BROKEN: should include subrepo t $ hg debugsub path s source s revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 BROKEN: should include subrepo t $ cat .hgsubstate e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s $ cat t/t t2 local removed, remote changed, keep removed $ hg co -C 11 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg merge --config ui.interactive=true 6 <<EOF > d > EOF remote [merge rev] changed subrepository t which local [working copy] removed use (c)hanged version or (d)elete? d 0 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg debugsub path s source s revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 $ cat .hgsubstate e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s $ hg ci -m 'local removed, remote changed, keep removed' created new head $ hg debugsub path s source s revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 $ cat .hgsubstate e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s local changed, remote removed, keep changed $ hg co -C 6 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg merge 11 local [working copy] changed subrepository t which remote [merge rev] removed use (c)hanged version or (d)elete? c 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) BROKEN: should include subrepo t $ hg debugsub path s source s revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 BROKEN: should include subrepo t $ cat .hgsubstate e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s $ hg ci -m 'local changed, remote removed, keep changed' created new head BROKEN: should include subrepo t $ hg debugsub path s source s revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 BROKEN: should include subrepo t $ cat .hgsubstate e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s $ cat t/t t2 local changed, remote removed, keep removed $ hg co -C 6 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg merge --config ui.interactive=true 11 <<EOF > d > EOF local [working copy] changed subrepository t which remote [merge rev] removed use (c)hanged version or (d)elete? d 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg debugsub path s source s revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 $ cat .hgsubstate e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s $ hg ci -m 'local changed, remote removed, keep removed' created new head $ hg debugsub path s source s revision e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 $ cat .hgsubstate e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s clean up to avoid having to fix up the tests below $ hg co -C 10 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cat >> $HGRCPATH <<EOF > [extensions] > strip= > EOF $ hg strip -r 11:15 saved backup bundle to $TESTTMP/t/.hg/strip-backup/*-backup.hg (glob) clone $ cd .. $ hg clone t tc updating to branch default cloning subrepo s from $TESTTMP/t/s cloning subrepo s/ss from $TESTTMP/t/s/ss cloning subrepo t from $TESTTMP/t/t 3 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd tc $ hg debugsub path s source s revision fc627a69481fcbe5f1135069e8a3881c023e4cf5 path t source t revision 20a0db6fbf6c3d2836e6519a642ae929bfc67c0e $ cd .. clone with subrepo disabled (update should fail) $ hg clone t -U tc2 --config subrepos.allowed=false $ hg update -R tc2 --config subrepos.allowed=false abort: subrepos not enabled (see 'hg help config.subrepos' for details) [255] $ ls -A tc2 .hg .hgsub .hgsubstate a $ hg clone t tc3 --config subrepos.allowed=false updating to branch default abort: subrepos not enabled (see 'hg help config.subrepos' for details) [255] $ ls -A tc3 .hg .hgsub .hgsubstate a And again with just the hg type disabled $ hg clone t -U tc4 --config subrepos.hg:allowed=false $ hg update -R tc4 --config subrepos.hg:allowed=false abort: hg subrepos not allowed (see 'hg help config.subrepos' for details) [255] $ ls -A tc4 .hg .hgsub .hgsubstate a $ hg clone t tc5 --config subrepos.hg:allowed=false updating to branch default abort: hg subrepos not allowed (see 'hg help config.subrepos' for details) [255] $ ls -A tc5 .hg .hgsub .hgsubstate a push $ cd tc $ echo bah > t/t $ hg ci -m11 committing subrepository t $ hg push pushing to $TESTTMP/t no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss no changes made to subrepo s since last push to $TESTTMP/t/s pushing subrepo t to $TESTTMP/t/t searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files push -f $ echo bah > s/a $ hg ci -m12 committing subrepository s $ hg push pushing to $TESTTMP/t no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss pushing subrepo s to $TESTTMP/t/s searching for changes abort: push creates new remote head 12a213df6fa9 (in subrepository "s") (merge or see 'hg help push' for details about pushing new heads) [255] $ hg push -f pushing to $TESTTMP/t pushing subrepo s/ss to $TESTTMP/t/s/ss searching for changes no changes found pushing subrepo s to $TESTTMP/t/s searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) pushing subrepo t to $TESTTMP/t/t searching for changes no changes found searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files check that unmodified subrepos are not pushed $ hg clone . ../tcc updating to branch default cloning subrepo s from $TESTTMP/tc/s cloning subrepo s/ss from $TESTTMP/tc/s/ss cloning subrepo t from $TESTTMP/tc/t 3 files updated, 0 files merged, 0 files removed, 0 files unresolved the subrepos on the new clone have nothing to push to its source $ hg push -R ../tcc . pushing to . no changes made to subrepo s/ss since last push to s/ss no changes made to subrepo s since last push to s no changes made to subrepo t since last push to t searching for changes no changes found [1] the subrepos on the source do not have a clean store versus the clone target because they were never explicitly pushed to the source $ hg push ../tcc pushing to ../tcc pushing subrepo s/ss to ../tcc/s/ss searching for changes no changes found pushing subrepo s to ../tcc/s searching for changes no changes found pushing subrepo t to ../tcc/t searching for changes no changes found searching for changes no changes found [1] after push their stores become clean $ hg push ../tcc pushing to ../tcc no changes made to subrepo s/ss since last push to ../tcc/s/ss no changes made to subrepo s since last push to ../tcc/s no changes made to subrepo t since last push to ../tcc/t searching for changes no changes found [1] updating a subrepo to a different revision or changing its working directory does not make its store dirty $ hg -R s update '.^' 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg push pushing to $TESTTMP/t no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss no changes made to subrepo s since last push to $TESTTMP/t/s no changes made to subrepo t since last push to $TESTTMP/t/t searching for changes no changes found [1] $ echo foo >> s/a $ hg push pushing to $TESTTMP/t no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss no changes made to subrepo s since last push to $TESTTMP/t/s no changes made to subrepo t since last push to $TESTTMP/t/t searching for changes no changes found [1] $ hg -R s update -C tip 1 files updated, 0 files merged, 0 files removed, 0 files unresolved committing into a subrepo makes its store (but not its parent's store) dirty $ echo foo >> s/ss/a $ hg -R s/ss commit -m 'test dirty store detection' $ hg out -S -r `hg log -r tip -T "{node|short}"` comparing with $TESTTMP/t searching for changes no changes found comparing with $TESTTMP/t/s searching for changes no changes found comparing with $TESTTMP/t/s/ss searching for changes changeset: 1:79ea5566a333 tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: test dirty store detection comparing with $TESTTMP/t/t searching for changes no changes found $ hg push pushing to $TESTTMP/t pushing subrepo s/ss to $TESTTMP/t/s/ss searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files no changes made to subrepo s since last push to $TESTTMP/t/s no changes made to subrepo t since last push to $TESTTMP/t/t searching for changes no changes found [1] a subrepo store may be clean versus one repo but not versus another $ hg push pushing to $TESTTMP/t no changes made to subrepo s/ss since last push to $TESTTMP/t/s/ss no changes made to subrepo s since last push to $TESTTMP/t/s no changes made to subrepo t since last push to $TESTTMP/t/t searching for changes no changes found [1] $ hg push ../tcc pushing to ../tcc pushing subrepo s/ss to ../tcc/s/ss searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files no changes made to subrepo s since last push to ../tcc/s no changes made to subrepo t since last push to ../tcc/t searching for changes no changes found [1] update $ cd ../t $ hg up -C # discard our earlier merge 1 files updated, 0 files merged, 0 files removed, 0 files unresolved updated to "c373c8102e68: 12" 2 other heads for branch "default" $ echo blah > t/t $ hg ci -m13 committing subrepository t backout calls revert internally with minimal opts, which should not raise KeyError $ hg backout ".^" --no-commit 0 files updated, 0 files merged, 0 files removed, 0 files unresolved changeset c373c8102e68 backed out, don't forget to commit. $ hg up -C # discard changes 1 files updated, 0 files merged, 0 files removed, 0 files unresolved updated to "925c17564ef8: 13" 2 other heads for branch "default" pull $ cd ../tc $ hg pull pulling from $TESTTMP/t searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files new changesets 925c17564ef8 (run 'hg update' to get a working copy) should pull t $ hg incoming -S -r `hg log -r tip -T "{node|short}"` comparing with $TESTTMP/t no changes found comparing with $TESTTMP/t/s searching for changes no changes found comparing with $TESTTMP/t/s/ss searching for changes no changes found comparing with $TESTTMP/t/t searching for changes changeset: 5:52c0adc0515a tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: 13 $ hg up pulling subrepo t from $TESTTMP/t/t searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files new changesets 52c0adc0515a 0 files updated, 0 files merged, 0 files removed, 0 files unresolved updated to "925c17564ef8: 13" 2 other heads for branch "default" $ cat t/t blah bogus subrepo path aborts $ echo 'bogus=[boguspath' >> .hgsub $ hg ci -m 'bogus subrepo path' abort: missing ] in subrepository source [255] Issue1986: merge aborts when trying to merge a subrepo that shouldn't need merging # subrepo layout # # o 5 br # /| # o | 4 default # | | # | o 3 br # |/| # o | 2 default # | | # | o 1 br # |/ # o 0 default $ cd .. $ rm -rf sub $ hg init main $ cd main $ hg init s $ cd s $ echo a > a $ hg ci -Am1 adding a $ hg branch br marked working directory as branch br (branches are permanent and global, did you want a bookmark?) $ echo a >> a $ hg ci -m1 $ hg up default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo b > b $ hg ci -Am1 adding b $ hg up br 1 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg merge tip 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg ci -m1 $ hg up 2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo c > c $ hg ci -Am1 adding c $ hg up 3 1 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg merge 4 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg ci -m1 # main repo layout: # # * <-- try to merge default into br again # .`| # . o 5 br --> substate = 5 # . | # o | 4 default --> substate = 4 # | | # | o 3 br --> substate = 2 # |/| # o | 2 default --> substate = 2 # | | # | o 1 br --> substate = 3 # |/ # o 0 default --> substate = 2 $ cd .. $ echo 's = s' > .hgsub $ hg -R s up 2 1 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg ci -Am1 adding .hgsub $ hg branch br marked working directory as branch br (branches are permanent and global, did you want a bookmark?) $ echo b > b $ hg -R s up 3 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg ci -Am1 adding b $ hg up default 1 files updated, 0 files merged, 1 files removed, 0 files unresolved $ echo c > c $ hg ci -Am1 adding c $ hg up 1 2 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg merge 2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg ci -m1 $ hg up 2 1 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg -R s up 4 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo d > d $ hg ci -Am1 adding d $ hg up 3 2 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg -R s up 5 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo e > e $ hg ci -Am1 adding e $ hg up 5 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg merge 4 # try to merge default into br again subrepository s diverged (local revision: f8f13b33206e, remote revision: a3f9062a4f88) you can (m)erge, keep (l)ocal [working copy] or keep (r)emote [merge rev]. what do you want to do? m 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ cd .. test subrepo delete from .hgsubstate $ hg init testdelete $ mkdir testdelete/nested testdelete/nested2 $ hg init testdelete/nested $ hg init testdelete/nested2 $ echo test > testdelete/nested/foo $ echo test > testdelete/nested2/foo $ hg -R testdelete/nested add adding testdelete/nested/foo $ hg -R testdelete/nested2 add adding testdelete/nested2/foo $ hg -R testdelete/nested ci -m test $ hg -R testdelete/nested2 ci -m test $ echo nested = nested > testdelete/.hgsub $ echo nested2 = nested2 >> testdelete/.hgsub $ hg -R testdelete add adding testdelete/.hgsub $ hg -R testdelete ci -m "nested 1 & 2 added" $ echo nested = nested > testdelete/.hgsub $ hg -R testdelete ci -m "nested 2 deleted" $ cat testdelete/.hgsubstate bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested $ hg -R testdelete remove testdelete/.hgsub $ hg -R testdelete ci -m ".hgsub deleted" $ cat testdelete/.hgsubstate bdf5c9a3103743d900b12ae0db3ffdcfd7b0d878 nested test repository cloning $ mkdir mercurial mercurial2 $ hg init nested_absolute $ echo test > nested_absolute/foo $ hg -R nested_absolute add adding nested_absolute/foo $ hg -R nested_absolute ci -mtest $ cd mercurial $ hg init nested_relative $ echo test2 > nested_relative/foo2 $ hg -R nested_relative add adding nested_relative/foo2 $ hg -R nested_relative ci -mtest2 $ hg init main $ echo "nested_relative = ../nested_relative" > main/.hgsub $ echo "nested_absolute = `pwd`/nested_absolute" >> main/.hgsub $ hg -R main add adding main/.hgsub $ hg -R main ci -m "add subrepos" $ cd .. $ hg clone mercurial/main mercurial2/main updating to branch default 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cat mercurial2/main/nested_absolute/.hg/hgrc \ > mercurial2/main/nested_relative/.hg/hgrc [paths] default = $TESTTMP/mercurial/nested_absolute [paths] default = $TESTTMP/mercurial/nested_relative $ rm -rf mercurial mercurial2 Issue1977: multirepo push should fail if subrepo push fails $ hg init repo $ hg init repo/s $ echo a > repo/s/a $ hg -R repo/s ci -Am0 adding a $ echo s = s > repo/.hgsub $ hg -R repo ci -Am1 adding .hgsub $ hg clone repo repo2 updating to branch default cloning subrepo s from $TESTTMP/repo/s 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg -q -R repo2 pull -u $ echo 1 > repo2/s/a $ hg -R repo2/s ci -m2 $ hg -q -R repo2/s push $ hg -R repo2/s up -C 0 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo 2 > repo2/s/b $ hg -R repo2/s ci -m3 -A adding b created new head $ hg -R repo2 ci -m3 $ hg -q -R repo2 push abort: push creates new remote head cc505f09a8b2 (in subrepository "s") (merge or see 'hg help push' for details about pushing new heads) [255] $ hg -R repo update 0 files updated, 0 files merged, 0 files removed, 0 files unresolved test if untracked file is not overwritten (this tests also has a change to update .hgsubstate and merge it within the same second. It should mark is are modified , even if none of mode, size and timestamp of it isn't changed on the filesystem (see also issue4583)) $ echo issue3276_ok > repo/s/b $ hg -R repo2 push -f -q $ hg -R repo update b: untracked file differs abort: untracked files in working directory differ from files in requested revision (in subrepository "s") [255] $ cat repo/s/b issue3276_ok $ rm repo/s/b $ hg -R repo revert --all reverting repo/.hgsubstate reverting subrepo s $ hg -R repo update 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cat repo/s/b 2 $ rm -rf repo2 repo Issue1852 subrepos with relative paths always push/pull relative to default Prepare a repo with subrepo $ hg init issue1852a $ cd issue1852a $ hg init sub/repo $ echo test > sub/repo/foo $ hg -R sub/repo add sub/repo/foo $ echo sub/repo = sub/repo > .hgsub $ hg add .hgsub $ hg ci -mtest committing subrepository sub/repo $ echo test >> sub/repo/foo $ hg ci -mtest committing subrepository sub/repo $ hg cat sub/repo/foo test test $ hg cat sub/repo/foo -Tjson | sed 's|\\\\|/|g' [ { "data": "test\ntest\n", "path": "foo" } ] non-exact match: $ hg cat -T '{path|relpath}\n' 'glob:**' .hgsub .hgsubstate sub/repo/foo $ hg cat -T '{path|relpath}\n' 're:^sub' sub/repo/foo missing subrepos in working directory: $ mkdir -p tmp/sub/repo $ hg cat -r 0 --output tmp/%p_p sub/repo/foo $ cat tmp/sub/repo/foo_p test $ mv sub/repo sub_ $ hg cat sub/repo/baz skipping missing subrepository: sub/repo [1] $ rm -rf sub/repo $ mv sub_ sub/repo $ cd .. Create repo without default path, pull top repo, and see what happens on update $ hg init issue1852b $ hg -R issue1852b pull issue1852a pulling from issue1852a requesting all changes adding changesets adding manifests adding file changes added 2 changesets with 3 changes to 2 files new changesets 19487b456929:be5eb94e7215 (run 'hg update' to get a working copy) $ hg -R issue1852b update abort: default path for subrepository not found (in subrepository "sub/repo") [255] Ensure a full traceback, not just the SubrepoAbort part $ hg -R issue1852b update --traceback 2>&1 | grep 'raise error\.Abort' raise error.Abort(_(b"default path for subrepository not found")) Pull -u now doesn't help $ hg -R issue1852b pull -u issue1852a pulling from issue1852a searching for changes no changes found Try the same, but with pull -u $ hg init issue1852c $ hg -R issue1852c pull -r0 -u issue1852a pulling from issue1852a adding changesets adding manifests adding file changes added 1 changesets with 2 changes to 2 files new changesets 19487b456929 cloning subrepo sub/repo from issue1852a/sub/repo 2 files updated, 0 files merged, 0 files removed, 0 files unresolved Try to push from the other side $ hg -R issue1852a push `pwd`/issue1852c pushing to $TESTTMP/issue1852c pushing subrepo sub/repo to $TESTTMP/issue1852c/sub/repo searching for changes no changes found searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files Incoming and outgoing should not use the default path: $ hg clone -q issue1852a issue1852d $ hg -R issue1852d outgoing --subrepos issue1852c comparing with issue1852c searching for changes no changes found comparing with issue1852c/sub/repo searching for changes no changes found [1] $ hg -R issue1852d incoming --subrepos issue1852c comparing with issue1852c searching for changes no changes found comparing with issue1852c/sub/repo searching for changes no changes found [1] Check that merge of a new subrepo doesn't write the uncommitted state to .hgsubstate (issue4622) $ hg init issue1852a/addedsub $ echo zzz > issue1852a/addedsub/zz.txt $ hg -R issue1852a/addedsub ci -Aqm "initial ZZ" $ hg clone issue1852a/addedsub issue1852d/addedsub updating to branch default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo def > issue1852a/sub/repo/foo $ hg -R issue1852a ci -SAm 'tweaked subrepo' adding tmp/sub/repo/foo_p committing subrepository sub/repo $ echo 'addedsub = addedsub' >> issue1852d/.hgsub $ echo xyz > issue1852d/sub/repo/foo $ hg -R issue1852d pull -u pulling from $TESTTMP/issue1852a searching for changes adding changesets adding manifests adding file changes added 1 changesets with 2 changes to 2 files new changesets c82b79fdcc5b subrepository sub/repo diverged (local revision: f42d5c7504a8, remote revision: 46cd4aac504c) you can (m)erge, keep (l)ocal [working copy] or keep (r)emote [destination]. what do you want to do? m pulling subrepo sub/repo from $TESTTMP/issue1852a/sub/repo searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files new changesets 46cd4aac504c subrepository sources for sub/repo differ you can use (l)ocal source (f42d5c7504a8) or (r)emote source (46cd4aac504c). what do you want to do? l 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cat issue1852d/.hgsubstate f42d5c7504a811dda50f5cf3e5e16c3330b87172 sub/repo Check status of files when none of them belong to the first subrepository: $ hg init subrepo-status $ cd subrepo-status $ hg init subrepo-1 $ hg init subrepo-2 $ cd subrepo-2 $ touch file $ hg add file $ cd .. $ echo subrepo-1 = subrepo-1 > .hgsub $ echo subrepo-2 = subrepo-2 >> .hgsub $ hg add .hgsub $ hg ci -m 'Added subrepos' committing subrepository subrepo-2 $ hg st subrepo-2/file Check that share works with subrepo $ hg --config extensions.share= share . ../shared updating working directory sharing subrepo subrepo-1 from $TESTTMP/subrepo-status/subrepo-1 sharing subrepo subrepo-2 from $TESTTMP/subrepo-status/subrepo-2 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ find ../shared/* | sort ../shared/subrepo-1 ../shared/subrepo-1/.hg ../shared/subrepo-1/.hg/cache ../shared/subrepo-1/.hg/cache/storehash ../shared/subrepo-1/.hg/cache/storehash/* (glob) ../shared/subrepo-1/.hg/hgrc ../shared/subrepo-1/.hg/requires ../shared/subrepo-1/.hg/sharedpath ../shared/subrepo-1/.hg/wcache ../shared/subrepo-2 ../shared/subrepo-2/.hg ../shared/subrepo-2/.hg/branch ../shared/subrepo-2/.hg/cache ../shared/subrepo-2/.hg/cache/storehash ../shared/subrepo-2/.hg/cache/storehash/* (glob) ../shared/subrepo-2/.hg/dirstate ../shared/subrepo-2/.hg/hgrc ../shared/subrepo-2/.hg/requires ../shared/subrepo-2/.hg/sharedpath ../shared/subrepo-2/.hg/wcache ../shared/subrepo-2/.hg/wcache/checkisexec (execbit !) ../shared/subrepo-2/.hg/wcache/checklink (symlink no-rust !) ../shared/subrepo-2/.hg/wcache/checklink-target (symlink no-rust !) ../shared/subrepo-2/.hg/wcache/manifestfulltextcache (reporevlogstore !) ../shared/subrepo-2/file $ hg -R ../shared in abort: repository default not found [255] $ hg -R ../shared/subrepo-2 showconfig paths paths.default=$TESTTMP/subrepo-status/subrepo-2 $ hg -R ../shared/subrepo-1 sum --remote parent: -1:000000000000 tip (empty repository) branch: default commit: (clean) update: (current) remote: (synced) Check hg update --clean $ cd $TESTTMP/t $ rm -r t/t.orig $ hg status -S --all C .hgsub C .hgsubstate C a C s/.hgsub C s/.hgsubstate C s/a C s/ss/a C t/t $ echo c1 > s/a $ cd s $ echo c1 > b $ echo c1 > c $ hg add b $ cd .. $ hg status -S M s/a A s/b ? s/c $ hg update -C 1 files updated, 0 files merged, 0 files removed, 0 files unresolved updated to "925c17564ef8: 13" 2 other heads for branch "default" $ hg status -S ? s/b ? s/c Sticky subrepositories, no changes $ cd $TESTTMP/t $ hg id 925c17564ef8 tip $ hg -R s id 12a213df6fa9 tip $ hg -R t id 52c0adc0515a tip $ hg update 11 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg id 365661e5936a $ hg -R s id fc627a69481f $ hg -R t id e95bcfa18a35 Sticky subrepositories, file changes $ touch s/f1 $ touch t/f1 $ hg add -S s/f1 $ hg add -S t/f1 $ hg id 365661e5936a+ $ hg -R s id fc627a69481f+ $ hg -R t id e95bcfa18a35+ $ hg update tip subrepository s diverged (local revision: fc627a69481f, remote revision: 12a213df6fa9) you can (m)erge, keep (l)ocal [working copy] or keep (r)emote [destination]. what do you want to do? m subrepository sources for s differ you can use (l)ocal source (fc627a69481f) or (r)emote source (12a213df6fa9). what do you want to do? l subrepository t diverged (local revision: e95bcfa18a35, remote revision: 52c0adc0515a) you can (m)erge, keep (l)ocal [working copy] or keep (r)emote [destination]. what do you want to do? m subrepository sources for t differ you can use (l)ocal source (e95bcfa18a35) or (r)emote source (52c0adc0515a). what do you want to do? l 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg id 925c17564ef8+ tip $ hg -R s id fc627a69481f+ $ hg -R t id e95bcfa18a35+ $ hg update --clean tip 1 files updated, 0 files merged, 0 files removed, 0 files unresolved Sticky subrepository, revision updates $ hg id 925c17564ef8 tip $ hg -R s id 12a213df6fa9 tip $ hg -R t id 52c0adc0515a tip $ cd s $ hg update -r -2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd ../t $ hg update -r 2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd .. $ hg update 10 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f) you can (m)erge, keep (l)ocal [working copy] or keep (r)emote [destination]. what do you want to do? m subrepository t diverged (local revision: 52c0adc0515a, remote revision: 20a0db6fbf6c) you can (m)erge, keep (l)ocal [working copy] or keep (r)emote [destination]. what do you want to do? m subrepository sources for t differ (in checked out version) you can use (l)ocal source (7af322bc1198) or (r)emote source (20a0db6fbf6c). what do you want to do? l 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg id e45c8b14af55+ $ hg -R s id 02dcf1d70411 $ hg -R t id 7af322bc1198 Sticky subrepository, file changes and revision updates $ touch s/f1 $ touch t/f1 $ hg add -S s/f1 $ hg add -S t/f1 $ hg id e45c8b14af55+ $ hg -R s id 02dcf1d70411+ $ hg -R t id 7af322bc1198+ $ hg update tip subrepository s diverged (local revision: 12a213df6fa9, remote revision: 12a213df6fa9) you can (m)erge, keep (l)ocal [working copy] or keep (r)emote [destination]. what do you want to do? m subrepository sources for s differ you can use (l)ocal source (02dcf1d70411) or (r)emote source (12a213df6fa9). what do you want to do? l subrepository t diverged (local revision: 52c0adc0515a, remote revision: 52c0adc0515a) you can (m)erge, keep (l)ocal [working copy] or keep (r)emote [destination]. what do you want to do? m subrepository sources for t differ you can use (l)ocal source (7af322bc1198) or (r)emote source (52c0adc0515a). what do you want to do? l 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg id 925c17564ef8+ tip $ hg -R s id 02dcf1d70411+ $ hg -R t id 7af322bc1198+ Sticky repository, update --clean $ hg update --clean tip 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg id 925c17564ef8 tip $ hg -R s id 12a213df6fa9 tip $ hg -R t id 52c0adc0515a tip Test subrepo already at intended revision: $ cd s $ hg update fc627a69481f 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd .. $ hg update 11 subrepository s diverged (local revision: 12a213df6fa9, remote revision: fc627a69481f) you can (m)erge, keep (l)ocal [working copy] or keep (r)emote [destination]. what do you want to do? m 0 files updated, 0 files merged, 0 files removed, 0 files unresolved 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg id -n 11+ $ hg -R s id fc627a69481f $ hg -R t id e95bcfa18a35 Test that removing .hgsubstate doesn't break anything: $ hg rm -f .hgsubstate $ hg ci -mrm nothing changed [1] $ hg log -vr tip changeset: 13:925c17564ef8 tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 files: .hgsubstate description: 13 Test that removing .hgsub removes .hgsubstate: $ hg rm .hgsub $ hg ci -mrm2 created new head $ hg log -vr tip changeset: 14:2400bccd50af tag: tip parent: 11:365661e5936a user: test date: Thu Jan 01 00:00:00 1970 +0000 files: .hgsub .hgsubstate description: rm2 Test issue3153: diff -S with deleted subrepos $ hg diff --nodates -S -c . diff -r 365661e5936a -r 2400bccd50af .hgsub --- a/.hgsub +++ /dev/null @@ -1,2 +0,0 @@ -s = s -t = t diff -r 365661e5936a -r 2400bccd50af .hgsubstate --- a/.hgsubstate +++ /dev/null @@ -1,2 +0,0 @@ -fc627a69481fcbe5f1135069e8a3881c023e4cf5 s -e95bcfa18a358dc4936da981ebf4147b4cad1362 t Test behavior of add for explicit path in subrepo: $ cd .. $ hg init explicit $ cd explicit $ echo s = s > .hgsub $ hg add .hgsub $ hg init s $ hg ci -m0 Adding with an explicit path in a subrepo adds the file $ echo c1 > f1 $ echo c2 > s/f2 $ hg st -S ? f1 ? s/f2 $ hg add s/f2 $ hg st -S A s/f2 ? f1 $ hg ci -R s -m0 $ hg ci -Am1 adding f1 Adding with an explicit path in a subrepo with -S has the same behavior $ echo c3 > f3 $ echo c4 > s/f4 $ hg st -S ? f3 ? s/f4 $ hg add -S s/f4 $ hg st -S A s/f4 ? f3 $ hg ci -R s -m1 $ hg ci -Ama2 adding f3 Adding without a path or pattern silently ignores subrepos $ echo c5 > f5 $ echo c6 > s/f6 $ echo c7 > s/f7 $ hg st -S ? f5 ? s/f6 ? s/f7 $ hg add adding f5 $ hg st -S A f5 ? s/f6 ? s/f7 $ hg ci -R s -Am2 adding f6 adding f7 $ hg ci -m3 Adding without a path or pattern with -S also adds files in subrepos $ echo c8 > f8 $ echo c9 > s/f9 $ echo c10 > s/f10 $ hg st -S ? f8 ? s/f10 ? s/f9 $ hg add -S adding f8 adding s/f10 adding s/f9 $ hg st -S A f8 A s/f10 A s/f9 $ hg ci -R s -m3 $ hg ci -m4 Adding with a pattern silently ignores subrepos $ echo c11 > fm11 $ echo c12 > fn12 $ echo c13 > s/fm13 $ echo c14 > s/fn14 $ hg st -S ? fm11 ? fn12 ? s/fm13 ? s/fn14 $ hg add 'glob:**fm*' adding fm11 $ hg st -S A fm11 ? fn12 ? s/fm13 ? s/fn14 $ hg ci -R s -Am4 adding fm13 adding fn14 $ hg ci -Am5 adding fn12 Adding with a pattern with -S also adds matches in subrepos $ echo c15 > fm15 $ echo c16 > fn16 $ echo c17 > s/fm17 $ echo c18 > s/fn18 $ hg st -S ? fm15 ? fn16 ? s/fm17 ? s/fn18 $ hg add -S 'glob:**fm*' adding fm15 adding s/fm17 $ hg st -S A fm15 A s/fm17 ? fn16 ? s/fn18 $ hg ci -R s -Am5 adding fn18 $ hg ci -Am6 adding fn16 Test behavior of forget for explicit path in subrepo: Forgetting an explicit path in a subrepo untracks the file $ echo c19 > s/f19 $ hg add s/f19 $ hg st -S A s/f19 $ hg forget s/f19 $ hg st -S ? s/f19 $ rm s/f19 $ cd .. Courtesy phases synchronisation to publishing server does not block the push (issue3781) $ cp -R main issue3781 $ cp -R main issue3781-dest $ cd issue3781-dest/s $ hg phase tip # show we have draft changeset 5: draft $ chmod a-w .hg/store/phaseroots # prevent phase push $ cd ../../issue3781 $ cat >> .hg/hgrc << EOF > [paths] > default=../issue3781-dest/ > EOF $ hg push --config devel.legacy.exchange=bundle1 pushing to $TESTTMP/issue3781-dest pushing subrepo s to $TESTTMP/issue3781-dest/s searching for changes no changes found searching for changes no changes found [1] # clean the push cache $ rm s/.hg/cache/storehash/* $ hg push # bundle2+ pushing to $TESTTMP/issue3781-dest pushing subrepo s to $TESTTMP/issue3781-dest/s searching for changes no changes found searching for changes no changes found [1] $ cd .. Test phase choice for newly created commit with "phases.subrepochecks" configuration $ cd t $ hg update -q -r 12 $ cat >> s/ss/.hg/hgrc <<EOF > [phases] > new-commit = secret > EOF $ cat >> s/.hg/hgrc <<EOF > [phases] > new-commit = draft > EOF $ echo phasecheck1 >> s/ss/a $ hg -R s commit -S --config phases.checksubrepos=abort -m phasecheck1 committing subrepository ss transaction abort! rollback completed abort: can't commit in draft phase conflicting secret from subrepository ss [255] $ echo phasecheck2 >> s/ss/a $ hg -R s commit -S --config phases.checksubrepos=ignore -m phasecheck2 committing subrepository ss $ hg -R s/ss phase tip 3: secret $ hg -R s phase tip 6: draft $ echo phasecheck3 >> s/ss/a $ hg -R s commit -S -m phasecheck3 committing subrepository ss warning: changes are committed in secret phase from subrepository ss $ hg -R s/ss phase tip 4: secret $ hg -R s phase tip 7: secret $ cat >> t/.hg/hgrc <<EOF > [phases] > new-commit = draft > EOF $ cat >> .hg/hgrc <<EOF > [phases] > new-commit = public > EOF $ echo phasecheck4 >> s/ss/a $ echo phasecheck4 >> t/t $ hg commit -S -m phasecheck4 committing subrepository s committing subrepository s/ss warning: changes are committed in secret phase from subrepository ss committing subrepository t warning: changes are committed in secret phase from subrepository s created new head $ hg -R s/ss phase tip 5: secret $ hg -R s phase tip 8: secret $ hg -R t phase tip 6: draft $ hg phase tip 15: secret $ cd .. Test that commit --secret works on both repo and subrepo (issue4182) $ cd main $ echo secret >> b $ echo secret >> s/b $ hg commit --secret --subrepo -m "secret" committing subrepository s $ hg phase -r . 6: secret $ cd s $ hg phase -r . 6: secret $ cd ../../ Test "subrepos" template keyword $ cd t $ hg update -q 15 $ cat > .hgsub <<EOF > s = s > EOF $ hg commit -m "16" warning: changes are committed in secret phase from subrepository s (addition of ".hgsub" itself) $ hg diff --nodates -c 1 .hgsubstate diff -r f7b1eb17ad24 -r 7cf8cfea66e4 .hgsubstate --- /dev/null +++ b/.hgsubstate @@ -0,0 +1,1 @@ +e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s $ hg log -r 1 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}" f7b1eb17ad24 000000000000 s (modification of existing entry) $ hg diff --nodates -c 2 .hgsubstate diff -r 7cf8cfea66e4 -r df30734270ae .hgsubstate --- a/.hgsubstate +++ b/.hgsubstate @@ -1,1 +1,1 @@ -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s +dc73e2e6d2675eb2e41e33c205f4bdab4ea5111d s $ hg log -r 2 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}" 7cf8cfea66e4 000000000000 s (addition of entry) $ hg diff --nodates -c 5 .hgsubstate diff -r 7cf8cfea66e4 -r 1f14a2e2d3ec .hgsubstate --- a/.hgsubstate +++ b/.hgsubstate @@ -1,1 +1,2 @@ e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t $ hg log -r 5 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}" 7cf8cfea66e4 000000000000 t (removal of existing entry) $ hg diff --nodates -c 16 .hgsubstate diff -r 8bec38d2bd0b -r f2f70bc3d3c9 .hgsubstate --- a/.hgsubstate +++ b/.hgsubstate @@ -1,2 +1,1 @@ 0731af8ca9423976d3743119d0865097c07bdc1b s -e202dc79b04c88a636ea8913d9182a1346d9b3dc t $ hg log -r 16 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}" 8bec38d2bd0b 000000000000 t (merging) $ hg diff --nodates -c 9 .hgsubstate diff -r f6affe3fbfaa -r f0d2028bf86d .hgsubstate --- a/.hgsubstate +++ b/.hgsubstate @@ -1,1 +1,2 @@ fc627a69481fcbe5f1135069e8a3881c023e4cf5 s +60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t $ hg log -r 9 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}" f6affe3fbfaa 1f14a2e2d3ec t (removal of ".hgsub" itself) $ hg diff --nodates -c 8 .hgsubstate diff -r f94576341bcf -r 96615c1dad2d .hgsubstate --- a/.hgsubstate +++ /dev/null @@ -1,2 +0,0 @@ -e4ece1bf43360ddc8f6a96432201a37b7cd27ae4 s -7af322bc1198a32402fe903e0b7ebcfc5c9bf8f4 t $ hg log -r 8 --template "{p1node|short} {p2node|short}\n{subrepos % '{subrepo}\n'}" f94576341bcf 000000000000 Test that '[paths]' is configured correctly at subrepo creation $ cd $TESTTMP/tc $ cat > .hgsub <<EOF > # to clear bogus subrepo path 'bogus=[boguspath' > s = s > t = t > EOF $ hg update -q --clean null $ rm -rf s t $ cat >> .hg/hgrc <<EOF > [paths] > default-push = /foo/bar > EOF $ hg update -q $ cat s/.hg/hgrc [paths] default = $TESTTMP/t/s default-push = /foo/bar/s $ cat s/ss/.hg/hgrc [paths] default = $TESTTMP/t/s/ss default-push = /foo/bar/s/ss $ cat t/.hg/hgrc [paths] default = $TESTTMP/t/t default-push = /foo/bar/t $ cd $TESTTMP/t $ hg up -qC 0 $ echo 'bar' > bar.txt $ hg ci -Am 'branch before subrepo add' adding bar.txt created new head $ hg merge -r "first(subrepo('s'))" 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg status -S -X '.hgsub*' A s/a ? s/b ? s/c ? s/f1 $ hg status -S --rev 'p2()' A bar.txt ? s/b ? s/c ? s/f1 $ hg diff -S -X '.hgsub*' --nodates diff -r 000000000000 s/a --- /dev/null +++ b/s/a @@ -0,0 +1,1 @@ +a $ hg diff -S --rev 'p2()' --nodates diff -r 7cf8cfea66e4 bar.txt --- /dev/null +++ b/bar.txt @@ -0,0 +1,1 @@ +bar $ hg diff -X '.hgsub*' --nodates s diff -r 000000000000 s/a --- /dev/null +++ b/s/a @@ -0,0 +1,1 @@ +a $ hg diff -X '.hgsub*' --nodates s/a diff -r 000000000000 s/a --- /dev/null +++ b/s/a @@ -0,0 +1,1 @@ +a $ cd .. test for ssh exploit 2017-07-25 $ cat >> $HGRCPATH << EOF > [ui] > ssh = sh -c "read l; read l; read l" > EOF $ hg init malicious-proxycommand $ cd malicious-proxycommand $ echo 's = [hg]ssh://-oProxyCommand=touch${IFS}owned/path' > .hgsub $ hg init s $ cd s $ echo init > init $ hg add adding init $ hg commit -m init $ cd .. $ hg add .hgsub $ hg ci -m 'add subrepo' $ cd .. $ hg clone malicious-proxycommand malicious-proxycommand-clone updating to branch default cloning subrepo s from ssh://-oProxyCommand%3Dtouch%24%7BIFS%7Downed/path abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path' (in subrepository "s") [255] also check that a percent encoded '-' (%2D) doesn't work $ cd malicious-proxycommand $ echo 's = [hg]ssh://%2DoProxyCommand=touch${IFS}owned/path' > .hgsub $ hg ci -m 'change url to percent encoded' $ cd .. $ rm -r malicious-proxycommand-clone $ hg clone malicious-proxycommand malicious-proxycommand-clone updating to branch default cloning subrepo s from ssh://-oProxyCommand%3Dtouch%24%7BIFS%7Downed/path abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path' (in subrepository "s") [255] also check for a pipe $ cd malicious-proxycommand $ echo 's = [hg]ssh://fakehost|touch${IFS}owned/path' > .hgsub $ hg ci -m 'change url to pipe' $ cd .. $ rm -r malicious-proxycommand-clone $ hg clone malicious-proxycommand malicious-proxycommand-clone updating to branch default cloning subrepo s from ssh://fakehost%7Ctouch%24%7BIFS%7Downed/path abort: no suitable response from remote hg [255] $ [ ! -f owned ] || echo 'you got owned' also check that a percent encoded '|' (%7C) doesn't work $ cd malicious-proxycommand $ echo 's = [hg]ssh://fakehost%7Ctouch%20owned/path' > .hgsub $ hg ci -m 'change url to percent encoded pipe' $ cd .. $ rm -r malicious-proxycommand-clone $ hg clone malicious-proxycommand malicious-proxycommand-clone updating to branch default cloning subrepo s from ssh://fakehost%7Ctouch%20owned/path abort: no suitable response from remote hg [255] $ [ ! -f owned ] || echo 'you got owned' and bad usernames: $ cd malicious-proxycommand $ echo 's = [hg]ssh://-oProxyCommand=touch owned@example.com/path' > .hgsub $ hg ci -m 'owned username' $ cd .. $ rm -r malicious-proxycommand-clone $ hg clone malicious-proxycommand malicious-proxycommand-clone updating to branch default cloning subrepo s from ssh://-oProxyCommand%3Dtouch%20owned@example.com/path abort: potentially unsafe url: 'ssh://-oProxyCommand=touch owned@example.com/path' (in subrepository "s") [255] Test convert subrepositories including merge (issue5526): $ hg init tconv $ hg convert --config extensions.convert= -q t/s tconv/s $ hg convert --config extensions.convert= -q t/s/ss tconv/s/ss $ hg convert --config extensions.convert= -q t/t tconv/t convert shouldn't fail because of pseudo filenode: $ hg convert --config extensions.convert= t tconv scanning source... sorting... converting... 17 0 16 1 15 2 14 3 13 4 12 5 11 6 10 7 9 8 8 9 7 10 6 11 5 12 4 13 3 rm2 2 phasecheck4 1 16 0 branch before subrepo add converted .hgsubstate should point to valid nodes: $ hg up -R tconv 9 3 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cat tconv/.hgsubstate fc627a69481fcbe5f1135069e8a3881c023e4cf5 s 60ca1237c19474e7a3978b0dc1ca4e6f36d51382 t