changeset 2115:fd77b7ee4aac

Fix issue 165: `hg status' with abs path containing a symlink-to-dir fails
author Jim Meyering <list+hg@meyering.net>
date Fri, 21 Apr 2006 16:09:43 -0700
parents 98cc126f9f3f
children 366e6328d10e 760339ccc799
files mercurial/util.py tests/test-symlinks tests/test-symlinks.out
diffstat 3 files changed, 43 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/util.py	Fri Apr 21 15:47:27 2006 -0700
+++ b/mercurial/util.py	Fri Apr 21 16:09:43 2006 -0700
@@ -215,6 +215,30 @@
     elif name == root:
         return ''
     else:
+        # Determine whether `name' is in the hierarchy at or beneath `root',
+        # by iterating name=dirname(name) until that causes no change (can't
+        # check name == '/', because that doesn't work on windows).  For each
+        # `name', compare dev/inode numbers.  If they match, the list `rel'
+        # holds the reversed list of components making up the relative file
+        # name we want.
+        root_st = os.stat(root)
+        rel = []
+        while True:
+            try:
+                name_st = os.stat(name)
+            except OSError:
+                break
+            if os.path.samestat(name_st, root_st):
+                rel.reverse()
+                name = os.path.join(*rel)
+                audit_path(name)
+                return pconvert(name)
+            dirname, basename = os.path.split(name)
+            rel.append(basename)
+            if dirname == name:
+                break
+            name = dirname
+
         raise Abort('%s not under root' % myname)
 
 def matcher(canonroot, cwd='', names=['.'], inc=[], exc=[], head='', src=None):
--- a/tests/test-symlinks	Fri Apr 21 15:47:27 2006 -0700
+++ b/tests/test-symlinks	Fri Apr 21 16:09:43 2006 -0700
@@ -40,3 +40,18 @@
 # it should show a.c, dir/a.o and dir/b.o deleted
 hg status
 hg status a.c
+
+echo '# test absolute path through symlink outside repo'
+cd ..
+p=`pwd`
+hg init x
+ln -s x y
+cd x
+touch f
+hg add f
+hg status $p/y/f
+
+echo '# try symlink outside repo to file inside'
+ln -s x/f ../z
+# this should fail
+hg status ../z && { echo hg mistakenly exited with status 0; exit 1; } || :
--- a/tests/test-symlinks.out	Fri Apr 21 15:47:27 2006 -0700
+++ b/tests/test-symlinks.out	Fri Apr 21 16:09:43 2006 -0700
@@ -9,3 +9,7 @@
 ? .hgignore
 a.c: unsupported file type (type is fifo)
 ! a.c
+# test absolute path through symlink outside repo
+A f
+# try symlink outside repo to file inside
+abort: ../z not under root