Skip to content

Commit a005085

Browse files
committed
git-merge: do up-to-date check also for all strategies
This clarifies the logic to omit fast-forward check and omit trivial merge before running the specified strategy. The "index_merge" variable started out as a flag to say "do not do anything clever", but when recursive was changed to skip the trivial merge, the semantics were changed and the variable alone does not make sense anymore. This splits the variable into two, allow_fast_forward (which is almost always true, and avoids making a merge commit when the other commit is a descendant of our branch, but is set to false for ours and subtree) and allow_trivial_merge (which is false for ours, recursive and subtree). Unlike the earlier implementation, the "ours" strategy allows an up-to-date condition. When we are up-to-date, the result will be our commit, and by definition, we will have our tree as the result. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9277d60 commit a005085

File tree

2 files changed

+97
-15
lines changed

2 files changed

+97
-15
lines changed

git-merge.sh

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ LF='
1919
all_strategies='recur recursive octopus resolve stupid ours subtree'
2020
default_twohead_strategies='recursive'
2121
default_octopus_strategies='octopus'
22-
no_trivial_merge_strategies='ours subtree'
22+
no_fast_forward_strategies='subtree ours'
23+
no_trivial_strategies='recursive recur subtree ours'
2324
use_strategies=
2425

25-
index_merge=t
26+
allow_fast_forward=t
27+
allow_trivial_merge=t
2628

2729
dropsave() {
2830
rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
@@ -265,11 +267,20 @@ esac
265267

266268
for s in $use_strategies
267269
do
268-
for nt in $no_trivial_merge_strategies
270+
for ss in $no_fast_forward_strategies
269271
do
270272
case " $s " in
271-
*" $nt "*)
272-
index_merge=f
273+
*" $ss "*)
274+
allow_fast_forward=f
275+
break
276+
;;
277+
esac
278+
done
279+
for ss in $no_trivial_strategies
280+
do
281+
case " $s " in
282+
*" $ss "*)
283+
allow_trivial_merge=f
273284
break
274285
;;
275286
esac
@@ -286,10 +297,7 @@ case "$#" in
286297
esac
287298
echo "$head" >"$GIT_DIR/ORIG_HEAD"
288299

289-
case "$index_merge,$#,$common,$no_commit" in
290-
f,*)
291-
# We've been told not to try anything clever. Skip to real merge.
292-
;;
300+
case "$allow_fast_forward,$#,$common,$no_commit" in
293301
?,*,'',*)
294302
# No common ancestors found. We need a real merge.
295303
;;
@@ -299,7 +307,7 @@ f,*)
299307
finish_up_to_date "Already up-to-date."
300308
exit 0
301309
;;
302-
?,1,"$head",*)
310+
t,1,"$head",*)
303311
# Again the most common case of merging one remote.
304312
echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $1)"
305313
git update-index --refresh 2>/dev/null
@@ -322,11 +330,8 @@ f,*)
322330
# We are not doing octopus, not fast forward, and have only
323331
# one common.
324332
git update-index --refresh 2>/dev/null
325-
case " $use_strategies " in
326-
*' recursive '*|*' recur '*)
327-
: run merge later
328-
;;
329-
*)
333+
case "$allow_trivial_merge" in
334+
t)
330335
# See if it is really trivial.
331336
git var GIT_COMMITTER_IDENT >/dev/null || exit
332337
echo "Trying really trivial in-index merge..."

t/t6028-merge-up-to-date.sh

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/bin/sh
2+
3+
test_description='merge fast forward and up to date'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success setup '
8+
>file &&
9+
git add file &&
10+
test_tick &&
11+
git commit -m initial &&
12+
git tag c0 &&
13+
14+
echo second >file &&
15+
git add file &&
16+
test_tick &&
17+
git commit -m second &&
18+
git tag c1 &&
19+
git branch test
20+
'
21+
22+
test_expect_success 'merge -s recursive up-to-date' '
23+
24+
git reset --hard c1 &&
25+
test_tick &&
26+
git merge -s recursive c0 &&
27+
expect=$(git rev-parse c1) &&
28+
current=$(git rev-parse HEAD) &&
29+
test "$expect" = "$current"
30+
31+
'
32+
33+
test_expect_success 'merge -s recursive fast-forward' '
34+
35+
git reset --hard c0 &&
36+
test_tick &&
37+
git merge -s recursive c1 &&
38+
expect=$(git rev-parse c1) &&
39+
current=$(git rev-parse HEAD) &&
40+
test "$expect" = "$current"
41+
42+
'
43+
44+
test_expect_success 'merge -s ours up-to-date' '
45+
46+
git reset --hard c1 &&
47+
test_tick &&
48+
git merge -s ours c0 &&
49+
expect=$(git rev-parse c1) &&
50+
current=$(git rev-parse HEAD) &&
51+
test "$expect" = "$current"
52+
53+
'
54+
55+
test_expect_success 'merge -s ours fast-forward' '
56+
57+
git reset --hard c0 &&
58+
test_tick &&
59+
git merge -s ours c1 &&
60+
expect=$(git rev-parse c0^{tree}) &&
61+
current=$(git rev-parse HEAD^{tree}) &&
62+
test "$expect" = "$current"
63+
64+
'
65+
66+
test_expect_success 'merge -s subtree up-to-date' '
67+
68+
git reset --hard c1 &&
69+
test_tick &&
70+
git merge -s subtree c0 &&
71+
expect=$(git rev-parse c1) &&
72+
current=$(git rev-parse HEAD) &&
73+
test "$expect" = "$current"
74+
75+
'
76+
77+
test_done

0 commit comments

Comments
 (0)