How can I undo a `git pull` and restore my repository to the previous state?

I’m looking for a safe way to git undo pull and bring my repository back to exactly how it was before I ran git pull.

Here’s what happened: I pulled changes from the remote, and it ended up merging updates into files that I didn’t want touched yet. I only wanted some of the incoming changes, not all of them. Unfortunately, the pull already happened, and now my working tree isn’t in the state I want.

From what I understand, this was essentially a merge (or fast-forward), and now I’m trying to undo that merge cleanly without making things worse.

I checked the reflog and saw something like this (simplified and rewritten):

git reflog

Output:

abc1234 HEAD@{0}: pull: fast-forward
def5678 HEAD@{1}: clone: from remote-repo

At this point, I’m unsure about the safest next step. I’ve seen suggestions to use a hard reset, but I don’t want to accidentally lose more work or mess up the repo again.

Is running something like this the correct approach for a git undo pull scenario?

git reset --hard HEAD@{1}

Could someone walk me through the exact steps to revert the pull and explain what’s happening under the hood, so I know I’m doing this safely?

Any clear guidance would be greatly appreciated , I just want my repo back to the state it was in before the pull :pray:

I’ve had the same situation a few times, and the most straightforward way is to use git reflog to see where your branch was before the pull and then reset to that commit. For example:

git reflog
# find the commit before the pull, e.g., HEAD@{1}
git reset --hard HEAD@{1}

This essentially moves your branch back in time to where it was before the pull. Be aware that --hard will reset both your working directory and index, so any uncommitted changes will be lost. I usually stash anything I’m unsure about first:

git stash

This approach has saved me multiple times when a pull brought in unwanted changes. It’s simple, effective, and uses Git’s own history to “rewind” safely.

If you have local changes that you don’t want to lose, I personally prefer a “soft” or “mixed” reset rather than --hard. This way, your working files aren’t thrown away:

git reset --merge OR git reset --soft HEAD@{1}

With this, the commit history is reverted, but your local changes remain in your working directory. It’s a safer option if you’ve modified files locally and don’t want to lose them. I use this method whenever I’m not 100% sure about overwriting files.

Sometimes, I don’t want to completely rewind the pull because I actually want some of the changes but not others. In that case, I’ll do a revert of the merge commit instead of a full reset:

git log
# find the merge commit hash from the pull
git revert -m 1 <merge-commit-hash>

This creates a new commit that undoes the merge, leaving your history intact. It’s a bit more work than a hard reset, but it’s safer for collaborative projects where you don’t want to rewrite history and risk affecting others.