Sling Academy
Home/DevOps/Explaining ‘git rebase –preserve-merges’ with examples

Explaining ‘git rebase –preserve-merges’ with examples

Last updated: January 27, 2024

Introduction

Version control systems are quintessential in software development, and ‘Git’ is synonymous with this role. ‘Git rebase’ is one of the most powerful features offered by Git, allowing developers to maintain a clean, linear project history. However, rebasing can sometimes disrupt the merge commits in your history. This is where the ‘–preserve-merges’ option comes in, helping you rebase without losing the context of your merge commits. In this article, we delve into the ‘git rebase –preserve-merges’ command with step-by-step examples.

Understanding Git Rebase

Before jumping into ‘–preserve-merges’, let’s get a quick overview of the standard ‘git rebase’ command. Rebasing is the process of moving or combining a sequence of commits to a new base commit. Rebasing is a cleaner alternative to merging, offering a streamlined linear history.

git checkout feature-branch
git rebase master

This set of commands changes the base of the ‘feature-branch’ to the latest commit on the ‘master’ branch.

The Need for –preserve-merges

When you perform a standard rebase, Git linearizes all commits, which means it could unintentionally flatten merge commits. Merge commits are those that bring together the histories of two divergent branches—preserving the fact that separate development histories were brought together.

The ‘–preserve-merges’ option is a way to tell Git to try and recreate the merge commits instead of flattening them during the process of a rebase.

Basic Usage of –preserve-merges

Now, let’s explore a basic example:

git checkout feature-branch
git rebase --preserve-merges master

Output: The output would show Git rebasing each commit from ‘feature-branch’ onto ‘master’, while also replying the merges with their original context and dates intact.

Rebasing Across Multiple Branches

Consider we have a more complex history with multiple topic branches merged into a longer-lived ‘feature-branch’.

git checkout complex-feature-branch
git rebase --preserve-merges master

this prevents your complex merges between topic branches in your ‘complex-feature-branch’ from being flattened out.

Dealing with Conflicts

While using ‘–preserve-merges’ during a rebase, you may run into conflicts. Handling these requires careful attention to each conflict:

# Suppose there's a conflict
git status
git add .
git rebase --continue
git log --graph --oneline

Once resolved, the preserved merges will demonstrate Git’s ability to keep the context of the merge while applying the upstream changes.

Preserving Merges with Tags and Branches

Another strength of ‘–preserve-merges’ is seeing tags and branches move along with their associated merge points:

# Assume that 'feature-branch' has several tags
git rebase --preserve-merges interacting-tags

Looking at the log graph post-rebase, one can observe that the tags which were assigned to certain commits during your development process will still point to these, even after changing the base with a rebase.

Combining –preserve-merges with Interactive Rebasing

For more advanced Git users, interactive rebasing allows for meticulous control:

git checkout feature-branch
git rebase -i --preserve-merges master

This opens your default text editor, presenting a script containing all the commits being rebased, which you can now edit, reorder, squash, or fix.

Visualizing the Effect of –preserve-merges

It can be helpful to visualize the outcomes:

git checkout pre-rebase
git log --graph --oneline --all
# Note the structure 
# Perform the rebase
git rebase --preserve-merges post-rebase
# See the outcomes with the same log command

You’ll see the former merge architecture being lifted and reapplied onto the new base, which is indicative of ‘–preserve-merge’s functionality.

Considering Alternatives to –preserve-merges

It’s important to recognize that in newer versions of Git, ‘–preserve-merges’ has been deprecated in favor of the more robust ‘–rebase-merges’ flag. Here’s an example of how to use the new flag:

git checkout feature-branch
git rebase --rebase-merges master

For those on newer versions of Git, ‘–rebase-merges’ is preferred. It offers not just preservation but also improved functionality and interactivity.

Conclusion

In conclusion, understanding ‘git rebase –preserve-merges’ can be vital for manipulating complex Git histories. However, it’s also essential to stay updated with Git’s evolving feature set and best practices such as using the ‘–rebase-merges’ flag on newer versions.

Next Article: How to set up your own private Git server on Ubuntu

Previous Article: How to filter commits by message in Git log

Series: Git & GitHub Tutorials

DevOps

You May Also Like

  • How to reset Ubuntu to factory settings (4 approaches)
  • Making GET requests with cURL: A practical guide (with examples)
  • Git: What is .DS_Store and should you ignore it?
  • NGINX underscores_in_headers: Explained with examples
  • How to use Jenkins CI with private GitHub repositories
  • Terraform: Understanding State and State Files (with Examples)
  • SHA1, SHA256, and SHA512 in Terraform: A Practical Guide
  • CSRF Protection in Jenkins: An In-depth Guide (with examples)
  • Terraform: How to Merge 2 Maps
  • Terraform: How to extract filename/extension from a path
  • JSON encoding/decoding in Terraform: Explained with examples
  • Sorting Lists in Terraform: A Practical Guide
  • Terraform: How to trigger a Lambda function on resource creation
  • How to use Terraform templates
  • Understanding terraform_remote_state data source: Explained with examples
  • Jenkins Authorization: A Practical Guide (with examples)
  • Solving Jenkins Pipeline NotSerializableException: groovy.json.internal.LazyMap
  • Understanding Artifacts in Jenkins: A Practical Guide (with examples)
  • Using Jenkins with AWS EC2 and S3: A Practical Guide