Skip to content

Commit 031e2f7

Browse files
newrengitster
authored andcommitted
pull: abort by default when fast-forwarding is not possible
We have for some time shown a long warning when the user does not specify how to reconcile divergent branches with git pull. Make it an error now. Initial-patch-by: Alex Henrie <alexhenrie24@gmail.com> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent adc27d6 commit 031e2f7

13 files changed

+84
-78
lines changed

Documentation/git-pull.txt

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,18 @@ SYNOPSIS
1515
DESCRIPTION
1616
-----------
1717

18-
Incorporates changes from a remote repository into the current
19-
branch. In its default mode, `git pull` is shorthand for
20-
`git fetch` followed by `git merge FETCH_HEAD`.
21-
22-
More precisely, 'git pull' runs 'git fetch' with the given
23-
parameters and calls 'git merge' to merge the retrieved branch
24-
heads into the current branch.
25-
With `--rebase`, it runs 'git rebase' instead of 'git merge'.
18+
Incorporates changes from a remote repository into the current branch.
19+
If the current branch is behind the remote, then by default it will
20+
fast-forward the current branch to match the remote. If the current
21+
branch and the remote have diverged, the user needs to specify how to
22+
reconcile the divergent branches with `--no-ff`, `--ff`, or `--rebase`
23+
(or the corresponding configuration options in `pull.ff` or
24+
`pull.rebase`).
25+
26+
More precisely, `git pull` runs `git fetch` with the given parameters
27+
and then depending on configuration options or command line flags,
28+
will call either `git merge` or `git rebase` to reconcile diverging
29+
branches.
2630

2731
<repository> should be the name of a remote repository as
2832
passed to linkgit:git-fetch[1]. <refspec> can name an

builtin/pull.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -927,9 +927,9 @@ static int get_can_ff(struct object_id *orig_head, struct object_id *orig_merge_
927927

928928
static void show_advice_pull_non_ff(void)
929929
{
930-
advise(_("Pulling without specifying how to reconcile divergent branches is\n"
931-
"discouraged. You can squelch this message by running one of the following\n"
932-
"commands sometime before your next pull:\n"
930+
advise(_("You have divergent branches and need to specify how to reconcile them.\n"
931+
"You can do so by running one of the following commands sometime before\n"
932+
"your next pull:\n"
933933
"\n"
934934
" git config pull.rebase false # merge (the default strategy)\n"
935935
" git config pull.rebase true # rebase\n"
@@ -1067,8 +1067,10 @@ int cmd_pull(int argc, const char **argv, const char *prefix)
10671067
opt_rebase = REBASE_FALSE;
10681068
}
10691069
/* If no action specified and we can't fast forward, then warn. */
1070-
if (!opt_ff && rebase_unspecified && !can_ff)
1070+
if (!opt_ff && rebase_unspecified && !can_ff) {
10711071
show_advice_pull_non_ff();
1072+
die(_("Need to specify how to reconcile divergent branches."));
1073+
}
10721074

10731075
if (opt_rebase) {
10741076
int ret = 0;

t/t4013-diff-various.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ test_expect_success setup '
6565
export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&
6666
6767
git checkout master &&
68-
git pull -s ours . side &&
68+
git pull -s ours --no-rebase . side &&
6969
7070
GIT_AUTHOR_DATE="2006-06-26 00:05:00 +0000" &&
7171
GIT_COMMITTER_DATE="2006-06-26 00:05:00 +0000" &&

t/t5520-pull.sh

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,12 @@ test_expect_success 'the default remote . should not break explicit pull' '
136136
git reset --hard HEAD^ &&
137137
echo file >expect &&
138138
test_cmp expect file &&
139-
git pull . second &&
139+
git pull --no-rebase . second &&
140140
echo modified >expect &&
141141
test_cmp expect file &&
142142
git reflog -1 >reflog.actual &&
143143
sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy &&
144-
echo "OBJID HEAD@{0}: pull . second: Fast-forward" >reflog.expected &&
144+
echo "OBJID HEAD@{0}: pull --no-rebase . second: Fast-forward" >reflog.expected &&
145145
test_cmp reflog.expected reflog.fuzzy
146146
'
147147

@@ -226,7 +226,7 @@ test_expect_success 'fail if the index has unresolved entries' '
226226
test_commit modified2 file &&
227227
git ls-files -u >unmerged &&
228228
test_must_be_empty unmerged &&
229-
test_must_fail git pull . second &&
229+
test_must_fail git pull --no-rebase . second &&
230230
git ls-files -u >unmerged &&
231231
test_file_not_empty unmerged &&
232232
cp file expected &&
@@ -409,37 +409,37 @@ test_expect_success 'pull --rebase --no-autostash & rebase.autostash unset' '
409409

410410
test_expect_success 'pull succeeds with dirty working directory and merge.autostash set' '
411411
test_config merge.autostash true &&
412-
test_pull_autostash 2
412+
test_pull_autostash 2 --no-rebase
413413
'
414414

415415
test_expect_success 'pull --autostash & merge.autostash=true' '
416416
test_config merge.autostash true &&
417-
test_pull_autostash 2 --autostash
417+
test_pull_autostash 2 --autostash --no-rebase
418418
'
419419

420420
test_expect_success 'pull --autostash & merge.autostash=false' '
421421
test_config merge.autostash false &&
422-
test_pull_autostash 2 --autostash
422+
test_pull_autostash 2 --autostash --no-rebase
423423
'
424424

425425
test_expect_success 'pull --autostash & merge.autostash unset' '
426426
test_unconfig merge.autostash &&
427-
test_pull_autostash 2 --autostash
427+
test_pull_autostash 2 --autostash --no-rebase
428428
'
429429

430430
test_expect_success 'pull --no-autostash & merge.autostash=true' '
431431
test_config merge.autostash true &&
432-
test_pull_autostash_fail --no-autostash
432+
test_pull_autostash_fail --no-autostash --no-rebase
433433
'
434434

435435
test_expect_success 'pull --no-autostash & merge.autostash=false' '
436436
test_config merge.autostash false &&
437-
test_pull_autostash_fail --no-autostash
437+
test_pull_autostash_fail --no-autostash --no-rebase
438438
'
439439

440440
test_expect_success 'pull --no-autostash & merge.autostash unset' '
441441
test_unconfig merge.autostash &&
442-
test_pull_autostash_fail --no-autostash
442+
test_pull_autostash_fail --no-autostash --no-rebase
443443
'
444444

445445
test_expect_success 'pull.rebase' '

t/t5521-pull-options.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ test_expect_success 'git pull --force' '
113113
git pull two &&
114114
test_commit A &&
115115
git branch -f origin &&
116-
git pull --all --force
116+
git pull --no-rebase --all --force
117117
)
118118
'
119119

@@ -179,7 +179,7 @@ test_expect_success 'git pull --allow-unrelated-histories' '
179179
(
180180
cd dst &&
181181
test_must_fail git pull ../src side &&
182-
git pull --allow-unrelated-histories ../src side
182+
git pull --no-rebase --allow-unrelated-histories ../src side
183183
)
184184
'
185185

t/t5524-pull-msg.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ test_expect_success setup '
2828
test_expect_success pull '
2929
(
3030
cd cloned &&
31-
git pull --log &&
31+
git pull --no-rebase --log &&
3232
git log -2 &&
3333
git cat-file commit HEAD >result &&
3434
grep Dollar result
@@ -41,7 +41,7 @@ test_expect_success '--log=1 limits shortlog length' '
4141
git reset --hard HEAD^ &&
4242
test "$(cat afile)" = original &&
4343
test "$(cat bfile)" = added &&
44-
git pull --log=1 &&
44+
git pull --no-rebase --log=1 &&
4545
git log -3 &&
4646
git cat-file commit HEAD >result &&
4747
grep Dollar result &&

t/t5553-set-upstream.sh

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,27 +108,27 @@ test_expect_success 'setup commit on main and other pull' '
108108

109109
test_expect_success 'pull --set-upstream upstream main sets branch main but not other' '
110110
clear_config main other &&
111-
git pull --set-upstream upstream main &&
111+
git pull --no-rebase --set-upstream upstream main &&
112112
check_config main upstream refs/heads/main &&
113113
check_config_missing other
114114
'
115115

116116
test_expect_success 'pull --set-upstream main:other2 does not set the branch other2' '
117117
clear_config other2 &&
118-
git pull --set-upstream upstream main:other2 &&
118+
git pull --no-rebase --set-upstream upstream main:other2 &&
119119
check_config_missing other2
120120
'
121121

122122
test_expect_success 'pull --set-upstream upstream other sets branch main' '
123123
clear_config main other &&
124-
git pull --set-upstream upstream other &&
124+
git pull --no-rebase --set-upstream upstream other &&
125125
check_config main upstream refs/heads/other &&
126126
check_config_missing other
127127
'
128128

129129
test_expect_success 'pull --set-upstream upstream tag does not set the tag' '
130130
clear_config three &&
131-
git pull --tags --set-upstream upstream three &&
131+
git pull --no-rebase --tags --set-upstream upstream three &&
132132
check_config_missing three
133133
'
134134

@@ -144,16 +144,16 @@ test_expect_success 'pull --set-upstream http://nosuchdomain.example.com fails w
144144

145145
test_expect_success 'pull --set-upstream upstream HEAD sets branch HEAD' '
146146
clear_config main other &&
147-
git pull --set-upstream upstream HEAD &&
147+
git pull --no-rebase --set-upstream upstream HEAD &&
148148
check_config main upstream HEAD &&
149149
git checkout other &&
150-
git pull --set-upstream upstream HEAD &&
150+
git pull --no-rebase --set-upstream upstream HEAD &&
151151
check_config other upstream HEAD
152152
'
153153

154154
test_expect_success 'pull --set-upstream upstream with more than one branch does nothing' '
155155
clear_config main three &&
156-
git pull --set-upstream upstream main three &&
156+
git pull --no-rebase --set-upstream upstream main three &&
157157
check_config_missing main &&
158158
check_config_missing three
159159
'

t/t5604-clone-reference.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ test_expect_success 'updating origin' '
8787
'
8888

8989
test_expect_success 'pulling changes from origin' '
90-
git -C C pull origin
90+
git -C C pull --no-rebase origin
9191
'
9292

9393
# the 2 local objects are commit and tree from the merge
@@ -96,7 +96,7 @@ test_expect_success 'that alternate to origin gets used' '
9696
'
9797

9898
test_expect_success 'pulling changes from origin' '
99-
git -C D pull origin
99+
git -C D pull --no-rebase origin
100100
'
101101

102102
# the 5 local objects are expected; file3 blob, commit in A to add it

t/t6402-merge-rename.sh

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ test_expect_success 'setup' '
103103
test_expect_success 'pull renaming branch into unrenaming one' \
104104
'
105105
git show-branch &&
106-
test_expect_code 1 git pull . white &&
106+
test_expect_code 1 git pull --no-rebase . white &&
107107
git ls-files -s &&
108108
git ls-files -u B >b.stages &&
109109
test_line_count = 3 b.stages &&
@@ -121,7 +121,7 @@ test_expect_success 'pull renaming branch into another renaming one' \
121121
rm -f B &&
122122
git reset --hard &&
123123
git checkout red &&
124-
test_expect_code 1 git pull . white &&
124+
test_expect_code 1 git pull --no-rebase . white &&
125125
git ls-files -u B >b.stages &&
126126
test_line_count = 3 b.stages &&
127127
git ls-files -s N >n.stages &&
@@ -137,7 +137,7 @@ test_expect_success 'pull unrenaming branch into renaming one' \
137137
'
138138
git reset --hard &&
139139
git show-branch &&
140-
test_expect_code 1 git pull . main &&
140+
test_expect_code 1 git pull --no-rebase . main &&
141141
git ls-files -u B >b.stages &&
142142
test_line_count = 3 b.stages &&
143143
git ls-files -s N >n.stages &&
@@ -153,7 +153,7 @@ test_expect_success 'pull conflicting renames' \
153153
'
154154
git reset --hard &&
155155
git show-branch &&
156-
test_expect_code 1 git pull . blue &&
156+
test_expect_code 1 git pull --no-rebase . blue &&
157157
git ls-files -u A >a.stages &&
158158
test_line_count = 1 a.stages &&
159159
git ls-files -u B >b.stages &&
@@ -173,7 +173,7 @@ test_expect_success 'interference with untracked working tree file' '
173173
git reset --hard &&
174174
git show-branch &&
175175
echo >A this file should not matter &&
176-
test_expect_code 1 git pull . white &&
176+
test_expect_code 1 git pull --no-rebase . white &&
177177
test_path_is_file A
178178
'
179179

@@ -183,7 +183,7 @@ test_expect_success 'interference with untracked working tree file' '
183183
git show-branch &&
184184
rm -f A &&
185185
echo >A this file should not matter &&
186-
test_expect_code 1 git pull . red &&
186+
test_expect_code 1 git pull --no-rebase . red &&
187187
test_path_is_file A
188188
'
189189

@@ -193,7 +193,7 @@ test_expect_success 'interference with untracked working tree file' '
193193
git checkout -f main &&
194194
git tag -f anchor &&
195195
git show-branch &&
196-
git pull . yellow &&
196+
git pull --no-rebase . yellow &&
197197
test_path_is_missing M &&
198198
git reset --hard anchor
199199
'
@@ -220,7 +220,7 @@ test_expect_success 'updated working tree file should prevent the merge' '
220220
echo >>M one line addition &&
221221
cat M >M.saved &&
222222
git update-index M &&
223-
test_expect_code 128 git pull . yellow &&
223+
test_expect_code 128 git pull --no-rebase . yellow &&
224224
test_cmp M M.saved &&
225225
rm -f M.saved
226226
'
@@ -232,7 +232,7 @@ test_expect_success 'interference with untracked working tree file' '
232232
git tag -f anchor &&
233233
git show-branch &&
234234
echo >M this file should not matter &&
235-
git pull . main &&
235+
git pull --no-rebase . main &&
236236
test_path_is_file M &&
237237
! {
238238
git ls-files -s |

t/t6409-merge-subtree.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ test_expect_success 'merge update' '
100100
git checkout -b topic_2 &&
101101
git commit -m "update git-gui" &&
102102
cd ../git &&
103-
git pull -s subtree gui topic_2 &&
103+
git pull --no-rebase -s subtree gui topic_2 &&
104104
git ls-files -s >actual &&
105105
(
106106
echo "100644 $o3 0 git-gui/git-gui.sh" &&
@@ -129,7 +129,7 @@ test_expect_success 'initial ambiguous subtree' '
129129
test_expect_success 'merge using explicit' '
130130
cd ../git &&
131131
git reset --hard topic_2 &&
132-
git pull -Xsubtree=git-gui gui topic_2 &&
132+
git pull --no-rebase -Xsubtree=git-gui gui topic_2 &&
133133
git ls-files -s >actual &&
134134
(
135135
echo "100644 $o3 0 git-gui/git-gui.sh" &&
@@ -142,7 +142,7 @@ test_expect_success 'merge using explicit' '
142142
test_expect_success 'merge2 using explicit' '
143143
cd ../git &&
144144
git reset --hard topic_2 &&
145-
git pull -Xsubtree=git-gui2 gui topic_2 &&
145+
git pull --no-rebase -Xsubtree=git-gui2 gui topic_2 &&
146146
git ls-files -s >actual &&
147147
(
148148
echo "100644 $o1 0 git-gui/git-gui.sh" &&

0 commit comments

Comments
 (0)