How do I revert a merge commit that has already been pushed to remote in Git?

To revert a merge commit that has already been pushed to a remote repository in Git, follow these steps:

1. Identify the Merge Commit

Find the hash of the merge commit you want to revert:

git log --oneline --merges

2. Revert the Merge Commit

Use git revert with the -m 1 flag to specify the mainline branch (typically 1 for the branch you merged into):

git revert -m 1 <merge-commit-hash>

Example:

git revert -m 1 a1b2c3d

3. Resolve Conflicts (If Any)

If the revert causes conflicts:

  1. Manually resolve the conflicts.
  2. Stage the resolved files:
   git add <file1> <file2>
  1. Continue the revert:
   git revert --continue

4. Push the Revert Commit

Push the new revert commit to the remote:

git push origin <branch-name>

Key Notes

  • Why -m 1? Merge commits have two parents. -m 1 tells Git to treat the first parent (the branch you merged into, like main) as the mainline.
  • Avoid Future Merge Issues: After reverting a merge, re-merging the same branch later may require additional steps (see Caveats below).
  • Force Push Warning: Do not force-push (git push --force) unless you’re certain no one else has pulled the original merge commit.

Example Workflow

# 1. Find the merge commit
git log --oneline --merges
# Output: a1b2c3d (HEAD -> main) Merge branch 'feature'

# 2. Revert the merge
git revert -m 1 a1b2c3d

# 3. Push the revert
git push origin main

Caveats

  1. Re-Merging the Same Branch:
  • Git will not reapply changes from the original merge unless you revert the revert commit first.
  • Example workflow for re-merging:
    bash git revert <revert-commit-hash> # Undo the revert git merge feature --no-ff # Merge again with --no-ff
  1. Alternative: Remove the Merge Commit (Dangerous):
  • Use git reset to erase the merge commit (only if the branch is not shared):
    bash git reset --hard HEAD~1 # Remove the merge commit git push --force origin <branch-name>

Summary

  • Use git revert -m 1 to safely undo a pushed merge commit.
  • Communicate with your team before force-pushing.
  • For future merges, use --no-ff to preserve merge history.

Leave a Reply

Your email address will not be published. Required fields are marked *