315

I would like to undo my git pull on account of unwanted commits on the remote origin, but I don't know to which revision I have to reset back to.

How can I just go back to the state before I did the git pull on the remote origin?

Kartins
  • 3,469
  • 3
  • 17
  • 17
  • 8
    Side note: you may find it useful to `git fetch upstream` first, then take a quick look at `git diff upstream/branch` to see what you will be merging in. If all is well, then proceed with `git merge upstream/branch` – Shahbaz Oct 17 '13 at 15:51
  • 5
    You will lose all your street cred and be docked a week's pay if any hipster brogrammer sees you do **git** commands from a GUI, but both **GitHub Desktop** and **Atom** have safe, straightforward buttons to `undo` commits and checkboxes to easily and clearly stage and unstage files. GUIs are people too! – Dem Pilafian Jun 15 '19 at 06:25

8 Answers8

484

Or to make it more explicit than the other answer:

git pull 

whoops?

git reset --keep HEAD@{1}

Versions of git older than 1.7.1 do not have --keep. If you use such version, you could use --hard - but that is a dangerous operation because it loses any local changes.


To the commenter

ORIG_HEAD is previous state of HEAD, set by commands that have possibly dangerous behavior, to be easy to revert them. It is less useful now that Git has reflog: HEAD@{1} is roughly equivalent to ORIG_HEAD (HEAD@{1} is always last value of HEAD, ORIG_HEAD is last value of HEAD before dangerous operation)

Matthieu Moy
  • 15,151
  • 5
  • 38
  • 65
sehe
  • 374,641
  • 47
  • 450
  • 633
  • `HEAD@{1}` at that point would be the same as `orig_head`, no? EDIT: found an excellent answer ("Yes, kind of the same") to that question in http://stackoverflow.com/questions/964876/head-and-orig-head-in-git – conny Apr 28 '11 at 08:21
  • 2
    what is the difference between HEAD@{1} and HEAD^ ? – hugemeow Aug 28 '12 at 06:11
  • 8
    @hugemeow That would be a fine SO question. Meanwhile [`man git-rev-parse`](http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html) describes this. `HEAD@{1}` is the previous value of symbolic `HEAD` in the [`reflog`](http://gitready.com/intermediate/2009/02/09/reflog-your-safety-net.html) whereas `HEAD^` is the (first) _parent revision_ of the current `HEAD`. These two need nod be equivalent (e.g. after a rebase, a hard reset, a branch switch and such things). Do read the linked article for reflog. Cheers – sehe Aug 28 '12 at 07:34
  • 13
    PowerShell users, escape the brackets with a backtick: ``git reset HEAD@`{1`}`` – Robert Claypool Feb 15 '13 at 15:33
  • 5
    http://ss64.com/ps/syntax-esc.html I think you have wanted to type `HEAD@\`{1\`}`, or for that matter do what works on POSIX shells too: `'HEAD@{1}'` – sehe Feb 15 '13 at 15:38
  • git was definitely authored by /bin/bash users. "git reset HEAD@{1}" is hostile syntax for csh derivatives. – ctpenrose Oct 01 '13 at 22:58
  • 2
    I think it not only reset the pull, but also my commits =( – falsarella Apr 24 '15 at 23:41
  • 1
    I had to use `git reset --hard HEAD@{1}` – Victor Ferreira Feb 25 '16 at 20:32
  • you might need to do `git checkout -- .` after that. But be careful that will discard all changes in working directory – Waqleh Mar 09 '16 at 15:20
  • `git reset` does not remove files and directories added by the pull. `git reset --hard` destroys my local changes. Is there way just to undo the damage an erroneous git pull caused? – jmster Mar 17 '17 at 09:15
  • @jmster you apparently had local changes before doing the pull?. I use `autostash` for this kind of situation. Git will print the ids of automatically created stashes. I'm surprised you can pull with local changes. Maybe it's just something I automatically avoid – sehe Mar 17 '17 at 12:48
  • @sehe Yes, I usually have local changes. git pull (without --rebase) does not care about them unless it needs to overwrite some file. I will try out rebase.autostash, thank you. – jmster Mar 21 '17 at 13:16
  • 2
    `git reset` does not do the right thing here: it changes what `HEAD` points to, but not the content of the worktree. Others suggested `git checkout` or `git reset --hard`, but both are dangerous commands that destroy any uncommitted changes. I suggest using `git reset --keep HEAD@{1}` instead: `--keep` instructs git to keep uncommitted changes, but it does change the worktree. – Matthieu Moy Jul 04 '17 at 21:36
  • @MatthieuMoy adding. I think that flag was added later, but yeah, that's nice to have – sehe Jul 04 '17 at 21:44
  • I disagree with the new sentence. `git reset` was wrong even without local changes: it does not change the worktree at all (i.e. it does not "reset" the merge in local files). You want `--keep` anyway (or, if you like loosing data, `--hard` but I wouldn't recommend it in any case). – Matthieu Moy Jul 05 '17 at 06:46
  • @MatthieuMoy Yeah. Strangely, `--hard` is what I always used. No clue why I didn't mention it before. Cheers. – sehe Jul 05 '17 at 06:51
  • 1
    Good, now I fully agree with the answer. Thanks. For completeness I've added the version of Git where `--keep` was introduced. – Matthieu Moy Jul 05 '17 at 06:55
  • don't do it!! it totally screw up local – Nicolas S.Xu Aug 09 '18 at 19:11
  • It is much better than `git reset --hard` & then checkout modified files – ray Jan 15 '19 at 12:52
  • This question and answer is already explained here. https://stackoverflow.com/q/1223354/10373693 – Abhishek Kumar Sep 29 '19 at 16:24
  • @sehe Your answer saved me so much work I almost lost after mistakenly applied pull --rebase from an empty repository. Thank you so much, sir! I owe you a beer :) – Nekto Apr 27 '20 at 01:17
  • is ORIG_HEAD a keyword recognized by git or is it just a name you choose to refer to the head before the pull? –  May 07 '21 at 15:40
  • @FrankPuck It's recognized by Git: https://git-scm.com/docs/git-rev-parse (actually just noticed I linked to **and** quoted the relevant explanation in the answer text. Oh well) – sehe May 07 '21 at 15:49
82

git reflog show should show you the history of HEAD. You can use that to figure out where you were before the pull. Then you can reset your HEAD to that commit.

Noufal Ibrahim
  • 71,383
  • 13
  • 135
  • 169
  • git reflog show gave this output: c9e5e4d HEAD@{0}: pull : Fast forward 1c86a22 HEAD@{1}: pull origin master: Fast forward 05c141a HEAD@{2}: pull : Fast forward Can I safely reset the HEAD to HEAD@{1} – Kartins Apr 28 '11 at 09:32
  • The other answer by sehe has details on how to get there. – Noufal Ibrahim Apr 28 '11 at 09:37
  • This was super-useful after a disastrous commit somehow interspersed merge commits into my history. Got them out by looking for a last-known good in the reflog and then force pushing. – Domenic May 07 '12 at 18:42
  • What if `pull` is the first action? If `pull` is at `HEAD@{1}`, and nothing else before that, how do you revert to a state before that? – O.O Jul 16 '13 at 17:17
  • Recreate the repository? – Noufal Ibrahim Jul 17 '13 at 05:49
47

This worked for me.

git reset --hard ORIG_HEAD 

Undo a merge or pull:

$ git pull                         (1)
Auto-merging nitfol
CONFLICT (content): Merge conflict in nitfol
Automatic merge failed; fix conflicts and then commit the result.
$ git reset --hard                 (2)
$ git pull . topic/branch          (3)
Updating from 41223... to 13134...
Fast-forward
$ git reset --hard ORIG_HEAD       (4)

Checkout this: HEAD and ORIG_HEAD in Git for more.

Community
  • 1
  • 1
Parag Tyagi
  • 8,780
  • 3
  • 42
  • 47
21

Find the <SHA#> for the commit you want to go. You can find it in github or by typing git log or git reflog show at the command line and then do git reset --hard <SHA#>

Nina
  • 211
  • 2
  • 3
10

to undo git pull

git reset --hard HEAD^

takes your local repo back to previous commit state. (Note: HEAD^ means the first immediate parent of the tip of the current branch. HEAD^ is short for HEAD^1, and you can also go further up if you want (e.g. HEAD^2 , HEAD^3 ...). after reset, if some unknown files left (files that arrived as a result of original git pull), they will be listed as untracked files and you can clean them up using

  git clean -fd
pref
  • 1,651
  • 14
  • 24
9

Even though the above solutions do work, This answer is for you in case you want to reverse the clock instead of undoing a git pull. I mean if you want to get your exact repo the way it was X Mins back then run this command

git reset --hard branchName@{"X Minutes ago"}

Note: before you actually go ahead and run this command please only try this command if you are sure about the time you want to go back to and heres about my situation.

I was currently on a branch develop, I was supposed to checkout to a new branch and pull in another branch lets say Branch A but I accidentally ran git pull origin A before checking out.

so to undo this change I tried this command

git reset --hard develop@{"10 Minutes ago"}

if you are on windows cmd and get error: unknown switch `e

try adding quotes like this

git reset --hard 'develop@{"10 Minutes ago"}'

Mahesh Jamdade
  • 17,235
  • 8
  • 110
  • 131
4

From https://git-scm.com/docs/git-reset#Documentation/git-reset.txt-Undoamergeorpullinsideadirtyworkingtree

Undo a merge or pull inside a dirty working tree

$ git pull           (1)
Auto-merging nitfol
Merge made by recursive.
 nitfol               |   20 +++++----
 ...
$ git reset --merge ORIG_HEAD      (2)

Even if you may have local modifications in your working tree, you can safely say git pull when you know that the change in the other branch does not overlap with them.

After inspecting the result of the merge, you may find that the change in the other branch is unsatisfactory. Running git reset --hard ORIG_HEAD will let you go back to where you were, but it will discard your local changes, which you do not want. git reset --merge keeps your local changes.

See also https://stackoverflow.com/a/30345382/621690

Risadinha
  • 16,058
  • 2
  • 88
  • 91
2

Reset the master branch:

git reset --hard origin/master
Yo Yo Roshan
  • 129
  • 6