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