All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [PATCH 6/6] Introduce fast forward option only
Date: Wed, 21 May 2008 18:16:49 -0700	[thread overview]
Message-ID: <1211419009-9741-7-git-send-email-gitster@pobox.com> (raw)
In-Reply-To: <1211419009-9741-6-git-send-email-gitster@pobox.com>

From: Sverre Hvammen Johansen <hvammen@gmail.com>

This commit introduces fast forward option 'only'.  With --ff=only
merge succeeds only if it resolves to fast-forward merge.

This feature is useful for cases where a rebase is desired
instead of a real merge.  This option can then be used to
avoid an accidental merge.

See the documentation for further details.

Signed-off-by: Sverre Hvammen Johansen <hvammen@gmail.com>
---
 Documentation/fast-forward-options.txt |    9 ++
 git-merge.sh                           |   12 +-
 git-pull.sh                            |    2 +-
 t/t7601-merge-ff-options.sh            |  214 ++++++++++++++++++++++++++++++++
 4 files changed, 231 insertions(+), 6 deletions(-)

diff --git a/Documentation/fast-forward-options.txt b/Documentation/fast-forward-options.txt
index 9374aa9..41580ea 100644
--- a/Documentation/fast-forward-options.txt
+++ b/Documentation/fast-forward-options.txt
@@ -12,6 +12,10 @@ never::
 	Generate a merge commit even if the merge resolves as a
 	fast-forward.  This option is equivalent of '--no-ff'.
 
+only::
+	Only allow a fast-forward.  The merge will fail unless HEAD is
+	up to date or the merge resolves as a fast-forward.
+
 If your workflow is always to branch from the special branch
 ("master") when working on a topic and merge that back to "master", if
 you happen to have worked only on a single topic and the "master" was
@@ -42,3 +46,8 @@ The first merge of topicA or the only merge of topicB would have
 resulted in a fast forward without '--ff=never'.  Topic A consist of
 those commits that can be reached from master^2 without passing
 through any of the first-parent ancestries of master.
+
+However, if the workflow require that the branch you are merging with
+is based on the current HEAD you can use "only fast forward" policy to
+enforce fast forward or a failure.  The last merge of topicA in
+the example above would have failed with '--ff=only'.
diff --git a/git-merge.sh b/git-merge.sh
index 775dae7..b87e125 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -168,21 +168,21 @@ parse_config () {
 			no_commit=t ;;
 		--ff)
 			case "$2" in
-			allow|never)
+			allow|never|only)
 				fast_forward=$2; shift ;;
 			-*)
 				fast_forward=allow ;;
 			*)
-				die "Available fast-forward options are: allow and newer" ;;
+				die "Available fast-forward options are: allow, newer, and only" ;;
 			esac
 			;;
 		--ff=*)
 			fast_forward=${1#--ff=}
 			case "$fast_forward" in
-			allow|never)
+			allow|never|only)
 				;;
 			*)
-				die "Available fast-forward options are: allow and newer" ;;
+				die "Available fast-forward options are: allow, newer, and only" ;;
 			esac
 			;;
 		--no-ff)
@@ -209,7 +209,7 @@ parse_config () {
 		shift
 	done
 	test "$fast_forward" = allow -o "$squash" = "" ||
-		die "You cannot combine --squash with --ff=never"
+		die "You cannot combine --squash with --ff=never or --ff=only."
 	args_left=$#
 }
 
@@ -347,6 +347,8 @@ find_reduced_parents "$@"
 # ff_head may be included here or later in actual parents
 if test -n "$reduced_parents"
 then
+	test $fast_forward = only &&
+		die "--ff=only can not handle more than one real parent"
 	test $head = $ff_head ||
 		reduced_parents="$ff_head$LF$reduced_parents"
 fi
diff --git a/git-pull.sh b/git-pull.sh
index 9e91e75..c5fa1ee 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -41,7 +41,7 @@ do
 		no_ff=--ff ;;
 	--no-ff)
 		no_ff=--no-ff ;;
-	--ff=allow|--ff=never)
+	--ff=allow|--ff=only|--ff=never)
 		no_ff=$1 ;;
 	-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
 		--strateg=*|--strategy=*|\
diff --git a/t/t7601-merge-ff-options.sh b/t/t7601-merge-ff-options.sh
index c7c6d14..56e8370 100755
--- a/t/t7601-merge-ff-options.sh
+++ b/t/t7601-merge-ff-options.sh
@@ -662,4 +662,218 @@ test_expect_success 'merge c1 with new repository (pull --ff=never)' '
 
 test_debug 'gitk --all'
 
+test_expect_success 'merge c0 with c1 (--ff=only overrides --no-ff)' '
+	git reset --hard c0 &&
+	git config branch.master.mergeoptions "--no-ff" &&
+	git merge --ff=only c1 &&
+	verify_merge file result.1 &&
+	verify_head $c1
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c0 with c1 (--ff=only in config)' '
+	git reset --hard c0 &&
+	git config branch.master.mergeoptions "--ff=only" &&
+	git merge c1 &&
+	test_tick &&
+	verify_merge file result.1 &&
+	verify_head $c1
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c1 with c0 (--ff=only in config)' '
+	git reset --hard c1 &&
+	git config branch.master.mergeoptions "--ff=only" &&
+	git merge c0 &&
+	verify_merge file result.1 &&
+	verify_head $c1
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c1 with c2 (--ff=only in config)' '
+	git reset --hard c1 &&
+	test_tick &&
+	git config branch.master.mergeoptions "--ff=only" &&
+	test_must_fail git merge c2 &&
+	verify_merge file result.1 &&
+	verify_head $c1
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c0 with c1 (--ff=only)' '
+	git reset --hard c0 &&
+	test_tick &&
+	git merge --ff=only c1 &&
+	verify_merge file result.1 &&
+	verify_head $c1
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c1 with c0 (--ff=only)' '
+	git reset --hard c1 &&
+	test_tick &&
+	git merge --ff=only c0 &&
+	verify_merge file result.1 &&
+	verify_head $c1
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c0 with c1 and c2 (--ff=only)' '
+	git reset --hard c0 &&
+	test_must_fail git merge --ff=only c1 c2 &&
+	verify_merge file result.0 &&
+	verify_head $c0
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c1 with c0 (--ff=only)' '
+	git reset --hard c1 &&
+	test_tick &&
+	git merge --ff=only c0 &&
+	verify_merge file result.1 &&
+	verify_head $c1
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c1 with c2 (--ff=only overrides --no-ff)' '
+	git reset --hard c1 &&
+	git config branch.master.mergeoptions "--no-ff" &&
+	test_tick &&
+	test_must_fail git merge c2 --ff=only &&
+	verify_merge file result.1 &&
+	verify_head $c1
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c0 with c1 (--no-ff overrides --ff=only)' '
+	git reset --hard c0 &&
+	git config branch.master.mergeoptions "--ff=only" &&
+	test_tick &&
+	git merge --no-ff c1 &&
+	verify_merge file result.1 &&
+	verify_parents $c0 $c1
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c1 with c2 (--ff owerrides --ff=only)' '
+	git reset --hard c1 &&
+	git config branch.master.mergeoptions "--ff=only" &&
+	test_tick &&
+	git merge --ff c2 &&
+	verify_merge file result.1-5 &&
+	verify_parents $c1 $c2
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c1 with x0 (--squash combined with --ff=only)' '
+	git reset --hard c1 &&
+	git config branch.master.mergeoptions "" &&
+	test_tick &&
+	test_must_fail git merge x0 --squash --ff=only &&
+	verify_merge file result.1 &&
+	verify_head $c1
+'
+
+test_debug 'gitk --all'
+
+
+test_expect_success 'merge x0 with c1 (--squash combined with --ff=only)' '
+	git reset --hard x0 &&
+	git config branch.master.mergeoptions "" &&
+	test_tick &&
+	test_must_fail git merge c1 --squash --ff=only &&
+	verify_merge file result.1-5 &&
+	verify_head $x0
+'
+
+test_debug 'gitk --all'
+
+
+test_expect_success 'merge c1 with c2 (--squash combined with --ff=only)' '
+	git reset --hard c1 &&
+	git config branch.master.mergeoptions "" &&
+	test_tick &&
+	test_must_fail git merge c2 --squash --ff=only &&
+	verify_merge file result.1 &&
+	verify_head $c1
+'
+
+test_debug 'gitk --all'
+
+
+test_expect_success 'merge c1 with x0 (--no-commit combined with --ff=only)' '
+	git reset --hard c1 &&
+	git config branch.master.mergeoptions "" &&
+	test_tick &&
+	git merge x0 --no-commit --ff=only &&
+	verify_merge file result.1-5 &&
+	verify_head $x0
+'
+
+test_debug 'gitk --all'
+
+
+test_expect_success 'merge x0 with c1 (--no-commit combined with --ff=only)' '
+	git reset --hard x0 &&
+	git config branch.master.mergeoptions "" &&
+	test_tick &&
+	git merge c1 --no-commit --ff=only &&
+	verify_merge file result.1-5 &&
+	verify_head $x0
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c1 with c2 (--no-commit combined with --ff=only)' '
+	git reset --hard c1 &&
+	git config branch.master.mergeoptions "" &&
+	test_tick &&
+	test_must_fail git merge c2 --no-commit --ff=only &&
+	verify_merge file result.1 &&
+	verify_head $c1
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c1 with x1 (pull --ff=only)' '
+	git reset --hard c1 &&
+	test_tick &&
+	git pull --ff=only clone refs/heads/master &&
+	verify_merge file result.1-13 &&
+	verify_head $x1
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge x2 with x1 (pull --ff=only)' '
+	git reset --hard x2 &&
+	test_tick &&
+	test_must_fail git pull --ff=only clone refs/heads/master &&
+	verify_merge file result.5-13 &&
+	verify_head $x2
+'
+
+test_debug 'gitk --all'
+
+test_expect_success 'merge c1 with new repository (pull --ff=only)' '
+	git reset --hard c1 &&
+	test_tick &&
+	test_must_fail git pull --ff=only new refs/heads/master &&
+	verify_merge file result.1 &&
+	verify_head $c1
+'
+
+test_debug 'gitk --all'
+
 test_done
-- 
1.5.5.1.499.g878b8

  reply	other threads:[~2008-05-22  1:18 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-22  1:16 [PATCH 0/6] Forwarding Sverre's "merge --ff=<allow,only,never>" series Junio C Hamano
2008-05-22  1:16 ` [PATCH 1/6] Documentation for joining more than two histories Junio C Hamano
2008-05-22  1:16   ` [PATCH 2/6] New merge tests Junio C Hamano
2008-05-22  1:16     ` [PATCH 3/6] Introduce -ff=<fast forward option> Junio C Hamano
2008-05-22  1:16       ` [PATCH 4/6] Restructure git-merge.sh Junio C Hamano
2008-05-22  1:16         ` [PATCH 5/6] Head reduction before selecting merge strategy Junio C Hamano
2008-05-22  1:16           ` Junio C Hamano [this message]
2008-05-22 10:48         ` [PATCH 4/6] Restructure git-merge.sh Johannes Schindelin
2008-05-22 12:50           ` Johannes Schindelin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1211419009-9741-7-git-send-email-gitster@pobox.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.