|  | #!/bin/sh | 
|  | # | 
|  | # Copyright (c) 2005 Junio C Hamano | 
|  | # | 
|  |  | 
|  | test_description='See why rewinding head breaks send-pack | 
|  |  | 
|  | ' | 
|  | . ./test-lib.sh | 
|  |  | 
|  | cnt=64 | 
|  | test_expect_success setup ' | 
|  | test_tick && | 
|  | mkdir mozart mozart/is && | 
|  | echo "Commit #0" >mozart/is/pink && | 
|  | git update-index --add mozart/is/pink && | 
|  | tree=$(git write-tree) && | 
|  | commit=$(echo "Commit #0" | git commit-tree $tree) && | 
|  | zero=$commit && | 
|  | parent=$zero && | 
|  | i=0 && | 
|  | while test $i -le $cnt | 
|  | do | 
|  | i=$(($i+1)) && | 
|  | test_tick && | 
|  | echo "Commit #$i" >mozart/is/pink && | 
|  | git update-index --add mozart/is/pink && | 
|  | tree=$(git write-tree) && | 
|  | commit=$(echo "Commit #$i" | git commit-tree $tree -p $parent) && | 
|  | git update-ref refs/tags/commit$i $commit && | 
|  | parent=$commit || return 1 | 
|  | done && | 
|  | git update-ref HEAD "$commit" && | 
|  | git clone ./. victim && | 
|  | ( cd victim && git config receive.denyCurrentBranch warn && git log ) && | 
|  | git update-ref HEAD "$zero" && | 
|  | parent=$zero && | 
|  | i=0 && | 
|  | while test $i -le $cnt | 
|  | do | 
|  | i=$(($i+1)) && | 
|  | test_tick && | 
|  | echo "Rebase #$i" >mozart/is/pink && | 
|  | git update-index --add mozart/is/pink && | 
|  | tree=$(git write-tree) && | 
|  | commit=$(echo "Rebase #$i" | git commit-tree $tree -p $parent) && | 
|  | git update-ref refs/tags/rebase$i $commit && | 
|  | parent=$commit || return 1 | 
|  | done && | 
|  | git update-ref HEAD "$commit" && | 
|  | echo Rebase && | 
|  | git log' | 
|  |  | 
|  | test_expect_success 'pack the source repository' ' | 
|  | git repack -a -d && | 
|  | git prune | 
|  | ' | 
|  |  | 
|  | test_expect_success 'pack the destination repository' ' | 
|  | ( | 
|  | cd victim && | 
|  | git repack -a -d && | 
|  | git prune | 
|  | ) | 
|  | ' | 
|  |  | 
|  | test_expect_success 'refuse pushing rewound head without --force' ' | 
|  | pushed_head=$(git rev-parse --verify master) && | 
|  | victim_orig=$(cd victim && git rev-parse --verify master) && | 
|  | test_must_fail git send-pack ./victim master && | 
|  | victim_head=$(cd victim && git rev-parse --verify master) && | 
|  | test "$victim_head" = "$victim_orig" && | 
|  | # this should update | 
|  | git send-pack --force ./victim master && | 
|  | victim_head=$(cd victim && git rev-parse --verify master) && | 
|  | test "$victim_head" = "$pushed_head" | 
|  | ' | 
|  |  | 
|  | test_expect_success \ | 
|  | 'push can be used to delete a ref' ' | 
|  | ( cd victim && git branch extra master ) && | 
|  | git send-pack ./victim :extra master && | 
|  | ( cd victim && | 
|  | test_must_fail git rev-parse --verify extra ) | 
|  | ' | 
|  |  | 
|  | test_expect_success 'refuse deleting push with denyDeletes' ' | 
|  | ( | 
|  | cd victim && | 
|  | ( git branch -D extra || : ) && | 
|  | git config receive.denyDeletes true && | 
|  | git branch extra master | 
|  | ) && | 
|  | test_must_fail git send-pack ./victim :extra master | 
|  | ' | 
|  |  | 
|  | test_expect_success 'cannot override denyDeletes with git -c send-pack' ' | 
|  | ( | 
|  | cd victim && | 
|  | test_might_fail git branch -D extra && | 
|  | git config receive.denyDeletes true && | 
|  | git branch extra master | 
|  | ) && | 
|  | test_must_fail git -c receive.denyDeletes=false \ | 
|  | send-pack ./victim :extra master | 
|  | ' | 
|  |  | 
|  | test_expect_success 'override denyDeletes with git -c receive-pack' ' | 
|  | ( | 
|  | cd victim && | 
|  | test_might_fail git branch -D extra && | 
|  | git config receive.denyDeletes true && | 
|  | git branch extra master | 
|  | ) && | 
|  | git send-pack \ | 
|  | --receive-pack="git -c receive.denyDeletes=false receive-pack" \ | 
|  | ./victim :extra master | 
|  | ' | 
|  |  | 
|  | test_expect_success 'denyNonFastforwards trumps --force' ' | 
|  | ( | 
|  | cd victim && | 
|  | ( git branch -D extra || : ) && | 
|  | git config receive.denyNonFastforwards true | 
|  | ) && | 
|  | victim_orig=$(cd victim && git rev-parse --verify master) && | 
|  | test_must_fail git send-pack --force ./victim master^:master && | 
|  | victim_head=$(cd victim && git rev-parse --verify master) && | 
|  | test "$victim_orig" = "$victim_head" | 
|  | ' | 
|  |  | 
|  | test_expect_success 'push --all excludes remote tracking hierarchy' ' | 
|  | mkdir parent && | 
|  | ( | 
|  | cd parent && | 
|  | git init && : >file && git add file && git commit -m add | 
|  | ) && | 
|  | git clone parent child && | 
|  | ( | 
|  | cd child && git push --all | 
|  | ) && | 
|  | ( | 
|  | cd parent && | 
|  | test -z "$(git for-each-ref refs/remotes/origin)" | 
|  | ) | 
|  | ' | 
|  |  | 
|  | rewound_push_setup() { | 
|  | rm -rf parent child && | 
|  | mkdir parent && | 
|  | ( | 
|  | cd parent && | 
|  | git init && | 
|  | echo one >file && git add file && git commit -m one && | 
|  | git config receive.denyCurrentBranch warn && | 
|  | echo two >file && git commit -a -m two | 
|  | ) && | 
|  | git clone parent child && | 
|  | ( | 
|  | cd child && git reset --hard HEAD^ | 
|  | ) | 
|  | } | 
|  |  | 
|  | rewound_push_succeeded() { | 
|  | cmp ../parent/.git/refs/heads/master .git/refs/heads/master | 
|  | } | 
|  |  | 
|  | rewound_push_failed() { | 
|  | if rewound_push_succeeded | 
|  | then | 
|  | false | 
|  | else | 
|  | true | 
|  | fi | 
|  | } | 
|  |  | 
|  | test_expect_success 'pushing explicit refspecs respects forcing' ' | 
|  | rewound_push_setup && | 
|  | parent_orig=$(cd parent && git rev-parse --verify master) && | 
|  | ( | 
|  | cd child && | 
|  | test_must_fail git send-pack ../parent \ | 
|  | refs/heads/master:refs/heads/master | 
|  | ) && | 
|  | parent_head=$(cd parent && git rev-parse --verify master) && | 
|  | test "$parent_orig" = "$parent_head" && | 
|  | ( | 
|  | cd child && | 
|  | git send-pack ../parent \ | 
|  | +refs/heads/master:refs/heads/master | 
|  | ) && | 
|  | parent_head=$(cd parent && git rev-parse --verify master) && | 
|  | child_head=$(cd parent && git rev-parse --verify master) && | 
|  | test "$parent_head" = "$child_head" | 
|  | ' | 
|  |  | 
|  | test_expect_success 'pushing wildcard refspecs respects forcing' ' | 
|  | rewound_push_setup && | 
|  | parent_orig=$(cd parent && git rev-parse --verify master) && | 
|  | ( | 
|  | cd child && | 
|  | test_must_fail git send-pack ../parent \ | 
|  | "refs/heads/*:refs/heads/*" | 
|  | ) && | 
|  | parent_head=$(cd parent && git rev-parse --verify master) && | 
|  | test "$parent_orig" = "$parent_head" && | 
|  | ( | 
|  | cd child && | 
|  | git send-pack ../parent \ | 
|  | "+refs/heads/*:refs/heads/*" | 
|  | ) && | 
|  | parent_head=$(cd parent && git rev-parse --verify master) && | 
|  | child_head=$(cd parent && git rev-parse --verify master) && | 
|  | test "$parent_head" = "$child_head" | 
|  | ' | 
|  |  | 
|  | test_expect_success 'deny pushing to delete current branch' ' | 
|  | rewound_push_setup && | 
|  | ( | 
|  | cd child && | 
|  | test_must_fail git send-pack ../parent :refs/heads/master 2>errs | 
|  | ) | 
|  | ' | 
|  |  | 
|  | test_done |