Recent chats
ASKGEEZ Q&A GUIDETechnology & devices

How can I tell whether a Git merge will fast-forward or create a merge commit?

Quick answer

A merge can fast-forward when the current branch tip is an ancestor of the branch being merged: Git moves the current branch pointer forward without adding a merge commit. If both branches have commits the other does not, their histories have diverged and a true merge is needed, recorded in a merge commit. Compare the commit ranges before merging; they show history relationships, not whether conflicts will occur. [S1]

LET’S WORK THROUGH IT

The question, the details, the next step.

Question

What exactly should I check before merging topic into my current branch? I want to know whether Git will fast-forward or add a merge commit.

Geez

The key question is whether the current branch tip is an ancestor of topic’s tip. If it is, Git can fast-forward: it advances the current branch pointer to topic without creating an extra commit. If both branches have commits the other does not, their histories have diverged; a true merge is needed and is recorded in a merge commit with both tips as parents. [S1]

First, check which branch you are on and inspect the commit ranges:

git branch --show-current

git log --oneline HEAD..topic

git log --oneline topic..HEAD

The first range lists commits reachable from topic but not from your current HEAD. The second lists commits reachable from your current branch but not from topic. [S1] These commands describe the relationship between the tips; they do not promise that a merge will be conflict-free. [S1]

Follow-up question

Can you show me how to read those ranges with a small local example?

Geez

Assume your current branch is main and you plan to merge topic. These are illustrative histories, not output from a real repository.

In a fast-forwardable history, main points to an earlier commit on the path to topic:

A---B---C---D
    ^       ^
   main    topic

Here, main is an ancestor of topic. Git can move main to D without creating a merge commit. [S1] git log --oneline HEAD..topic shows commits ahead on topic, while git log --oneline topic..HEAD shows no commits unique to main.

A diverged history has commits on both sides of a shared ancestor:

      C---D  topic
     /
A---B
     \
      E---F  main

Each range has commits: HEAD..topic shows C and D, while topic..HEAD shows E and F. A true merge is needed, recorded in a merge commit with both branch tips as parents. [S1]

Follow-up question

Is git merge-base useful too, and what if I want to require a fast-forward?

Geez

git merge-base HEAD topic helps you inspect the common ancestor of the two tips. Compare the result with the tips: if the current tip is already on the history leading to topic, the relationship permits a fast-forward. If each tip has commits beyond the shared history, the branches have diverged. The Git manual identifies git merge-base as a way to inspect ancestry. [S1]

If you want to suppress a fast-forward and record a merge commit even when one is possible, Git documents --no-ff for that purpose. [S1] That option changes how the merge is recorded; it does not tell you whether the histories have diverged. Inspect the ranges first to understand the relationship.

Follow-up question

Could you give me a reusable pre-merge routine, and clarify what it cannot tell me?

Geez

For a local example, replace topic with the branch you plan to merge, then run:

git branch --show-current
git log --oneline HEAD..topic
git log --oneline topic..HEAD
git merge-base HEAD topic

Read both log ranges, not just the common ancestor. If HEAD..topic has commits and topic..HEAD has none, the current branch is behind topic in a fast-forwardable relationship. If both ranges have commits, the histories have diverged and a true merge is needed. If neither has commits, there are no commits reachable from either tip that are absent from the other. [S1]

These checks describe commit relationships, not whether the eventual merge will be conflict-free. [S1] If you want a merge commit even when fast-forwarding is possible, Git documents --no-ff for that purpose. [S1]

A practical checklist

  • Confirm the current branch with git branch --show-current.

  • Replace topic with the exact branch you plan to merge.

  • Inspect both git log --oneline HEAD..topic and git log --oneline topic..HEAD.

  • Use git merge-base HEAD topic to help identify the shared ancestor.

  • Treat ancestry checks as history information, not a prediction of merge conflicts.

  • Use --no-ff if you want a merge commit even when a fast-forward is possible.

A few more useful answers

If `git log topic..HEAD` shows commits, can the merge still fast-forward?

If that range shows commits unique to the current branch while topic also has commits beyond the shared history, the histories have diverged, so a true merge is needed. [S1]

Does a fast-forward check tell me whether there will be conflicts?

No. Ancestry and commit-range checks describe the relationship between branch tips; they do not guarantee a conflict-free merge. [S1]

Can I choose to create a merge commit even when Git could fast-forward?

Yes. Git documents --no-ff as a way to suppress a fast-forward and record a merge commit instead. [S1]

Sources

References used for this guide.

  1. [S1] Git git-merge documentation: fast-forward and true merges
    git-scm.com · Checked

YOUR QUESTION. YOUR DETAILS.

Let’s work through your situation.

Get a tailored answer or help with your next task. Starts at $1, with a quote before you pay.

Ask your own question
← Back to Geez at Work