. ./test-lib.sh
-test_expect_success 'set up test data and helpers' '
- printf "%s\n" 1 2 3 4 5 6 7 8 9 >file &&
- printf "%s\n" "1 X" 2 3 4 5 6 7 8 9 >file.1 &&
- printf "%s\n" 1 2 3 4 "5 X" 6 7 8 9 >file.5 &&
- printf "%s\n" 1 2 3 4 5 6 7 8 "9 X" >file.9 &&
- printf "%s\n" "1 X" 2 3 4 5 6 7 8 9 >result.1 &&
- printf "%s\n" "1 X" 2 3 4 "5 X" 6 7 8 9 >result.1-5 &&
- printf "%s\n" "1 X" 2 3 4 "5 X" 6 7 8 "9 X" >result.1-5-9 &&
-
- create_merge_msgs() {
- echo "Merge commit '\''c2'\''" >msg.1-5 &&
- echo "Merge commit '\''c2'\''; commit '\''c3'\''" >msg.1-5-9 &&
- {
- echo "Squashed commit of the following:" &&
- echo &&
- git log --no-merges ^HEAD c1
- } >squash.1 &&
- {
- echo "Squashed commit of the following:" &&
- echo &&
- git log --no-merges ^HEAD c2
- } >squash.1-5 &&
- {
- echo "Squashed commit of the following:" &&
- echo &&
- git log --no-merges ^HEAD c2 c3
- } >squash.1-5-9 &&
- echo >msg.nolog &&
- {
- echo "* commit '\''c3'\'':" &&
- echo " commit 3" &&
- echo
- } >msg.log
- } &&
-
- verify_merge() {
- test_cmp "$2" "$1" &&
- git update-index --refresh &&
- git diff --exit-code &&
- if test -n "$3"
- then
- git show -s --pretty=format:%s HEAD >msg.act &&
- test_cmp "$3" msg.act
- fi
- } &&
-
- verify_head() {
- echo "$1" >head.expected &&
- git rev-parse HEAD >head.actual &&
- test_cmp head.expected head.actual
- } &&
-
- verify_parents() {
- printf "%s\n" "$@" >parents.expected &&
- >parents.actual &&
- i=1 &&
- while test $i -le $#
- do
- git rev-parse HEAD^$i >>parents.actual &&
- i=$(expr $i + 1) ||
- return 1
- done &&
- test_cmp parents.expected parents.actual
- } &&
-
- verify_mergeheads() {
- printf "%s\n" "$@" >mergehead.expected &&
- test_cmp mergehead.expected .git/MERGE_HEAD
- } &&
-
- verify_no_mergehead() {
- ! test -e .git/MERGE_HEAD
- }
-'
+printf '%s\n' 1 2 3 4 5 6 7 8 9 >file
+printf '%s\n' '1 X' 2 3 4 5 6 7 8 9 >file.1
+printf '%s\n' 1 2 3 4 '5 X' 6 7 8 9 >file.5
+printf '%s\n' 1 2 3 4 5 6 7 8 '9 X' >file.9
+printf '%s\n' '1 X' 2 3 4 5 6 7 8 9 >result.1
+printf '%s\n' '1 X' 2 3 4 '5 X' 6 7 8 9 >result.1-5
+printf '%s\n' '1 X' 2 3 4 '5 X' 6 7 8 '9 X' >result.1-5-9
+>empty
+
+create_merge_msgs () {
+ echo "Merge tag 'c2'" >msg.1-5 &&
+ echo "Merge tags 'c2' and 'c3'" >msg.1-5-9 &&
+ {
+ echo "Squashed commit of the following:" &&
+ echo &&
+ git log --no-merges ^HEAD c1
+ } >squash.1 &&
+ {
+ echo "Squashed commit of the following:" &&
+ echo &&
+ git log --no-merges ^HEAD c2
+ } >squash.1-5 &&
+ {
+ echo "Squashed commit of the following:" &&
+ echo &&
+ git log --no-merges ^HEAD c2 c3
+ } >squash.1-5-9 &&
+ echo >msg.nolog &&
+ {
+ echo "* tag 'c3':" &&
+ echo " commit 3" &&
+ echo
+ } >msg.log
+}
+
+verify_merge () {
+ test_cmp "$2" "$1" &&
+ git update-index --refresh &&
+ git diff --exit-code &&
+ if test -n "$3"
+ then
+ git show -s --pretty=format:%s HEAD >msg.act &&
+ test_cmp "$3" msg.act
+ fi
+}
+
+verify_head () {
+ echo "$1" >head.expected &&
+ git rev-parse HEAD >head.actual &&
+ test_cmp head.expected head.actual
+}
+
+verify_parents () {
+ printf '%s\n' "$@" >parents.expected &&
+ >parents.actual &&
+ i=1 &&
+ while test $i -le $#
+ do
+ git rev-parse HEAD^$i >>parents.actual &&
+ i=$(expr $i + 1) ||
+ return 1
+ done &&
+ test_must_fail git rev-parse --verify "HEAD^$i" &&
+ test_cmp parents.expected parents.actual
+}
+
+verify_mergeheads () {
+ printf '%s\n' "$@" >mergehead.expected &&
+ while read sha1 rest
+ do
+ git rev-parse $sha1
+ done <.git/MERGE_HEAD >mergehead.actual &&
+ test_cmp mergehead.expected mergehead.actual
+}
+
+verify_no_mergehead () {
+ ! test -e .git/MERGE_HEAD
+}
test_expect_success 'setup' '
git add file &&
test_must_fail git merge
'
+test_expect_success 'merge -h with invalid index' '
+ mkdir broken &&
+ (
+ cd broken &&
+ git init &&
+ >.git/index &&
+ test_expect_code 129 git merge -h 2>usage
+ ) &&
+ grep "[Uu]sage: git merge" broken/usage
+'
+
test_expect_success 'reject non-strategy with a git-merge-foo name' '
test_must_fail git merge -s index c1
'
test_debug 'git log --graph --decorate --oneline --all'
-test_expect_success 'failing merges with --ff-only' '
+test_expect_success 'merges with --ff-only' '
git reset --hard c1 &&
test_tick &&
test_must_fail git merge --ff-only c2 &&
test_must_fail git merge --ff-only c3 &&
- test_must_fail git merge --ff-only c2 c3
+ test_must_fail git merge --ff-only c2 c3 &&
+ git reset --hard c0 &&
+ git merge c3 &&
+ verify_head $c3
+'
+
+test_expect_success 'merges with merge.ff=only' '
+ git reset --hard c1 &&
+ test_tick &&
+ test_when_finished "git config --unset merge.ff" &&
+ git config merge.ff only &&
+ test_must_fail git merge c2 &&
+ test_must_fail git merge c3 &&
+ test_must_fail git merge c2 c3 &&
+ git reset --hard c0 &&
+ git merge c3 &&
+ verify_head $c3
'
test_expect_success 'merge c0 with c1 (no-commit)' '
test_debug 'git log --graph --decorate --oneline --all'
+test_expect_success 'merge c1 with c2 (log in config)' '
+ git config branch.master.mergeoptions "" &&
+ git reset --hard c1 &&
+ git merge --log c2 &&
+ git show -s --pretty=tformat:%s%n%b >expect &&
+
+ git config branch.master.mergeoptions --log &&
+ git reset --hard c1 &&
+ git merge c2 &&
+ git show -s --pretty=tformat:%s%n%b >actual &&
+
+ test_cmp expect actual
+'
+
+test_expect_success 'merge c1 with c2 (log in config gets overridden)' '
+ test_when_finished "git config --remove-section branch.master" &&
+ test_when_finished "git config --remove-section merge" &&
+ test_might_fail git config --remove-section branch.master &&
+ test_might_fail git config --remove-section merge &&
+
+ git reset --hard c1 &&
+ git merge c2 &&
+ git show -s --pretty=tformat:%s%n%b >expect &&
+
+ git config branch.master.mergeoptions "--no-log" &&
+ git config merge.log true &&
+ git reset --hard c1 &&
+ git merge c2 &&
+ git show -s --pretty=tformat:%s%n%b >actual &&
+
+ test_cmp expect actual
+'
+
test_expect_success 'merge c1 with c2 (squash in config)' '
git reset --hard c1 &&
git config branch.master.mergeoptions "--squash" &&
test_debug 'git log --graph --decorate --oneline --all'
+test_expect_success 'merge c0 with c1 (merge.ff=false)' '
+ git reset --hard c0 &&
+ git config merge.ff false &&
+ test_tick &&
+ git merge c1 &&
+ git config --remove-section merge &&
+ verify_merge file result.1 &&
+ verify_parents $c0 $c1
+'
+test_debug 'git log --graph --decorate --oneline --all'
+
+test_expect_success 'combine branch.master.mergeoptions with merge.ff' '
+ git reset --hard c0 &&
+ git config branch.master.mergeoptions --ff &&
+ git config merge.ff false &&
+ test_tick &&
+ git merge c1 &&
+ git config --remove-section "branch.master" &&
+ git config --remove-section "merge" &&
+ verify_merge file result.1 &&
+ verify_parents "$c0"
+'
+
+test_expect_success 'tolerate unknown values for merge.ff' '
+ git reset --hard c0 &&
+ git config merge.ff something-new &&
+ test_tick &&
+ git merge c1 2>message &&
+ git config --remove-section "merge" &&
+ verify_head "$c1" &&
+ test_cmp empty message
+'
+
test_expect_success 'combining --squash and --no-ff is refused' '
+ git reset --hard c0 &&
test_must_fail git merge --squash --no-ff c1 &&
test_must_fail git merge --no-ff --squash c1
'
test_expect_success 'in-index merge' '
git reset --hard c0 &&
git merge --no-ff -s resolve c1 >out &&
- grep "Wonderful." out &&
+ test_i18ngrep "Wonderful." out &&
verify_parents $c0 $c1
'
test_debug 'git log --graph --decorate --oneline --all'
+cat >editor <<\EOF
+#!/bin/sh
+# Add a new message string that was not in the template
+(
+ echo "Merge work done on the side branch c1"
+ echo
+ cat <"$1"
+) >"$1.tmp" && mv "$1.tmp" "$1"
+# strip comments and blank lines from end of message
+sed -e '/^#/d' < "$1" | sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' > expected
+EOF
+chmod 755 editor
+
+test_expect_success 'merge --no-ff --edit' '
+ git reset --hard c0 &&
+ EDITOR=./editor git merge --no-ff --edit c1 &&
+ verify_parents $c0 $c1 &&
+ git cat-file commit HEAD >raw &&
+ grep "work done on the side branch" raw &&
+ sed "1,/^$/d" >actual raw &&
+ test_cmp actual expected
+'
+
test_done