]> arthur.barton.de Git - bup.git/commitdiff
Make bup-split commits appear as files to the vfs layer.
authorYung-Chin Oei <yungchin@yungchin.nl>
Mon, 8 Oct 2012 14:08:34 +0000 (15:08 +0100)
committerRob Browning <rlb@defaultvalue.org>
Sun, 6 Apr 2014 20:16:35 +0000 (15:16 -0500)
When viewing branches that were generated by bup-split through bup-fuse
(or any other frontend relying on vfs.py), these are presented as trees
of the hashsplitted blobs. This means that bup-split output is only
usefully accessible through bup-join.

This change makes bup-split store named commits such that they appear as
files, named with the last component of their branch name(*). That is,
from the vfs layer, they now appear like so:
    branch_name/latest/branch_basename

(*) While bup doesn't currently handle slashes in branch names, patches
    to this end are on the mailing list, so this patch should handle
    them, in anticipation of their general support in bup.

To address potential concerns: the storage format is changed in subtle
ways, in that the top level tree now contains a "normally" named object,
rather than byte-offset names.  However, bup-join doesn't care about
this, and as bup-join was previously the only way to use these commits,
the user experience is not affected.

We also add a test for the new functionality. (The test uses an empty
string as input data, because this is the second way in which this patch
changes the behaviour of bup-split: previously, passing empty strings to
bup-split would make it generate an empty git tree, whereas now it
relies on hashsplit.split_to_blob_or_tree() to make a blob for the empty
string. This is meaningful because vfs.py chokes on empty git trees.)

Signed-off-by: Yung-Chin Oei <yungchin@yungchin.nl>
[rlb@defaultvalue.org: rebase to current master; adjust code indentation.]

cmd/split-cmd.py
lib/bup/hashsplit.py
t/test.sh

index 9cb35441e591b1e9c8a1571988cdd1bd42e08b4e..2ab4d2b2b76b3f83edc22054aa93e3b0322c081e 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env python
-import sys, time
+import os, sys, time
 from bup import hashsplit, git, options, client
 from bup.helpers import *
 
@@ -137,11 +137,20 @@ if pack_writer and opt.blobs:
         print sha.encode('hex')
         reprogress()
 elif pack_writer:  # tree or commit or name
-    shalist = hashsplit.split_to_shalist(pack_writer.new_blob,
-                                         pack_writer.new_tree,
-                                         files,
-                                         keep_boundaries=opt.keep_boundaries,
-                                         progress=prog)
+    if opt.name: # insert dummy_name which may be used as a restore target
+        mode, sha = \
+            hashsplit.split_to_blob_or_tree(pack_writer.new_blob,
+                                            pack_writer.new_tree,
+                                            files,
+                                            keep_boundaries=opt.keep_boundaries,
+                                            progress=prog)
+        dummy_name = git.mangle_name(os.path.basename(opt.name),
+                                     hashsplit.GIT_MODE_FILE, mode)
+        shalist = [(mode, dummy_name, sha)]
+    else:
+        shalist = hashsplit.split_to_shalist(
+                      pack_writer.new_blob, pack_writer.new_tree, files,
+                      keep_boundaries=opt.keep_boundaries, progress=prog)
     tree = pack_writer.new_tree(shalist)
 else:
     last = 0
index bd3cb24b9f727de92a098fc027f2a03ae1f277ec..72ea20de997709df26f1e4d316cf5534a4483990 100644 (file)
@@ -168,9 +168,10 @@ def split_to_shalist(makeblob, maketree, files,
         return _make_shalist(stacks[-1])[0]
 
 
-def split_to_blob_or_tree(makeblob, maketree, files, keep_boundaries):
+def split_to_blob_or_tree(makeblob, maketree, files,
+                          keep_boundaries, progress=None):
     shalist = list(split_to_shalist(makeblob, maketree,
-                                    files, keep_boundaries))
+                                    files, keep_boundaries, progress))
     if len(shalist) == 1:
         return (shalist[0][0], shalist[0][2])
     elif len(shalist) == 0:
index dd4592c08eb118739b900e2f1d347b758f2343ab..2483222da8ea9a23e9b3cccce7987134b176fd8c 100755 (executable)
--- a/t/test.sh
+++ b/t/test.sh
@@ -144,6 +144,7 @@ WVPASSEQ "$(cat tag[ab].tmp | bup split -b --git-ids)" \
          "$(cat tagab.tmp)"
 WVPASS bup split --bench -b <"$top/t/testfile1" >tags1.tmp
 WVPASS bup split -vvvv -b "$top/t/testfile2" >tags2.tmp
+WVPASS echo -n "" | bup split -n split_empty_string.tmp
 WVPASS bup margin
 WVPASS bup midx -f
 WVPASS bup midx --check -a
@@ -206,6 +207,7 @@ WVPASS diff -u "$top/t/testfile1" out1.tmp
 WVPASS diff -u "$top/t/testfile2" out2.tmp
 WVPASS diff -u "$top/t/testfile2" out2t.tmp
 WVPASS diff -u "$top/t/testfile2" out2c.tmp
+WVPASSEQ "$(bup join split_empty_string.tmp)" ""
 
 WVSTART "save/git-fsck"
 (
@@ -233,6 +235,9 @@ WVPASS force-delete buprestore.tmp
 WVPASS bup restore -C buprestore.tmp "/master/latest/$tmpdir/$D/"
 WVPASS touch $D/non-existent-file buprestore.tmp/non-existent-file # else diff fails
 WVPASS diff -ur $D/ buprestore.tmp/
+rm -f split_empty_string.tmp
+WVPASS bup restore split_empty_string.tmp/latest/split_empty_string.tmp
+WVPASSEQ "$(cat split_empty_string.tmp)" ""
 
 (
     tmp=testrestore.tmp