1#!/bin/sh
2
3. git-sh-setup || die "Not a git archive"
4
5get_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
31get_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
54get_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
69canon_refs_list_for_fetch () {
70 for ref
71 do
72 force=
73 case "$ref" in
74 +*)
75 ref=$(expr "$ref" : '\+\(.*\)')
76 force=+
77 ;;
78 esac
79 expr "$ref" : '.*:' >/dev/null || ref="${ref}:"
80 remote=$(expr "$ref" : '\([^:]*\):')
81 local=$(expr "$ref" : '[^:]*:\(.*\)')
82 case "$remote" in
83 '') remote=HEAD ;;
84 refs/heads/* | refs/tags/*) ;;
85 heads/* | tags/* ) remote="refs/$remote" ;;
86 *) remote="refs/heads/$remote" ;;
87 esac
88 case "$local" in
89 '') local= ;;
90 refs/heads/* | refs/tags/*) ;;
91 heads/* | tags/* ) local="refs/$local" ;;
92 *) local="refs/heads/$local" ;;
93 esac
94 echo "${force}${remote}:${local}"
95 done
96}
97
98# Returns list of src: (no store), or src:dst (store)
99get_remote_default_refs_for_fetch () {
100 data_source=$(get_data_source "$1")
101 case "$data_source" in
102 '' | branches-partial)
103 echo "HEAD:" ;;
104 branches)
105 remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
106 case "$remote_branch" in '') remote_branch=master ;; esac
107 echo "refs/heads/${remote_branch}:refs/heads/$1"
108 ;;
109 remotes)
110 canon_refs_list_for_fetch $(sed -ne '/^Pull: */{
111 s///p
112 }' "$GIT_DIR/remotes/$1")
113 ;;
114 *)
115 die "internal error: get-remote-default-ref-for-push $1" ;;
116 esac
117}
118
119get_remote_refs_for_push () {
120 case "$#" in
121 0) die "internal error: get-remote-refs-for-push." ;;
122 1) get_remote_default_refs_for_push "$@" ;;
123 *) shift; echo "$@" ;;
124 esac
125}
126
127get_remote_refs_for_fetch () {
128 case "$#" in
129 0)
130 die "internal error: get-remote-refs-for-fetch." ;;
131 1)
132 get_remote_default_refs_for_fetch "$@" ;;
133 *)
134 shift
135 tag_just_seen=
136 for ref
137 do
138 if test "$tag_just_seen"
139 then
140 echo "refs/tags/${ref}:refs/tags/${ref}"
141 tag_just_seen=
142 continue
143 else
144 case "$ref" in
145 tag)
146 tag_just_seen=yes
147 continue
148 ;;
149 esac
150 fi
151 canon_refs_list_for_fetch "$ref"
152 done
153 ;;
154 esac
155}
156
157resolve_alternates () {
158 # original URL (xxx.git)
159 top_=`expr "$1" : '\([^:]*:/*[^/]*\)/'`
160 while read path
161 do
162 case "$path" in
163 \#* | '')
164 continue ;;
165 /*)
166 echo "$top_$path/" ;;
167 ../*)
168 # relative -- ugly but seems to work.
169 echo "$1/objects/$path/" ;;
170 *)
171 # exit code may not be caught by the reader.
172 echo "bad alternate: $path"
173 exit 1 ;;
174 esac
175 done
176}