Article Summaries | Different Merge Types in Git

January 6th, 2024

Article: Different Merge Types in Git

Recently, we had a merge conflict at work that required truly understanding the different types of merges that git offers, and how those types of merges differ from one another. In searching for a true understanding of Git’s behavior, I found the article above, which cemented the inner workings of these merge types in Git for me, and I wanted to summarize it here. I’d highly recommend reading the article above as it is succinct and describes the different merge types well, however, I also hope to offer something to you in my summary of the article below.

Git Merge Types Summary:

Merge

A standard merge will take each commit in the branch being merged and add them to the history of the base branch based on the timestamp of when they were created. It will also create a merge commit, a special type of “empty” commit that indicates when the merge occurred.

  • Command:

    git merge X
    
  • Advantages:

    • Most descriptive and verbose history, tells us exactly when things happened, and helps give the best context about code changes.
    • Allows us to see a graph of when branches were made using git log --oneline --graph, which can help in understanding why changes were made and when.
    • Allows us to see each commit that made up the eventually merged changes, with no loss of granularity.
  • Disadvantages:

    • Merge commits are often seen as messy as they are empty and only really there for historical reasons. Can be especially confusing if you are trying to revert a set of changes.
    • Can end up having a complex graph of previous branches that’s more difficult to read.
  • Example:

    EventMerge
    Base Branch State BeforeA---B---C---D (base)
    Branch to Merge (X) StateE---F (branch)
    Command Executedgit merge X
    Resultant Base Branch StateA---B---C---D---E---F---M (merged)

Fast Forward Merge

If we change our example so no new commits were made to the base branch since our branch was created, Git can do something called a “Fast Forward Merge”. This is the same as a Merge but does not create a merge commit.

  • Command:

    git merge --ff-only X
    
  • Advantages:

    • Keeps a very clean commit history.
    • Allows us to see each commit that made up the eventually merged changes, with no loss of granularity.
  • Disadvantages:

    • Can only be done when the base branch hasn’t had any new commits, a rarity in a shared repository.
    • Can be seen as an inaccurate view of history as it hasn’t captured that a branch was created or when it was merged.
  • Example:

    EventFast Forward Merge
    Base Branch State BeforeA---B---C---D (base)
    Branch to Merge (X) StateE---F (branch)
    Command Executedgit merge --ff-only X
    Resultant Base Branch StateA---B---C---D---F (merged)

Squash & Merge

Squash takes all the commits in the branch to be merged (e.g. (A, B, C)) and melds them into 1 commit. That commit is then added to the history, but none of the commits that made up the branch are preserved.

  • Command:

    git merge --squash X
    
  • Advantages:

    • Keeps a very clean commit history.
    • Can look at a single commit to see a full piece of work, rather than sifting through multiple commits in the log.
  • Disadvantages:

    • Loss of granularity, any useful detail in those commits that made up the branch is lost, as are any interesting decisions, changes in logic, etc., captured during the development process.
  • Example:

    EventSquash & Merge
    Base Branch State BeforeA---B---C---D (base)
    Branch to Merge (X) StateE---F (branch)
    Command Executedgit merge --squash X
    Resultant Base Branch StateA---B---C---D---S (merged)

Rebase & Merge

A rebase and merge will take where the branch was created and move that point to the last commit into the base branch, then reapply the commits on top of those changes.

  • Command:

    git pull origin base
    git checkout branch
    git rebase base
    git checkout base
    git merge branch
    
  • Advantages:

    • Keeps a very clean commit history.
    • Keeps the individual commit granularity.
  • Disadvantages:

    • Can cause frustration as, if someone were to commit to the base branch before you get to merge, you have to rebase again.
    • Can be seen as an inaccurate view of history as it hasn’t captured that a branch was created or when it was merged.
    • Difficult to see which commits relate to which PR or branch.
  • Example:

EventRebase & Merge
Base Branch State BeforeA---B---C---D (base)
Branch to Merge (X) StateE---F (branch)
Command ExecutedSee Above
Resultant Base Branch StateA---B---C---D---E’---F’ (merged)

Please note that after rebase and merge, the commit SHAs for the branch to be merged (X) will change. In the example, E and F become E' and F' after the rebase.

Octopus Merge

An Octopus Merge is a special type of merge in Git where more than two branches are merged simultaneously. It creates a complex merge commit with multiple parent branches, resembling an octopus with multiple tentacles.

  • Command:

    git merge branch1 branch2 branch3 ...
    
  • Advantages:

    • Allows simultaneous merging of changes from multiple branches.
    • Useful when changes in several branches need to be integrated together.
  • Disadvantages:

    • Complexity increases with the number of branches merged.
    • Requires careful handling to resolve potential conflicts in a multi-branch merge.
  • Example:

    EventOctopus Merge
    Base Branch State BeforeA---B---C (base)
    Branches to Merge (X, Y, Z) StatesD---E (branch X), F---G (branch Y), H---I (branch Z)
    Command Executedgit merge X Y Z
    Resultant Base Branch StateA---B---C---M (merged)
  • Note: Octopus Merges are less common and are typically used when integrating changes from multiple branches into a common base. The resultant commit (M) will have multiple parent branches.