diff --git a/tests/test-audit-path.t b/tests/test-audit-path.t --- a/tests/test-audit-path.t +++ b/tests/test-audit-path.t @@ -129,3 +129,104 @@ attack /tmp/test [255] $ cd .. + +Test symlink traversal on merge: +-------------------------------- + +#if symlink + +set up symlink hell + + $ mkdir merge-symlink-out + $ hg init merge-symlink + $ cd merge-symlink + $ touch base + $ hg commit -qAm base + $ ln -s ../merge-symlink-out a + $ hg commit -qAm 'symlink a -> ../merge-symlink-out' + $ hg up -q 0 + $ mkdir a + $ touch a/poisoned + $ hg commit -qAm 'file a/poisoned' + $ hg log -G -T '{rev}: {desc}\n' + @ 2: file a/poisoned + | + | o 1: symlink a -> ../merge-symlink-out + |/ + o 0: base + + +try trivial merge + + $ hg up -qC 1 + $ hg merge 2 + abort: path 'a/poisoned' traverses symbolic link 'a' + [255] + +try rebase onto other revision: cache of audited paths should be discarded, +and the rebase should fail (issue5628) + + $ hg up -qC 2 + $ hg rebase -s 2 -d 1 --config extensions.rebase= + rebasing 2:e73c21d6b244 "file a/poisoned" (tip) + saved backup bundle to * (glob) + $ ls ../merge-symlink-out + poisoned + + $ cd .. + +Test symlink traversal on update: +--------------------------------- + + $ mkdir update-symlink-out + $ hg init update-symlink + $ cd update-symlink + $ ln -s ../update-symlink-out a + $ hg commit -qAm 'symlink a -> ../update-symlink-out' + $ hg rm a + $ mkdir a && touch a/b + $ hg ci -qAm 'file a/b' a/b + $ hg up -qC 0 + $ hg rm a + $ mkdir a && touch a/c + $ hg ci -qAm 'rm a, file a/c' + $ hg log -G -T '{rev}: {desc}\n' + @ 2: rm a, file a/c + | + | o 1: file a/b + |/ + o 0: symlink a -> ../update-symlink-out + + +try linear update where symlink already exists: + + $ hg up -qC 0 + $ hg up 1 + abort: path 'a/b' traverses symbolic link 'a' + [255] + +try linear update including symlinked directory and its content: paths are +audited first by calculateupdates(), where no symlink is created so both +'a' and 'a/b' are taken as good paths. still applyupdates() should fail. + + $ hg up -qC null + $ hg up 1 + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ ls ../update-symlink-out + b + $ rm ../update-symlink-out/b + +try branch update replacing directory with symlink, and its content: the +path 'a' is audited as a directory first, which should be audited again as +a symlink. + + $ rm -f a + $ hg up -qC 2 + $ hg up 1 + 2 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ ls ../update-symlink-out + b + + $ cd .. + +#endif diff --git a/tests/test-commandserver.t b/tests/test-commandserver.t --- a/tests/test-commandserver.t +++ b/tests/test-commandserver.t @@ -908,3 +908,80 @@ cases. *** runcommand log 0 bar (bar) *** runcommand verify -q + + $ cd .. + +Test symlink traversal over cached audited paths: +------------------------------------------------- + +#if symlink + +set up symlink hell + + $ mkdir merge-symlink-out + $ hg init merge-symlink + $ cd merge-symlink + $ touch base + $ hg commit -qAm base + $ ln -s ../merge-symlink-out a + $ hg commit -qAm 'symlink a -> ../merge-symlink-out' + $ hg up -q 0 + $ mkdir a + $ touch a/poisoned + $ hg commit -qAm 'file a/poisoned' + $ hg log -G -T '{rev}: {desc}\n' + @ 2: file a/poisoned + | + | o 1: symlink a -> ../merge-symlink-out + |/ + o 0: base + + +try trivial merge after update: cache of audited paths should be discarded, +and the merge should fail (issue5628) + + $ hg up -q null + >>> from hgclient import readchannel, runcommand, check + >>> @check + ... def merge(server): + ... readchannel(server) + ... # audit a/poisoned as a good path + ... runcommand(server, ['up', '-qC', '2']) + ... runcommand(server, ['up', '-qC', '1']) + ... # here a is a symlink, so a/poisoned is bad + ... runcommand(server, ['merge', '2']) + *** runcommand up -qC 2 + *** runcommand up -qC 1 + *** runcommand merge 2 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ ls ../merge-symlink-out + poisoned + +cache of repo.auditor should be discarded, so matcher would never traverse +symlinks: + + $ hg up -qC 0 + $ touch ../merge-symlink-out/poisoned + >>> from hgclient import readchannel, runcommand, check + >>> @check + ... def files(server): + ... readchannel(server) + ... runcommand(server, ['up', '-qC', '2']) + ... # audit a/poisoned as a good path + ... runcommand(server, ['files', 'a/poisoned']) + ... runcommand(server, ['up', '-qC', '0']) + ... runcommand(server, ['up', '-qC', '1']) + ... # here 'a' is a symlink, so a/poisoned should be warned + ... runcommand(server, ['files', 'a/poisoned']) + *** runcommand up -qC 2 + *** runcommand files a/poisoned + a/poisoned + *** runcommand up -qC 0 + *** runcommand up -qC 1 + *** runcommand files a/poisoned + [1] + + $ cd .. + +#endif