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

Move logic for creating blog from path to dulwich.index.

Jelmer Vernooij 11 жил өмнө
parent
commit
0706c4861c

+ 35 - 0
dulwich/index.py

@@ -26,6 +26,7 @@ import struct
 
 
 from dulwich.file import GitFile
 from dulwich.file import GitFile
 from dulwich.objects import (
 from dulwich.objects import (
+    Blob,
     S_IFGITLINK,
     S_IFGITLINK,
     S_ISGITLINK,
     S_ISGITLINK,
     Tree,
     Tree,
@@ -452,3 +453,37 @@ def build_index_from_tree(prefix, index_path, object_store, tree_id,
         index[entry.path] = index_entry_from_stat(st, entry.sha, 0)
         index[entry.path] = index_entry_from_stat(st, entry.sha, 0)
 
 
     index.write()
     index.write()
+
+
+def blob_from_path_and_stat(path, st):
+    """Create a blob from a path and a stat object.
+
+    :param path: Full path to file
+    :param st: A stat object
+    :return: A `Blob` object
+    """
+    blob = Blob()
+    if not stat.S_ISLNK(st.st_mode):
+        f = open(path, 'rb')
+        try:
+            blob.data = f.read()
+        finally:
+            f.close()
+    else:
+        blob.data = os.readlink(path)
+    return blob
+
+
+def get_unstaged_changes(index, path):
+    """Walk through an index and check for differences against working tree.
+
+    :param index: index to check
+    :param path: path in which to find files
+    :yields: paths with unstaged changes
+    """
+    # For each entry in the index check the sha1 & ensure not staged
+    for name, entry in index.iteritems():
+        fp = os.path.join(path, name)
+        blob = blob_from_path_and_stat(fp, os.lstat(fp))
+        if blob.id != entry[-2]:
+            yield name

+ 2 - 21
dulwich/porcelain.py

@@ -54,8 +54,8 @@ from dulwich.errors import (
     SendPackError,
     SendPackError,
     UpdateRefsError,
     UpdateRefsError,
     )
     )
+from dulwich.index import get_unstaged_changes
 from dulwich.objects import (
 from dulwich.objects import (
-    Blob,
     Tag,
     Tag,
     parse_timezone,
     parse_timezone,
     )
     )
@@ -505,7 +505,7 @@ def status(repo):
     # 1. Get status of staged
     # 1. Get status of staged
     tracked_changes = get_tree_changes(repo)
     tracked_changes = get_tree_changes(repo)
     # 2. Get status of unstaged
     # 2. Get status of unstaged
-    unstaged_changes = list(get_unstaged_changes(repo))
+    unstaged_changes = list(get_unstaged_changes(repo.open_index(), repo.path))
     # TODO - Status of untracked - add untracked changes, need gitignore.
     # TODO - Status of untracked - add untracked changes, need gitignore.
     untracked_changes = []
     untracked_changes = []
     return GitStatus(tracked_changes, unstaged_changes, untracked_changes)
     return GitStatus(tracked_changes, unstaged_changes, untracked_changes)
@@ -537,22 +537,3 @@ def get_tree_changes(repo):
         else:
         else:
             raise AssertionError('git mv ops not yet supported')
             raise AssertionError('git mv ops not yet supported')
     return tracked_changes
     return tracked_changes
-
-
-def get_unstaged_changes(repo):
-    """Walk through the index check for differences against working tree.
-
-    :param repo: repo path or object
-    :param tracked_changes: list of paths already staged
-    :yields: paths not staged
-    """
-    r = open_repo(repo)
-    index = r.open_index()
-
-    # For each entry in the index check the sha1 & ensure not staged
-    for entry in index.iteritems():
-        fp = os.path.join(r.path, entry[0])
-        with open(fp, 'rb') as f:
-            sha1 = Blob.from_string(f.read()).id
-        if sha1 != entry[1][-2]:
-            yield entry[0]

+ 5 - 11
dulwich/repo.py

@@ -742,13 +742,15 @@ class Repo(BaseRepo):
         """
         """
         if isinstance(paths, basestring):
         if isinstance(paths, basestring):
             paths = [paths]
             paths = [paths]
-        from dulwich.index import index_entry_from_stat
+        from dulwich.index import (
+            blob_from_path_and_stat,
+            index_entry_from_stat,
+            )
         index = self.open_index()
         index = self.open_index()
         for path in paths:
         for path in paths:
             full_path = os.path.join(self.path, path)
             full_path = os.path.join(self.path, path)
             try:
             try:
                 st = os.lstat(full_path)
                 st = os.lstat(full_path)
-                is_symbolic_link = stat.S_ISLNK(st.st_mode)
             except OSError:
             except OSError:
                 # File no longer exists
                 # File no longer exists
                 try:
                 try:
@@ -756,15 +758,7 @@ class Repo(BaseRepo):
                 except KeyError:
                 except KeyError:
                     pass  # already removed
                     pass  # already removed
             else:
             else:
-                blob = Blob()
-                if not is_symbolic_link:
-                    f = open(full_path, 'rb')
-                    try:
-                        blob.data = f.read()
-                    finally:
-                        f.close()
-                else:
-                    blob.data = os.readlink(full_path)
+                blob = blob_from_path_and_stat(full_path, st)
                 self.object_store.add_object(blob)
                 self.object_store.add_object(blob)
                 index[path] = index_entry_from_stat(st, blob.id, 0)
                 index[path] = index_entry_from_stat(st, blob.id, 0)
         index.write()
         index.write()

+ 36 - 3
dulwich/tests/test_index.py

@@ -31,6 +31,7 @@ from dulwich.index import (
     build_index_from_tree,
     build_index_from_tree,
     cleanup_mode,
     cleanup_mode,
     commit_tree,
     commit_tree,
+    get_unstaged_changes,
     index_entry_from_stat,
     index_entry_from_stat,
     read_index,
     read_index,
     write_cache_time,
     write_cache_time,
@@ -300,19 +301,51 @@ class BuildIndexTests(TestCase):
         # filed
         # filed
         dpath = os.path.join(repo.path, 'c', 'd')
         dpath = os.path.join(repo.path, 'c', 'd')
         self.assertTrue(os.path.exists(dpath))
         self.assertTrue(os.path.exists(dpath))
-        self.assertReasonableIndexEntry(index['c/d'], 
+        self.assertReasonableIndexEntry(index['c/d'],
             stat.S_IFREG | 0o644, 6, filed.id)
             stat.S_IFREG | 0o644, 6, filed.id)
         self.assertFileContents(dpath, 'file d')
         self.assertFileContents(dpath, 'file d')
 
 
         # symlink to d
         # symlink to d
         epath = os.path.join(repo.path, 'c', 'e')
         epath = os.path.join(repo.path, 'c', 'e')
         self.assertTrue(os.path.exists(epath))
         self.assertTrue(os.path.exists(epath))
-        self.assertReasonableIndexEntry(index['c/e'], 
+        self.assertReasonableIndexEntry(index['c/e'],
             stat.S_IFLNK, 1, filee.id)
             stat.S_IFLNK, 1, filee.id)
         self.assertFileContents(epath, 'd', symlink=True)
         self.assertFileContents(epath, 'd', symlink=True)
 
 
         # Verify no extra files
         # Verify no extra files
         self.assertEquals(['.git', 'a', 'b', 'c'],
         self.assertEquals(['.git', 'a', 'b', 'c'],
             sorted(os.listdir(repo.path)))
             sorted(os.listdir(repo.path)))
-        self.assertEquals(['d', 'e'], 
+        self.assertEquals(['d', 'e'],
             sorted(os.listdir(os.path.join(repo.path, 'c'))))
             sorted(os.listdir(os.path.join(repo.path, 'c'))))
+
+
+class BuildIndexTests(TestCase):
+
+    def test_get_unstaged_changes(self):
+        """Unit test for get_unstaged_changes."""
+
+        repo_dir = tempfile.mkdtemp()
+        repo = Repo.init(repo_dir)
+        self.addCleanup(shutil.rmtree, repo_dir)
+
+        # Commit a dummy file then modify it
+        foo1_fullpath = os.path.join(repo_dir, 'foo1')
+        with open(foo1_fullpath, 'w') as f:
+            f.write('origstuff')
+
+        foo2_fullpath = os.path.join(repo_dir, 'foo2')
+        with open(foo2_fullpath, 'w') as f:
+            f.write('origstuff')
+
+        repo.stage(['foo1', 'foo2'])
+        repo.do_commit('test status', author='', committer='')
+
+        with open(foo1_fullpath, 'w') as f:
+            f.write('newstuff')
+
+        # modify access and modify time of path
+        os.utime(foo1_fullpath, (0, 0))
+
+        changes = get_unstaged_changes(repo.open_index(), repo_dir)
+
+        self.assertEquals(list(changes), ['foo1'])

+ 0 - 26
dulwich/tests/test_porcelain.py

@@ -530,32 +530,6 @@ class StatusTests(PorcelainTestCase):
         self.assertEquals(results.staged['add'][0], filename_add)
         self.assertEquals(results.staged['add'][0], filename_add)
         self.assertEquals(results.unstaged, ['foo'])
         self.assertEquals(results.unstaged, ['foo'])
 
 
-    def test_get_unstaged_changes(self):
-        """Unit test for get_unstaged_changes."""
-
-        # Commit a dummy file then modify it
-        foo1_fullpath = os.path.join(self.repo.path, 'foo1')
-        with open(foo1_fullpath, 'w') as f:
-            f.write('origstuff')
-
-        foo2_fullpath = os.path.join(self.repo.path, 'foo2')
-        with open(foo2_fullpath, 'w') as f:
-            f.write('origstuff')
-
-        porcelain.add(repo=self.repo.path, paths=['foo1', 'foo2'])
-        porcelain.commit(repo=self.repo.path, message='test status',
-            author='', committer='')
-
-        with open(foo1_fullpath, 'w') as f:
-            f.write('newstuff')
-
-        # modify access and modify time of path
-        os.utime(foo1_fullpath, (0, 0))
-
-        changes = porcelain.get_unstaged_changes(self.repo.path)
-
-        self.assertEquals(list(changes), ['foo1'])
-
     def test_get_tree_changes_add(self):
     def test_get_tree_changes_add(self):
         """Unit test for get_tree_changes add."""
         """Unit test for get_tree_changes add."""