Git/Fix public rebase

From Sidvind
Jump to: navigation, search

After accidentally rebasing a commit that had been pushed to a public repository a merge is required. This makes the history look nasty (same commit message repeated twice and a merge with no diff.)

Initial state[edit]

 *   9570459 (origin/branch, branch) Merge branch 'branch' of ... into branch
 |\  
 | * e98531c C1
 * | 16d3ba1 C2
 * | af9ee86 B
 |/  
 * 1538c65 A

Where C1 and C2 is identical. Merge contains no chages.

Local[edit]

 % git reset --hard 16d3ba1
 HEAD is now at 16d3ba1 C2

This moves local HEAD to the rebased commit.

 *   9570459 (origin/branch) Merge branch 'branch' of ... into branch
 |\  
 | * e53d2fc C1
 * | 16d3ba1 (HEAD, branch) C2
 * | af9ee86 B
 |/  
 * 1538c65 A

However remote is still "wrong" and you cannot push:

 % git push origin branch
 To ...
  ! [rejected]        branch -> branch (non-fast-forward)
 error: failed to push some refs to '...'
 To prevent you from losing history, non-fast-forward updates were rejected
 Merge the remote changes (e.g. 'git pull') before pushing again.  See the
 'Note about fast-forwards' section of 'git push --help' for details.

If you pull HEAD whould be fast-forwared back to 9570459.

Remote[edit]

Adding the --force flag when pushing allows you push:

 % git push origin branch --force
 Total 0 (delta 0), reused 0 (delta 0)
 To ...
  + 9570459...16d3ba1 branch -> branch (forced update)

But use with caution! While e53d2fc (C1) and 9570459 (merge) is not 100% lost nothing will refer to them anymore (thus won't show up anywhere).

 * 16d3ba1 (HEAD, origin/branch, branch) C2
 * a5a9739 B
 * 1538c65 A