How to replace one git branch with another
Replacing one Git branch with another is a destructive operation that rewrites the history of the target branch. The method you provided using git merge -s ours
is a clever and safe way to achieve this without a hard reset. This guide will walk you through the process, explain the commands, and provide a clear, step-by-step example.
The Problem: Overwriting a Branch's History
You have a main
branch with a long history of commits, but a new feature branch, let's call it feature-alpha
, has the "correct" and desired state of the repository. You want to completely discard the history of main
and replace it with the history and content of feature-alpha
, as if main
never existed. This is a common need when a branch has become too polluted, or you're preparing for a major release.
The method you provided is an elegant solution because it uses a specific merge strategy to "replace" the content of the main
branch while still maintaining a single, linear history.
The Solution: Using the ours
Merge Strategy
The ours
merge strategy is a powerful but often misunderstood tool. When you run git merge -s ours <other-branch>
, Git performs a merge but automatically resolves every single conflict by favoring "our" version—the version on the branch you're currently on. It effectively discards all changes from the other branch you're merging in.
The key to your solution is to flip this logic. You don't want to discard the changes from feature-alpha
; you want to discard the changes from main
. By merging main
into feature-alpha
with the ours
strategy, you create a new commit that has the same content as feature-alpha
but has two parents: the tip of main
and the tip of feature-alpha
. This "dummy" merge commit is the bridge that allows you to safely overwrite main
's history.
Step-by-Step Guide
For this example, we'll replace the content and history of the main
branch with the feature-alpha
branch.
Step 1: Prepare the main
Branch
First, you need to be on the main
branch and ensure it's up-to-date with the remote repository. This prevents you from accidentally overwriting someone else's work.
git checkout main
git pull
Step 2: Create a Bridge with the ours
Strategy
Next, you'll switch to the feature-alpha
branch. You'll then perform a merge from main
, but with the ours
strategy. This merge will create a new commit on feature-alpha
that has the history of both branches but contains only the files from feature-alpha
.
git checkout feature-alpha
git merge -s ours main
At this point, you've created a new merge commit on feature-alpha
. The important thing is that this commit's content is identical to the original feature-alpha
, but its history now links back to main
.
Step 3: Fast-Forward the main
Branch
Now, switch back to the main
branch. You can now perform a normal merge from feature-alpha
. Since feature-alpha
contains a merge commit with main
as a parent, Git can perform a fast-forward merge. This means Git will simply move the main
branch pointer to the same commit that feature-alpha
is pointing to, effectively replacing the entire history of main
.
git checkout main
git merge feature-alpha
Step 4: Push the Changes to the Remote
Finally, push the new main
branch to the remote repository. Because you have rewritten the history, you must use a force push. Be extremely careful with this step! It will overwrite the remote main
branch for all collaborators.
git push --force origin main
Before doing this, it's critical to communicate with your team to ensure no one is actively working on the main
branch. A safer alternative is to use git push --force-with-lease
, which will only succeed if the remote branch has not been updated since your last pull, preventing you from overwriting others' work.
Alternative Method: The Hard Reset (Less Safe)
For completeness, another way to achieve this is with a hard reset, but it is more dangerous because it's easier to make a mistake.
git checkout feature-alpha
git push --force origin feature-alpha:main
This command checks out feature-alpha
and then forces the remote main
branch to point to the same commits as feature-alpha
, effectively overwriting main
's history. This is a much shorter but more risky method. The ours
merge strategy is generally preferred because it maintains a clean, understandable merge commit in the history.
The easiest working strategy here would be
git checkout main
git pull
git checkout featurebranch
git merge -s ours main
git checkout main
git merge featurebranch
git checkout ours .