Przeglądaj źródła

clarify interaction with new files and autocrlf=input

Peter Rowlands 4 lat temu
rodzic
commit
a019df7640
4 zmienionych plików z 24 dodań i 31 usunięć
  1. 1 3
      dulwich/index.py
  2. 18 23
      dulwich/line_ending.py
  3. 1 1
      dulwich/porcelain.py
  4. 4 4
      dulwich/tests/test_index.py

+ 1 - 3
dulwich/index.py

@@ -800,7 +800,7 @@ def _has_directory_changed(tree_path, entry):
     return False
 
 
-def get_unstaged_changes(index: Index, repo, filter_blob_callback=None):
+def get_unstaged_changes(index: Index, root_path, filter_blob_callback=None):
     """Walk through an index and check for differences against working tree.
 
     Args:
@@ -808,7 +808,6 @@ def get_unstaged_changes(index: Index, repo, filter_blob_callback=None):
       root_path: path in which to find files
     Returns: iterator over paths with unstaged changes
     """
-    root_path = repo.path
     # For each entry in the index check the sha1 & ensure not staged
     if not isinstance(root_path, bytes):
         root_path = os.fsencode(root_path)
@@ -828,7 +827,6 @@ def get_unstaged_changes(index: Index, repo, filter_blob_callback=None):
             blob = blob_from_path_and_stat(full_path, st)
 
             if filter_blob_callback is not None:
-                # Check if the file is already in the index
                 try:
                     index[tree_path]
                     new_file = False

+ 18 - 23
dulwich/line_ending.py

@@ -31,8 +31,14 @@ The normalization is a two-fold process that happens at two moments:
   when doing a `git add` call. We call this process the write filter in this
   module.
 
-The normalization only happens when the resulting file does not exists yet.
-For the write filter, they are files that are shown as added in status.
+Note that when checking status (getting unstaged changes), whether or not
+normalization is done on write depends on whether or not the file in the
+working dir has also been normalized on read:
+
+- For autocrlf=true all files are always normalized on both read and write.
+- For autocrlf=input files are only normalized once - whenever a new file is
+  added to the index. Since files which already exist in the index are
+  unmodified on read, they are also left unmodified upon subsequent writes.
 
 One thing to know is that Git does line-ending normalization only on text
 files. How does Git know that a file is text? We can either mark a file as a
@@ -234,33 +240,22 @@ class BlobNormalizer(object):
             core_eol, core_autocrlf, self.gitattributes
         )
 
-    def checkin_normalize(self, blob, tree_path, new_file=True):
-        """ Normalize a blob during a checkin operation
-
-        new_file is set to True by default for backward-compatibility
-        """
-        if not new_file:
-            # Line-ending normalization only happens for new files, aka files
-            # not already commited
-            return blob
-
-        if self.fallback_write_filter is not None:
+    def checkin_normalize(self, blob, tree_path, new_file=False):
+        """Normalize a blob during a checkin operation"""
+        # Existing files should only be normalized on checkin if it was
+        # previously normalized on checkout
+        if (
+            self.fallback_write_filter is not None
+            and (self.fallback_read_filter is not None or new_file)
+        ):
             return normalize_blob(
                 blob, self.fallback_write_filter, binary_detection=True
             )
 
         return blob
 
-    def checkout_normalize(self, blob, tree_path, new_file=True):
-        """ Normalize a blob during a checkout operation
-
-        new_file is set to True by default for backward-compatibility
-        """
-        if not new_file:
-            # Line-ending normalization only happens for new files, aka files
-            # not already commited
-            return blob
-
+    def checkout_normalize(self, blob, tree_path):
+        """Normalize a blob during a checkout operation"""
         if self.fallback_read_filter is not None:
             return normalize_blob(
                 blob, self.fallback_read_filter, binary_detection=True

+ 1 - 1
dulwich/porcelain.py

@@ -1214,7 +1214,7 @@ def status(repo=".", ignored=False):
         index = r.open_index()
         normalizer = r.get_blob_normalizer()
         filter_callback = normalizer.checkin_normalize
-        unstaged_changes = list(get_unstaged_changes(index, r, filter_callback))
+        unstaged_changes = list(get_unstaged_changes(index, r.path, filter_callback))
 
         untracked_paths = get_untracked_paths(
             r.path, r.path, index, exclude_ignored=not ignored

+ 4 - 4
dulwich/tests/test_index.py

@@ -720,7 +720,7 @@ class GetUnstagedChangesTests(TestCase):
             # modify access and modify time of path
             os.utime(foo1_fullpath, (0, 0))
 
-            changes = get_unstaged_changes(repo.open_index(), repo)
+            changes = get_unstaged_changes(repo.open_index(), repo_dir)
 
             self.assertEqual(list(changes), [b"foo1"])
 
@@ -745,7 +745,7 @@ class GetUnstagedChangesTests(TestCase):
 
             os.unlink(foo1_fullpath)
 
-            changes = get_unstaged_changes(repo.open_index(), repo)
+            changes = get_unstaged_changes(repo.open_index(), repo_dir)
 
             self.assertEqual(list(changes), [b"foo1"])
 
@@ -771,7 +771,7 @@ class GetUnstagedChangesTests(TestCase):
             os.remove(foo1_fullpath)
             os.mkdir(foo1_fullpath)
 
-            changes = get_unstaged_changes(repo.open_index(), repo)
+            changes = get_unstaged_changes(repo.open_index(), repo_dir)
 
             self.assertEqual(list(changes), [b"foo1"])
 
@@ -798,7 +798,7 @@ class GetUnstagedChangesTests(TestCase):
             os.remove(foo1_fullpath)
             os.symlink(os.path.dirname(foo1_fullpath), foo1_fullpath)
 
-            changes = get_unstaged_changes(repo.open_index(), repo)
+            changes = get_unstaged_changes(repo.open_index(), repo_dir)
 
             self.assertEqual(list(changes), [b"foo1"])