* [PATCH 0/2] add support for per branch merge policy @ 2007-09-20 12:53 Lars Hjemli 2007-09-20 12:53 ` [PATCH 1/2] git-merge: add option --no-ff Lars Hjemli 2007-09-20 13:07 ` [PATCH 0/2] add support for per branch merge policy Lars Hjemli 0 siblings, 2 replies; 8+ messages in thread From: Lars Hjemli @ 2007-09-20 12:53 UTC (permalink / raw) To: Junio C Hamano; +Cc: git These two patches extends git-merge with the options --ff and --no-ff, and uses the configuration setting branch.<name>.integrationonly to select the default policy per branch (it obviously defaults to --ff), as mentioned in http://article.gmane.org/gmane.comp.version-control.git/41980 This can also be used as a clean solution to the problem related to fast-forward merges between git-svn tracking branches, especially if git-svn could be taught to set integrationonly=true on all relevant branches whenever this setting is undefined. Diffstat: Documentation/config.txt | 7 +++ Documentation/git-svn.txt | 17 ++++++ Documentation/merge-options.txt | 13 +++++ git-merge.sh | 30 ++++++++++- t/t6029-merge-integration.sh | 108 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 172 insertions(+), 3 deletions(-) ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] git-merge: add option --no-ff 2007-09-20 12:53 [PATCH 0/2] add support for per branch merge policy Lars Hjemli @ 2007-09-20 12:53 ` Lars Hjemli 2007-09-20 12:53 ` [PATCH 2/2] add support for branch.<name>.integrationonly Lars Hjemli 2007-09-20 13:07 ` [PATCH 0/2] add support for per branch merge policy Lars Hjemli 1 sibling, 1 reply; 8+ messages in thread From: Lars Hjemli @ 2007-09-20 12:53 UTC (permalink / raw) To: Junio C Hamano; +Cc: git This option forces all merges to create a "true" merge commit, i.e. a commit with multiple parents. A fast-forward merge will often be considered The Right Thing when working in a distributed environment, but it doesn't work well when the branches to be merged originated in subversion and the merge commit will be pushed back with 'git svn dcommit'. In this case, a fast-forward merge will make git-svn mistakenly think that the current branch is tracking the merged upstream branch. But if the merge is created with --no-ff, 'git svn dcommit' will work as expected (and the history in subversion and git will be equal). There are also a use-case for --no-ff in 'native git' when integrating topic branches: if the merge of a topic-branch results in a fast-forward operation, there will be no way to detect that the topic-branch ever existed. This might be good or bad dependent on project policy, but both options (ff/no-ff) are technically sane. Signed-off-by: Lars Hjemli <hjemli@gmail.com> --- Documentation/git-svn.txt | 13 +++++++++++ Documentation/merge-options.txt | 5 ++++ git-merge.sh | 13 +++++++++- t/t6029-merge-integration.sh | 46 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 2 deletions(-) create mode 100755 t/t6029-merge-integration.sh diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index e157c6a..619023d 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -475,6 +475,19 @@ use 'git-svn rebase' to update your work branch instead of 'git pull' or when committing into SVN, which can lead to merge commits reversing previous commits in SVN. +If you use 'git-svn dcommit' to commit your local work to the upstream +subversion branch, merge commits are usually handled correctly, i.e. +git-svn will only follow the first parent of each merge commit and create +a single subversion revision for each of them. An exception is when two +subversion branches has been merged locally and the merge ended up as a +fast-forward operation. This will make git-svn believe that there are no +local changes to dcommit. To work around this issue, one can redo the +merge using the --no-ff option: + + $ git reset --hard HEAD@{1} ## undo the fast-forward merge + $ git merge --no-ff <branch> + + DESIGN PHILOSOPHY ----------------- Merge tracking in Subversion is lacking and doing branched development diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index d64c259..b34b888 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -25,3 +25,8 @@ If there is no `-s` option, a built-in list of strategies is used instead (`git-merge-recursive` when merging a single head, `git-merge-octopus` otherwise). + +--no-ff:: + Force the creation of a merge commit even when the merge would + have resolved as a fast-forward operation. See gitlink:git-svn[1] + for a use-case for this option. diff --git a/git-merge.sh b/git-merge.sh index 3a01db0..70ca5ff 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # -USAGE='[-n] [--summary] [--no-commit] [--squash] [-s <strategy>] [-m=<merge-message>] <commit>+' +USAGE='[-n] [--summary] [--no-commit] [--no-ff] [--squash] [-s <strategy>] [-m=<merge-message>] <commit>+' SUBDIRECTORY_OK=Yes . git-sh-setup @@ -165,6 +165,9 @@ do merge_msg="$1" have_message=t ;; + --no-ff) + allow_fast_forward=f + ;; -*) usage ;; *) break ;; esac @@ -444,7 +447,13 @@ done # auto resolved the merge cleanly. if test '' != "$result_tree" then - parents=$(git show-branch --independent "$head" "$@" | sed -e 's/^/-p /') + if test "$allow_fast_forward" = "f" + then + parents=$(git rev-parse "$head" "$@") + else + parents=$(git show-branch --independent "$head" "$@") + fi + parents=$(echo "$parents" | sed -e 's/^/-p /') result_commit=$(printf '%s\n' "$merge_msg" | git commit-tree $result_tree $parents) || exit finish "$result_commit" "Merge made by $wt_strategy." dropsave diff --git a/t/t6029-merge-integration.sh b/t/t6029-merge-integration.sh new file mode 100755 index 0000000..6ba7dd9 --- /dev/null +++ b/t/t6029-merge-integration.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +test_description='merge --no-ff' + +. ./test-lib.sh + +test_expect_success setup ' + >file && + git add file && + test_tick && + git commit -m initial && + git tag c0 && + c0=$(git rev-parse c0) + + echo second >file && + git add file && + test_tick && + git commit -m second && + git tag c1 && + c1=$(git rev-parse c1) + git branch test +' + +test_expect_success 'merge c1' ' + + git reset --hard c0 && + test_tick && + git merge c1 && + test $c0 = $(git rev-parse HEAD^) && + test $c1 = $(git rev-parse HEAD) + +' + +test_expect_success 'merge --no-ff c1' ' + + git reset --hard c0 && + test_tick && + git merge --no-ff c1 && + test $c0 = $(git rev-parse HEAD^1) && + test $c1 = $(git rev-parse HEAD^2) + +' + +test_debug 'gitk &' + +test_done -- 1.5.3.2.82.g75c8d ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] add support for branch.<name>.integrationonly 2007-09-20 12:53 ` [PATCH 1/2] git-merge: add option --no-ff Lars Hjemli @ 2007-09-20 12:53 ` Lars Hjemli 2007-09-20 13:14 ` Johannes Schindelin 0 siblings, 1 reply; 8+ messages in thread From: Lars Hjemli @ 2007-09-20 12:53 UTC (permalink / raw) To: Junio C Hamano; +Cc: git This setting can be used to set --no-ff as default merge policy for selected branches. There is also a new new merge-option, --ff, which can be used to override the default. Signed-off-by: Lars Hjemli <hjemli@gmail.com> --- Documentation/config.txt | 7 ++++ Documentation/git-svn.txt | 4 ++ Documentation/merge-options.txt | 14 +++++++-- git-merge.sh | 19 ++++++++++- t/t6029-merge-integration.sh | 64 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 102 insertions(+), 6 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 015910f..fa7c3c1 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -337,6 +337,13 @@ branch.<name>.merge:: branch.<name>.merge to the desired branch, and use the special setting `.` (a period) for branch.<name>.remote. +branch.<name>.integrationonly:: + When merging into branch <name>, this setting specifies whether + fast-forward merges are disallowed. The setting can be overridden + by the --ff and --no-ff options of gitlink:git-merge[1]. See + gitlink:git-svn[1] for information about this setting when + working with subversion branches. Defaults to false. + clean.requireForce:: A boolean to make git-clean do nothing unless given -f or -n. Defaults to false. diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 619023d..55828a3 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -487,6 +487,10 @@ merge using the --no-ff option: $ git reset --hard HEAD@{1} ## undo the fast-forward merge $ git merge --no-ff <branch> +Alternatively, one can configure the appropriate local branches to use +--no-ff as default by setting branch.<name>.integrationonly=true in +$GIT_DIR/config. + DESIGN PHILOSOPHY ----------------- diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index b34b888..f83bba9 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -26,7 +26,15 @@ is used instead (`git-merge-recursive` when merging a single head, `git-merge-octopus` otherwise). +--ff:: + Explicitly allow fast-forward merges. This can be used to + override the merge policy of the current branch, as specified + by the branch.<branch>.integrationonly configuration setting (see + gitlink:git-config[1] for further details). + --no-ff:: - Force the creation of a merge commit even when the merge would - have resolved as a fast-forward operation. See gitlink:git-svn[1] - for a use-case for this option. + Explicitly disallow fast-forward merges. This can be used to + override the merge policy of the current branch, as specified + by the branch.<branch>.integrationonly configuration setting (see + gitlink:git-config[1] for further details, and gitlink:git-svn[1] + for a use-case for this option). diff --git a/git-merge.sh b/git-merge.sh index 70ca5ff..4775767 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # -USAGE='[-n] [--summary] [--no-commit] [--no-ff] [--squash] [-s <strategy>] [-m=<merge-message>] <commit>+' +USAGE='[-n] [--summary] [--no-commit] [--ff] [--no-ff] [--squash] [-s <strategy>] [-m=<merge-message>] <commit>+' SUBDIRECTORY_OK=Yes . git-sh-setup @@ -23,7 +23,7 @@ no_fast_forward_strategies='subtree ours' no_trivial_strategies='recursive recur subtree ours' use_strategies= -allow_fast_forward=t +allow_fast_forward= allow_trivial_merge=t dropsave() { @@ -165,6 +165,9 @@ do merge_msg="$1" have_message=t ;; + --ff) + allow_fast_forward=t + ;; --no-ff) allow_fast_forward=f ;; @@ -245,6 +248,18 @@ do done set x $remoteheads ; shift +if test -z "$allow_fast_forward" +then + branch=$(git-symbolic-ref HEAD | sed -e 's|^refs/heads/||') + integrate=$(git config --bool "branch.$branch.integrationonly") + if test -n "$branch" -a "$integrate" = "true" + then + allow_fast_forward=f + else + allow_fast_forward=t + fi +fi + case "$use_strategies" in '') case "$#" in diff --git a/t/t6029-merge-integration.sh b/t/t6029-merge-integration.sh index 6ba7dd9..c5ffa34 100755 --- a/t/t6029-merge-integration.sh +++ b/t/t6029-merge-integration.sh @@ -31,6 +31,8 @@ test_expect_success 'merge c1' ' ' +test_debug 'gitk' + test_expect_success 'merge --no-ff c1' ' git reset --hard c0 && @@ -41,6 +43,66 @@ test_expect_success 'merge --no-ff c1' ' ' -test_debug 'gitk &' +test_debug 'gitk' + +test_expect_success 'setup integrationonly' ' + + git config branch.master.integrationonly true + +' + +test_expect_success 'merge c1' ' + + git reset --hard c0 && + test_tick && + git merge c1 && + test $c0 = $(git rev-parse HEAD^1) && + test $c1 = $(git rev-parse HEAD^2) + +' + +test_debug 'gitk' + +test_expect_success 'merge c1 --ff' ' + + git reset --hard c0 && + test_tick && + git merge --ff c1 && + test $c0 = $(git rev-parse HEAD^) && + test $c1 = $(git rev-parse HEAD) + +' + +test_debug 'gitk' + +test_expect_success 'revert integrationonly' ' + + git config branch.master.integrationonly false + +' + +test_expect_success 'merge c1' ' + + git reset --hard c0 && + test_tick && + git merge c1 && + test $c0 = $(git rev-parse HEAD^) && + test $c1 = $(git rev-parse HEAD) + +' + +test_debug 'gitk' + +test_expect_success 'merge c1 --no-ff' ' + + git reset --hard c0 && + test_tick && + git merge --no-ff c1 && + test $c0 = $(git rev-parse HEAD^1) && + test $c1 = $(git rev-parse HEAD^2) + +' + +test_debug 'gitk' test_done -- 1.5.3.2.82.g75c8d ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] add support for branch.<name>.integrationonly 2007-09-20 12:53 ` [PATCH 2/2] add support for branch.<name>.integrationonly Lars Hjemli @ 2007-09-20 13:14 ` Johannes Schindelin 2007-09-20 13:36 ` Matthieu Moy 0 siblings, 1 reply; 8+ messages in thread From: Johannes Schindelin @ 2007-09-20 13:14 UTC (permalink / raw) To: Lars Hjemli; +Cc: Junio C Hamano, git Hi, On Thu, 20 Sep 2007, Lars Hjemli wrote: > +branch.<name>.integrationonly:: Why not have something like branch.<name>.mergeOptions instead? Ciao, Dscho ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] add support for branch.<name>.integrationonly 2007-09-20 13:14 ` Johannes Schindelin @ 2007-09-20 13:36 ` Matthieu Moy 0 siblings, 0 replies; 8+ messages in thread From: Matthieu Moy @ 2007-09-20 13:36 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Lars Hjemli, Junio C Hamano, git Johannes Schindelin <Johannes.Schindelin@gmx.de> writes: > On Thu, 20 Sep 2007, Lars Hjemli wrote: > >> +branch.<name>.integrationonly:: > > Why not have something like branch.<name>.mergeOptions instead? Why make it plural? I agree that it's better to have a multiple values option than having just "true/false", which makes it more extensible, but I don't understand the kind of things you could put here that wouldn't be better located in a separate configuration option. -- Matthieu ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 0/2] add support for per branch merge policy 2007-09-20 12:53 [PATCH 0/2] add support for per branch merge policy Lars Hjemli 2007-09-20 12:53 ` [PATCH 1/2] git-merge: add option --no-ff Lars Hjemli @ 2007-09-20 13:07 ` Lars Hjemli 2007-09-20 13:24 ` Johannes Schindelin 1 sibling, 1 reply; 8+ messages in thread From: Lars Hjemli @ 2007-09-20 13:07 UTC (permalink / raw) To: Junio C Hamano; +Cc: git On 9/20/07, Lars Hjemli <hjemli@gmail.com> wrote: > branch.<name>.integrationonly Btw: we might want to call this 'branch.<name>.mergepolicy' with the possible values 'synchronize' and 'integrate'. -- larsh ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 0/2] add support for per branch merge policy 2007-09-20 13:07 ` [PATCH 0/2] add support for per branch merge policy Lars Hjemli @ 2007-09-20 13:24 ` Johannes Schindelin 2007-09-20 13:38 ` Lars Hjemli 0 siblings, 1 reply; 8+ messages in thread From: Johannes Schindelin @ 2007-09-20 13:24 UTC (permalink / raw) To: Lars Hjemli; +Cc: Junio C Hamano, git Hi, On Thu, 20 Sep 2007, Lars Hjemli wrote: > On 9/20/07, Lars Hjemli <hjemli@gmail.com> wrote: > > branch.<name>.integrationonly > > Btw: we might want to call this 'branch.<name>.mergepolicy' with the > possible values 'synchronize' and 'integrate'. IMHO this is way too limiting. Ciao, Dscho ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 0/2] add support for per branch merge policy 2007-09-20 13:24 ` Johannes Schindelin @ 2007-09-20 13:38 ` Lars Hjemli 0 siblings, 0 replies; 8+ messages in thread From: Lars Hjemli @ 2007-09-20 13:38 UTC (permalink / raw) To: Johannes Schindelin; +Cc: Junio C Hamano, git [...joining two posts in one...] On 9/20/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote: > > On 9/20/07, Lars Hjemli <hjemli@gmail.com> wrote: > > > branch.<name>.integrationonly > > > > Btw: we might want to call this 'branch.<name>.mergepolicy' with the > > possible values 'synchronize' and 'integrate'. > > IMHO this is way too limiting. > Why not have something like branch.<name>.mergeOptions instead? Yeah, that would be more powerful, I'll give it a try. -- larsh ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2007-09-20 13:38 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-09-20 12:53 [PATCH 0/2] add support for per branch merge policy Lars Hjemli 2007-09-20 12:53 ` [PATCH 1/2] git-merge: add option --no-ff Lars Hjemli 2007-09-20 12:53 ` [PATCH 2/2] add support for branch.<name>.integrationonly Lars Hjemli 2007-09-20 13:14 ` Johannes Schindelin 2007-09-20 13:36 ` Matthieu Moy 2007-09-20 13:07 ` [PATCH 0/2] add support for per branch merge policy Lars Hjemli 2007-09-20 13:24 ` Johannes Schindelin 2007-09-20 13:38 ` Lars Hjemli
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).