diff --git a/add b/add index ff15bb5..d999b99 100755 --- a/add +++ b/add @@ -7,18 +7,18 @@ import sys import index -filenames = subprocess.check_output(['find'] + sys.argv[1:] + ['!', '-type', 'd']).splitlines() +filenames = subprocess.check_output(['find'] + sys.argv[1:] + ['!', '-type', 'd']).splitlines() # for directories entries = index.read_index() for filename in filenames: entries = [e for e in entries if e[0] != filename] if os.path.exists(filename): - if os.path.islink(filename): + if os.path.islink(filename): # for symlinks mode = 0120000 with open('.zit/blob.tmp', 'w') as f: f.write(os.readlink(filename)) sha1 = subprocess.check_output(['hash-object', 'blob', '.zit/blob.tmp']).strip() else: - if os.access(filename, os.X_OK): + if os.access(filename, os.X_OK): # for executable files mode = 0100755 else: mode = 0100644 diff --git a/branch b/branch index ed66566..e437fac 100755 --- a/branch +++ b/branch @@ -1,7 +1,7 @@ #!/bin/bash -e if [[ $# -eq 0 ]]; then - headref=$(symbolic-ref HEAD | sed -e 's|^refs/heads/||') + headref=$(symbolic-ref HEAD | sed -e 's|^refs/heads/||') # for current branch echo "*$headref" cd .zit/refs/heads ls | grep -vxF $headref diff --git a/checkout b/checkout index a2a97c9..79b9a7a 100755 --- a/checkout +++ b/checkout @@ -11,5 +11,7 @@ checkout-index if [[ -f .zit/refs/heads/$revision ]]; then symbolic-ref HEAD refs/heads/$revision else + rev-parse $revision > .zit/HEAD.tmp + mv .zit/HEAD.tmp .zit/HEAD echo "You are in 'detached HEAD' state." >&2 fi diff --git a/checkout-index b/checkout-index index fa49836..1f7000a 100755 --- a/checkout-index +++ b/checkout-index @@ -13,8 +13,10 @@ for filename, mode, sha1 in entries: subprocess.check_call(['mkdir', '-p', './' + os.path.dirname(filename)]) # TODO git 1.0 doesn't seem to unlink deleted files subprocess.check_call(['cat-file', 'blob', sha1.encode('hex')], stdout=open(filename, 'w')) - if mode == 0100755: + if mode == 0100755: # for executable files os.chmod(filename, 0755) - elif mode == 0120000: + elif mode == 0120000: # for symlinks target = open(filename).read() + if os.path.exists(filename): + os.unlink(filename) os.symlink(target, filename) diff --git a/commit b/commit index a293c7e..dc5ccc3 100755 --- a/commit +++ b/commit @@ -1,6 +1,6 @@ #!/bin/bash -e -if [[ -f .zit/$(symbolic-ref HEAD) ]]; then +if [[ -f .zit/$(symbolic-ref HEAD) ]]; then # for non-initial commit parents='-p HEAD' fi echo '# write a commit message' > .zit/COMMIT_EDITMSG diff --git a/commit-tree b/commit-tree index 3916f87..5decf3e 100755 --- a/commit-tree +++ b/commit-tree @@ -1,5 +1,6 @@ #!/bin/bash -e +# for non-hardcoded commit export ZIT_AUTHOR_NAME="${ZIT_AUTHOR_NAME-Frank N. Stein}" export ZIT_AUTHOR_EMAIL="${ZIT_AUTHOR_EMAIL-eat@brains.com}" export ZIT_COMMITTER_NAME="${ZIT_COMMITTER_NAME-$ZIT_AUTHOR_NAME}" @@ -7,7 +8,7 @@ export ZIT_COMMITTER_EMAIL="${ZIT_COMMITTER_EMAIL-$ZIT_AUTHOR_EMAIL}" echo tree $1 > .zit/commit.tmp shift -while [[ $1 == -p ]]; do +while [[ $1 == -p ]]; do # for non-initial commit parent=$(rev-parse $2) echo parent $parent >> .zit/commit.tmp shift; shift diff --git a/init b/init index c5174e9..8c8f280 100755 --- a/init +++ b/init @@ -3,6 +3,7 @@ mkdir -p "$1/.zit/objects" echo 'ref: refs/heads/master' > "$1/.zit/HEAD" +# for git compatibility ln -s .zit "$1/.git" mkdir "$1/.git/info" echo .zit > "$1/.git/info/exclude" diff --git a/rev-parse b/rev-parse index 2f05eed..7b0a465 100755 --- a/rev-parse +++ b/rev-parse @@ -6,15 +6,15 @@ import sys # sha1_name.c:get_sha1 def get_sha1(name): - if name[-2] == '~': + if name[-2] == '~': # for ~ name = name[:-2] + '^' * int(name[-1]) - if name[-1] == '^': + if name[-1] == '^': # for ^ sha1 = get_sha1(name[:-1]) contents = subprocess.check_output(['cat-file', 'commit', sha1]) parent = next(line for line in contents.splitlines() if line.startswith('parent ')) return parent.split(' ')[1] - if '^{' in name: + if '^{' in name: # for ^{type} name, requested_type = name.rsplit('^{', 1) assert requested_type[-1] == '}' requested_type = requested_type[:-1] diff --git a/test b/test index 3039aa8..d6228b6 100755 --- a/test +++ b/test @@ -13,101 +13,124 @@ get_md5() { } header 'Initializing repo... [zit, init]' +[[ $1 == --keep ]] && { keep=1; shift; } +ZIT="${1-zit}" trap 'echo -e "\e[31mFAIL\e[0m"' ERR repo="$PWD/test.tmp" rm -rf "$repo" -zit init "$repo" -[[ $1 != --keep ]] && trap 'rm -rf "$repo"' EXIT +$ZIT init "$repo" +[[ -n $keep ]] || trap 'rm -rf "$repo"' EXIT cd "$repo" [[ $(<.zit/HEAD) == 'ref: refs/heads/master' ]] +[[ ${ZIT::1} == / ]] || ZIT="../$ZIT" header 'Writing a blob object... [hash-object]' echo "I'm a little teapot" > lullaby -[[ $(zit hash-object blob lullaby) == 3eb7f9afc452afe452b99d478d89264380622248 ]] +[[ $($ZIT hash-object blob lullaby) == 3eb7f9afc452afe452b99d478d89264380622248 ]] header 'Reading an object... [cat-file]' -[[ $(zit cat-file -t 3eb7f9afc452afe452b99d478d89264380622248 ) == blob ]] -[[ $(zit cat-file blob 3eb7f9afc452afe452b99d478d89264380622248 ) == "I'm a little teapot" ]] +[[ $($ZIT cat-file -t 3eb7f9afc452afe452b99d478d89264380622248 ) == blob ]] +[[ $($ZIT cat-file blob 3eb7f9afc452afe452b99d478d89264380622248 ) == "I'm a little teapot" ]] header 'Writing to the index... [index.py]' -PYTHONPATH=.. /usr/bin/python -c 'import index; index.write_index([("lullaby", 0100644, "\x3e\xb7\xf9\xaf\xc4\x52\xaf\xe4\x52\xb9\x9d\x47\x8d\x89\x26\x43\x80\x62\x22\x48")])' +PYTHONPATH=$(dirname "$ZIT") /usr/bin/python -c 'import index; index.write_index([("lullaby", 0100644, "\x3e\xb7\xf9\xaf\xc4\x52\xaf\xe4\x52\xb9\x9d\x47\x8d\x89\x26\x43\x80\x62\x22\x48")])' [[ $(get_md5 .zit/index) == 06432001fc95f78cd6353321f7c95009 ]] header 'Adding a file to the index... [add]' echo here > handle -zit add handle -[[ $(zit cat-file blob 012ea92e81171f5ef7486696878656c5263cf722 ) == here ]] +$ZIT add handle +[[ $($ZIT cat-file blob 012ea92e81171f5ef7486696878656c5263cf722 ) == here ]] [[ $(get_md5 .zit/index) == 61728e18ee75d24576d9ea2b626fb1ff ]] header 'Reading the index... [index.py]' -[[ $(PYTHONPATH=.. /usr/bin/python -c 'import index; print index.read_index()') == "[('handle', 33188, '\x01.\xa9.\x81\x17\x1f^\xf7Hf\x96\x87\x86V\xc5&<\xf7\"'), ('lullaby', 33188, '>\xb7\xf9\xaf\xc4R\xaf\xe4R\xb9\x9dG\x8d\x89&C\x80b\"H')]" ]] +[[ $(PYTHONPATH=$(dirname "$ZIT") /usr/bin/python -c 'import index; print index.read_index()') == "[('handle', 33188, '\x01.\xa9.\x81\x17\x1f^\xf7Hf\x96\x87\x86V\xc5&<\xf7\"'), ('lullaby', 33188, '>\xb7\xf9\xaf\xc4R\xaf\xe4R\xb9\x9dG\x8d\x89&C\x80b\"H')]" ]] header 'Writing the index to a tree object... [write-tree]' -initial_tree=$(zit write-tree) +initial_tree=$($ZIT write-tree) [[ $initial_tree == f65ccd4f10cb3416c7be6601bafd2371a784054f ]] header 'Writing an initial commit object... [commit-tree]' -export ZIT_AUTHOR_NAME='Miss Teapot' ZIT_AUTHOR_EMAIL=miss@tea.spot -initial_commit=$(echo initial commit | zit commit-tree $initial_tree) -[[ $(zit cat-file commit $initial_commit ) =~ ^"tree $initial_tree -author Miss Teapot "[0-9]*\ [+-][0-9]{4}" -committer Miss Teapot "[0-9]*\ [+-][0-9]{4}" +initial_commit=$(echo initial commit | $ZIT commit-tree $initial_tree) +[[ $($ZIT cat-file commit $initial_commit ) =~ ^"tree $initial_tree +author "[^\<]*" <"[^\>]*"> "[0-9]*\ [+-][0-9]{4}" +committer "[^\<]*" <"[^\>]*"> "[0-9]*\ [+-][0-9]{4}" initial commit"$ ]] header 'Create a branch ref [update-ref]' -zit update-ref refs/heads/initial $initial_commit +$ZIT update-ref refs/heads/initial $initial_commit [[ $(<.zit/refs/heads/initial) == $initial_commit ]] header 'Read HEAD symbolic ref [symbolic-ref]' -[[ $(zit symbolic-ref HEAD) == refs/heads/master ]] +[[ $($ZIT symbolic-ref HEAD) == refs/heads/master ]] header 'Birth master branch [update-ref, get-sha1-basic, rev-parse]' -zit update-ref HEAD $initial_commit -[[ $(zit rev-parse HEAD) == $initial_commit ]] +$ZIT update-ref HEAD $initial_commit +[[ $($ZIT rev-parse HEAD) == $initial_commit ]] header 'Delete and create a branch [branch]' -zit branch -d initial +$ZIT branch -d initial [[ ! -f .zit/refs/heads/initial ]] -zit branch initial +$ZIT branch initial [[ $(<.zit/refs/heads/initial) == $initial_commit ]] header 'Writing another commit object... [commit, commit-tree]' echo 'short and stout' > lullaby -zit add lullaby -echo 'second verse' | EDITOR=tee zit commit > /dev/null +$ZIT add lullaby +EDITOR=tee $ZIT commit <<< 'second verse' > /dev/null second_tree=3c1bea2d45d260a3836794e04a4bbef34e3c2459 -[[ $(zit cat-file commit $(zit rev-parse HEAD) ) =~ ^"tree $second_tree +second_commit=$($ZIT rev-parse HEAD) +[[ $($ZIT cat-file commit $second_commit ) =~ ^"tree $second_tree parent $initial_commit -author Miss Teapot "[0-9]*\ [+-][0-9]{4}" -committer Miss Teapot "[0-9]*\ [+-][0-9]{4}" +author "[^\<]*" <"[^\>]*"> "[0-9]*\ [+-][0-9]{4}" +committer "[^\<]*" <"[^\>]*"> "[0-9]*\ [+-][0-9]{4}" second verse"$ ]] header 'Parse ^ and ~ revisions [rev-parse]' -[[ $(zit rev-parse HEAD^) == $initial_commit ]] -[[ $(zit rev-parse HEAD~1) == $initial_commit ]] -[[ $(zit rev-parse initial~0) == $initial_commit ]] +[[ $($ZIT rev-parse HEAD^) == $initial_commit ]] +[[ $($ZIT rev-parse HEAD~1) == $initial_commit ]] +[[ $($ZIT rev-parse initial~0) == $initial_commit ]] header 'Parse ^{type} revisions [rev-parse]' -[[ $(zit rev-parse HEAD^{tree}) == $second_tree ]] -[[ $(zit rev-parse HEAD^^{tree}) == $initial_tree ]] +[[ $($ZIT rev-parse HEAD^{tree}) == $second_tree ]] +[[ $($ZIT rev-parse HEAD^^{tree}) == $initial_tree ]] header 'Reading tree object into the index... [read-tree]' -zit read-tree $initial_tree +$ZIT read-tree $initial_tree [[ $(get_md5 .zit/index) == 61728e18ee75d24576d9ea2b626fb1ff ]] header 'Checkout from the index [checkout-index]' -zit checkout-index +$ZIT checkout-index [[ $( /dev/null +[[ $($ZIT rev-parse HEAD^{tree}) == 6a8ad12fa34d4f1ea64abb28c8ae143b1e8fde40 ]] + +header 'Checkout a new branch [checkout, checkout-index]' +rm -rf handle and +$ZIT checkout -b stanza +[[ $(<.zit/HEAD) == 'ref: refs/heads/stanza' ]] +[[ -x handle ]] +[[ $(python -c 'import os; print os.readlink("and/spout")') == ../handle ]] + +[[ -n $keep ]] || { rm -rf "$repo"; trap '' EXIT; } header PASS