| 1 | #!/bin/sh |
| 2 | # Copyright (c) 2012 Felipe Contreras |
| 3 | |
| 4 | # The first argument can be a url when the fetch/push command was a url |
| 5 | # instead of a configured remote. In this case, use a generic alias. |
| 6 | if test "$1" = "testgit::$2"; then |
| 7 | alias=_ |
| 8 | else |
| 9 | alias=$1 |
| 10 | fi |
| 11 | url=$2 |
| 12 | |
| 13 | dir="$GIT_DIR/testgit/$alias" |
| 14 | |
| 15 | if ! git rev-parse --is-inside-git-dir |
| 16 | then |
| 17 | exit 1 |
| 18 | fi |
| 19 | |
| 20 | h_refspec="refs/heads/*:refs/testgit/$alias/heads/*" |
| 21 | t_refspec="refs/tags/*:refs/testgit/$alias/tags/*" |
| 22 | |
| 23 | if test -n "$GIT_REMOTE_TESTGIT_NOREFSPEC" |
| 24 | then |
| 25 | h_refspec="" |
| 26 | t_refspec="" |
| 27 | fi |
| 28 | |
| 29 | unset $(git rev-parse --local-env-vars) |
| 30 | GIT_DIR=$(git -C "$url" rev-parse --absolute-git-dir) |
| 31 | export GIT_DIR |
| 32 | |
| 33 | force= |
| 34 | object_format= |
| 35 | |
| 36 | mkdir -p "$dir" |
| 37 | |
| 38 | if test -z "$GIT_REMOTE_TESTGIT_NO_MARKS" |
| 39 | then |
| 40 | gitmarks="$dir/git.marks" |
| 41 | testgitmarks="$dir/testgit.marks" |
| 42 | test -e "$gitmarks" || >"$gitmarks" |
| 43 | test -e "$testgitmarks" || >"$testgitmarks" |
| 44 | fi |
| 45 | |
| 46 | while read line |
| 47 | do |
| 48 | case $line in |
| 49 | capabilities) |
| 50 | echo 'import' |
| 51 | echo 'export' |
| 52 | test -n "$h_refspec" && echo "refspec $h_refspec" |
| 53 | test -n "$t_refspec" && echo "refspec $t_refspec" |
| 54 | if test -n "$gitmarks" |
| 55 | then |
| 56 | echo "*import-marks $gitmarks" |
| 57 | echo "*export-marks $gitmarks" |
| 58 | fi |
| 59 | test -n "$GIT_REMOTE_TESTGIT_SIGNED_TAGS" && echo "signed-tags" |
| 60 | test -n "$GIT_REMOTE_TESTGIT_NO_PRIVATE_UPDATE" && echo "no-private-update" |
| 61 | echo 'option' |
| 62 | echo 'object-format' |
| 63 | echo |
| 64 | ;; |
| 65 | list) |
| 66 | test -n "$object_format" && |
| 67 | echo ":object-format $(git rev-parse --show-object-format=storage)" |
| 68 | git for-each-ref --format='? %(refname)' 'refs/heads/' 'refs/tags/' |
| 69 | head=$(git symbolic-ref HEAD) |
| 70 | echo "@$head HEAD" |
| 71 | echo |
| 72 | ;; |
| 73 | import*) |
| 74 | # read all import lines |
| 75 | while true |
| 76 | do |
| 77 | ref="${line#* }" |
| 78 | refs="$refs $ref" |
| 79 | read line |
| 80 | test "${line%% *}" != "import" && break |
| 81 | done |
| 82 | |
| 83 | if test -n "$gitmarks" |
| 84 | then |
| 85 | echo "feature import-marks=$gitmarks" |
| 86 | echo "feature export-marks=$gitmarks" |
| 87 | fi |
| 88 | |
| 89 | if test -n "$GIT_REMOTE_TESTGIT_FAILURE" |
| 90 | then |
| 91 | echo "feature done" |
| 92 | exit 1 |
| 93 | fi |
| 94 | |
| 95 | echo "feature done" |
| 96 | git fast-export \ |
| 97 | ${h_refspec:+"--refspec=$h_refspec"} \ |
| 98 | ${t_refspec:+"--refspec=$t_refspec"} \ |
| 99 | ${testgitmarks:+"--import-marks=$testgitmarks"} \ |
| 100 | ${testgitmarks:+"--export-marks=$testgitmarks"} \ |
| 101 | $refs |
| 102 | echo "done" |
| 103 | ;; |
| 104 | export) |
| 105 | if test -n "$GIT_REMOTE_TESTGIT_FAILURE" |
| 106 | then |
| 107 | # consume input so fast-export doesn't get SIGPIPE; |
| 108 | # git would also notice that case, but we want |
| 109 | # to make sure we are exercising the later |
| 110 | # error checks |
| 111 | while read line; do |
| 112 | test "done" = "$line" && break |
| 113 | done |
| 114 | exit 1 |
| 115 | fi |
| 116 | |
| 117 | before=$(git for-each-ref --format=' %(refname) %(objectname) ') |
| 118 | |
| 119 | git fast-import \ |
| 120 | ${force:+--force} \ |
| 121 | ${testgitmarks:+"--import-marks=$testgitmarks"} \ |
| 122 | ${testgitmarks:+"--export-marks=$testgitmarks"} \ |
| 123 | --quiet |
| 124 | |
| 125 | # figure out which refs were updated |
| 126 | git for-each-ref --format='%(refname) %(objectname)' | |
| 127 | while read ref a |
| 128 | do |
| 129 | case "$before" in |
| 130 | *" $ref $a "*) |
| 131 | continue ;; # unchanged |
| 132 | esac |
| 133 | if test -z "$GIT_REMOTE_TESTGIT_PUSH_ERROR" |
| 134 | then |
| 135 | echo "ok $ref" |
| 136 | else |
| 137 | echo "error $ref $GIT_REMOTE_TESTGIT_PUSH_ERROR" |
| 138 | fi |
| 139 | done |
| 140 | |
| 141 | echo |
| 142 | ;; |
| 143 | option\ *) |
| 144 | read cmd opt val <<-EOF |
| 145 | $line |
| 146 | EOF |
| 147 | case $opt in |
| 148 | force) |
| 149 | test $val = "true" && force="true" || force= |
| 150 | echo "ok" |
| 151 | ;; |
| 152 | object-format) |
| 153 | test $val = "true" && object_format="true" || object_format= |
| 154 | echo "ok" |
| 155 | ;; |
| 156 | *) |
| 157 | echo "unsupported" |
| 158 | ;; |
| 159 | esac |
| 160 | ;; |
| 161 | '') |
| 162 | exit |
| 163 | ;; |
| 164 | esac |
| 165 | done |