Skip to content

Commit eb2a8d9

Browse files
pyokagangitster
authored andcommitted
pull: handle git-fetch's options as well
While parsing the command-line arguments, git-pull stops parsing at the first unrecognized option, assuming that any subsequent options are for git-fetch, and can thus be kept in the shell's positional parameters list, so that it can be passed to git-fetch via the expansion of "$@". However, certain functions in git-pull assume that the positional parameters do not contain any options: * error_on_no_merge_candidates() uses the number of positional parameters to determine which error message to print out, and will thus print the wrong message if git-fetch's options are passed in as well. * the call to get_remote_merge_branch() assumes that the positional parameters only contains the optional repo and refspecs, and will thus silently fail if git-fetch's options are passed in as well. * --dry-run is a valid git-fetch option, but if provided after any git-fetch options, it is not recognized by git-pull and thus git-pull will continue to run the merge or rebase. Fix these bugs by teaching git-pull to parse git-fetch's options as well. Add tests to prevent regressions. This removes the limitation where git-fetch's options have to come after git-merge's and git-rebase's options on the command line. Update the documentation to reflect this. Signed-off-by: Paul Tan <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 2c9c1c5 commit eb2a8d9

File tree

4 files changed

+68
-6
lines changed

4 files changed

+68
-6
lines changed

Documentation/git-pull.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,6 @@ pulling or stash them away with linkgit:git-stash[1].
7474
OPTIONS
7575
-------
7676

77-
Options meant for 'git pull' itself and the underlying 'git merge'
78-
must be given before the options meant for 'git fetch'.
79-
8077
-q::
8178
--quiet::
8279
This is passed to both underlying git-fetch to squelch reporting of

git-pull.sh

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ bool_or_string_config () {
4444

4545
strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
4646
log_arg= verbosity= progress= recurse_submodules= verify_signatures=
47-
merge_args= edit= rebase_args=
47+
merge_args= edit= rebase_args= all= append= upload_pack= force= tags= prune=
48+
keep= depth= unshallow= update_shallow= refmap=
4849
curr_branch=$(git symbolic-ref -q HEAD)
4950
curr_branch_short="${curr_branch#refs/heads/}"
5051
rebase=$(bool_or_string_config branch.$curr_branch_short.rebase)
@@ -166,11 +167,39 @@ do
166167
--d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run)
167168
dry_run=--dry-run
168169
;;
170+
--all|--no-all)
171+
all=$1 ;;
172+
-a|--append|--no-append)
173+
append=$1 ;;
174+
--upload-pack=*|--no-upload-pack)
175+
upload_pack=$1 ;;
176+
-f|--force|--no-force)
177+
force="$force $1" ;;
178+
-t|--tags|--no-tags)
179+
tags=$1 ;;
180+
-p|--prune|--no-prune)
181+
prune=$1 ;;
182+
-k|--keep|--no-keep)
183+
keep=$1 ;;
184+
--depth=*|--no-depth)
185+
depth=$1 ;;
186+
--unshallow|--no-unshallow)
187+
unshallow=$1 ;;
188+
--update-shallow|--no-update-shallow)
189+
update_shallow=$1 ;;
190+
--refmap=*|--no-refmap)
191+
refmap=$1 ;;
169192
-h|--help-all)
170193
usage
171194
;;
195+
--)
196+
shift
197+
break
198+
;;
199+
-*)
200+
usage
201+
;;
172202
*)
173-
# Pass thru anything that may be meant for fetch.
174203
break
175204
;;
176205
esac
@@ -248,7 +277,9 @@ test true = "$rebase" && {
248277
oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch 2>/dev/null)
249278
}
250279
orig_head=$(git rev-parse -q --verify HEAD)
251-
git fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok "$@" || exit 1
280+
git fetch $verbosity $progress $dry_run $recurse_submodules $all $append \
281+
$upload_pack $force $tags $prune $keep $depth $unshallow $update_shallow \
282+
$refmap --update-head-ok "$@" || exit 1
252283
test -z "$dry_run" || exit 0
253284

254285
curr_head=$(git rev-parse -q --verify HEAD)

t/t5520-pull.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,18 @@ test_expect_success 'fail if no configuration for current branch' '
160160
test "$(cat file)" = file
161161
'
162162

163+
test_expect_success 'pull --all: fail if no configuration for current branch' '
164+
git remote add test_remote . &&
165+
test_when_finished "git remote remove test_remote" &&
166+
git checkout -b test copy^ &&
167+
test_when_finished "git checkout -f copy && git branch -D test" &&
168+
test_config branch.test.remote test_remote &&
169+
test "$(cat file)" = file &&
170+
test_must_fail git pull --all 2>err &&
171+
test_i18ngrep "There is no tracking information" err &&
172+
test "$(cat file)" = file
173+
'
174+
163175
test_expect_success 'fail if upstream branch does not exist' '
164176
git checkout -b test copy^ &&
165177
test_when_finished "git checkout -f copy && git branch -D test" &&
@@ -365,6 +377,14 @@ test_expect_success '--rebase with rebased upstream' '
365377
366378
'
367379

380+
test_expect_success '--rebase -f with rebased upstream' '
381+
test_when_finished "test_might_fail git rebase --abort" &&
382+
git reset --hard to-rebase-orig &&
383+
git pull --rebase -f me copy &&
384+
test "conflicting modification" = "$(cat file)" &&
385+
test file = "$(cat file2)"
386+
'
387+
368388
test_expect_success '--rebase with rebased default upstream' '
369389
370390
git update-ref refs/remotes/me/copy copy-orig &&

t/t5521-pull-options.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,18 @@ test_expect_success 'git pull --dry-run' '
130130
)
131131
'
132132

133+
test_expect_success 'git pull --all --dry-run' '
134+
test_when_finished "rm -rf cloneddry" &&
135+
git init clonedry &&
136+
(
137+
cd clonedry &&
138+
git remote add origin ../parent &&
139+
git pull --all --dry-run &&
140+
test_path_is_missing .git/FETCH_HEAD &&
141+
test_path_is_missing .git/refs/remotes/origin/master &&
142+
test_path_is_missing .git/index &&
143+
test_path_is_missing file
144+
)
145+
'
146+
133147
test_done

0 commit comments

Comments
 (0)