Hrm… can you really recover branches and tags once you delete them?

I was under the impression commits were retained but removing labels (tags, branches, remotes) was unrecoverable and immediate.

You can't recover where your references were but all the objects (anything with a SHA1) are still there.

reflog tells you when you created/changed a label and what ID it had, so you can recover them.

Has anyone written a tool to actually does this? I want to add that to my post-rewrite hook immediately so that I can gain peace of mind I will always be able to switch to a branch where I can study the previous reality after rebasing a new one.

My project https://github.com/arxanas/git-branchless does this. Use `git undo -i` to get a graphical view of where branches were at an arbitrary previous point in time.

It's worth noting that, in principle, there are cases where the reflog will have never observed a branch move. The reflog we usually look at is that of HEAD; if HEAD did not have the branch checked out when it moved, then that information will be lost. (For example, if you run `git branch -f my-branch abc123`, the branch will be forcibly reassigned without having been checked out.) See https://github.com/arxanas/git-branchless/wiki/Architecture#... for more details.