Skip to content

Commit 12d4ffa

Browse files
committed
Merge branch 'sb/pull-rebase'
* sb/pull-rebase: parse-remote: remove unused functions parse-remote: support default reflist in get_remote_merge_branch parse-remote: function to get the tracking branch to be merge
2 parents 451316d + 62d955f commit 12d4ffa

4 files changed

Lines changed: 43 additions & 221 deletions

File tree

Documentation/git-parse-remote.txt

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,6 @@ routines to parse files under $GIT_DIR/remotes/ and
1717
$GIT_DIR/branches/ and configuration variables that are related
1818
to fetching, pulling and pushing.
1919

20-
The primary entry points are:
21-
22-
get_remote_refs_for_fetch::
23-
Given the list of user-supplied `<repo> <refspec>...`,
24-
return the list of refs to fetch after canonicalizing
25-
them into `$GIT_DIR` relative paths
26-
(e.g. `refs/heads/foo`). When `<refspec>...` is empty
27-
the returned list of refs consists of the defaults
28-
for the given `<repo>`, if specified in
29-
`$GIT_DIR/remotes/`, `$GIT_DIR/branches/`, or `remote.*.fetch`
30-
configuration.
31-
32-
get_remote_refs_for_push::
33-
Given the list of user-supplied `<repo> <refspec>...`,
34-
return the list of refs to push in a form suitable to be
35-
fed to the 'git-send-pack' command. When `<refspec>...`
36-
is empty the returned list of refs consists of the
37-
defaults for the given `<repo>`, if specified in
38-
`$GIT_DIR/remotes/`.
39-
4020
Author
4121
------
4222
Written by Junio C Hamano.

git-parse-remote.sh

Lines changed: 27 additions & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -60,205 +60,36 @@ get_default_remote () {
6060
echo ${origin:-origin}
6161
}
6262

63-
get_remote_default_refs_for_push () {
64-
data_source=$(get_data_source "$1")
65-
case "$data_source" in
66-
'' | branches | self)
67-
;; # no default push mapping, just send matching refs.
68-
config)
69-
git config --get-all "remote.$1.push" ;;
70-
remotes)
71-
sed -ne '/^Push: */{
72-
s///p
73-
}' "$GIT_DIR/remotes/$1" ;;
74-
*)
75-
die "internal error: get-remote-default-ref-for-push $1" ;;
76-
esac
77-
}
78-
79-
# Called from canon_refs_list_for_fetch -d "$remote", which
80-
# is called from get_remote_default_refs_for_fetch to grok
81-
# refspecs that are retrieved from the configuration, but not
82-
# from get_remote_refs_for_fetch when it deals with refspecs
83-
# supplied on the command line. $ls_remote_result has the list
84-
# of refs available at remote.
85-
#
86-
# The first token returned is either "explicit" or "glob"; this
87-
# is to help prevent randomly "globbed" ref from being chosen as
88-
# a merge candidate
89-
expand_refs_wildcard () {
90-
echo "$ls_remote_result" |
91-
git fetch--tool expand-refs-wildcard "-" "$@"
92-
}
93-
94-
# Subroutine to canonicalize remote:local notation.
95-
canon_refs_list_for_fetch () {
96-
# If called from get_remote_default_refs_for_fetch
97-
# leave the branches in branch.${curr_branch}.merge alone,
98-
# or the first one otherwise; add prefix . to the rest
99-
# to prevent the secondary branches to be merged by default.
100-
merge_branches=
101-
curr_branch=
102-
if test "$1" = "-d"
103-
then
104-
shift ; remote="$1" ; shift
105-
set $(expand_refs_wildcard "$remote" "$@")
106-
is_explicit="$1"
107-
shift
108-
if test "$remote" = "$(get_default_remote)"
109-
then
110-
curr_branch=$(git symbolic-ref -q HEAD | \
111-
sed -e 's|^refs/heads/||')
112-
merge_branches=$(git config \
113-
--get-all "branch.${curr_branch}.merge")
114-
fi
115-
if test -z "$merge_branches" && test $is_explicit != explicit
116-
then
117-
merge_branches=..this.will.never.match.any.ref..
118-
fi
119-
fi
120-
for ref
121-
do
122-
force=
123-
case "$ref" in
124-
+*)
125-
ref=$(expr "z$ref" : 'z+\(.*\)')
126-
force=+
127-
;;
128-
esac
129-
expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
130-
remote=$(expr "z$ref" : 'z\([^:]*\):')
131-
local=$(expr "z$ref" : 'z[^:]*:\(.*\)')
132-
dot_prefix=.
133-
if test -z "$merge_branches"
134-
then
135-
merge_branches=$remote
136-
dot_prefix=
137-
else
138-
for merge_branch in $merge_branches
139-
do
140-
[ "$remote" = "$merge_branch" ] &&
141-
dot_prefix= && break
142-
done
143-
fi
144-
case "$remote" in
145-
'' | HEAD ) remote=HEAD ;;
146-
refs/*) ;;
147-
heads/* | tags/* | remotes/* ) remote="refs/$remote" ;;
148-
*) remote="refs/heads/$remote" ;;
149-
esac
150-
case "$local" in
151-
'') local= ;;
152-
refs/*) ;;
153-
heads/* | tags/* | remotes/* ) local="refs/$local" ;;
154-
*) local="refs/heads/$local" ;;
155-
esac
156-
157-
if local_ref_name=$(expr "z$local" : 'zrefs/\(.*\)')
158-
then
159-
git check-ref-format "$local_ref_name" ||
160-
die "* refusing to create funny ref '$local_ref_name' locally"
161-
fi
162-
echo "${dot_prefix}${force}${remote}:${local}"
163-
done
164-
}
165-
166-
# Returns list of src: (no store), or src:dst (store)
167-
get_remote_default_refs_for_fetch () {
168-
data_source=$(get_data_source "$1")
169-
case "$data_source" in
170-
'')
171-
echo "HEAD:" ;;
172-
self)
173-
canon_refs_list_for_fetch -d "$1" \
174-
$(git for-each-ref --format='%(refname):')
175-
;;
176-
config)
177-
canon_refs_list_for_fetch -d "$1" \
178-
$(git config --get-all "remote.$1.fetch") ;;
179-
branches)
180-
remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
181-
case "$remote_branch" in '') remote_branch=master ;; esac
182-
echo "refs/heads/${remote_branch}:refs/heads/$1"
183-
;;
184-
remotes)
185-
canon_refs_list_for_fetch -d "$1" $(sed -ne '/^Pull: */{
186-
s///p
187-
}' "$GIT_DIR/remotes/$1")
188-
;;
189-
*)
190-
die "internal error: get-remote-default-ref-for-fetch $1" ;;
191-
esac
192-
}
193-
194-
get_remote_refs_for_push () {
63+
get_remote_merge_branch () {
19564
case "$#" in
196-
0) die "internal error: get-remote-refs-for-push." ;;
197-
1) get_remote_default_refs_for_push "$@" ;;
198-
*) shift; echo "$@" ;;
199-
esac
200-
}
201-
202-
get_remote_refs_for_fetch () {
203-
case "$#" in
204-
0)
205-
die "internal error: get-remote-refs-for-fetch." ;;
206-
1)
207-
get_remote_default_refs_for_fetch "$@" ;;
208-
*)
209-
shift
210-
tag_just_seen=
211-
for ref
212-
do
213-
if test "$tag_just_seen"
214-
then
215-
echo "refs/tags/${ref}:refs/tags/${ref}"
216-
tag_just_seen=
217-
continue
218-
else
219-
case "$ref" in
220-
tag)
221-
tag_just_seen=yes
222-
continue
223-
;;
224-
esac
225-
fi
226-
canon_refs_list_for_fetch "$ref"
227-
done
65+
0|1)
66+
origin="$1"
67+
default=$(get_default_remote)
68+
test -z "$origin" && origin=$default
69+
curr_branch=$(git symbolic-ref -q HEAD)
70+
[ "$origin" = "$default" ] &&
71+
echo $(git for-each-ref --format='%(upstream)' $curr_branch)
22872
;;
229-
esac
230-
}
231-
232-
resolve_alternates () {
233-
# original URL (xxx.git)
234-
top_=`expr "z$1" : 'z\([^:]*:/*[^/]*\)/'`
235-
while read path
236-
do
237-
case "$path" in
238-
\#* | '')
239-
continue ;;
240-
/*)
241-
echo "$top_$path/" ;;
242-
../*)
243-
# relative -- ugly but seems to work.
244-
echo "$1/objects/$path/" ;;
245-
*)
246-
# exit code may not be caught by the reader.
247-
echo "bad alternate: $path"
248-
exit 1 ;;
249-
esac
250-
done
251-
}
252-
253-
get_uploadpack () {
254-
data_source=$(get_data_source "$1")
255-
case "$data_source" in
256-
config)
257-
uplp=$(git config --get "remote.$1.uploadpack")
258-
echo ${uplp:-git-upload-pack}
259-
;;
26073
*)
261-
echo "git-upload-pack"
74+
repo=$1
75+
shift
76+
ref=$1
77+
# FIXME: It should return the tracking branch
78+
# Currently only works with the default mapping
79+
case "$ref" in
80+
+*)
81+
ref=$(expr "z$ref" : 'z+\(.*\)')
26282
;;
83+
esac
84+
expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
85+
remote=$(expr "z$ref" : 'z\([^:]*\):')
86+
case "$remote" in
87+
'' | HEAD ) remote=HEAD ;;
88+
heads/*) remote=${remote#heads/} ;;
89+
refs/heads/*) remote=${remote#refs/heads/} ;;
90+
refs/* | tags/* | remotes/* ) remote=
91+
esac
92+
93+
[ -n "$remote" ] && echo "refs/remotes/$repo/$remote"
26394
esac
26495
}

git-pull.sh

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,9 @@ test true = "$rebase" && {
125125
die "refusing to pull with rebase: your working tree is not up-to-date"
126126

127127
. git-parse-remote &&
128-
origin="$1"
129-
test -z "$origin" && origin=$(get_default_remote)
130-
reflist="$(get_remote_refs_for_fetch "$@" 2>/dev/null |
131-
sed "s|refs/heads/\(.*\):|\1|")" &&
128+
reflist="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
132129
oldremoteref="$(git rev-parse -q --verify \
133-
"refs/remotes/$origin/$reflist")"
130+
"$reflist")"
134131
}
135132
orig_head=$(git rev-parse -q --verify HEAD)
136133
git fetch $verbosity --update-head-ok "$@" || exit 1

t/t5520-pull.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,20 +92,34 @@ test_expect_success '--rebase with rebased upstream' '
9292
9393
git remote add -f me . &&
9494
git checkout copy &&
95+
git tag copy-orig &&
9596
git reset --hard HEAD^ &&
9697
echo conflicting modification > file &&
9798
git commit -m conflict file &&
9899
git checkout to-rebase &&
99100
echo file > file2 &&
100101
git commit -m to-rebase file2 &&
102+
git tag to-rebase-orig &&
101103
git pull --rebase me copy &&
102104
test "conflicting modification" = "$(cat file)" &&
103105
test file = $(cat file2)
104106
105107
'
106108

109+
test_expect_success '--rebase with rebased default upstream' '
110+
111+
git update-ref refs/remotes/me/copy copy-orig &&
112+
git checkout --track -b to-rebase2 me/copy &&
113+
git reset --hard to-rebase-orig &&
114+
git pull --rebase &&
115+
test "conflicting modification" = "$(cat file)" &&
116+
test file = $(cat file2)
117+
118+
'
119+
107120
test_expect_success 'pull --rebase dies early with dirty working directory' '
108121
122+
git checkout to-rebase &&
109123
git update-ref refs/remotes/me/copy copy^ &&
110124
COPY=$(git rev-parse --verify me/copy) &&
111125
git rebase --onto $COPY copy &&

0 commit comments

Comments
 (0)