merge: do not create a signed tag merge under --ff-only option

Starting at release v1.7.9, if you ask to merge a signed tag, "git merge"
always creates a merge commit, even when the tag points at a commit that
happens to be a descendant of your current commit.

Unfortunately, this interacts rather badly for people who use --ff-only to
make sure that their branch is free of local developments. It used to be
possible to say:

	$ git checkout -b frotz v1.7.9~30
        $ git merge --ff-only v1.7.9

and expect that the resulting tip of frotz branch matches v1.7.9^0 (aka
the commit tagged as v1.7.9), but this fails with the updated Git with:

	fatal: Not possible to fast-forward, aborting.

because a merge that merges v1.7.9 tag to v1.7.9~30 cannot be created by
fast forwarding.

We could teach users that now they have to do

	$ git merge --ff-only v1.7.9^0

but it is far more pleasant for users if we DWIMmed this ourselves.

When an integrator pulls in a topic from a lieutenant via a signed tag,
even when the work done by the lieutenant happens to fast-forward, the
integrator wants to have a merge record, so the integrator will not be
asking for --ff-only when running "git pull" in such a case. Therefore,
this change should not regress the support for the use case v1.7.9 wanted
to add.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Junio C Hamano 2012-02-05 16:22:12 -08:00
parent 828ea97de4
commit b5c9f1c1b0
2 changed files with 15 additions and 1 deletions

View File

@ -1283,7 +1283,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
sha1_to_hex(commit->object.sha1)); sha1_to_hex(commit->object.sha1));
setenv(buf.buf, argv[i], 1); setenv(buf.buf, argv[i], 1);
strbuf_reset(&buf); strbuf_reset(&buf);
if (merge_remote_util(commit) && if (!fast_forward_only &&
merge_remote_util(commit) &&
merge_remote_util(commit)->obj && merge_remote_util(commit)->obj &&
merge_remote_util(commit)->obj->type == OBJ_TAG) { merge_remote_util(commit)->obj->type == OBJ_TAG) {
option_edit = 1; option_edit = 1;

View File

@ -27,6 +27,7 @@ Testing basic merge operations/option parsing.
' '
. ./test-lib.sh . ./test-lib.sh
. "$TEST_DIRECTORY"/lib-gpg.sh
printf '%s\n' 1 2 3 4 5 6 7 8 9 >file 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 X' 2 3 4 5 6 7 8 9 >file.1
@ -670,4 +671,16 @@ test_expect_success 'merge --no-ff --edit' '
test_cmp actual expected test_cmp actual expected
' '
test_expect_success GPG 'merge --ff-only tag' '
git reset --hard c0 &&
git commit --allow-empty -m "A newer commit" &&
git tag -s -m "A newer commit" signed &&
git reset --hard c0 &&
git merge --ff-only signed &&
git rev-parse signed^0 >expect &&
git rev-parse HEAD >actual &&
test_cmp actual expect
'
test_done test_done