{"thread":{"id":"9984","subject":"[PATCH 2/6] git-merge: fix faulty SQUASH_MSG","startedAt":"2007-09-23T22:51:39Z","lastAt":"2007-09-23T22:51:45Z","messageCount":7,"participants":["Lars Hjemli"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"53867","messageId":"1190587905-700-1-git-send-email-hjemli@gmail.com","threadId":"9984","inReplyTo":null,"subject":"[PATCH 0/6] per branch options for git-merge","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-09-23T22:51:39Z","receivedAt":"2007-09-23T22:51:39Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This patch-series implements support for per branch configuration of\ngit-merge, using entries (branch.<name>.mergeoptions) in .git/config.\nSince this makes it possible to specify --no-commit and --squash as\ndefault options for git-merge, the new options --commit and --no-squash\nare added to enable users to override such defaults.\n\nThere is also a new option, --no-ff, which can be used to force git-merge\nto create a merge commit even when the merge was a fast-forward (and a\nmatching --ff option to allow overrides).\n\nShortlog:\n  Add test-script for git-merge porcelain\n  git-merge: fix faulty SQUASH_MSG\n  git-merge: refactor option parsing\n  git-merge: add support for branch.<name>.mergeoptions\n  git-merge: add support for --commit and --no-squash\n  git-merge: add --ff and --no-ff options\n\nDiffstat:\n Documentation/config.txt        |    6 +\n Documentation/git-merge.txt     |    4 +\n Documentation/merge-options.txt |   17 ++\n git-merge.sh                    |   65 +++++-\n t/t7600-merge.sh                |  440 +++++++++++++++++++++++++++++++++++++++\n 5 files changed, 521 insertions(+), 11 deletions(-)\n"},{"id":"53866","messageId":"1190587905-700-2-git-send-email-hjemli@gmail.com","threadId":"9984","inReplyTo":"1190587905-700-1-git-send-email-hjemli@gmail.com","subject":"[PATCH 1/6] Add test-script for git-merge porcelain","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-09-23T22:51:40Z","receivedAt":"2007-09-23T22:51:40Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This test-script excercises the porcelainish aspects of git-merge, and\ndoes it thoroughly enough to detect a small bug already noticed by Junio:\nsquashing an octopus generates a faulty .git/SQUASH_MSG.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n t/t7600-merge.sh |  344 ++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 344 insertions(+), 0 deletions(-)\n create mode 100755 t/t7600-merge.sh\n\ndiff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\nnew file mode 100755\nindex 0000000..dec6ea2\n--- /dev/null\n+++ b/t/t7600-merge.sh\n@@ -0,0 +1,344 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2007 Lars Hjemli\n+#\n+\n+test_description='git-merge\n+\n+Testing basic merge operations/option parsing.'\n+\n+. ./test-lib.sh\n+\n+cat >file <<EOF\n+1\n+2\n+3\n+4\n+5\n+6\n+7\n+8\n+9\n+EOF\n+\n+cat >file.1 <<EOF\n+1 X\n+2\n+3\n+4\n+5\n+6\n+7\n+8\n+9\n+EOF\n+\n+cat >file.5 <<EOF\n+1\n+2\n+3\n+4\n+5 X\n+6\n+7\n+8\n+9\n+EOF\n+\n+cat >file.9 <<EOF\n+1\n+2\n+3\n+4\n+5\n+6\n+7\n+8\n+9 X\n+EOF\n+\n+cat  >result.1 <<EOF\n+1 X\n+2\n+3\n+4\n+5\n+6\n+7\n+8\n+9\n+EOF\n+\n+cat >result.1-5 <<EOF\n+1 X\n+2\n+3\n+4\n+5 X\n+6\n+7\n+8\n+9\n+EOF\n+\n+cat >result.1-5-9 <<EOF\n+1 X\n+2\n+3\n+4\n+5 X\n+6\n+7\n+8\n+9 X\n+EOF\n+\n+create_merge_msgs() {\n+\techo \"Merge commit 'c2'\" >msg.1-5 &&\n+\techo \"Merge commit 'c2'; commit 'c3'\" >msg.1-5-9 &&\n+\techo \"Squashed commit of the following:\" >squash.1 &&\n+\techo >>squash.1 &&\n+\tgit log --no-merges ^HEAD c1 >>squash.1 &&\n+\techo \"Squashed commit of the following:\" >squash.1-5 &&\n+\techo >>squash.1-5 &&\n+\tgit log --no-merges ^HEAD c2 >>squash.1-5 &&\n+\techo \"Squashed commit of the following:\" >squash.1-5-9 &&\n+\techo >>squash.1-5-9 &&\n+\tgit log --no-merges ^HEAD c2 c3 >>squash.1-5-9\n+}\n+\n+verify_diff() {\n+\tif ! diff -u \"$1\" \"$2\"\n+\tthen\n+\t\techo \"$3\"\n+\t\tfalse\n+\tfi\n+}\n+\n+verify_merge() {\n+\tverify_diff \"$2\" \"$1\" \"[OOPS] bad merge result\" &&\n+\tif test $(git ls-files -u | wc -l) -gt 0\n+\tthen\n+\t\techo \"[OOPS] unmerged files\"\n+\t\tfalse\n+\tfi &&\n+\tif ! git diff --exit-code\n+\tthen\n+\t\techo \"[OOPS] working tree != index\"\n+\t\tfalse\n+\tfi &&\n+\tif test -n \"$3\"\n+\tthen\n+\t\tgit show -s --pretty=format:%s HEAD >msg.act &&\n+\t\tverify_diff \"$3\" msg.act \"[OOPS] bad merge message\"\n+\tfi\n+}\n+\n+verify_head() {\n+\tif test \"$1\" != \"$(git rev-parse HEAD)\"\n+\tthen\n+\t\techo \"[OOPS] HEAD != $1\"\n+\t\tfalse\n+\tfi\n+}\n+\n+verify_parents() {\n+\ti=1\n+\twhile test $# -gt 0\n+\tdo\n+\t\tif test \"$1\" != \"$(git rev-parse HEAD^$i)\"\n+\t\tthen\n+\t\t\techo \"[OOPS] HEAD^$i != $1\"\n+\t\t\treturn 1\n+\t\tfi\n+\t\ti=$(expr $i + 1)\n+\t\tshift\n+\tdone\n+}\n+\n+verify_mergeheads() {\n+\ti=1\n+\tif ! test -f .git/MERGE_HEAD\n+\tthen\n+\t\techo \"[OOPS] MERGE_HEAD is missing\"\n+\t\tfalse\n+\tfi &&\n+\twhile test $# -gt 0\n+\tdo\n+\t\thead=$(head -n $i .git/MERGE_HEAD | tail -n 1)\n+\t\tif test \"$1\" != \"$head\"\n+\t\tthen\n+\t\t\techo \"[OOPS] MERGE_HEAD $i != $1\"\n+\t\t\treturn 1\n+\t\tfi\n+\t\ti=$(expr $i + 1)\n+\t\tshift\n+\tdone\n+}\n+\n+verify_no_mergehead() {\n+\tif test -f .git/MERGE_HEAD\n+\tthen\n+\t\techo \"[OOPS] MERGE_HEAD exists\"\n+\t\tfalse\n+\tfi\n+}\n+\n+\n+test_expect_success 'setup' '\n+\tgit add file &&\n+\ttest_tick &&\n+\tgit commit -m \"commit 0\" &&\n+\tgit tag c0 &&\n+\tc0=$(git rev-parse HEAD) &&\n+\tcp file.1 file &&\n+\tgit add file &&\n+\ttest_tick &&\n+\tgit commit -m \"commit 1\" &&\n+\tgit tag c1 &&\n+\tc1=$(git rev-parse HEAD) &&\n+\tgit reset --hard \"$c0\" &&\n+\tcp file.5 file &&\n+\tgit add file &&\n+\ttest_tick &&\n+\tgit commit -m \"commit 2\" &&\n+\tgit tag c2 &&\n+\tc2=$(git rev-parse HEAD) &&\n+\tgit reset --hard \"$c0\" &&\n+\tcp file.9 file &&\n+\tgit add file &&\n+\ttest_tick &&\n+\tgit commit -m \"commit 3\" &&\n+\tgit tag c3 &&\n+\tc3=$(git rev-parse HEAD)\n+\tgit reset --hard \"$c0\" &&\n+\tcreate_merge_msgs\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'test option parsing' '\n+\tif git merge -$ c1\n+\tthen\n+\t\techo \"[OOPS] -$ accepted\"\n+\t\tfalse\n+\tfi &&\n+\tif git merge --no-such c1\n+\tthen\n+\t\techo \"[OOPS] --no-such accepted\"\n+\t\tfalse\n+\tfi &&\n+\tif git merge -s foobar c1\n+\tthen\n+\t\techo \"[OOPS] -s foobar accepted\"\n+\t\tfalse\n+\tfi &&\n+\tif git merge -s=foobar c1\n+\tthen\n+\t\techo \"[OOPS] -s=foobar accepted\"\n+\t\tfalse\n+\tfi &&\n+\tif git merge -m\n+\tthen\n+\t\techo \"[OOPS] missing commit msg accepted\"\n+\t\tfalse\n+\tfi &&\n+\tif git merge\n+\tthen\n+\t\techo \"[OOPS] missing commit references accepted\"\n+\t\tfalse\n+\tfi\n+'\n+\n+test_expect_success 'merge c0 with c1' '\n+\tgit reset --hard c0 &&\n+\tgit merge c1 &&\n+\tverify_merge file result.1 &&\n+\tverify_head \"$c1\"\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'merge c1 with c2' '\n+\tgit reset --hard c1 &&\n+\ttest_tick &&\n+\tgit merge c2 &&\n+\tverify_merge file result.1-5 msg.1-5 &&\n+\tverify_parents $c1 $c2\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'merge c1 with c2 and c3' '\n+\tgit reset --hard c1 &&\n+\ttest_tick &&\n+\tgit merge c2 c3 &&\n+\tverify_merge file result.1-5-9 msg.1-5-9 &&\n+\tverify_parents $c1 $c2 $c3\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'merge c0 with c1 (no-commit)' '\n+\tgit reset --hard c0 &&\n+\tgit merge --no-commit c1 &&\n+\tverify_merge file result.1 &&\n+\tverify_head $c1\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'merge c1 with c2 (no-commit)' '\n+\tgit reset --hard c1 &&\n+\tgit merge --no-commit c2 &&\n+\tverify_merge file result.1-5 &&\n+\tverify_head $c1 &&\n+\tverify_mergeheads $c2\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'merge c1 with c2 and c3 (no-commit)' '\n+\tgit reset --hard c1 &&\n+\tgit merge --no-commit c2 c3 &&\n+\tverify_merge file result.1-5-9 &&\n+\tverify_head $c1 &&\n+\tverify_mergeheads $c2 $c3\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'merge c0 with c1 (squash)' '\n+\tgit reset --hard c0 &&\n+\tgit merge --squash c1 &&\n+\tverify_merge file result.1 &&\n+\tverify_head $c0 &&\n+\tverify_no_mergehead &&\n+\tverify_diff squash.1 .git/SQUASH_MSG \"[OOPS] bad squash message\"\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'merge c1 with c2 (squash)' '\n+\tgit reset --hard c1 &&\n+\tgit merge --squash c2 &&\n+\tverify_merge file result.1-5 &&\n+\tverify_head $c1 &&\n+\tverify_no_mergehead &&\n+\tverify_diff squash.1-5 .git/SQUASH_MSG \"[OOPS] bad squash message\"\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'merge c1 with c2 and c3 (squash)' '\n+\tgit reset --hard c1 &&\n+\tgit merge --squash c2 c3 &&\n+\tverify_merge file result.1-5-9 &&\n+\tverify_head $c1 &&\n+\tverify_no_mergehead &&\n+\tverify_diff squash.1-5-9 .git/SQUASH_MSG \"[OOPS] bad squash message\"\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_done\n-- \n1.5.3.2.82.g75c8d\n"},{"id":"53862","messageId":"1190587905-700-3-git-send-email-hjemli@gmail.com","threadId":"9984","inReplyTo":"1190587905-700-2-git-send-email-hjemli@gmail.com","subject":"[PATCH 2/6] git-merge: fix faulty SQUASH_MSG","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-09-23T22:51:41Z","receivedAt":"2007-09-23T22:51:41Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"Only the first 'remote' head is currently specified as an argument to 'git\nlog' when generating a SQUSH_MSG, which makes the generated message fail\nto mention every commit involved in the merge. This fixes the problem.\n\nNoticed-by: Junio C Hamano <gitster@pobox.com>\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n git-merge.sh |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/git-merge.sh b/git-merge.sh\nindex 3a01db0..3857634 100755\n--- a/git-merge.sh\n+++ b/git-merge.sh\n@@ -59,7 +59,7 @@ finish_up_to_date () {\n squash_message () {\n \techo Squashed commit of the following:\n \techo\n-\tgit log --no-merges ^\"$head\" $remote\n+\tgit log --no-merges ^\"$head\" $remoteheads\n }\n \n finish () {\n-- \n1.5.3.2.82.g75c8d\n"},{"id":"53864","messageId":"1190587905-700-4-git-send-email-hjemli@gmail.com","threadId":"9984","inReplyTo":"1190587905-700-3-git-send-email-hjemli@gmail.com","subject":"[PATCH 3/6] git-merge: refactor option parsing","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-09-23T22:51:42Z","receivedAt":"2007-09-23T22:51:42Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"Move the option parsing into a separate function as preparation for reuse\nby the next commit.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n git-merge.sh |   20 ++++++++++++++------\n 1 files changed, 14 insertions(+), 6 deletions(-)\n\ndiff --git a/git-merge.sh b/git-merge.sh\nindex 3857634..68b3503 100755\n--- a/git-merge.sh\n+++ b/git-merge.sh\n@@ -119,11 +119,7 @@ merge_name () {\n \tfi\n }\n \n-case \"$#\" in 0) usage ;; esac\n-\n-have_message=\n-while case \"$#\" in 0) break ;; esac\n-do\n+parse_option () {\n \tcase \"$1\" in\n \t-n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\\\n \t\t--no-summa|--no-summar|--no-summary)\n@@ -166,9 +162,21 @@ do\n \t\thave_message=t\n \t\t;;\n \t-*)\tusage ;;\n-\t*)\tbreak ;;\n+\t*)\treturn 1 ;;\n \tesac\n \tshift\n+\targs_left=\"$#\"\n+}\n+\n+case \"$#\" in 0) usage ;; esac\n+\n+have_message=\n+while parse_option \"$@\"\n+do\n+\twhile test $args_left -lt $#\n+\tdo\n+\t\tshift\n+\tdone\n done\n \n if test -z \"$show_diffstat\"; then\n-- \n1.5.3.2.82.g75c8d\n"},{"id":"53868","messageId":"1190587905-700-5-git-send-email-hjemli@gmail.com","threadId":"9984","inReplyTo":"1190587905-700-4-git-send-email-hjemli@gmail.com","subject":"[PATCH 4/6] git-merge: add support for branch.<name>.mergeoptions","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-09-23T22:51:43Z","receivedAt":"2007-09-23T22:51:43Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This enables per branch configuration of merge options. Currently, the most\nuseful options to specify per branch are --squash, --summary/--no-summary\nand possibly --strategy, but all options are supported.\n\nNote: Options containing whitespace will _not_ be handled correctly. Luckily,\nthe only option which can include whitespace is --message and it doesn't\nmake much sense to give that option a default value.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n Documentation/config.txt    |    6 ++++\n Documentation/git-merge.txt |    4 +++\n git-merge.sh                |   21 ++++++++++++++++\n t/t7600-merge.sh            |   54 +++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 85 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 015910f..d3c25f3 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -337,6 +337,12 @@ branch.<name>.merge::\n \tbranch.<name>.merge to the desired branch, and use the special setting\n \t`.` (a period) for branch.<name>.remote.\n \n+branch.<name>.mergeoptions::\n+\tSets default options for merging into branch <name>. The syntax and\n+\tsupported options are equal to that of gitlink:git-merge[1], but\n+\toption values containing whitespace characters are currently not\n+\tsupported.\n+\n clean.requireForce::\n \tA boolean to make git-clean do nothing unless given -f or -n.  Defaults\n \tto false.\ndiff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt\nindex 144bc16..b1771a1 100644\n--- a/Documentation/git-merge.txt\n+++ b/Documentation/git-merge.txt\n@@ -58,6 +58,10 @@ merge.verbosity::\n \tabove outputs debugging information.  The default is level 2.\n \tCan be overriden by 'GIT_MERGE_VERBOSITY' environment variable.\n \n+branch.<name>.mergeoptions::\n+\tSets default options for merging into branch <name>. The syntax and\n+\tsupported options are equal to that of git-merge, but option values\n+\tcontaining whitespace characters are currently not supported.\n \n HOW MERGE WORKS\n ---------------\ndiff --git a/git-merge.sh b/git-merge.sh\nindex 68b3503..e95d4a7 100755\n--- a/git-merge.sh\n+++ b/git-merge.sh\n@@ -168,9 +168,30 @@ parse_option () {\n \targs_left=\"$#\"\n }\n \n+parse_config () {\n+\twhile test $# -gt 0\n+\tdo\n+\t\tparse_option \"$@\" || usage\n+\t\twhile test $args_left -lt $#\n+\t\tdo\n+\t\t\tshift\n+\t\tdone\n+\tdone\n+}\n+\n case \"$#\" in 0) usage ;; esac\n \n have_message=\n+\n+if branch=$(git-symbolic-ref -q HEAD)\n+then\n+\tmergeopts=$(git config \"branch.${branch#refs/heads/}.mergeoptions\")\n+\tif test -n \"$mergeopts\"\n+\tthen\n+\t\tparse_config $mergeopts\n+\tfi\n+fi\n+\n while parse_option \"$@\"\n do\n \twhile test $args_left -lt $#\ndiff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\nindex dec6ea2..110974c 100755\n--- a/t/t7600-merge.sh\n+++ b/t/t7600-merge.sh\n@@ -341,4 +341,58 @@ test_expect_success 'merge c1 with c2 and c3 (squash)' '\n \n test_debug 'gitk --all'\n \n+test_expect_success 'merge c1 with c2 (no-commit in config)' '\n+\tgit reset --hard c1 &&\n+\tgit config branch.master.mergeoptions \"--no-commit\" &&\n+\tgit merge c2 &&\n+\tverify_merge file result.1-5 &&\n+\tverify_head $c1 &&\n+\tverify_mergeheads $c2\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'merge c1 with c2 (squash in config)' '\n+\tgit reset --hard c1 &&\n+\tgit config branch.master.mergeoptions \"--squash\" &&\n+\tgit merge c2 &&\n+\tverify_merge file result.1-5 &&\n+\tverify_head $c1 &&\n+\tverify_no_mergehead &&\n+\tverify_diff squash.1-5 .git/SQUASH_MSG \"[OOPS] bad squash message\"\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'override config option -n' '\n+\tgit reset --hard c1 &&\n+\tgit config branch.master.mergeoptions \"-n\" &&\n+\ttest_tick &&\n+\tgit merge --summary c2 >diffstat.txt &&\n+\tverify_merge file result.1-5 msg.1-5 &&\n+\tverify_parents $c1 $c2 &&\n+\tif ! grep -e \"^ file | \\+2 +-$\" diffstat.txt\n+\tthen\n+\t\techo \"[OOPS] diffstat was not generated\"\n+\tfi\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'override config option --summary' '\n+\tgit reset --hard c1 &&\n+\tgit config branch.master.mergeoptions \"--summary\" &&\n+\ttest_tick &&\n+\tgit merge -n c2 >diffstat.txt &&\n+\tverify_merge file result.1-5 msg.1-5 &&\n+\tverify_parents $c1 $c2 &&\n+\tif grep -e \"^ file | \\+2 +-$\" diffstat.txt\n+\tthen\n+\t\techo \"[OOPS] diffstat was generated\"\n+\t\tfalse\n+\tfi\n+'\n+\n+test_debug 'gitk --all'\n+\n test_done\n-- \n1.5.3.2.82.g75c8d\n"},{"id":"53863","messageId":"1190587905-700-6-git-send-email-hjemli@gmail.com","threadId":"9984","inReplyTo":"1190587905-700-5-git-send-email-hjemli@gmail.com","subject":"[PATCH 5/6] git-merge: add support for --commit and --no-squash","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-09-23T22:51:44Z","receivedAt":"2007-09-23T22:51:44Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"These options can be used to override --no-commit and --squash, which is\nneeded since --no-commit and --squash now can be specified as default merge\noptions in $GIT_DIR/config.\n\nThe change also introduces slightly different behavior for --no-commit:\nwhen specified, it explicitly overrides --squash. Earlier,\n'git merge --squash --no-commit' would result in a squashed merge (i.e. no\n$GIT_DIR/MERGE_HEAD was created) but with this patch the command will\nbehave as if --squash hadn't been specified.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n Documentation/merge-options.txt |    8 ++++++++\n git-merge.sh                    |    8 ++++++--\n t/t7600-merge.sh                |   22 ++++++++++++++++++++++\n 3 files changed, 36 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt\nindex d64c259..0464a34 100644\n--- a/Documentation/merge-options.txt\n+++ b/Documentation/merge-options.txt\n@@ -10,6 +10,10 @@\n \tnot autocommit, to give the user a chance to inspect and\n \tfurther tweak the merge result before committing.\n \n+--commit::\n+\tPerform the merge and commit the result. This option can\n+\tbe used to override --no-commit.\n+\n --squash::\n \tProduce the working tree and index state as if a real\n \tmerge happened, but do not actually make a commit or\n@@ -19,6 +23,10 @@\n \ttop of the current branch whose effect is the same as\n \tmerging another branch (or more in case of an octopus).\n \n+--no-squash::\n+\tPerform the merge and commit the result. This option can\n+\tbe used to override --squash.\n+\n -s <strategy>, \\--strategy=<strategy>::\n \tUse the given merge strategy; can be supplied more than\n \tonce to specify them in the order they should be tried.\ndiff --git a/git-merge.sh b/git-merge.sh\nindex e95d4a7..ee8342d 100755\n--- a/git-merge.sh\n+++ b/git-merge.sh\n@@ -3,7 +3,7 @@\n # Copyright (c) 2005 Junio C Hamano\n #\n \n-USAGE='[-n] [--summary] [--no-commit] [--squash] [-s <strategy>] [-m=<merge-message>] <commit>+'\n+USAGE='[-n] [--summary] [--[no-]commit] [--[no-]squash] [-s <strategy>] [-m=<merge-message>] <commit>+'\n \n SUBDIRECTORY_OK=Yes\n . git-sh-setup\n@@ -128,8 +128,12 @@ parse_option () {\n \t\tshow_diffstat=t ;;\n \t--sq|--squ|--squa|--squas|--squash)\n \t\tsquash=t no_commit=t ;;\n+\t--no-sq|--no-squ|--no-squa|--no-squas|--no-squash)\n+\t\tsquash= no_commit= ;;\n+\t--c|--co|--com|--comm|--commi|--commit)\n+\t\tsquash= no_commit= ;;\n \t--no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)\n-\t\tno_commit=t ;;\n+\t\tsquash= no_commit=t ;;\n \t-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\\\n \t\t--strateg=*|--strategy=*|\\\n \t-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)\ndiff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\nindex 110974c..b0ef488 100755\n--- a/t/t7600-merge.sh\n+++ b/t/t7600-merge.sh\n@@ -395,4 +395,26 @@ test_expect_success 'override config option --summary' '\n \n test_debug 'gitk --all'\n \n+test_expect_success 'merge c1 with c2 (override --no-commit)' '\n+\tgit reset --hard c1 &&\n+\tgit config branch.master.mergeoptions \"--no-commit\" &&\n+\ttest_tick &&\n+\tgit merge --commit c2 &&\n+\tverify_merge file result.1-5 msg.1-5 &&\n+\tverify_parents $c1 $c2\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'merge c1 with c2 (override --squash)' '\n+\tgit reset --hard c1 &&\n+\tgit config branch.master.mergeoptions \"--squash\" &&\n+\ttest_tick &&\n+\tgit merge --no-squash c2 &&\n+\tverify_merge file result.1-5 msg.1-5 &&\n+\tverify_parents $c1 $c2\n+'\n+\n+test_debug 'gitk --all'\n+\n test_done\n-- \n1.5.3.2.82.g75c8d\n"},{"id":"53865","messageId":"1190587905-700-7-git-send-email-hjemli@gmail.com","threadId":"9984","inReplyTo":"1190587905-700-6-git-send-email-hjemli@gmail.com","subject":"[PATCH 6/6] git-merge: add --ff and --no-ff options","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-09-23T22:51:45Z","receivedAt":"2007-09-23T22:51:45Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"These new options can be used to control the policy for fast-forward\nmerges: --ff allows it (this is the default) while --no-ff will create\na merge commit.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n Documentation/merge-options.txt |    9 +++++++++\n git-merge.sh                    |   22 ++++++++++++++++------\n t/t7600-merge.sh                |   20 ++++++++++++++++++++\n 3 files changed, 45 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt\nindex 0464a34..9f1fc82 100644\n--- a/Documentation/merge-options.txt\n+++ b/Documentation/merge-options.txt\n@@ -27,6 +27,15 @@\n \tPerform the merge and commit the result. This option can\n \tbe used to override --squash.\n \n+--no-ff::\n+\tGenerate a merge commit even if the merge resolved as a\n+\tfast-forward.\n+\n+--ff::\n+\tDo not generate a merge commit if the merge resolved as\n+\ta fast-forward, only update the branch pointer. This is\n+\tthe default behavior of git-merge.\n+\n -s <strategy>, \\--strategy=<strategy>::\n \tUse the given merge strategy; can be supplied more than\n \tonce to specify them in the order they should be tried.\ndiff --git a/git-merge.sh b/git-merge.sh\nindex ee8342d..212e0ee 100755\n--- a/git-merge.sh\n+++ b/git-merge.sh\n@@ -3,7 +3,7 @@\n # Copyright (c) 2005 Junio C Hamano\n #\n \n-USAGE='[-n] [--summary] [--[no-]commit] [--[no-]squash] [-s <strategy>] [-m=<merge-message>] <commit>+'\n+USAGE='[-n] [--summary] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s <strategy>] [-m=<merge-message>] <commit>+'\n \n SUBDIRECTORY_OK=Yes\n . git-sh-setup\n@@ -127,13 +127,17 @@ parse_option () {\n \t--summary)\n \t\tshow_diffstat=t ;;\n \t--sq|--squ|--squa|--squas|--squash)\n-\t\tsquash=t no_commit=t ;;\n+\t\tallow_fast_forward=t squash=t no_commit=t ;;\n \t--no-sq|--no-squ|--no-squa|--no-squas|--no-squash)\n-\t\tsquash= no_commit= ;;\n+\t\tallow_fast_forward=t squash= no_commit= ;;\n \t--c|--co|--com|--comm|--commi|--commit)\n-\t\tsquash= no_commit= ;;\n+\t\tallow_fast_forward=t squash= no_commit= ;;\n \t--no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)\n-\t\tsquash= no_commit=t ;;\n+\t\tallow_fast_forward=t squash= no_commit=t ;;\n+\t--ff)\n+\t\tallow_fast_forward=t squash= no_commit= ;;\n+\t--no-ff)\n+\t\tallow_fast_forward=false squash= no_commit= ;;\n \t-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\\\n \t\t--strateg=*|--strategy=*|\\\n \t-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)\n@@ -477,7 +481,13 @@ done\n # auto resolved the merge cleanly.\n if test '' != \"$result_tree\"\n then\n-    parents=$(git show-branch --independent \"$head\" \"$@\" | sed -e 's/^/-p /')\n+    if test \"$allow_fast_forward\" = \"t\"\n+    then\n+        parents=$(git show-branch --independent \"$head\" \"$@\")\n+    else\n+        parents=$(git rev-parse \"$head\" \"$@\")\n+    fi\n+    parents=$(echo \"$parents\" | sed -e 's/^/-p /')\n     result_commit=$(printf '%s\\n' \"$merge_msg\" | git commit-tree $result_tree $parents) || exit\n     finish \"$result_commit\" \"Merge made by $wt_strategy.\"\n     dropsave\ndiff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\nindex b0ef488..6424c6e 100755\n--- a/t/t7600-merge.sh\n+++ b/t/t7600-merge.sh\n@@ -417,4 +417,24 @@ test_expect_success 'merge c1 with c2 (override --squash)' '\n \n test_debug 'gitk --all'\n \n+test_expect_success 'merge c0 with c1 (no-ff)' '\n+\tgit reset --hard c0 &&\n+\ttest_tick &&\n+\tgit merge --no-ff c1 &&\n+\tverify_merge file result.1 &&\n+\tverify_parents $c0 $c1\n+'\n+\n+test_debug 'gitk --all'\n+\n+test_expect_success 'merge c0 with c1 (ff overrides no-ff)' '\n+\tgit reset --hard c0 &&\n+\tgit config branch.master.mergeoptions \"--no-ff\" &&\n+\tgit merge --ff c1 &&\n+\tverify_merge file result.1 &&\n+\tverify_head $c1\n+'\n+\n+test_debug 'gitk --all'\n+\n test_done\n-- \n1.5.3.2.82.g75c8d\n"}]}