Code

update hook: redirect _both_ diagnostic lines to stderr upon tag failure
[git.git] / git-parse-remote.sh
1 #!/bin/sh
3 # git-ls-remote could be called from outside a git managed repository;
4 # this would fail in that case and would issue an error message.
5 GIT_DIR=$(git-rev-parse --git-dir 2>/dev/null) || :;
7 get_data_source () {
8         case "$1" in
9         */*)
10                 echo ''
11                 ;;
12         *)
13                 if test "$(git-repo-config --get "remote.$1.url")"
14                 then
15                         echo config
16                 elif test -f "$GIT_DIR/remotes/$1"
17                 then
18                         echo remotes
19                 elif test -f "$GIT_DIR/branches/$1"
20                 then
21                         echo branches
22                 else
23                         echo ''
24                 fi ;;
25         esac
26 }
28 get_remote_url () {
29         data_source=$(get_data_source "$1")
30         case "$data_source" in
31         '')
32                 echo "$1"
33                 ;;
34         config)
35                 git-repo-config --get "remote.$1.url"
36                 ;;
37         remotes)
38                 sed -ne '/^URL: */{
39                         s///p
40                         q
41                 }' "$GIT_DIR/remotes/$1"
42                 ;;
43         branches)
44                 sed -e 's/#.*//' "$GIT_DIR/branches/$1"
45                 ;;
46         *)
47                 die "internal error: get-remote-url $1" ;;
48         esac
49 }
51 get_default_remote () {
52         curr_branch=$(git-symbolic-ref HEAD | sed -e 's|^refs/heads/||')
53         origin=$(git-repo-config --get "branch.$curr_branch.remote")
54         echo ${origin:-origin}
55 }
57 get_remote_default_refs_for_push () {
58         data_source=$(get_data_source "$1")
59         case "$data_source" in
60         '' | branches)
61                 ;; # no default push mapping, just send matching refs.
62         config)
63                 git-repo-config --get-all "remote.$1.push" ;;
64         remotes)
65                 sed -ne '/^Push: */{
66                         s///p
67                 }' "$GIT_DIR/remotes/$1" ;;
68         *)
69                 die "internal error: get-remote-default-ref-for-push $1" ;;
70         esac
71 }
73 # Called from canon_refs_list_for_fetch -d "$remote", which
74 # is called from get_remote_default_refs_for_fetch to grok
75 # refspecs that are retrieved from the configuration, but not
76 # from get_remote_refs_for_fetch when it deals with refspecs
77 # supplied on the command line.  $ls_remote_result has the list
78 # of refs available at remote.
79 expand_refs_wildcard () {
80         for ref
81         do
82                 lref=${ref#'+'}
83                 # a non glob pattern is given back as-is.
84                 expr "z$lref" : 'zrefs/.*/\*:refs/.*/\*$' >/dev/null || {
85                         echo "$ref"
86                         continue
87                 }
89                 from=`expr "z$lref" : 'z\(refs/.*/\)\*:refs/.*/\*$'`
90                 to=`expr "z$lref" : 'zrefs/.*/\*:\(refs/.*/\)\*$'`
91                 local_force=
92                 test "z$lref" = "z$ref" || local_force='+'
93                 echo "$ls_remote_result" |
94                 sed -e '/\^{}$/d' |
95                 (
96                         IFS='   '
97                         while read sha1 name
98                         do
99                                 # ignore the ones that do not start with $from
100                                 mapped=${name#"$from"}
101                                 test "z$name" = "z$mapped" && continue
102                                 echo "${local_force}${name}:${to}${mapped}"
103                         done
104                 )
105         done
108 # Subroutine to canonicalize remote:local notation.
109 canon_refs_list_for_fetch () {
110         # If called from get_remote_default_refs_for_fetch
111         # leave the branches in branch.${curr_branch}.merge alone,
112         # or the first one otherwise; add prefix . to the rest
113         # to prevent the secondary branches to be merged by default.
114         merge_branches=
115         curr_branch=
116         if test "$1" = "-d"
117         then
118                 shift ; remote="$1" ; shift
119                 set x $(expand_refs_wildcard "$@")
120                 shift
121                 if test "$remote" = "$(get_default_remote)"
122                 then
123                         curr_branch=$(git-symbolic-ref HEAD | \
124                             sed -e 's|^refs/heads/||')
125                         merge_branches=$(git-repo-config \
126                             --get-all "branch.${curr_branch}.merge")
127                 fi
128         fi
129         for ref
130         do
131                 force=
132                 case "$ref" in
133                 +*)
134                         ref=$(expr "z$ref" : 'z+\(.*\)')
135                         force=+
136                         ;;
137                 esac
138                 expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
139                 remote=$(expr "z$ref" : 'z\([^:]*\):')
140                 local=$(expr "z$ref" : 'z[^:]*:\(.*\)')
141                 dot_prefix=.
142                 if test -z "$merge_branches"
143                 then
144                         merge_branches=$remote
145                         dot_prefix=
146                 else
147                         for merge_branch in $merge_branches
148                         do
149                             if  test "$remote" = "$merge_branch" ||
150                                 test "$local" = "$merge_branch"
151                             then
152                                     dot_prefix=
153                                     break
154                             fi
155                         done
156                 fi
157                 case "$remote" in
158                 '') remote=HEAD ;;
159                 refs/heads/* | refs/tags/* | refs/remotes/*) ;;
160                 heads/* | tags/* | remotes/* ) remote="refs/$remote" ;;
161                 *) remote="refs/heads/$remote" ;;
162                 esac
163                 case "$local" in
164                 '') local= ;;
165                 refs/heads/* | refs/tags/* | refs/remotes/*) ;;
166                 heads/* | tags/* | remotes/* ) local="refs/$local" ;;
167                 *) local="refs/heads/$local" ;;
168                 esac
170                 if local_ref_name=$(expr "z$local" : 'zrefs/\(.*\)')
171                 then
172                    git-check-ref-format "$local_ref_name" ||
173                    die "* refusing to create funny ref '$local_ref_name' locally"
174                 fi
175                 echo "${dot_prefix}${force}${remote}:${local}"
176         done
179 # Returns list of src: (no store), or src:dst (store)
180 get_remote_default_refs_for_fetch () {
181         data_source=$(get_data_source "$1")
182         case "$data_source" in
183         '')
184                 echo "HEAD:" ;;
185         config)
186                 canon_refs_list_for_fetch -d "$1" \
187                         $(git-repo-config --get-all "remote.$1.fetch") ;;
188         branches)
189                 remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
190                 case "$remote_branch" in '') remote_branch=master ;; esac
191                 echo "refs/heads/${remote_branch}:refs/heads/$1"
192                 ;;
193         remotes)
194                 canon_refs_list_for_fetch -d "$1" $(sed -ne '/^Pull: */{
195                                                 s///p
196                                         }' "$GIT_DIR/remotes/$1")
197                 ;;
198         *)
199                 die "internal error: get-remote-default-ref-for-push $1" ;;
200         esac
203 get_remote_refs_for_push () {
204         case "$#" in
205         0) die "internal error: get-remote-refs-for-push." ;;
206         1) get_remote_default_refs_for_push "$@" ;;
207         *) shift; echo "$@" ;;
208         esac
211 get_remote_refs_for_fetch () {
212         case "$#" in
213         0)
214             die "internal error: get-remote-refs-for-fetch." ;;
215         1)
216             get_remote_default_refs_for_fetch "$@" ;;
217         *)
218             shift
219             tag_just_seen=
220             for ref
221             do
222                 if test "$tag_just_seen"
223                 then
224                     echo "refs/tags/${ref}:refs/tags/${ref}"
225                     tag_just_seen=
226                     continue
227                 else
228                     case "$ref" in
229                     tag)
230                         tag_just_seen=yes
231                         continue
232                         ;;
233                     esac
234                 fi
235                 canon_refs_list_for_fetch "$ref"
236             done
237             ;;
238         esac
241 resolve_alternates () {
242         # original URL (xxx.git)
243         top_=`expr "z$1" : 'z\([^:]*:/*[^/]*\)/'`
244         while read path
245         do
246                 case "$path" in
247                 \#* | '')
248                         continue ;;
249                 /*)
250                         echo "$top_$path/" ;;
251                 ../*)
252                         # relative -- ugly but seems to work.
253                         echo "$1/objects/$path/" ;;
254                 *)
255                         # exit code may not be caught by the reader.
256                         echo "bad alternate: $path"
257                         exit 1 ;;
258                 esac
259         done