Skip to content

Commit

Permalink
support directories
Browse files Browse the repository at this point in the history
  • Loading branch information
Joe Mou committed Apr 22, 2019
1 parent b77784b commit 060ac76
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 29 deletions.
27 changes: 15 additions & 12 deletions read-tree
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@ import sys

import index

_, tree_sha1 = sys.argv
tree = subprocess.check_output(['cat-file', 'tree', tree_sha1])
entries = []
while tree:
header, rest = tree.split('\0', 1)
mode, filename = header.split(' ', 1)
rawsha1 = rest[:20]
tree = rest[20:]
# TODO handle directories
if mode != '040000':
entries.append((filename, int(mode, 8), rawsha1))
def unpack_trees(tree_sha1, base):
tree = subprocess.check_output(['cat-file', 'tree', tree_sha1])
entries = []
while tree:
header, rest = tree.split('\0', 1)
mode, filename = header.split(' ', 1)
rawsha1 = rest[:20]
tree = rest[20:]
if mode == '40000': # for directories
entries += unpack_trees(rawsha1.encode('hex'), filename + '/')
else:
entries.append((base + filename, int(mode, 8), rawsha1))
return entries

index.write_index(entries)
_, tree_sha1 = sys.argv
index.write_index(unpack_trees(tree_sha1, ''))
28 changes: 21 additions & 7 deletions test
Original file line number Diff line number Diff line change
Expand Up @@ -117,20 +117,34 @@ header 'Checkout detached HEAD [checkout]'
$ZIT checkout HEAD
[[ $(<.zit/HEAD) == $second_commit ]]

header 'Commit executable file, symlink, and directory [add]'
header 'Commit executable file, symlink [add]'
chmod +x handle
mkdir and
ln -s ../handle and/spout
git add handle and/spout
ln -s handle spout
git add handle spout
EDITOR=tee $ZIT commit <<< 'first stanza' > /dev/null
[[ $($ZIT rev-parse HEAD^{tree}) == 6a8ad12fa34d4f1ea64abb28c8ae143b1e8fde40 ]]
[[ $($ZIT rev-parse HEAD^{tree}) == 32b256d0e79f6c2a3ccca5ef6bd67aa7b37fc6eb ]]

header 'Checkout a new branch [checkout, checkout-index]'
rm -rf handle and
rm -f handle spout
$ZIT checkout -b stanza
[[ $(<.zit/HEAD) == 'ref: refs/heads/stanza' ]]
[[ -x handle ]]
[[ $(python -c 'import os; print os.readlink("and/spout")') == ../handle ]]
[[ $(python -c 'import os; print os.readlink("spout")') == handle ]]

header 'Commit directory [write-tree]'
mkdir stanza2
echo 'When I get all steamed up' > stanza2/line1
echo 'hear me shout' > stanza2/line2
echo 'tip me over and pour me out' > stanza2/line3
git add stanza2
EDITOR=tee $ZIT commit <<< 'second stanza' > /dev/null
[[ $($ZIT rev-parse HEAD^{tree}) == 211fce66889894e23c9d710e2ae9df93066be410 ]]

header 'Checkout a new branch [checkout, checkout-index]'
rm -rf stanza
$ZIT checkout stanza
[[ $(<.zit/HEAD) == 'ref: refs/heads/stanza' ]]
[[ $(<stanza2/line1) == 'When I get all steamed up' ]]

[[ -n $keep ]] || { rm -rf "$repo"; trap '' EXIT; }
header PASS
35 changes: 25 additions & 10 deletions write-tree
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,29 @@ import subprocess

import index

entries = index.read_index()
# TODO write directories recursively? groupby?
f = open('.zit/tree.tmp', 'w')
for filename, mode, rawsha1 in entries:
f.write('{:o} '.format(mode))
f.write(filename)
f.write('\0')
f.write(rawsha1)
f.close()
def write_tree(entries, base):
i = 0
buf = ''
while i < len(entries):
filename, mode, rawsha1 = entries[i]

subprocess.check_call(['hash-object', 'tree', '.zit/tree.tmp'])
# for directories
if not filename.startswith(base):
break
filename = filename[len(base):]
if '/' in filename:
filename = filename.split('/', 1)[0]
num_written, sha1 = write_tree(entries[i:], base + filename + '/')
i += num_written
i -= 1 # write the directory entry, but don't count it
mode = 040000
rawsha1 = bytearray.fromhex(sha1)

buf += '{:o} {}\0{}'.format(mode, filename, rawsha1)
i += 1
with open('.zit/tree.tmp', 'w') as f:
f.write(buf)
return i, subprocess.check_output(['hash-object', 'tree', '.zit/tree.tmp']).strip()

_, sha1 = write_tree(index.read_index(), '')
print sha1

0 comments on commit 060ac76

Please sign in to comment.