fetch,parse-remote,fmt-merge-msg: refs/remotes/* support
[git.git] / git-parse-remote.sh
1 #!/bin/sh
2
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) || :;
6
7 get_data_source () {
8         case "$1" in
9         */*)
10                 # Not so fast.  This could be the partial URL shorthand...
11                 token=$(expr "$1" : '\([^/]*\)/')
12                 remainder=$(expr "$1" : '[^/]*/\(.*\)')
13                 if test -f "$GIT_DIR/branches/$token"
14                 then
15                         echo branches-partial
16                 else
17                         echo ''
18                 fi
19                 ;;
20         *)
21                 if test -f "$GIT_DIR/remotes/$1"
22                 then
23                         echo remotes
24                 elif test -f "$GIT_DIR/branches/$1"
25                 then
26                         echo branches
27                 else
28                         echo ''
29                 fi ;;
30         esac
31 }
32
33 get_remote_url () {
34         data_source=$(get_data_source "$1")
35         case "$data_source" in
36         '')
37                 echo "$1" ;;
38         remotes)
39                 sed -ne '/^URL: */{
40                         s///p
41                         q
42                 }' "$GIT_DIR/remotes/$1" ;;
43         branches)
44                 sed -e 's/#.*//' "$GIT_DIR/branches/$1" ;;
45         branches-partial)
46                 token=$(expr "$1" : '\([^/]*\)/')
47                 remainder=$(expr "$1" : '[^/]*/\(.*\)')
48                 url=$(sed -e 's/#.*//' "$GIT_DIR/branches/$token")
49                 echo "$url/$remainder"
50                 ;;
51         *)
52                 die "internal error: get-remote-url $1" ;;
53         esac
54 }
55
56 get_remote_default_refs_for_push () {
57         data_source=$(get_data_source "$1")
58         case "$data_source" in
59         '' | branches | branches-partial)
60                 ;; # no default push mapping, just send matching refs.
61         remotes)
62                 sed -ne '/^Push: */{
63                         s///p
64                 }' "$GIT_DIR/remotes/$1" ;;
65         *)
66                 die "internal error: get-remote-default-ref-for-push $1" ;;
67         esac
68 }
69
70 # Subroutine to canonicalize remote:local notation.
71 canon_refs_list_for_fetch () {
72         # Leave only the first one alone; add prefix . to the rest
73         # to prevent the secondary branches to be merged by default.
74         dot_prefix=
75         for ref
76         do
77                 force=
78                 case "$ref" in
79                 +*)
80                         ref=$(expr "$ref" : '\+\(.*\)')
81                         force=+
82                         ;;
83                 esac
84                 expr "$ref" : '.*:' >/dev/null || ref="${ref}:"
85                 remote=$(expr "$ref" : '\([^:]*\):')
86                 local=$(expr "$ref" : '[^:]*:\(.*\)')
87                 case "$remote" in
88                 '') remote=HEAD ;;
89                 refs/heads/* | refs/tags/* | refs/remotes/*) ;;
90                 heads/* | tags/* | remotes/* ) remote="refs/$remote" ;;
91                 *) remote="refs/heads/$remote" ;;
92                 esac
93                 case "$local" in
94                 '') local= ;;
95                 refs/heads/* | refs/tags/* | refs/remotes/*) ;;
96                 heads/* | tags/* | remotes/* ) local="refs/$local" ;;
97                 *) local="refs/heads/$local" ;;
98                 esac
99
100                 if local_ref_name=$(expr "$local" : 'refs/\(.*\)')
101                 then
102                    git-check-ref-format "$local_ref_name" ||
103                    die "* refusing to create funny ref '$local_ref_name' locally"
104                 fi
105                 echo "${dot_prefix}${force}${remote}:${local}"
106                 dot_prefix=.
107         done
108 }
109
110 # Returns list of src: (no store), or src:dst (store)
111 get_remote_default_refs_for_fetch () {
112         data_source=$(get_data_source "$1")
113         case "$data_source" in
114         '' | branches-partial)
115                 echo "HEAD:" ;;
116         branches)
117                 remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
118                 case "$remote_branch" in '') remote_branch=master ;; esac
119                 echo "refs/heads/${remote_branch}:refs/heads/$1"
120                 ;;
121         remotes)
122                 # This prefixes the second and later default refspecs
123                 # with a '.', to signal git-fetch to mark them
124                 # not-for-merge.
125                 canon_refs_list_for_fetch $(sed -ne '/^Pull: */{
126                                                 s///p
127                                         }' "$GIT_DIR/remotes/$1")
128                 ;;
129         *)
130                 die "internal error: get-remote-default-ref-for-push $1" ;;
131         esac
132 }
133
134 get_remote_refs_for_push () {
135         case "$#" in
136         0) die "internal error: get-remote-refs-for-push." ;;
137         1) get_remote_default_refs_for_push "$@" ;;
138         *) shift; echo "$@" ;;
139         esac
140 }
141
142 get_remote_refs_for_fetch () {
143         case "$#" in
144         0)
145             die "internal error: get-remote-refs-for-fetch." ;;
146         1)
147             get_remote_default_refs_for_fetch "$@" ;;
148         *)
149             shift
150             tag_just_seen=
151             for ref
152             do
153                 if test "$tag_just_seen"
154                 then
155                     echo "refs/tags/${ref}:refs/tags/${ref}"
156                     tag_just_seen=
157                     continue
158                 else
159                     case "$ref" in
160                     tag)
161                         tag_just_seen=yes
162                         continue
163                         ;;
164                     esac
165                 fi
166                 canon_refs_list_for_fetch "$ref"
167             done
168             ;;
169         esac
170 }
171
172 resolve_alternates () {
173         # original URL (xxx.git)
174         top_=`expr "$1" : '\([^:]*:/*[^/]*\)/'`
175         while read path
176         do
177                 case "$path" in
178                 \#* | '')
179                         continue ;;
180                 /*)
181                         echo "$top_$path/" ;;
182                 ../*)
183                         # relative -- ugly but seems to work.
184                         echo "$1/objects/$path/" ;;
185                 *)
186                         # exit code may not be caught by the reader.
187                         echo "bad alternate: $path"
188                         exit 1 ;;
189                 esac
190         done
191 }