| #!/bin/sh |
| # Copyright (c) 2012 Felipe Contreras |
| |
| # The first argument can be a url when the fetch/push command was a url |
| # instead of a configured remote. In this case, use a generic alias. |
| if test "$1" = "testgit::$2"; then |
| alias=_ |
| else |
| alias=$1 |
| fi |
| url=$2 |
| |
| dir="$GIT_DIR/testgit/$alias" |
| |
| if ! git rev-parse --is-inside-git-dir |
| then |
| exit 1 |
| fi |
| |
| h_refspec="refs/heads/*:refs/testgit/$alias/heads/*" |
| t_refspec="refs/tags/*:refs/testgit/$alias/tags/*" |
| |
| if test -n "$GIT_REMOTE_TESTGIT_NOREFSPEC" |
| then |
| h_refspec="" |
| t_refspec="" |
| fi |
| |
| GIT_DIR="$url/.git" |
| export GIT_DIR |
| |
| force= |
| object_format= |
| |
| mkdir -p "$dir" |
| |
| if test -z "$GIT_REMOTE_TESTGIT_NO_MARKS" |
| then |
| gitmarks="$dir/git.marks" |
| testgitmarks="$dir/testgit.marks" |
| test -e "$gitmarks" || >"$gitmarks" |
| test -e "$testgitmarks" || >"$testgitmarks" |
| fi |
| |
| while read line |
| do |
| case $line in |
| capabilities) |
| echo 'import' |
| echo 'export' |
| test -n "$h_refspec" && echo "refspec $h_refspec" |
| test -n "$t_refspec" && echo "refspec $t_refspec" |
| if test -n "$gitmarks" |
| then |
| echo "*import-marks $gitmarks" |
| echo "*export-marks $gitmarks" |
| fi |
| test -n "$GIT_REMOTE_TESTGIT_SIGNED_TAGS" && echo "signed-tags" |
| test -n "$GIT_REMOTE_TESTGIT_NO_PRIVATE_UPDATE" && echo "no-private-update" |
| echo 'option' |
| echo 'object-format' |
| echo |
| ;; |
| list) |
| test -n "$object_format" && |
| echo ":object-format $(git rev-parse --show-object-format=storage)" |
| git for-each-ref --format='? %(refname)' 'refs/heads/' 'refs/tags/' |
| head=$(git symbolic-ref HEAD) |
| echo "@$head HEAD" |
| echo |
| ;; |
| import*) |
| # read all import lines |
| while true |
| do |
| ref="${line#* }" |
| refs="$refs $ref" |
| read line |
| test "${line%% *}" != "import" && break |
| done |
| |
| if test -n "$gitmarks" |
| then |
| echo "feature import-marks=$gitmarks" |
| echo "feature export-marks=$gitmarks" |
| fi |
| |
| if test -n "$GIT_REMOTE_TESTGIT_FAILURE" |
| then |
| echo "feature done" |
| exit 1 |
| fi |
| |
| echo "feature done" |
| git fast-export \ |
| ${h_refspec:+"--refspec=$h_refspec"} \ |
| ${t_refspec:+"--refspec=$t_refspec"} \ |
| ${testgitmarks:+"--import-marks=$testgitmarks"} \ |
| ${testgitmarks:+"--export-marks=$testgitmarks"} \ |
| $refs |
| echo "done" |
| ;; |
| export) |
| if test -n "$GIT_REMOTE_TESTGIT_FAILURE" |
| then |
| # consume input so fast-export doesn't get SIGPIPE; |
| # git would also notice that case, but we want |
| # to make sure we are exercising the later |
| # error checks |
| while read line; do |
| test "done" = "$line" && break |
| done |
| exit 1 |
| fi |
| |
| before=$(git for-each-ref --format=' %(refname) %(objectname) ') |
| |
| git fast-import \ |
| ${force:+--force} \ |
| ${testgitmarks:+"--import-marks=$testgitmarks"} \ |
| ${testgitmarks:+"--export-marks=$testgitmarks"} \ |
| --quiet |
| |
| # figure out which refs were updated |
| git for-each-ref --format='%(refname) %(objectname)' | |
| while read ref a |
| do |
| case "$before" in |
| *" $ref $a "*) |
| continue ;; # unchanged |
| esac |
| if test -z "$GIT_REMOTE_TESTGIT_PUSH_ERROR" |
| then |
| echo "ok $ref" |
| else |
| echo "error $ref $GIT_REMOTE_TESTGIT_PUSH_ERROR" |
| fi |
| done |
| |
| echo |
| ;; |
| option\ *) |
| read cmd opt val <<-EOF |
| $line |
| EOF |
| case $opt in |
| force) |
| test $val = "true" && force="true" || force= |
| echo "ok" |
| ;; |
| object-format) |
| test $val = "true" && object_format="true" || object_format= |
| echo "ok" |
| ;; |
| *) |
| echo "unsupported" |
| ;; |
| esac |
| ;; |
| '') |
| exit |
| ;; |
| esac |
| done |