Parsing ref names that have slashes

36 views
Skip to first unread message

Stefan Buller

unread,
Jul 20, 2012, 6:27:42 PM7/20/12
to bup-...@googlegroups.com
I decided I would like to be able to arrange my saves in a custom
directory structure.

> bup save -n 'foo/bar'
> bup save -n 'foo/baz'

I'm trying to figure out how you're supposed to send patches for git;
in the meantime, I've attached a patch file here.
The code's got some copy/paste happening, and isn't extensively
tested, but does appear to work on my simple tests.
Comments welcome.

--
Stefan Buller
0001-Parse-ref-names-that-have-slashes.patch

Gabriel Filion

unread,
Jul 22, 2012, 2:22:55 PM7/22/12
to Stefan Buller, bup-...@googlegroups.com
oh, nice. this has been a bug (or let's say unimplemented feature) in
bup for a while. the patch looks quite simple, I'll take a look at it as
soon as I can.

--
Gabriel Filion

Gabriel Filion

unread,
Jul 25, 2012, 8:56:42 AM7/25/12
to Stefan Buller, bup-list
[brought back bup-...@googlegroups.com in the cc list since I suppose
you meant to send this message to everyone.]

On 12-07-24 05:14 PM, Stefan Buller wrote:
> Unfortunately, it turns out not to be so easy. The symbolic links
> within the directory are relative, meaning that adding an extra level
> to the hierarchy breaks them all.

oh that's too bad then.

> I'll have to spend some more time on
> this, or something. I'd had my hopes so high...

thanks for your work! I'll wait for the results :)

--
Gabriel Filion

Stefan Buller

unread,
Jul 25, 2012, 2:21:50 PM7/25/12
to bup-...@googlegroups.com, Stefan Buller

Signed-off-by: Stefan Buller <stefan...@gmail.com>
---
lib/bup/vfs.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 50 insertions(+), 6 deletions(-)

diff --git a/lib/bup/vfs.py b/lib/bup/vfs.py
index 4543553..7026b4d 100644
--- a/lib/bup/vfs.py
+++ b/lib/bup/vfs.py
@@ -96,6 +96,11 @@ def _chunkiter(hash, startofs):
else:
yield ''.join(cp().join(sha.encode('hex')))[skipmore:]

+def _depth(node):
+ if node.parent == None:
+ return 0
+ else:
+ return _depth(node.parent) + 1

class _ChunkReader:
def __init__(self, hash, isdir, startofs):
@@ -459,11 +464,36 @@ class TagDir(Node):
name = name[10:]
date = git.rev_get_date(sha.encode('hex'))
commithex = sha.encode('hex')
- target = '../.commit/%s/%s' % (commithex[:2], commithex[2:])
+ commitdir = ('../' * _depth(self)) + '.commit/'
+ target = commitdir + '%s/%s' % (commithex[:2], commithex[2:])
tag1 = FakeSymlink(self, name, target)
tag1.ctime = tag1.mtime = date
self._subs[name] = tag1

+class BranchDir(Node):
+ """A directory that represents part of a ref name"""
+ def __init__(self, parent, name):
+ Node.__init__(self, parent, name, GIT_MODE_TREE, EMPTY_SHA)
+ self.subitems = []
+
+ def _mksubs(self):
+ self._subs = {}
+ for (name, date, sha) in self.subitems:
+ parts = name.split('/')
+ head = parts[0]
+ rest = parts[1:]
+ if not rest:
+ n1 = BranchList(self, name, sha)
+ n1.ctime = n1.mtime = date
+ self._subs[name] = n1
+ else:
+ n1 = self._subs.get(head)
+ if not n1:
+ n1 = BranchDir(self, head)
+ self._subs[head] = n1
+ else:
+ pass
+ n1.subitems.append(rest)

class BranchList(Node):
"""A list of links to commits reachable by a branch in bup's repository.
@@ -484,7 +514,8 @@ class BranchList(Node):
l = time.localtime(date)
ls = time.strftime('%Y-%m-%d-%H%M%S', l)
commithex = commit.encode('hex')
- target = '../.commit/%s/%s' % (commithex[:2], commithex[2:])
+ commitdir = ('../' * _depth(self)) + '.commit/'
+ target = commitdir + '%s/%s' % (commithex[:2], commithex[2:])
n1 = FakeSymlink(self, ls, target)
n1.ctime = n1.mtime = date
self._subs[ls] = n1
@@ -498,7 +529,8 @@ class BranchList(Node):
if latest:
(date, commit) = latest
commithex = commit.encode('hex')
- target = '../.commit/%s/%s' % (commithex[:2], commithex[2:])
+ commitdir = ('../' * _depth(self)) + '.commit/'
+ target = commitdir + '%s/%s' % (commithex[:2], commithex[2:])
n1 = FakeSymlink(self, 'latest', target)
n1.ctime = n1.mtime = date
self._subs['latest'] = n1
@@ -529,6 +561,18 @@ class RefList(Node):
if name.startswith('refs/heads/'):
name = name[11:]
date = git.rev_get_date(sha.encode('hex'))
- n1 = BranchList(self, name, sha)
- n1.ctime = n1.mtime = date
- self._subs[name] = n1
+ parts = name.split('/')
+ head = parts[0]
+ rest = parts[1:]
+ if not rest:
+ n1 = BranchList(self, name, sha)
+ n1.ctime = n1.mtime = date
+ self._subs[name] = n1
+ else:
+ n1 = self._subs.get(head)
+ if not n1:
+ n1 = BranchDir(self, head)
+ self._subs[head] = n1
+ else:
+ pass
+ n1.subitems.append( ("/".join(rest), date, sha) )
--
1.7.9.5

Stefan Buller

unread,
Jul 25, 2012, 2:25:20 PM7/25/12
to bup-...@googlegroups.com
I'm still trying to get a handle on sending patches from git. Anyhow,
I've fixed up the symbolic links in this revision.

--
Stefan Buller

Gabriel Filion

unread,
Jul 28, 2012, 1:48:48 AM7/28/12
to Stefan Buller, bup-...@googlegroups.com
On 12-07-25 02:21 PM, Stefan Buller wrote:
>
> Signed-off-by: Stefan Buller <stefan...@gmail.com>

The code looks generally good to me. But I found an error that's created
by the change:

when the ref name has 3 levels (mine was dev/test/blah) then listing the
second level gives this error:

bup> ls dev/test/
error: need more than 1 value to unpack

also if I use tab on the third level (marked with I below) it spits out
a stack trace. this only happens if you haven't already tried to list
the directory like above:

bup> ls dev/test/I
File "/home/gabster/dev/bup/cmd/bup-ftp", line 99, in completer
_last_res = _completer_get_subs(line)
File "/home/gabster/dev/bup/cmd/bup-ftp", line 46, in _completer_get_subs
n.subs()))
File "/home/gabster/dev/bup/lib/bup/vfs.py", line 204, in subs
self._mksubs()
File "/home/gabster/dev/bup/lib/bup/vfs.py", line 484, in _mksubs
for (name, date, sha) in self.subitems:

--
Gabriel Filion

Stefan Buller

unread,
Jul 30, 2012, 2:08:32 PM7/30/12
to Gabriel Filion, bup-...@googlegroups.com
Thanks for the help testing.
I was going to pontificate on how nothing is easy, but this change was
a single line copied from elsewhere in the file. Hopefully third
time's the charm.

Also, a couple questions about sending patches:
I'm finding attaching the patch easier than in-lineing it - is this acceptable?
I've been re-submitting my patch with changes incorporated - would it
be preferable to send just the changes each time?

--
Stefan Buller
0001-Parse-ref-names-that-have-slashes.patch

Gabriel Filion

unread,
Aug 11, 2012, 4:58:45 PM8/11/12
to Stefan Buller, bup-...@googlegroups.com
On 12-07-30 02:08 PM, Stefan Buller wrote:
> Thanks for the help testing.

sure. actually thank _you_ for working on fixing things. it really helps
a lot :)

> Also, a couple questions about sending patches:
> I'm finding attaching the patch easier than in-lineing it - is this acceptable?
> I've been re-submitting my patch with changes incorporated - would it
> be preferable to send just the changes each time?

attaching works.. however it makes applying the patch a bit harder since
"git am" expects an inline patch.

the best method of sending a patch is through git send-email: you setup
a branch on which you keep your patch (or patch series) and when you're
ready, you can generate messages with "git format-patch -o
some-output-dir/ base_branch.." then you can "git send-email
--to="bup-...@googlegroups.com" some-output-dir/files [...]"

that way you don't have to deal with e-mail clients that break lines and
we can get the patch and the commit message all at once.


I'll test your patch and send feedback on it as soon as possible.

--
Gabriel Filion

Zoran Zaric

unread,
Oct 5, 2012, 8:31:54 AM10/5/12
to Gabriel Filion, Stefan Buller, bup-...@googlegroups.com
On Sat, Jul 28, 2012 at 01:48:48AM -0400, Gabriel Filion wrote:
> On 12-07-25 02:21 PM, Stefan Buller wrote:
> >
> > Signed-off-by: Stefan Buller <stefan...@gmail.com>
>
> The code looks generally good to me. But I found an error that's created
> by the change:
>
> when the ref name has 3 levels (mine was dev/test/blah) then listing the
> second level gives this error:

What's the state of this patch? Today I stubled about slashes not working in
branch names and remembered this thread.

Thanks,
Zoran

Stefan Buller

unread,
Oct 5, 2012, 1:14:19 PM10/5/12
to Zoran Zaric, Gabriel Filion, bup-...@googlegroups.com
I believe my last submission was working to my expectations. I've since decided against using slashes in branch names for other reasons, but the July 30th patch is still in my tree.

--
Stefan Buller

Zoran Zaric

unread,
Oct 5, 2012, 1:19:08 PM10/5/12
to Stefan Buller, Gabriel Filion, bup-...@googlegroups.com
ok I'll test it thanks!

Zoran
Reply all
Reply to author
Forward
0 new messages