Browse Source

Add porcelain.pack_objects.

Jelmer Vernooij 9 years ago
parent
commit
36d40a4d41
5 changed files with 51 additions and 0 deletions
  1. 2 0
      NEWS
  2. 22 0
      bin/dulwich
  3. 3 0
      dulwich/pack.py
  4. 23 0
      dulwich/porcelain.py
  5. 1 0
      dulwich/tests/test_object_store.py

+ 2 - 0
NEWS

@@ -16,6 +16,8 @@
     (Michael Edgar)
   * Add `Repo.discover` method. (B. M. Corser)
   * Add `dulwich.objectspec.parse_refspec`. (Jelmer Vernooij)
+  * Add `porcelain.pack_objects` and `porcelain.repack`.
+    (Jelmer Vernooij)
 
  BUG FIXES
 

+ 22 - 0
bin/dulwich

@@ -358,6 +358,27 @@ def cmd_ls_remote(args):
         sys.stdout.write("%s\t%s\n" % (ref, refs[ref]))
 
 
+def cmd_pack_objects(args):
+    opts, args = getopt(args, '', ['stdout'])
+    opts = dict(opts)
+    if len(args) < 1 and not '--stdout' in args:
+        print('Usage: dulwich pack-objects basename')
+        sys.exit(1)
+    object_ids = [l.strip() for l in sys.stdin.readlines()]
+    basename = args[0]
+    if '--stdout' in opts:
+        packf = getattr(sys.stdout, 'buffer', sys.stdout)
+        idxf = None
+        close = []
+    else:
+        packf = open(basename + '.pack', 'w')
+        idxf = open(basename + '.idx', 'w')
+        close = [packf, idxf]
+    porcelain.pack_objects('.', object_ids, packf, idxf)
+    for f in close:
+        f.close()
+
+
 commands = {
     "add": cmd_add,
     "archive": cmd_archive,
@@ -374,6 +395,7 @@ commands = {
     "init": cmd_init,
     "log": cmd_log,
     "ls-remote": cmd_ls_remote,
+    "pack-objects": cmd_pack_objects,
     "receive-pack": cmd_receive_pack,
     "repack": cmd_repack,
     "reset": cmd_reset,

+ 3 - 0
dulwich/pack.py

@@ -1794,6 +1794,9 @@ def write_pack_index_v2(f, entries, pack_checksum):
     return f.write_sha()
 
 
+write_pack_index = write_pack_index_v2
+
+
 class Pack(object):
     """A Git pack object."""
 

+ 23 - 0
dulwich/porcelain.py

@@ -75,6 +75,10 @@ from dulwich.objectspec import (
     parse_object,
     parse_reftuples,
     )
+from dulwich.pack import (
+    write_pack_index,
+    write_pack_objects,
+    )
 from dulwich.patch import write_tree_diff
 from dulwich.protocol import Protocol
 from dulwich.repo import (BaseRepo, Repo)
@@ -823,3 +827,22 @@ def repack(repo):
     """
     with open_repo_closing(repo) as r:
         r.object_store.pack_loose_objects()
+
+
+def pack_objects(repo, object_ids, packf, idxf, delta_window_size=None):
+    """Pack objects into a file.
+
+    :param repo: Path to the repository
+    :param object_ids: List of object ids to write
+    :param packf: File-like object to write to
+    :param idxf: File-like object to write to (can be None)
+    """
+    with open_repo_closing(repo) as r:
+        entries, data_sum = write_pack_objects(
+            packf,
+            r.object_store.iter_shas((oid, None) for oid in object_ids),
+            delta_window_size=delta_window_size)
+    if idxf is not None:
+        entries = [(k, v[0], v[1]) for (k, v) in entries.items()]
+        entries.sort()
+        write_pack_index(idxf, entries, data_sum)

+ 1 - 0
dulwich/tests/test_object_store.py

@@ -392,6 +392,7 @@ class TreeLookupPathTests(TestCase):
     def test_lookup_not_tree(self):
         self.assertRaises(NotTreeError, tree_lookup_path, self.get_object, self.tree_id, b'ad/b/j')
 
+
 class ObjectStoreGraphWalkerTests(TestCase):
 
     def get_walker(self, heads, parent_map):