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 <pyokagan@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
2c9c1c5178
commit
eb2a8d9ed3
@ -74,9 +74,6 @@ pulling or stash them away with linkgit:git-stash[1].
|
|||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
|
|
||||||
Options meant for 'git pull' itself and the underlying 'git merge'
|
|
||||||
must be given before the options meant for 'git fetch'.
|
|
||||||
|
|
||||||
-q::
|
-q::
|
||||||
--quiet::
|
--quiet::
|
||||||
This is passed to both underlying git-fetch to squelch reporting of
|
This is passed to both underlying git-fetch to squelch reporting of
|
||||||
|
37
git-pull.sh
37
git-pull.sh
@ -44,7 +44,8 @@ bool_or_string_config () {
|
|||||||
|
|
||||||
strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
|
strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
|
||||||
log_arg= verbosity= progress= recurse_submodules= verify_signatures=
|
log_arg= verbosity= progress= recurse_submodules= verify_signatures=
|
||||||
merge_args= edit= rebase_args=
|
merge_args= edit= rebase_args= all= append= upload_pack= force= tags= prune=
|
||||||
|
keep= depth= unshallow= update_shallow= refmap=
|
||||||
curr_branch=$(git symbolic-ref -q HEAD)
|
curr_branch=$(git symbolic-ref -q HEAD)
|
||||||
curr_branch_short="${curr_branch#refs/heads/}"
|
curr_branch_short="${curr_branch#refs/heads/}"
|
||||||
rebase=$(bool_or_string_config branch.$curr_branch_short.rebase)
|
rebase=$(bool_or_string_config branch.$curr_branch_short.rebase)
|
||||||
@ -166,11 +167,39 @@ do
|
|||||||
--d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run)
|
--d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run)
|
||||||
dry_run=--dry-run
|
dry_run=--dry-run
|
||||||
;;
|
;;
|
||||||
|
--all|--no-all)
|
||||||
|
all=$1 ;;
|
||||||
|
-a|--append|--no-append)
|
||||||
|
append=$1 ;;
|
||||||
|
--upload-pack=*|--no-upload-pack)
|
||||||
|
upload_pack=$1 ;;
|
||||||
|
-f|--force|--no-force)
|
||||||
|
force="$force $1" ;;
|
||||||
|
-t|--tags|--no-tags)
|
||||||
|
tags=$1 ;;
|
||||||
|
-p|--prune|--no-prune)
|
||||||
|
prune=$1 ;;
|
||||||
|
-k|--keep|--no-keep)
|
||||||
|
keep=$1 ;;
|
||||||
|
--depth=*|--no-depth)
|
||||||
|
depth=$1 ;;
|
||||||
|
--unshallow|--no-unshallow)
|
||||||
|
unshallow=$1 ;;
|
||||||
|
--update-shallow|--no-update-shallow)
|
||||||
|
update_shallow=$1 ;;
|
||||||
|
--refmap=*|--no-refmap)
|
||||||
|
refmap=$1 ;;
|
||||||
-h|--help-all)
|
-h|--help-all)
|
||||||
usage
|
usage
|
||||||
;;
|
;;
|
||||||
|
--)
|
||||||
|
shift
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
# Pass thru anything that may be meant for fetch.
|
|
||||||
break
|
break
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@ -248,7 +277,9 @@ test true = "$rebase" && {
|
|||||||
oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch 2>/dev/null)
|
oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch 2>/dev/null)
|
||||||
}
|
}
|
||||||
orig_head=$(git rev-parse -q --verify HEAD)
|
orig_head=$(git rev-parse -q --verify HEAD)
|
||||||
git fetch $verbosity $progress $dry_run $recurse_submodules --update-head-ok "$@" || exit 1
|
git fetch $verbosity $progress $dry_run $recurse_submodules $all $append \
|
||||||
|
$upload_pack $force $tags $prune $keep $depth $unshallow $update_shallow \
|
||||||
|
$refmap --update-head-ok "$@" || exit 1
|
||||||
test -z "$dry_run" || exit 0
|
test -z "$dry_run" || exit 0
|
||||||
|
|
||||||
curr_head=$(git rev-parse -q --verify HEAD)
|
curr_head=$(git rev-parse -q --verify HEAD)
|
||||||
|
@ -160,6 +160,18 @@ test_expect_success 'fail if no configuration for current branch' '
|
|||||||
test "$(cat file)" = file
|
test "$(cat file)" = file
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'pull --all: fail if no configuration for current branch' '
|
||||||
|
git remote add test_remote . &&
|
||||||
|
test_when_finished "git remote remove test_remote" &&
|
||||||
|
git checkout -b test copy^ &&
|
||||||
|
test_when_finished "git checkout -f copy && git branch -D test" &&
|
||||||
|
test_config branch.test.remote test_remote &&
|
||||||
|
test "$(cat file)" = file &&
|
||||||
|
test_must_fail git pull --all 2>err &&
|
||||||
|
test_i18ngrep "There is no tracking information" err &&
|
||||||
|
test "$(cat file)" = file
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'fail if upstream branch does not exist' '
|
test_expect_success 'fail if upstream branch does not exist' '
|
||||||
git checkout -b test copy^ &&
|
git checkout -b test copy^ &&
|
||||||
test_when_finished "git checkout -f copy && git branch -D test" &&
|
test_when_finished "git checkout -f copy && git branch -D test" &&
|
||||||
@ -365,6 +377,14 @@ test_expect_success '--rebase with rebased upstream' '
|
|||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success '--rebase -f with rebased upstream' '
|
||||||
|
test_when_finished "test_might_fail git rebase --abort" &&
|
||||||
|
git reset --hard to-rebase-orig &&
|
||||||
|
git pull --rebase -f me copy &&
|
||||||
|
test "conflicting modification" = "$(cat file)" &&
|
||||||
|
test file = "$(cat file2)"
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success '--rebase with rebased default upstream' '
|
test_expect_success '--rebase with rebased default upstream' '
|
||||||
|
|
||||||
git update-ref refs/remotes/me/copy copy-orig &&
|
git update-ref refs/remotes/me/copy copy-orig &&
|
||||||
|
@ -130,4 +130,18 @@ test_expect_success 'git pull --dry-run' '
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'git pull --all --dry-run' '
|
||||||
|
test_when_finished "rm -rf cloneddry" &&
|
||||||
|
git init clonedry &&
|
||||||
|
(
|
||||||
|
cd clonedry &&
|
||||||
|
git remote add origin ../parent &&
|
||||||
|
git pull --all --dry-run &&
|
||||||
|
test_path_is_missing .git/FETCH_HEAD &&
|
||||||
|
test_path_is_missing .git/refs/remotes/origin/master &&
|
||||||
|
test_path_is_missing .git/index &&
|
||||||
|
test_path_is_missing file
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user