From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:36
This patch-series implements support for per branch configuration of
git-merge, using entries (branch.<name>.mergeoptions) in .git/config.
There is also a new option, --no-ff, which can be used to force git-merge
to create merge commits even when the merge was a fast-forward.
Finally, the new optiond --ff and --commit can be used to override
setting specified in .git/config.
Note: patch 1/5 is a resend of the testscript for git-merge, this time
with correct mode bits.
Shortlog:
Add test-script for git-merge porcelain
git-merge: refactor option parsing
git-merge: add support for branch.<name>.mergeoptions
git-merge: add support for --commit
git-merge: add --ff and --no-ff options
Diffstat:
Documentation/config.txt | 6 +
Documentation/git-merge.txt | 4 +
Documentation/merge-options.txt | 13 ++
git-merge.sh | 56 +++++-
t/t7600-merge.sh | 414 +++++++++++++++++++++++++++++++++++++++
5 files changed, 483 insertions(+), 10 deletions(-)
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:36
Move the option parsing into a separate function as preparation for reuse
by the next commit.
Signed-off-by: Lars Hjemli <redacted>
---
git-merge.sh | 20 ++++++++++++++------
1 files changed, 14 insertions(+), 6 deletions(-)
@@ -0,0 +1,317 @@+#!/bin/sh+#+# Copyright (c) 2007 Lars Hjemli+#++test_description='git-merge++Testingbasicmergeoperations/optionparsing.'++../test-lib.sh++test_expect_success'setup''+echo"+1+2+3+4+5+6+7+8+9+" > file &&+gitaddfile&&+gitcommit-m"commit 0"&&+gittagc0&&+c0=$(gitrev-parseHEAD)&&+echo"+1X+2+3+4+5+6+7+8+9+" > file &&+gitaddfile&&+gitcommit-m"commit 1"&&+gittagc1&&+c1=$(gitrev-parseHEAD)&&+gitreset--hard"$c0"&&+echo"+1+2+3+4+5X+6+7+8+9+" > file &&+gitaddfile&&+gitcommit-m"commit 2"&&+gittagc2&&+c2=$(gitrev-parseHEAD)&&+gitreset--hard"$c0"&&+echo"+1+2+3+4+5+6+7+8+9X+" > file &&+gitaddfile&&+gitcommit-m"commit 3"&&+gittagc3&&+c3=$(gitrev-parseHEAD)+gitreset--hard"$c0"+'++test_debug'gitk --all'++test_expect_success'test option parsing''+ifgitmerge-$c1+then+echo"[OOPS] -$ accepted"+false+fi&&+ifgitmerge--no-suchc1+then+echo"[OOPS] --no-such accepted"+false+fi&&+ifgitmerge-sfoobarc1+then+echo"[OOPS] -s foobar accepted"+false+fi&&+ifgitmerge-s=foobarc1+then+echo"[OOPS] -s=foobar accepted"+false+fi&&+ifgitmerge-m+then+echo"[OOPS] missing commit msg accepted"+false+fi&&+ifgitmerge+then+echo"[OOPS] missing commit references accepted"+false+fi+'++test_expect_success'merge c0 with c1''+gitreset--hardc0&&+gitmergec1&&+test"$c1"="$(gitrev-parseHEAD)"+'++test_debug'gitk --all'++test_expect_success'verify merge result''+echo"+1X+2+3+4+5+6+7+8+9+" > result.1 &&+cmp-sfileresult.1+'++test_expect_success'merge c1 with c2''+gitreset--hardc1&&+gitmergec2&&+test"$c1"="$(gitrev-parseHEAD^1)"&&+test"$c2"="$(gitrev-parseHEAD^2)"+'++test_debug'gitk --all'++test_expect_success'verify merge result''+echo"+1X+2+3+4+5X+6+7+8+9+" > result.1-5 &&+cmp-sfileresult.1-5+'++test_expect_success'merge c1 with c2 and c3''+gitreset--hardc1&&+gitmergec2c3&&+test"$c1"="$(gitrev-parseHEAD^1)"&&+test"$c2"="$(gitrev-parseHEAD^2)"&&+test"$c3"="$(gitrev-parseHEAD^3)"+'++test_debug'gitk --all'++test_expect_success'verify merge result''+echo"+1X+2+3+4+5X+6+7+8+9X+" > result.1-5-9 &&+cmp-sfileresult.1-5-9+'++test_expect_success'merge c0 with c1 (no-commit)''+gitreset--hardc0&&+gitmerge--no-commitc1&&+iftest"$c1"!="$(gitrev-parseHEAD)"+then+echo"[OOPS] fast-forward not performed"+false+fi&&+if!cmp-sfileresult.1+then+echo"[OOPS] merge result is wrong"+false+fi+'++test_debug'gitk --all'++test_expect_success'merge c1 with c2 (no-commit)''+gitreset--hardc1&&+gitmerge--no-commitc2&&+iftest"$c1"!="$(gitrev-parseHEAD)"+then+echo"[OOPS] HEAD changed"+false+fi&&+if!cmp-sfileresult.1-5+then+echo"[OOPS] merge result is wrong"+false+fi&&+iftest"$c2"!="$(cat.git/MERGE_HEAD)"+then+echo"[OOPS] MERGE_HEAD is wrong"+false+fi+'++test_debug'gitk --all'++test_expect_success'merge c1 with c2 and c3 (no-commit)''+gitreset--hardc1&&+gitmerge--no-commitc2c3&&+iftest"$c1"!="$(gitrev-parseHEAD)"+then+echo"[OOPS] HEAD changed"+false+fi&&+if!cmp-sfileresult.1-5-9+then+echo"[OOPS] merge result is wrong"+false+fi&&+if!grep-q"$c2".git/MERGE_HEAD+then+echo"[OOPS] c2 not in MERGE_HEAD"+false+fi&&+if!grep-q"$c3".git/MERGE_HEAD+then+echo"[OOPS] c3 not in MERGE_HEAD"+false+fi+'++test_debug'gitk --all'++test_expect_success'merge c0 with c1 (squash)''+gitreset--hardc0&&+gitmerge--squashc1&&+iftest"$c0"!="$(gitrev-parseHEAD)"+then+echo"[OOPS] HEAD changed"+false+fi&&+if!cmp-sfileresult.1+then+echo"[OOPS] merge result is wrong"+false+fi&&+iftest-f.git/MERGE_HEAD+then+echo"[OOPS] MERGE_HEAD exists"+false+fi+'++test_debug'gitk --all'++test_expect_success'merge c1 with c2 (squash)''+gitreset--hardc1&&+gitmerge--squashc2&&+iftest"$c1"!="$(gitrev-parseHEAD)"+then+echo"[OOPS] new commit created"+false+fi&&+if!cmp-sfileresult.1-5+then+echo"[OOPS] merge result is wrong"+false+fi&&+iftest-f.git/MERGE_HEAD+then+echo"[OOPS] MERGE_HEAD exists"+false+fi+'++test_debug'gitk --all'++test_expect_success'merge c1 with c2 and c3 (squash)''+gitreset--hardc1&&+gitmerge--squashc2c3&&+iftest"$c1"!="$(gitrev-parseHEAD)"+then+echo"[OOPS] HEAD changed"+false+fi&&+if!cmp-sfileresult.1-5-9+then+echo"[OOPS] merge result is wrong"+false+fi&&+iftest-f.git/MERGE_HEAD+then+echo"[OOPS] MERGE_HEAD exists"+false+fi+'++test_debug'gitk --all'++test_done
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:36
This enables per branch configuration of merge options. Currently, the most
useful options to specify per branch are --squash, --summary/--no-summary
and possibly --strategy, but all options are supported.
Note: Options containing whitespace will _not_ be handled correctly. Luckily,
the only option which can include whitespace is --message and it doesn't
make much sense to give that option a default value.
Signed-off-by: Lars Hjemli <redacted>
---
Documentation/config.txt | 6 ++++
Documentation/git-merge.txt | 4 +++
git-merge.sh | 16 +++++++++++
t/t7600-merge.sh | 63 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 89 insertions(+), 0 deletions(-)
@@ -337,6 +337,12 @@ branch.<name>.merge:: branch.<name>.merge to the desired branch, and use the special setting `.` (a period) for branch.<name>.remote.+branch.<name>.mergeoptions::+ Sets default options for merging into branch <name>. The syntax and+ supported options are equal to that of gitlink:git-merge[1], but+ option values containing whitespace characters are currently not+ supported.+ clean.requireForce:: A boolean to make git-clean do nothing unless given -f or -n. Defaults to false.
@@ -58,6 +58,10 @@ merge.verbosity:: above outputs debugging information. The default is level 2. Can be overriden by 'GIT_MERGE_VERBOSITY' environment variable.+branch.<name>.mergeoptions::+ Sets default options for merging into branch <name>. The syntax and+ supported options are equal to that of git-merge, but option values+ containing whitespace characters are currently not supported. HOW MERGE WORKS ---------------
@@ -314,4 +314,67 @@ test_expect_success 'merge c1 with c2 and c3 (squash)' ' test_debug'gitk --all'+test_expect_success'merge c1 with c2 (no-commit in config)''+gitreset--hardc1&&+gitconfigbranch.master.mergeoptions"--no-commit"&&+gitmergec2&&+iftest"$c1"!="$(gitrev-parseHEAD)"+then+echo"[OOPS] HEAD changed"+false+fi&&+if!cmp-sfileresult.1-5+then+echo"[OOPS] merge result is wrong"+false+fi&&+iftest"$c2"!="$(cat.git/MERGE_HEAD)"+then+echo"[OOPS] MERGE_HEAD is wrong"+false+fi+'++test_expect_success'merge c1 with c2 (squash in config)''+gitreset--hardc1&&+gitconfigbranch.master.mergeoptions"--squash"&&+gitmergec2&&+iftest"$c1"!="$(gitrev-parseHEAD)"+then+echo"[OOPS] new commit created"+false+fi&&+if!cmp-sfileresult.1-5+then+echo"[OOPS] merge result is wrong"+false+fi&&+iftest-f.git/MERGE_HEAD+then+echo"[OOPS] MERGE_HEAD exists"+false+fi+'++test_expect_success'override config option -n''+gitreset--hardc1&&+gitconfigbranch.master.mergeoptions"-n"&&+gitmerge--summaryc2>diffstat.txt&&+if!grep-e"^ file | \+2 +-$"diffstat.txt+then+echo"[OOPS] diffstat was not generated"+fi+'++test_expect_success'override config option --summary''+gitreset--hardc1&&+gitconfigbranch.master.mergeoptions"--summary"&&+gitmerge-nc2>diffstat.txt&&+ifgrep-e"^ file | \+2 +-$"diffstat.txt+then+echo"[OOPS] diffstat was generated"+false+fi+'+ test_done
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:36
This option can be used to override --no-commit and --squash. The change
also introduces slightly different behavior for --no-commit: when specified,
it explicitly overrides --squash.
Signed-off-by: Lars Hjemli <redacted>
---
Documentation/merge-options.txt | 4 ++++
git-merge.sh | 6 ++++--
t/t7600-merge.sh | 16 ++++++++++++++++
3 files changed, 24 insertions(+), 2 deletions(-)
@@ -10,6 +10,10 @@ not autocommit, to give the user a chance to inspect and further tweak the merge result before committing.+--commit::+ Perform the merge and commit the result. This option can+ be used to override --no-commit and --squash.+ --squash:: Produce the working tree and index state as if a real merge happened, but do not actually make a commit or
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:36
These new options can be used to control the policy for fast-forward
merges: --ff allows it (this is the default) while --no-ff will create
a merge commit.
Signed-off-by: Lars Hjemli <redacted>
---
Documentation/merge-options.txt | 9 +++++++++
git-merge.sh | 20 +++++++++++++++-----
t/t7600-merge.sh | 18 ++++++++++++++++++
3 files changed, 42 insertions(+), 5 deletions(-)
@@ -23,6 +23,15 @@ top of the current branch whose effect is the same as merging another branch (or more in case of an octopus).+--no-ff::+ Generate a merge commit even if the merge resolved as a+ fast-forward.++--ff::+ Do not generate a merge commit if the merge resolved as+ a fast-forward, only update the branch pointer. This is+ the default behavior of git-merge.+ -s <strategy>, \--strategy=<strategy>:: Use the given merge strategy; can be supplied more than once to specify them in the order they should be tried.
@@ -470,7 +474,13 @@ done# auto resolved the merge cleanly.iftest''!="$result_tree"then-parents=$(gitshow-branch--independent"$head""$@"|sed-e's/^/-p /')+iftest"$allow_fast_forward"="t"+then+parents=$(gitshow-branch--independent"$head""$@")+else+parents=$(gitrev-parse"$head""$@")+fi+parents=$(echo"$parents"|sed-e's/^/-p /')result_commit=$(printf'%s\n'"$merge_msg"|gitcommit-tree$result_tree$parents)||exitfinish"$result_commit""Merge made by $wt_strategy."dropsave
Unless there is a compelling reason otherwise, I'd prefer tests
with a test vector like this to be spelled like this:
diff -u result.1 file
That is, compare to show the difference actual output might have
from the expected result. It's easier to spot the difference
when you later break things this way.
We might also want to test:
- the index is merged;
- the working tree matches the index;
- the merge message (e.g. "git show -s --pretty=format:%s
HEAD") is as expected;
Otherwise I think it is a good idea to add these tests.
By the way, I think squash_message() leaves a wrong message
template for an Octopus, which might be worth fixing.
From: Junio C Hamano <hidden> Date: 2016-06-15 22:43:36
Lars Hjemli [off-list ref] writes:
This option can be used to override --no-commit and --squash. The change
also introduces slightly different behavior for --no-commit: when specified,
it explicitly overrides --squash.
Makes me wonder if --no-squash also make sense to override a --squash.
Is this really needed? IOW, does it ever make sense to have --no-commit
in the configuration?
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:36
On 9/23/07, Junio C Hamano [off-list ref] wrote:
Lars Hjemli [off-list ref] writes:
quoted
This test-script tries to excercise the porcelainish aspects of git-merge.
It does exercise; no need for "tries to" ;-).
Heh, ok
quoted
+ cmp -s file result.1
+'
Unless there is a compelling reason otherwise, I'd prefer tests
with a test vector like this to be spelled like this:
diff -u result.1 file
That is, compare to show the difference actual output might have
from the expected result. It's easier to spot the difference
when you later break things this way.
We might also want to test:
- the index is merged;
- the working tree matches the index;
- the merge message (e.g. "git show -s --pretty=format:%s
HEAD") is as expected;
Yes, sorry for being lazy ;-) I'll add more thorough verification
Otherwise I think it is a good idea to add these tests.
By the way, I think squash_message() leaves a wrong message
template for an Octopus, which might be worth fixing.
Ok, I'll try to detect it in the test-script and send a proper fix.
Thanks for the review.
--
larsh
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:36
On 9/23/07, Junio C Hamano [off-list ref] wrote:
Lars Hjemli [off-list ref] writes:
quoted
This option can be used to override --no-commit and --squash. The change
also introduces slightly different behavior for --no-commit: when specified,
it explicitly overrides --squash.
Makes me wonder if --no-squash also make sense to override a --squash.
Is this really needed? IOW, does it ever make sense to have --no-commit
in the configuration?
Actually, I did add --no-squash but the semantics (and implementation)
was identical to --commit so I decided it wasn't worth it (but maybe
it is - just to avoid user confusion?).
--
larsh