2
0
Эх сурвалжийг харах

Merge branch '842-ext-symlink' of git://github.com/pmrowla/dulwich

Jelmer Vernooij 4 жил өмнө
parent
commit
e2250e0dc3

+ 12 - 2
dulwich/porcelain.py

@@ -239,7 +239,8 @@ def path_to_tree_path(repopath, path, tree_encoding=DEFAULT_ENCODING):
         if sys.platform == "win32":
             path = os.path.abspath(path)
 
-        path = Path(path).resolve()
+        path = Path(path)
+        resolved_path = path.resolve()
 
         # Resolve and abspath seems to behave differently regarding symlinks,
         # as we are doing abspath on the file path, we need to do the same on
@@ -249,7 +250,16 @@ def path_to_tree_path(repopath, path, tree_encoding=DEFAULT_ENCODING):
 
         repopath = Path(repopath).resolve()
 
-        relpath = path.relative_to(repopath)
+        try:
+            relpath = resolved_path.relative_to(repopath)
+        except ValueError:
+            # If path is a symlink that points to a file outside the repo, we
+            # want the relpath for the link itself, not the resolved target
+            if path.is_symlink():
+                parent = path.parent.resolve()
+                relpath = (parent / path.name).relative_to(repopath)
+            else:
+                raise
         if sys.platform == "win32":
             return str(relpath).replace(os.path.sep, "/").encode(tree_encoding)
         else:

+ 7 - 3
dulwich/tests/test_porcelain.py

@@ -1633,8 +1633,12 @@ class StatusTests(PorcelainTestCase):
             f.write("blah\n")
         with open(os.path.join(self.repo.path, "notignored"), "w") as f:
             f.write("blah\n")
+        os.symlink(
+            os.path.join(self.repo.path, os.pardir, "external_target"),
+            os.path.join(self.repo.path, "link"),
+        )
         self.assertEqual(
-            set(["ignored", "notignored", ".gitignore"]),
+            set(["ignored", "notignored", ".gitignore", "link"]),
             set(
                 porcelain.get_untracked_paths(
                     self.repo.path, self.repo.path, self.repo.open_index()
@@ -1642,11 +1646,11 @@ class StatusTests(PorcelainTestCase):
             ),
         )
         self.assertEqual(
-            set([".gitignore", "notignored"]),
+            set([".gitignore", "notignored", "link"]),
             set(porcelain.status(self.repo).untracked),
         )
         self.assertEqual(
-            set([".gitignore", "notignored", "ignored"]),
+            set([".gitignore", "notignored", "ignored", "link"]),
             set(porcelain.status(self.repo, ignored=True).untracked),
         )