From: Yung-Chin Oei Date: Mon, 8 Oct 2012 14:08:34 +0000 (+0100) Subject: Make bup-split commits appear as files to the vfs layer. X-Git-Tag: 0.26-rc1~16^2~1 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=bup.git;a=commitdiff_plain;h=6068aef0fae35566a5da926f141b9c69a3c38017 Make bup-split commits appear as files to the vfs layer. 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 [rlb@defaultvalue.org: rebase to current master; adjust code indentation.] --- diff --git a/cmd/split-cmd.py b/cmd/split-cmd.py index 9cb3544..2ab4d2b 100755 --- a/cmd/split-cmd.py +++ b/cmd/split-cmd.py @@ -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 diff --git a/lib/bup/hashsplit.py b/lib/bup/hashsplit.py index bd3cb24..72ea20d 100644 --- a/lib/bup/hashsplit.py +++ b/lib/bup/hashsplit.py @@ -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: diff --git a/t/test.sh b/t/test.sh index dd4592c..2483222 100755 --- 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