George Garside Blog

A place of many ramblings about macOS and development. If you find something useful on here, it's probably an accident.

git.day/6 • See all at git.day

Operations such as rebasing can put you in a confusing spot, especially if a mistake is made when rebasing such as using the wrong branch or commit.

Git creates the ref ORIG_HEAD where HEAD was before the rebase took place. This can be used to compare the pre- and post-rebase state, and reset back to the original state. An easy way to undo the potentially dangerous operation that just happened.

Using the rebase we did for Git of the day #5: git rebase --interactive as an example repo history, the Git history actually looks like this:

* (master) ffff F
| * (HEAD -> foo) eeeh E’
| * cccg C’
|/
| * (ORIG_HEAD) eeee E
| * dddd D
| * cccc C
|/
* bbbb B
* aaaa A

The highlighted lines are not part of any branch, only reachable from the ORIG_HEAD ref. This makes the commits invisible to git log --all which shows all branches, but the commits are still present until unreachable (after the next dangerous operation that sets ORIG_HEAD again, and garbage collection runs).

This makes git diff work with ORIG_HEAD just like any other commit sha or ref like HEAD. Then, to reset HEAD back to the state before the rebase took place, one can run

git reset --hard ORIG_HEAD

This ORIG_HEAD ref is created not just by rebase, but all sorts of potentially dangerous operations, including git reset, git merge and git cherry-pick. A quick way to undo these operations.

Leave a Reply

No comments