NeuroAgent

Git Hotfix to Feature Branch: No Duplicate Commits

Learn how to merge hotfix branches into feature branches in Git without creating duplicate commits. Discover cherry-pick, merge, and rebase approaches for clean Git workflows.

Question

How to merge a hotfix branch into a feature branch in Git without creating duplicate commits?

I’m working with Git and have the following workflow:

  1. Created repository:
bash
mkdir GitTest2
cd GitTest2
git init
  1. Made initial commits to master:
bash
echo "On Master" > file
git commit -a -m "Initial commit"
  1. Created feature1 branch and did some work:
bash
git branch feature1
git checkout feature1
echo "Feature1" > featureFile
git commit -a -m "Commit for feature1"
  1. Discovered a bug in master, created hotfix branch:
bash
git checkout master
git branch hotfix1
git checkout hotfix1
  1. Fixed the bug in hotfix branch and merged back to master:
bash
echo "Bugfix" > bugfixFile
git commit -a -m "Bugfix Commit"
git checkout master
git merge --no-ff hotfix1
  1. Continued development on feature1:
bash
git checkout feature1

Now I need to apply the hotfix to my feature branch because the bug also affects it. How can I achieve this without duplicating commits into my feature branch?

I want to avoid creating two new commits on my feature branch that have no relation to the feature implementation. This is especially important when using pull requests, as these commits would be included in the PR and require review even though they’ve already been reviewed as part of the hotfix.

I tried git merge master --ff-only but got “fatal: Not possible to fast-forward, aborting.” I’m not sure if this would have helped anyway.

What’s the best approach to merge a hotfix into a feature branch in this scenario?

NeuroAgent

To merge a hotfix branch into a feature branch in Git without creating duplicate commits, you have several effective approaches. The key is to integrate the hotfix changes cleanly while maintaining a clean commit history that doesn’t include unrelated commits in your feature branch pull requests.

The most common solutions are cherry-picking specific commits, merging with proper flags, or rebasing your feature branch. Each approach has different implications for your commit history and workflow.


Contents


Understanding the Problem

When you merge master (which now contains the hotfix) into feature1, Git will typically create a merge commit that includes the entire history from master up to the hotfix. This means not only will your hotfix be applied, but potentially other commits from master that don’t belong in your feature branch.

The issue you encountered with git merge master --ff-only failed because feature1 and master have diverged - feature1 doesn’t contain the hotfix commit, and master doesn’t contain the feature1 changes. A fast-forward merge isn’t possible in this scenario.

As the Atlassian Git tutorial explains, cherry-picking allows you to apply specific changes without merging entire branches, which is exactly what you need in this situation.


The cherry-pick approach is generally the cleanest method for applying hotfixes to feature branches without duplicating commits.

Step-by-step process:

  1. Identify the hotfix commit(s):
bash
git log master --oneline --grep="Bugfix"
  1. Switch to your feature branch:
bash
git checkout feature1
  1. Cherry-pick the specific hotfix commit:
bash
git cherry-pick <commit-hash>

Example with your scenario:

bash
git checkout feature1
git cherry-pick BugfixCommitHash

Benefits of cherry-picking:

  • Only applies the specific fix you need
  • Creates a new commit on feature1 that’s clearly related to the hotfix
  • Doesn’t pull in unrelated commits from master
  • Maintains separation of concerns

As Nick Janetakis explains, “It applies the change by creating a new commit for each ‘copied’ commit, you’ll end up with the same 2 commit details in each branch but the ‘copied’ commit will have a different git commit SHA.”

Handling conflicts:
If conflicts occur during cherry-pick:

bash
git cherry-pick --abort  # if you want to cancel
git cherry-pick --continue  # after resolving conflicts

Merge Approach: Direct Integration

While cherry-pick is often preferred, you can also use merge with specific strategies to control how commits are integrated.

Basic merge approach:

bash
git checkout feature1
git merge hotfix1

Using merge strategies:

  1. Recursive strategy with ours/their option:
bash
git checkout feature1
git merge -s recursive -X theirs hotfix1
  1. Using octopus for multiple branches:
bash
git checkout feature1
git merge --no-ff hotfix1

As mentioned in the Stack Overflow discussion, when you try to merge one branch with another, Git can simplify things by moving the pointer forward if there’s no divergent work to merge together.

Potential issues with merge:

  • May create a merge commit that includes unrelated history
  • Can make the feature branch history more complex
  • May pull in commits from master that don’t belong in feature1

Rebase Approach: Rewriting History

Rebasing can also be an effective approach, though it rewrites history which may not be suitable for all workflows.

Rebase feature branch onto master:

bash
git checkout feature1
git rebase master

How this works:

  • Git takes all commits from feature1 that aren’t in master
  • Temporarily removes them
  • Applies them on top of master (which includes the hotfix)
  • Re-applies the feature1 commits

As the Git documentation explains, “when you try to merge one commit with a commit that can be reached by following the first commit’s history, Git simplifies things by moving the pointer forward because there is no divergent work to merge together — this is called a ‘fast-forward.’”

Benefits of rebase:

  • Results in a linear history
  • Automatically incorporates the hotfix
  • No extra merge commits

Caveats:

  • Rewrites history (should not be used on shared branches)
  • Can cause conflicts that need resolution
  • Changes commit hashes

Comparison of Approaches

Approach History Impact Complexity Conflict Handling Best For
Cherry-pick Minimal (only specific commits) Low Manual per commit Targeted hotfix application
Merge Adds merge commit Low Automatic merge Simple integration
Rebase Rewrites history High Interactive Linear history preference

When to use each:

  • Cherry-pick: Best when you only want specific commits and want to keep feature branch history clean
  • Merge: Best when you want to preserve branch history and don’t mind merge commits
  • Rebase: Best when you want a linear history and can rewrite shared branch history

As discussed in the GitLab documentation, “Repeat for each branch that needs the contents of commit abc123f. If the code you need was added over the course of multiple commits, cherry-pick each of those commits into your desired target branch.”


Best Practices for Hotfix Integration

1. Create hotfixes from the correct base:

  • Hotfixes should typically be based on the production branch (master)
  • Avoid creating hotfixes from development branches

2. Keep hotfix focused:

  • Each hotfix should address a single issue
  • Don’t combine multiple fixes in one hotfix

3. Document the integration:

  • Use clear commit messages that reference the hotfix
  • Consider adding [hotfix] prefix to feature branch commits

4. Test after integration:

  • Always verify that the hotfix works in the feature branch context
  • Run tests to ensure the fix doesn’t break existing functionality

5. Communicate with your team:

  • Let team members know when hotfixes are applied to feature branches
  • Update any relevant documentation or tickets

As mentioned in the Linux Hint guide, “Create and switch to the ‘hotfix’ branch, perform the needed task and commit changes to the repository. Execute the ‘$ git merge –no-ff ’ command.”


Conclusion

For your specific scenario, I recommend using cherry-pick as the primary method to integrate the hotfix into your feature branch:

bash
git checkout feature1
git cherry-pick BugfixCommitHash

This approach will:

  • Apply only the specific bug fix to your feature branch
  • Create a clean, isolated commit for the hotfix in feature1
  • Avoid duplicating the entire master history
  • Keep your pull request focused on feature-related changes

If you need to apply multiple commits from the hotfix, cherry-pick each one individually. For more complex scenarios or when you prefer a linear history, consider rebasing your feature branch onto master.

Remember that the best approach depends on your team’s workflow, branching strategy, and how you manage code reviews. Choose the method that makes the most sense for your project’s specific needs and maintain clear communication about hotfix integrations to avoid confusion during code reviews.