Merge branch 'fixes'
[git.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                 echo "${dot_prefix}${force}${remote}:${local}"
98                 dot_prefix=.
99         done
100 }
101
102 # Returns list of src: (no store), or src:dst (store)
103 get_remote_default_refs_for_fetch () {
104         data_source=$(get_data_source "$1")
105         case "$data_source" in
106         '' | branches-partial)
107                 echo "HEAD:" ;;
108         branches)
109                 remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
110                 case "$remote_branch" in '') remote_branch=master ;; esac
111                 echo "refs/heads/${remote_branch}:refs/heads/$1"
112                 ;;
113         remotes)
114                 # This prefixes the second and later default refspecs
115                 # with a '.', to signal git-fetch to mark them
116                 # not-for-merge.
117                 canon_refs_list_for_fetch $(sed -ne '/^Pull: */{
118                                                 s///p
119                                         }' "$GIT_DIR/remotes/$1")
120                 ;;
121         *)
122                 die "internal error: get-remote-default-ref-for-push $1" ;;
123         esac
124 }
125
126 get_remote_refs_for_push () {
127         case "$#" in
128         0) die "internal error: get-remote-refs-for-push." ;;
129         1) get_remote_default_refs_for_push "$@" ;;
130         *) shift; echo "$@" ;;
131         esac
132 }
133
134 get_remote_refs_for_fetch () {
135         case "$#" in
136         0)
137             die "internal error: get-remote-refs-for-fetch." ;;
138         1)
139             get_remote_default_refs_for_fetch "$@" ;;
140         *)
141             shift
142             tag_just_seen=
143             for ref
144             do
145                 if test "$tag_just_seen"
146                 then
147                     echo "refs/tags/${ref}:refs/tags/${ref}"
148                     tag_just_seen=
149                     continue
150                 else
151                     case "$ref" in
152                     tag)
153                         tag_just_seen=yes
154                         continue
155                         ;;
156                     esac
157                 fi
158                 canon_refs_list_for_fetch "$ref"
159             done
160             ;;
161         esac
162 }
163
164 resolve_alternates () {
165         # original URL (xxx.git)
166         top_=`expr "$1" : '\([^:]*:/*[^/]*\)/'`
167         while read path
168         do
169                 case "$path" in
170                 \#* | '')
171                         continue ;;
172                 /*)
173                         echo "$top_$path/" ;;
174                 ../*)
175                         # relative -- ugly but seems to work.
176                         echo "$1/objects/$path/" ;;
177                 *)
178                         # exit code may not be caught by the reader.
179                         echo "bad alternate: $path"
180                         exit 1 ;;
181                 esac
182         done
183 }