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