1354

How can I uncommit my last commit in git?

Is it

git reset --hard HEAD

or

git reset --hard HEAD^

?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
richard
  • 13,881
  • 3
  • 18
  • 9

8 Answers8

2207

If you aren't totally sure what you mean by "uncommit" and don't know if you want to use git reset, please see "Revert to a previous Git commit".

If you're trying to understand git reset better, please see "Can you explain what "git reset" does in plain English?".


If you know you want to use git reset, it still depends what you mean by "uncommit". If all you want to do is undo the act of committing, leaving everything else intact, use:

git reset --soft HEAD^

If you want to undo the act of committing and everything you'd staged, but leave the work tree (your files) intact:

git reset HEAD^

And if you actually want to completely undo it, throwing away all uncommitted changes, resetting everything to the previous commit (as the original question asked):

git reset --hard HEAD^

The original question also asked it's HEAD^ not HEAD. HEAD refers to the current commit - generally, the tip of the currently checked-out branch. The ^ is a notation which can be attached to any commit specifier, and means "the commit before". So, HEAD^ is the commit before the current one, just as master^ is the commit before the tip of the master branch.

Here's the portion of the git-rev-parse documentation describing all of the ways to specify commits (^ is just a basic one among many).

sth
  • 222,467
  • 53
  • 283
  • 367
Cascabel
  • 479,068
  • 72
  • 370
  • 318
  • Re: "answers neglect to mention why it's HEAD^ not HEAD, which was the original question" - this seems wrong: the original question was not actually asking "why", just "which one is it".. It's nevertheless helpful to have more background than less. – inger Mar 02 '11 at 10:52
  • 73
    @Jefromi: every answer in this question is totally wrong to emphasize --hard, the --soft, is necessary for it to be "uncommit last commit", a --hard will not only uncommit but also destroy your commit. I nearly destroyed a whole day's of work since I didn't recheck what --hard meant assuming 70+ answer wouldn't be wrong. Fortunately reflog saved my day, but it wouldn't have to be that way. – Lie Ryan Apr 07 '12 at 04:27
  • 25
    @jameshfisher It's the answer to the original question ("which of these two is it?") and there was a giant warning right underneath it. I'm editing, but... if you see a question that looks from the title like what you want, and you just blindly run the first command you see in the first answer, *this is going to keep happening to you*. – Cascabel Jul 01 '14 at 16:17
  • 9
    `get reset --soft HEAD^` is what i was looking for!!! SO sweet, what is the term for putting changes into the current working head? or directory. – Mike Lyons Dec 05 '14 at 17:36
  • `git reset HEAD^` gives me `zsh: no matches found: HEAD^`, but `git reset HEAD~1` works – avjaarsveld Jan 29 '18 at 11:32
  • 14
    Note for zsh users: use `git reset 'HEAD^'` – vmarquet May 05 '18 at 17:35
  • @Cascabel, would you mind to add to the `git reset --soft HEAD^` that the changes remain staged? I think that beginners might get confused between the `soft` and the default (`mixed`) option. I would edit it myself, but I am not 100% sure this is the case. – toto_tico Aug 22 '18 at 08:06
  • @Cascabel, I was thinking that the source of the confusion migh come from the message that appears when changes are staged, `git status` is typed which is `use "git reset HEAD ..." to unstage`. The message is correct, but since changes are not yet commited, then `HEAD` should be used instead of `HEAD^`. Maybe, you would like to clarify that, otherwise somebody could conclude that resetting to the HEAD is always pointless. – toto_tico Aug 22 '18 at 08:11
  • 4
    What if your only commit local is the first commit?git reset --soft "HEAD^" fatal: ambiguous argument 'HEAD^': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git [...] -- [...]' – JDPeckham Jan 21 '19 at 18:42
  • 1
    When I type `git reset --hard HEAD^`, it asks `More?`, then I type `y`, and it says `fatal: ambiguous argument 'HEADy': unknown revision or path not in the working tree.` – pacoverflow Mar 25 '20 at 00:57
  • Use HEAD^^ if you using Windows – Eugene Maksimov May 11 '21 at 09:03
  • 3
    @EugeneMaksimov `git reset --hard "HEAD^"` works too for Windows – satk0 Apr 05 '22 at 20:23
  • git reset --soft HEAD^ worked for me – fudu Aug 08 '23 at 10:21
643

git reset --soft HEAD^ Will keep the modified changes in your working tree.

git reset --hard HEAD^ WILL THROW AWAY THE CHANGES YOU MADE !!!

Ghilas BELHADJ
  • 13,412
  • 10
  • 59
  • 99
nfm
  • 19,689
  • 15
  • 60
  • 90
390

To keep the changes from the commit you want to undo

git reset --soft HEAD^

To destroy the changes from the commit you want to undo

git reset --hard HEAD^

You can also say

git reset --soft HEAD~2

to go back 2 commits.

Edit: As charsi mentioned, if you are on Windows you will need to put HEAD or commit hash in quotes.

git reset --soft "HEAD^"
git reset --soft "asdf"
Alex K
  • 14,893
  • 4
  • 31
  • 32
  • 24
    `git reset --soft HEAD^ More? More? fatal: ambiguous argument 'HEAD ': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this: 'git [...] -- [...]'` What the heck? Why does nothing ever just work in `git`? I hate it. – Violet Giraffe Jun 27 '15 at 06:07
  • 37
    @VioletGiraffe you are probably on windows and need to do `git reset --soft "HEAD^"` – charsi Aug 17 '16 at 13:49
  • 6
    Great answer, what I do is create in ~/.gitconfig add [alias] uncommit = reset --soft HEAD^ .... Then I can just write git uncommit and it will soft reset last commit – WoodyDRN Aug 30 '16 at 09:23
  • 3
    Windows tip: if you're too lazy to type in the additional quotes you can also use HEAD~ (e.g. git reset --soft HEAD~) which is exactly the same as "HEAD^" :) – ABVincita Sep 21 '16 at 01:41
155

If you want to revert the commit WITHOUT throwing away work, use the --soft flag instead of --hard

git reset --soft HEAD^

Be careful ! reset --hard will remove your local (uncommitted) modifications, too.

git reset --hard HEAD^

note: if you're on windows you'll need to quote the HEAD^ so

git reset --hard "HEAD^"
Michael Peterson
  • 10,383
  • 3
  • 54
  • 51
tgeros
  • 2,592
  • 2
  • 18
  • 14
  • 4
    You don't have to quote the carat with the Git bash from msysgit. – Stuart P. Bentley Aug 11 '11 at 13:02
  • 56
    tried this and just lost days of work here. read below for the `soft` version that will retain your work locally. – barclay Mar 26 '15 at 16:29
  • 21
    Note that this not only undoes the act of committing, but also throws away your changes. – Viktor Dahl May 03 '15 at 23:25
  • 12
    Just as a note for anyone who has made the mistake of running this when they didn't want to discard the changes, **your changes are not gone**, they have just been hidden. You can undo this operation using `git reset --hard HEAD@{1}` to go back to where you just were. (`HEAD@{1}` means roughly "the commit I was just at 1 change ago", in this case the commit that you told Git you wanted to get rid of. Type `git reflog` to see all the recent changes.) – Soren Bjornstad Dec 01 '18 at 01:18
  • 2
    This doesn't remove uncommited modifications, this removes the whole commit with all the changes... Thankfully I could get my changes back using Soren's tip – Fabis Jun 18 '19 at 14:45
  • @Fabis: Actually, to be precise it does both -- my previous comment was only correct in the right context. Truly uncommitted changes are permanently lost, but the changes in your most recent commit can be restored with the provided tip. – Soren Bjornstad Sep 17 '19 at 21:03
  • you can undo a commit using `git reset --hard HEAD~1` – wui Jan 20 '20 at 12:01
  • This is ambiguous, as whether the exact thing removes the changes or not. Should be explicitly given the command for keeping the local modifications as this is risky – Sourav Sarkar Aug 15 '20 at 17:49
  • `git reset --soft HEAD\^` if using `zsh` – Harvinder Jul 08 '21 at 15:34
  • git reset --soft HEAD^ this one works, basically it will uncommit your local files and keep the changes on local – Frank Guo Mar 03 '22 at 10:12
44

Just a note - if you're using ZSH and see the error

zsh: no matches found: HEAD^

You need to escape the ^

git reset --soft HEAD\^
dax
  • 10,779
  • 8
  • 51
  • 86
32

If you commit to the wrong branch

While on the wrong branch:

  1. git log -2 gives you hashes of 2 last commits, let's say $prev and $last
  2. git checkout $prev checkout correct commit
  3. git checkout -b new-feature-branch creates a new branch for the feature
  4. git cherry-pick $last patches a branch with your changes

Then you can follow one of the methods suggested above to remove your commit from the first branch.

Nilanshu Jaiswal
  • 1,583
  • 3
  • 23
  • 34
20

If you haven't pushed your changes yet use git reset --soft [Hash for one commit] to rollback to a specific commit. --soft tells git to keep the changes being rolled back (i.e., mark the files as modified). --hard tells git to delete the changes being rolled back.

eebbesen
  • 5,070
  • 8
  • 48
  • 70
Allen Kenney
  • 471
  • 4
  • 5
  • 2
    I've just learned without ruining anything, that subsequent git reset --soft HEAD~ keeps rollin' back without an intervening commit. Fortunately, I push to a bare repository and recovered from that. Good to learn these things the non-destructive, recoverable way. – octopusgrabbus Aug 06 '15 at 20:37
5

Be careful with that.

But you can use the rebase command

git rebase -i HEAD~2

A vi will open and all you have to do is delete the line with the commit. Also can read instructions that were shown in proper edition @ vi. A couple of things can be performed on this mode.

Nilanshu Jaiswal
  • 1,583
  • 3
  • 23
  • 34
Filipe
  • 1,189
  • 4
  • 15
  • 30