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