浏览代码

Move checkout to index

Rename checkout to build_index_from_tree
Add index test
milki 13 年之前
父节点
当前提交
875f87bb61
共有 3 个文件被更改,包括 87 次插入44 次删除
  1. 33 0
      dulwich/index.py
  2. 4 44
      dulwich/repo.py
  3. 50 0
      dulwich/tests/test_index.py

+ 33 - 0
dulwich/index.py

@@ -387,3 +387,36 @@ def index_entry_from_stat(stat_val, hex_sha, flags, mode=None):
     return (stat_val.st_ctime, stat_val.st_mtime, stat_val.st_dev,
             stat_val.st_ino, mode, stat_val.st_uid,
             stat_val.st_gid, stat_val.st_size, hex_sha, flags)
+ 
+def build_index_from_tree(prefix, index_path, object_store, tree_id):
+    """Generate and materialize index from a tree
+
+    :param tree_id: Tree to materialize
+    :param prefix: Target dir for materialized index files
+    :param index_path: Target path for generated index
+    :param object_store: Non-empty object store holding tree contents
+
+    Note: existing index is wiped and contents are not merged
+    in a working dir. Suiteable only for fresh clones.
+    """
+
+    index = Index(index_path)
+
+    for entry in object_store.iter_tree_contents(tree_id):
+        full_path = os.path.join(prefix, entry.path)
+
+        if not os.path.exists( os.path.dirname(full_path) ):
+            os.makedirs(os.path.dirname(full_path))
+
+        # FIXME: Merge new index into working tree
+        with open(full_path, 'wb') as file:
+            # Write out file
+            file.write(object_store[entry.sha].as_raw_string()) 
+
+        os.chmod(full_path, entry.mode)
+
+        # Add file to index
+        st = os.stat(full_path)
+        index[entry.path] = index_entry_from_stat(st, entry.sha, 0)
+
+    index.write()

+ 4 - 44
dulwich/repo.py

@@ -1353,55 +1353,15 @@ class Repo(BaseRepo):
             target.refs.add_if_new(
                 'refs/heads/master',
                 self.refs['refs/heads/master'])
+
+            from dulwich.index import ( build_index_from_tree )
+            if not bare:
+                build_index_from_tree(target.path, target.index_path(), target.object_store, target['refs/heads/master'].tree);
         except KeyError:
             pass
 
-        target.checkout()
         return target
 
-    def checkout(self, branch='refs/heads/master'):
-        """Checkout a branch.
-
-        This current only supports checking out master on fresh clones.
-
-        :param branch: Branch to checkout
-        """
-
-        if self.bare:
-            raise # Cannot checkout in a bare repo
-
-        from dulwich.index import (
-                Index,
-                index_entry_from_stat
-                )
-        import stat
-
-        try:
-            index = self.open_index()
-            index.clear() # FIXME: When switching branches, merge working dir
-        except NoIndexPresent:
-            index = Index(self.index_path())
-
-        tree_id = self[branch].tree
-
-        # FIXME: When switching branches, merge working dir
-        for entry in self.object_store.iter_tree_contents(tree_id):
-            full_path = os.path.join(self.path, entry.path)
-
-            if not os.path.exists( os.path.dirname(full_path) ):
-                os.makedirs(os.path.dirname(full_path))
-
-            with open(full_path, 'wb') as file:
-                # Write out file
-                file.write(self.get_object(entry.sha).as_raw_string()) 
-                os.chmod(full_path, entry.mode)
-
-                # Add file to index
-                st = os.stat(full_path)
-                index[entry.path] = index_entry_from_stat(st, entry.sha, entry.mode)
-
-        index.write()
-
     def __repr__(self):
         return "<Repo at %r>" % self.path
 

+ 50 - 0
dulwich/tests/test_index.py

@@ -36,6 +36,7 @@ from dulwich.index import (
     read_index,
     write_cache_time,
     write_index,
+    build_index_from_tree,
     )
 from dulwich.object_store import (
     MemoryObjectStore,
@@ -44,6 +45,12 @@ from dulwich.objects import (
     Blob,
     )
 from dulwich.tests import TestCase
+from dulwich.repo import Repo
+from dulwich.tests.utils import (
+    open_repo,
+    tear_down_repo,
+)
+
 
 
 class IndexTestCase(TestCase):
@@ -208,3 +215,46 @@ class IndexEntryFromStatTests(TestCase):
             12288,
             '2222222222222222222222222222222222222222',
             0))
+
+
+class BuildIndexTests(TestCase):
+
+    def test_nonempty(self):
+        repo = open_repo('a.git')
+
+        target_repo_dir = tempfile.mkdtemp()
+        target_repo = Repo.init(target_repo_dir)
+
+        repo.fetch(target_repo)
+
+        target_repo.refs.add_if_new(
+                'refs/heads/master',
+                repo.refs['refs/heads/master'])
+
+        self.assertFalse(os.path.exists(target_repo.index_path()))
+        build_index_from_tree(target_repo.path, target_repo.index_path(),
+                target_repo.object_store, target_repo['refs/heads/master'].tree)
+        self.assertTrue(os.path.exists(target_repo.index_path()))
+ 
+        index = target_repo.open_index()
+
+        for entry in repo.object_store.iter_tree_contents(repo['refs/heads/master'].tree):
+            full_path = os.path.join(target_repo.path, entry.path)
+            self.assertTrue(os.path.exists(full_path))
+
+            st = os.stat(full_path)
+            f = open(full_path, 'rb')
+            blob = Blob()
+            try:
+                blob.data = f.read()
+            finally:
+                f.close()
+
+            index_entry = index_entry_from_stat(st, blob.id, 0)
+
+            index_entry_cmp = ((int(index_entry[0]),0), (int(index_entry[1]),0)) + (int(index_entry[2]),) + index_entry[3:]
+
+            self.assertEquals(index_entry_cmp, index[entry.path])
+
+        shutil.rmtree(target_repo.path)
+        tear_down_repo(repo)