---
title: "TIL: Recovering from an accidental force push in git"
date: 2023-03-17T08:07:08
slug: til-recovering-from-an-accidental-force-push-in-git

---
I don't normally force-push to repos, but I wanted to overwrite the contents of an old project with a new one of the same name. So last night, I created my new project, set the git origin url to the correct one (`git set-url origin git@...`), and then ran `git push -u origin main --force`. After that, I switched off my laptop and went to bed.

Then, this morning, I switch on my other machine and pull the project I'm working on aaaand... everything disappears. Oops. I wasn't thinking and set the wrong url in the repo, and force-pushed to the wrong repository. Luckily it was fairly easy to recover from this, and nothing there goes to prod so there were no services with downtime.

## Getting back to the correct commit

My first instinct was to check `git log`, but because `git push --force` overrides the log, all I saw was the classic "initial commit" message from my new project. However, you can still get the full commit history using [reflog](https://git-scm.com/docs/git-reflog).

Running `git reflog show` gave me a full log of every commit, even the ones from before the force-push. I could see after the two commits I'd accidentally pulled (one with my initial commit, one rebasing it onto my local repo), and then under that was the last real commit I made on the project. The entry looked a bit like this:

![51f1269 HEAD@{4}: commit: Store authors alongside webmention](./src/images/Screenshot-2023-03-17-at-08.01.48.png)

So, running `git checkout HEAD@{n}` where `n` was the number in the curly braces let me checkout my original changes in a detached state. Great, all was not lost!

## Pushing back to main

I didn't really care about the changes I currently had on the repo from the new project - it's just boilerplate setup, and it's still on my other machine anyway. So, to move my currently detached state back to the repo `HEAD`, I doubled down on my mistake and did a second force push: ` git push origin HEAD:main --force`.

And that worked! My git commit history is back, the files are visible on the remote repository, all is not lost.

## Lesson learned?

Eh, maybe? I wouldn't use `push --force` on anything that: a) wasn't owned by me, b) was deploying straight to production/was actually in use. This was just me being overtired and too lazy to delete & remake a repository. I'd probably do it again, which is why I'm writing this.
