]>
Commit | Line | Data |
---|---|---|
ac4b0cff JH |
1 | #!/bin/sh |
2 | ||
e8cc80d0 JH |
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) || :; | |
ac4b0cff JH |
6 | |
7 | get_data_source () { | |
8 | case "$1" in | |
9 | */*) | |
ea560e6d | 10 | echo '' |
ac4b0cff JH |
11 | ;; |
12 | *) | |
73136b2e JS |
13 | if test "$(git-repo-config --get "remote.$1.url")" |
14 | then | |
15 | echo config | |
16 | elif test -f "$GIT_DIR/remotes/$1" | |
ac4b0cff JH |
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 | } | |
27 | ||
28 | get_remote_url () { | |
29 | data_source=$(get_data_source "$1") | |
30 | case "$data_source" in | |
31 | '') | |
ea560e6d | 32 | echo "$1" |
73136b2e JS |
33 | ;; |
34 | config) | |
35 | git-repo-config --get "remote.$1.url" | |
36 | ;; | |
ac4b0cff JH |
37 | remotes) |
38 | sed -ne '/^URL: */{ | |
39 | s///p | |
40 | q | |
ea560e6d JH |
41 | }' "$GIT_DIR/remotes/$1" |
42 | ;; | |
ac4b0cff | 43 | branches) |
ea560e6d | 44 | sed -e 's/#.*//' "$GIT_DIR/branches/$1" |
ac4b0cff JH |
45 | ;; |
46 | *) | |
47 | die "internal error: get-remote-url $1" ;; | |
48 | esac | |
49 | } | |
50 | ||
648ad18f SB |
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 | } | |
56 | ||
ac4b0cff JH |
57 | get_remote_default_refs_for_push () { |
58 | data_source=$(get_data_source "$1") | |
59 | case "$data_source" in | |
ea560e6d | 60 | '' | branches) |
ac4b0cff | 61 | ;; # no default push mapping, just send matching refs. |
73136b2e JS |
62 | config) |
63 | git-repo-config --get-all "remote.$1.push" ;; | |
ac4b0cff JH |
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 | } | |
72 | ||
5677882b JH |
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. | |
fbc90123 JH |
79 | # |
80 | # The first token returned is either "explicit" or "glob"; this | |
81 | # is to help prevent randomly "globbed" ref from being chosen as | |
82 | # a merge candidate | |
5677882b | 83 | expand_refs_wildcard () { |
fbc90123 | 84 | first_one=yes |
5677882b JH |
85 | for ref |
86 | do | |
d945d4be | 87 | lref=${ref#'+'} |
5677882b | 88 | # a non glob pattern is given back as-is. |
d945d4be | 89 | expr "z$lref" : 'zrefs/.*/\*:refs/.*/\*$' >/dev/null || { |
fbc90123 JH |
90 | if test -n "$first_one" |
91 | then | |
92 | echo "explicit" | |
93 | first_one= | |
94 | fi | |
5677882b JH |
95 | echo "$ref" |
96 | continue | |
97 | } | |
d945d4be | 98 | |
fbc90123 JH |
99 | # glob |
100 | if test -n "$first_one" | |
101 | then | |
102 | echo "glob" | |
103 | first_one= | |
104 | fi | |
d945d4be JH |
105 | from=`expr "z$lref" : 'z\(refs/.*/\)\*:refs/.*/\*$'` |
106 | to=`expr "z$lref" : 'zrefs/.*/\*:\(refs/.*/\)\*$'` | |
107 | local_force= | |
108 | test "z$lref" = "z$ref" || local_force='+' | |
5677882b | 109 | echo "$ls_remote_result" | |
0c7a97fa | 110 | sed -e '/\^{}$/d' | |
5677882b JH |
111 | ( |
112 | IFS=' ' | |
113 | while read sha1 name | |
114 | do | |
0c7a97fa | 115 | # ignore the ones that do not start with $from |
5677882b | 116 | mapped=${name#"$from"} |
0c7a97fa | 117 | test "z$name" = "z$mapped" && continue |
d945d4be | 118 | echo "${local_force}${name}:${to}${mapped}" |
5677882b JH |
119 | done |
120 | ) | |
121 | done | |
122 | } | |
123 | ||
05dd8e2e | 124 | # Subroutine to canonicalize remote:local notation. |
ac4b0cff | 125 | canon_refs_list_for_fetch () { |
5372806a SB |
126 | # If called from get_remote_default_refs_for_fetch |
127 | # leave the branches in branch.${curr_branch}.merge alone, | |
128 | # or the first one otherwise; add prefix . to the rest | |
05dd8e2e | 129 | # to prevent the secondary branches to be merged by default. |
5372806a | 130 | merge_branches= |
62b339a5 | 131 | curr_branch= |
5372806a SB |
132 | if test "$1" = "-d" |
133 | then | |
134 | shift ; remote="$1" ; shift | |
fbc90123 JH |
135 | set $(expand_refs_wildcard "$@") |
136 | is_explicit="$1" | |
d41cb273 | 137 | shift |
5372806a SB |
138 | if test "$remote" = "$(get_default_remote)" |
139 | then | |
140 | curr_branch=$(git-symbolic-ref HEAD | \ | |
141 | sed -e 's|^refs/heads/||') | |
142 | merge_branches=$(git-repo-config \ | |
9e115549 | 143 | --get-all "branch.${curr_branch}.merge") |
5372806a | 144 | fi |
fbc90123 JH |
145 | if test -z "$merge_branches" && test $is_explicit != explicit |
146 | then | |
147 | merge_branches=..this.will.never.match.any.ref.. | |
148 | fi | |
5372806a | 149 | fi |
ac4b0cff JH |
150 | for ref |
151 | do | |
efe9bf0f JH |
152 | force= |
153 | case "$ref" in | |
154 | +*) | |
dfdcb558 | 155 | ref=$(expr "z$ref" : 'z+\(.*\)') |
efe9bf0f JH |
156 | force=+ |
157 | ;; | |
158 | esac | |
f327dbce MW |
159 | expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:" |
160 | remote=$(expr "z$ref" : 'z\([^:]*\):') | |
161 | local=$(expr "z$ref" : 'z[^:]*:\(.*\)') | |
5372806a SB |
162 | dot_prefix=. |
163 | if test -z "$merge_branches" | |
164 | then | |
165 | merge_branches=$remote | |
166 | dot_prefix= | |
167 | else | |
168 | for merge_branch in $merge_branches | |
169 | do | |
80c79776 JH |
170 | if test "$remote" = "$merge_branch" || |
171 | test "$local" = "$merge_branch" | |
172 | then | |
173 | dot_prefix= | |
174 | break | |
175 | fi | |
5372806a SB |
176 | done |
177 | fi | |
ac4b0cff JH |
178 | case "$remote" in |
179 | '') remote=HEAD ;; | |
687b8be8 EW |
180 | refs/heads/* | refs/tags/* | refs/remotes/*) ;; |
181 | heads/* | tags/* | remotes/* ) remote="refs/$remote" ;; | |
ac4b0cff JH |
182 | *) remote="refs/heads/$remote" ;; |
183 | esac | |
184 | case "$local" in | |
185 | '') local= ;; | |
687b8be8 EW |
186 | refs/heads/* | refs/tags/* | refs/remotes/*) ;; |
187 | heads/* | tags/* | remotes/* ) local="refs/$local" ;; | |
ac4b0cff JH |
188 | *) local="refs/heads/$local" ;; |
189 | esac | |
d8a1deec | 190 | |
f327dbce | 191 | if local_ref_name=$(expr "z$local" : 'zrefs/\(.*\)') |
d8a1deec JH |
192 | then |
193 | git-check-ref-format "$local_ref_name" || | |
194 | die "* refusing to create funny ref '$local_ref_name' locally" | |
195 | fi | |
05dd8e2e | 196 | echo "${dot_prefix}${force}${remote}:${local}" |
ac4b0cff JH |
197 | done |
198 | } | |
199 | ||
200 | # Returns list of src: (no store), or src:dst (store) | |
201 | get_remote_default_refs_for_fetch () { | |
202 | data_source=$(get_data_source "$1") | |
203 | case "$data_source" in | |
ea560e6d | 204 | '') |
ac4b0cff | 205 | echo "HEAD:" ;; |
73136b2e | 206 | config) |
5372806a | 207 | canon_refs_list_for_fetch -d "$1" \ |
73136b2e | 208 | $(git-repo-config --get-all "remote.$1.fetch") ;; |
ac4b0cff JH |
209 | branches) |
210 | remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1") | |
211 | case "$remote_branch" in '') remote_branch=master ;; esac | |
212 | echo "refs/heads/${remote_branch}:refs/heads/$1" | |
213 | ;; | |
214 | remotes) | |
5372806a | 215 | canon_refs_list_for_fetch -d "$1" $(sed -ne '/^Pull: */{ |
ac4b0cff JH |
216 | s///p |
217 | }' "$GIT_DIR/remotes/$1") | |
218 | ;; | |
219 | *) | |
220 | die "internal error: get-remote-default-ref-for-push $1" ;; | |
221 | esac | |
222 | } | |
223 | ||
224 | get_remote_refs_for_push () { | |
225 | case "$#" in | |
226 | 0) die "internal error: get-remote-refs-for-push." ;; | |
227 | 1) get_remote_default_refs_for_push "$@" ;; | |
228 | *) shift; echo "$@" ;; | |
229 | esac | |
230 | } | |
231 | ||
232 | get_remote_refs_for_fetch () { | |
233 | case "$#" in | |
234 | 0) | |
235 | die "internal error: get-remote-refs-for-fetch." ;; | |
236 | 1) | |
237 | get_remote_default_refs_for_fetch "$@" ;; | |
238 | *) | |
239 | shift | |
240 | tag_just_seen= | |
241 | for ref | |
242 | do | |
243 | if test "$tag_just_seen" | |
244 | then | |
245 | echo "refs/tags/${ref}:refs/tags/${ref}" | |
246 | tag_just_seen= | |
247 | continue | |
248 | else | |
249 | case "$ref" in | |
250 | tag) | |
efe9bf0f | 251 | tag_just_seen=yes |
ac4b0cff JH |
252 | continue |
253 | ;; | |
254 | esac | |
255 | fi | |
efe9bf0f | 256 | canon_refs_list_for_fetch "$ref" |
ac4b0cff JH |
257 | done |
258 | ;; | |
259 | esac | |
260 | } | |
4447badc JH |
261 | |
262 | resolve_alternates () { | |
263 | # original URL (xxx.git) | |
f327dbce | 264 | top_=`expr "z$1" : 'z\([^:]*:/*[^/]*\)/'` |
4447badc JH |
265 | while read path |
266 | do | |
267 | case "$path" in | |
268 | \#* | '') | |
269 | continue ;; | |
270 | /*) | |
271 | echo "$top_$path/" ;; | |
272 | ../*) | |
273 | # relative -- ugly but seems to work. | |
274 | echo "$1/objects/$path/" ;; | |
275 | *) | |
276 | # exit code may not be caught by the reader. | |
277 | echo "bad alternate: $path" | |
278 | exit 1 ;; | |
279 | esac | |
280 | done | |
281 | } |