Code

Do not support "partial URL shorthand" anymore.
[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                             [ "$remote" = "$merge_branch" ] &&
150                             dot_prefix= && break
151                         done
152                 fi
153                 case "$remote" in
154                 '') remote=HEAD ;;
155                 refs/heads/* | refs/tags/* | refs/remotes/*) ;;
156                 heads/* | tags/* | remotes/* ) remote="refs/$remote" ;;
157                 *) remote="refs/heads/$remote" ;;
158                 esac
159                 case "$local" in
160                 '') local= ;;
161                 refs/heads/* | refs/tags/* | refs/remotes/*) ;;
162                 heads/* | tags/* | remotes/* ) local="refs/$local" ;;
163                 *) local="refs/heads/$local" ;;
164                 esac
166                 if local_ref_name=$(expr "z$local" : 'zrefs/\(.*\)')
167                 then
168                    git-check-ref-format "$local_ref_name" ||
169                    die "* refusing to create funny ref '$local_ref_name' locally"
170                 fi
171                 echo "${dot_prefix}${force}${remote}:${local}"
172         done
175 # Returns list of src: (no store), or src:dst (store)
176 get_remote_default_refs_for_fetch () {
177         data_source=$(get_data_source "$1")
178         case "$data_source" in
179         '')
180                 echo "HEAD:" ;;
181         config)
182                 canon_refs_list_for_fetch -d "$1" \
183                         $(git-repo-config --get-all "remote.$1.fetch") ;;
184         branches)
185                 remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
186                 case "$remote_branch" in '') remote_branch=master ;; esac
187                 echo "refs/heads/${remote_branch}:refs/heads/$1"
188                 ;;
189         remotes)
190                 canon_refs_list_for_fetch -d "$1" $(sed -ne '/^Pull: */{
191                                                 s///p
192                                         }' "$GIT_DIR/remotes/$1")
193                 ;;
194         *)
195                 die "internal error: get-remote-default-ref-for-push $1" ;;
196         esac
199 get_remote_refs_for_push () {
200         case "$#" in
201         0) die "internal error: get-remote-refs-for-push." ;;
202         1) get_remote_default_refs_for_push "$@" ;;
203         *) shift; echo "$@" ;;
204         esac
207 get_remote_refs_for_fetch () {
208         case "$#" in
209         0)
210             die "internal error: get-remote-refs-for-fetch." ;;
211         1)
212             get_remote_default_refs_for_fetch "$@" ;;
213         *)
214             shift
215             tag_just_seen=
216             for ref
217             do
218                 if test "$tag_just_seen"
219                 then
220                     echo "refs/tags/${ref}:refs/tags/${ref}"
221                     tag_just_seen=
222                     continue
223                 else
224                     case "$ref" in
225                     tag)
226                         tag_just_seen=yes
227                         continue
228                         ;;
229                     esac
230                 fi
231                 canon_refs_list_for_fetch "$ref"
232             done
233             ;;
234         esac
237 resolve_alternates () {
238         # original URL (xxx.git)
239         top_=`expr "z$1" : 'z\([^:]*:/*[^/]*\)/'`
240         while read path
241         do
242                 case "$path" in
243                 \#* | '')
244                         continue ;;
245                 /*)
246                         echo "$top_$path/" ;;
247                 ../*)
248                         # relative -- ugly but seems to work.
249                         echo "$1/objects/$path/" ;;
250                 *)
251                         # exit code may not be caught by the reader.
252                         echo "bad alternate: $path"
253                         exit 1 ;;
254                 esac
255         done