Search code examples
gitgit-mergegit-tagfast-forward

How can I find what is preventing a fast forward merge?


We are doing Git Flow here, but now we need to create a hotfix branch from before Git Flow started. We have a v906b03 tag from before the creation of release and develop branches. We also have v914 and v915 tags from after Git Flow started.

The approach would be some in this lines:

$ git checkout master
$ git reset --hard v906b03 #make sure that master "passed by" v906b03
$ git branch v906b03-hotfix
$ git merge v914 #this merge should be a fast-forward
$ git merge v915 #this merge should be a fast-forward

Now, what I am getting is recursive merges for the merge with v914. I tried to find what v906b03 commits aren't reachable from v914 without luck. I tried git log --oneline --not v914 v906b03, but it was empty. I also tried git log --oneline v914..v906b03, that should be the same, also empty.

What is going on?


Solution

  • the default behavior for merging tags is to use --no-ff as a merge option

    That won't be the case anymore with Git 2.17 (Q2 2018)

    See commit adcc94a (14 Feb 2018) by Junio C Hamano (gitster).
    (Merged by Junio C Hamano -- gitster -- in commit f88590e, 06 Mar 2018)

    merge: allow fast-forward when merging a tracked tag

    Long time ago at fab47d0 ("merge: force edit and no-ff mode when merging a tag object", 2011-11-07, Git v1.7.9-rc0), "git merge" was made to always create a merge commit when merging a tag, even when the side branch being merged is a descendant of the current branch.

    This default is good for merges made by upstream maintainers to integrate work signed by downstream contributors, but will leave pointless no-ff merges when downstream contributors pull a newer release tag to make their long-running topic branches catch up with the upstream.
    When there is no local work left on the topic, such a merge should simply fast-forward to the commit pointed at by the release tag.

    Update the default (again) for "git merge" that merges a tag object to

    • (1) --no-ff (i.e. create a merge commit even when side branch fast forwards) if the tag being merged is not at its expected place in refs/tags/ hierarchy and
    • (2) --ff (i.e. allow fast-forward update when able) otherwise.