@@ -15,14 +15,16 @@ SYNOPSIS
DESCRIPTION
-----------
-Incorporates changes from a remote repository into the current
-branch. In its default mode, `git pull` is shorthand for
-`git fetch` followed by `git merge FETCH_HEAD`.
-
-More precisely, 'git pull' runs 'git fetch' with the given
-parameters and calls 'git merge' to merge the retrieved branch
-heads into the current branch.
-With `--rebase`, it runs 'git rebase' instead of 'git merge'.
+Incorporates changes from a remote repository into the current branch.
+If the current branch is behind the remote, then by default it will
+fast-forward the current branch to match the remote. If the current
+branch and the remote have diverged, the user needs to specify how to
+reconcile the divergent branches with --no-ff or --rebase (or the
+corresponding configuration options in pull.ff or pull.rebase).
+
+More precisely, 'git pull' runs 'git fetch' with the given parameters
+and then depending on config options or command line flags, will call
+either 'git merge' or 'git rebase' to reconcile diverging branches.
<repository> should be the name of a remote repository as
passed to linkgit:git-fetch[1]. <refspec> can name an
@@ -946,20 +946,20 @@ static int get_can_ff(struct object_id *orig_head, struct object_id *orig_merge_
return ret;
}
-static void show_advice_pull_non_ff(void)
+static void NORETURN die_pull_non_ff(void)
{
- advise(_("Pulling without specifying how to reconcile divergent branches is\n"
- "discouraged. You can squelch this message by running one of the following\n"
- "commands sometime before your next pull:\n"
- "\n"
- " git config pull.rebase false # merge (the default strategy)\n"
- " git config pull.rebase true # rebase\n"
- " git config pull.ff only # fast-forward only\n"
- "\n"
- "You can replace \"git config\" with \"git config --global\" to set a default\n"
- "preference for all repositories. You can also pass --rebase, --no-rebase,\n"
- "or --ff-only on the command line to override the configured default per\n"
- "invocation.\n"));
+ die(_("You have divergent branches and need to specify how to reconcile them.\n"
+ "You can do so by running one of the following commands sometime before\n"
+ "your next pull:\n"
+ "\n"
+ " git config pull.rebase false # merge (the default strategy)\n"
+ " git config pull.rebase true # rebase\n"
+ " git config pull.ff only # fast-forward only\n"
+ "\n"
+ "You can replace \"git config\" with \"git config --global\" to set a default\n"
+ "preference for all repositories. You can also pass --rebase, --no-rebase,\n"
+ "or --ff-only on the command line to override the configured default per\n"
+ "invocation.\n"));
}
int cmd_pull(int argc, const char **argv, const char *prefix)
@@ -1074,9 +1074,8 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
if (opt_ff) {
if (!strcmp(opt_ff, "--ff-only"))
die_ff_impossible();
- } else {
- if (rebase_unspecified && opt_verbosity >= 0)
- show_advice_pull_non_ff();
+ } else if (rebase_unspecified) {
+ die_pull_non_ff();
}
}
@@ -65,7 +65,7 @@ test_expect_success setup '
export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&
git checkout master &&
- git pull -s ours . side &&
+ git pull -s ours --no-rebase . side &&
GIT_AUTHOR_DATE="2006-06-26 00:05:00 +0000" &&
GIT_COMMITTER_DATE="2006-06-26 00:05:00 +0000" &&
@@ -136,12 +136,12 @@ test_expect_success 'the default remote . should not break explicit pull' '
git reset --hard HEAD^ &&
echo file >expect &&
test_cmp expect file &&
- git pull . second &&
+ git pull --no-rebase . second &&
echo modified >expect &&
test_cmp expect file &&
git reflog -1 >reflog.actual &&
sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy &&
- echo "OBJID HEAD@{0}: pull . second: Fast-forward" >reflog.expected &&
+ echo "OBJID HEAD@{0}: pull --no-rebase . second: Fast-forward" >reflog.expected &&
test_cmp reflog.expected reflog.fuzzy
'
@@ -226,7 +226,7 @@ test_expect_success 'fail if the index has unresolved entries' '
test_commit modified2 file &&
git ls-files -u >unmerged &&
test_must_be_empty unmerged &&
- test_must_fail git pull . second &&
+ test_must_fail git pull --no-rebase . second &&
git ls-files -u >unmerged &&
test_file_not_empty unmerged &&
cp file expected &&
@@ -409,37 +409,37 @@ test_expect_success 'pull --rebase --no-autostash & rebase.autostash unset' '
test_expect_success 'pull succeeds with dirty working directory and merge.autostash set' '
test_config merge.autostash true &&
- test_pull_autostash 2
+ test_pull_autostash 2 --no-rebase
'
test_expect_success 'pull --autostash & merge.autostash=true' '
test_config merge.autostash true &&
- test_pull_autostash 2 --autostash
+ test_pull_autostash 2 --autostash --no-rebase
'
test_expect_success 'pull --autostash & merge.autostash=false' '
test_config merge.autostash false &&
- test_pull_autostash 2 --autostash
+ test_pull_autostash 2 --autostash --no-rebase
'
test_expect_success 'pull --autostash & merge.autostash unset' '
test_unconfig merge.autostash &&
- test_pull_autostash 2 --autostash
+ test_pull_autostash 2 --autostash --no-rebase
'
test_expect_success 'pull --no-autostash & merge.autostash=true' '
test_config merge.autostash true &&
- test_pull_autostash_fail --no-autostash
+ test_pull_autostash_fail --no-autostash --no-rebase
'
test_expect_success 'pull --no-autostash & merge.autostash=false' '
test_config merge.autostash false &&
- test_pull_autostash_fail --no-autostash
+ test_pull_autostash_fail --no-autostash --no-rebase
'
test_expect_success 'pull --no-autostash & merge.autostash unset' '
test_unconfig merge.autostash &&
- test_pull_autostash_fail --no-autostash
+ test_pull_autostash_fail --no-autostash --no-rebase
'
test_expect_success 'pull.rebase' '
@@ -113,7 +113,7 @@ test_expect_success 'git pull --force' '
git pull two &&
test_commit A &&
git branch -f origin &&
- git pull --all --force
+ git pull --no-rebase --all --force
)
'
@@ -179,7 +179,7 @@ test_expect_success 'git pull --allow-unrelated-histories' '
(
cd dst &&
test_must_fail git pull ../src side &&
- git pull --allow-unrelated-histories ../src side
+ git pull --no-rebase --allow-unrelated-histories ../src side
)
'
@@ -28,7 +28,7 @@ test_expect_success setup '
test_expect_success pull '
(
cd cloned &&
- git pull --log &&
+ git pull --no-rebase --log &&
git log -2 &&
git cat-file commit HEAD >result &&
grep Dollar result
@@ -41,7 +41,7 @@ test_expect_success '--log=1 limits shortlog length' '
git reset --hard HEAD^ &&
test "$(cat afile)" = original &&
test "$(cat bfile)" = added &&
- git pull --log=1 &&
+ git pull --no-rebase --log=1 &&
git log -3 &&
git cat-file commit HEAD >result &&
grep Dollar result &&
@@ -108,27 +108,27 @@ test_expect_success 'setup commit on main and other pull' '
test_expect_success 'pull --set-upstream upstream main sets branch main but not other' '
clear_config main other &&
- git pull --set-upstream upstream main &&
+ git pull --no-rebase --set-upstream upstream main &&
check_config main upstream refs/heads/main &&
check_config_missing other
'
test_expect_success 'pull --set-upstream main:other2 does not set the branch other2' '
clear_config other2 &&
- git pull --set-upstream upstream main:other2 &&
+ git pull --no-rebase --set-upstream upstream main:other2 &&
check_config_missing other2
'
test_expect_success 'pull --set-upstream upstream other sets branch main' '
clear_config main other &&
- git pull --set-upstream upstream other &&
+ git pull --no-rebase --set-upstream upstream other &&
check_config main upstream refs/heads/other &&
check_config_missing other
'
test_expect_success 'pull --set-upstream upstream tag does not set the tag' '
clear_config three &&
- git pull --tags --set-upstream upstream three &&
+ git pull --no-rebase --tags --set-upstream upstream three &&
check_config_missing three
'
@@ -144,16 +144,16 @@ test_expect_success 'pull --set-upstream http://nosuchdomain.example.com fails w
test_expect_success 'pull --set-upstream upstream HEAD sets branch HEAD' '
clear_config main other &&
- git pull --set-upstream upstream HEAD &&
+ git pull --no-rebase --set-upstream upstream HEAD &&
check_config main upstream HEAD &&
git checkout other &&
- git pull --set-upstream upstream HEAD &&
+ git pull --no-rebase --set-upstream upstream HEAD &&
check_config other upstream HEAD
'
test_expect_success 'pull --set-upstream upstream with more than one branch does nothing' '
clear_config main three &&
- git pull --set-upstream upstream main three &&
+ git pull --no-rebase --set-upstream upstream main three &&
check_config_missing main &&
check_config_missing three
'
@@ -87,7 +87,7 @@ test_expect_success 'updating origin' '
'
test_expect_success 'pulling changes from origin' '
- git -C C pull origin
+ git -C C pull --no-rebase origin
'
# the 2 local objects are commit and tree from the merge
@@ -96,7 +96,7 @@ test_expect_success 'that alternate to origin gets used' '
'
test_expect_success 'pulling changes from origin' '
- git -C D pull origin
+ git -C D pull --no-rebase origin
'
# the 5 local objects are expected; file3 blob, commit in A to add it
@@ -103,7 +103,7 @@ test_expect_success 'setup' '
test_expect_success 'pull renaming branch into unrenaming one' \
'
git show-branch &&
- test_expect_code 1 git pull . white &&
+ test_expect_code 1 git pull --no-rebase . white &&
git ls-files -s &&
git ls-files -u B >b.stages &&
test_line_count = 3 b.stages &&
@@ -121,7 +121,7 @@ test_expect_success 'pull renaming branch into another renaming one' \
rm -f B &&
git reset --hard &&
git checkout red &&
- test_expect_code 1 git pull . white &&
+ test_expect_code 1 git pull --no-rebase . white &&
git ls-files -u B >b.stages &&
test_line_count = 3 b.stages &&
git ls-files -s N >n.stages &&
@@ -137,7 +137,7 @@ test_expect_success 'pull unrenaming branch into renaming one' \
'
git reset --hard &&
git show-branch &&
- test_expect_code 1 git pull . main &&
+ test_expect_code 1 git pull --no-rebase . main &&
git ls-files -u B >b.stages &&
test_line_count = 3 b.stages &&
git ls-files -s N >n.stages &&
@@ -153,7 +153,7 @@ test_expect_success 'pull conflicting renames' \
'
git reset --hard &&
git show-branch &&
- test_expect_code 1 git pull . blue &&
+ test_expect_code 1 git pull --no-rebase . blue &&
git ls-files -u A >a.stages &&
test_line_count = 1 a.stages &&
git ls-files -u B >b.stages &&
@@ -173,7 +173,7 @@ test_expect_success 'interference with untracked working tree file' '
git reset --hard &&
git show-branch &&
echo >A this file should not matter &&
- test_expect_code 1 git pull . white &&
+ test_expect_code 1 git pull --no-rebase . white &&
test_path_is_file A
'
@@ -183,7 +183,7 @@ test_expect_success 'interference with untracked working tree file' '
git show-branch &&
rm -f A &&
echo >A this file should not matter &&
- test_expect_code 1 git pull . red &&
+ test_expect_code 1 git pull --no-rebase . red &&
test_path_is_file A
'
@@ -193,7 +193,7 @@ test_expect_success 'interference with untracked working tree file' '
git checkout -f main &&
git tag -f anchor &&
git show-branch &&
- git pull . yellow &&
+ git pull --no-rebase . yellow &&
test_path_is_missing M &&
git reset --hard anchor
'
@@ -220,7 +220,7 @@ test_expect_success 'updated working tree file should prevent the merge' '
echo >>M one line addition &&
cat M >M.saved &&
git update-index M &&
- test_expect_code 128 git pull . yellow &&
+ test_expect_code 128 git pull --no-rebase . yellow &&
test_cmp M M.saved &&
rm -f M.saved
'
@@ -232,7 +232,7 @@ test_expect_success 'interference with untracked working tree file' '
git tag -f anchor &&
git show-branch &&
echo >M this file should not matter &&
- git pull . main &&
+ git pull --no-rebase . main &&
test_path_is_file M &&
! {
git ls-files -s |
@@ -100,7 +100,7 @@ test_expect_success 'merge update' '
git checkout -b topic_2 &&
git commit -m "update git-gui" &&
cd ../git &&
- git pull -s subtree gui topic_2 &&
+ git pull --no-rebase -s subtree gui topic_2 &&
git ls-files -s >actual &&
(
echo "100644 $o3 0 git-gui/git-gui.sh" &&
@@ -129,7 +129,7 @@ test_expect_success 'initial ambiguous subtree' '
test_expect_success 'merge using explicit' '
cd ../git &&
git reset --hard topic_2 &&
- git pull -Xsubtree=git-gui gui topic_2 &&
+ git pull --no-rebase -Xsubtree=git-gui gui topic_2 &&
git ls-files -s >actual &&
(
echo "100644 $o3 0 git-gui/git-gui.sh" &&
@@ -142,7 +142,7 @@ test_expect_success 'merge using explicit' '
test_expect_success 'merge2 using explicit' '
cd ../git &&
git reset --hard topic_2 &&
- git pull -Xsubtree=git-gui2 gui topic_2 &&
+ git pull --no-rebase -Xsubtree=git-gui2 gui topic_2 &&
git ls-files -s >actual &&
(
echo "100644 $o1 0 git-gui/git-gui.sh" &&
@@ -69,11 +69,11 @@ test_expect_success 'binary file with -Xours/-Xtheirs' '
'
test_expect_success 'pull passes -X to underlying merge' '
- git reset --hard main && git pull -s recursive -Xours . side &&
- git reset --hard main && git pull -s recursive -X ours . side &&
- git reset --hard main && git pull -s recursive -Xtheirs . side &&
- git reset --hard main && git pull -s recursive -X theirs . side &&
- git reset --hard main && test_must_fail git pull -s recursive -X bork . side
+ git reset --hard main && git pull --no-rebase -s recursive -Xours . side &&
+ git reset --hard main && git pull --no-rebase -s recursive -X ours . side &&
+ git reset --hard main && git pull --no-rebase -s recursive -Xtheirs . side &&
+ git reset --hard main && git pull --no-rebase -s recursive -X theirs . side &&
+ git reset --hard main && test_must_fail git pull --no-rebase -s recursive -X bork . side
'
test_expect_success SYMLINKS 'symlink with -Xours/-Xtheirs' '
@@ -86,10 +86,8 @@ test_expect_success 'pull.rebase not set and --ff-only given' '
test_expect_success 'pull.rebase not set (not-fast-forward)' '
git reset --hard c2 &&
- git -c color.advice=always pull . c1 2>err &&
- test_decode_color <err >decoded &&
- test_i18ngrep "<YELLOW>hint: " decoded &&
- test_i18ngrep "Pulling without specifying how to reconcile" decoded
+ test_must_fail git pull . c1 2>err &&
+ test_i18ngrep "You have divergent branches" err
'
test_expect_success 'pull.rebase not set and pull.ff=true (not-fast-forward)' '
@@ -68,7 +68,7 @@ test_expect_success 'merge c1 with c2, c3, c4, c5' '
test_expect_success 'pull c2, c3, c4, c5 into c1' '
git reset --hard c1 &&
- git pull . c2 c3 c4 c5 &&
+ git pull --no-rebase . c2 c3 c4 c5 &&
test "$(git rev-parse c1)" != "$(git rev-parse HEAD)" &&
test "$(git rev-parse c1)" = "$(git rev-parse HEAD^1)" &&
test "$(git rev-parse c2)" = "$(git rev-parse HEAD^2)" &&