3568

I would like to know how to delete a commit.

By delete, I mean it is as if I didn't make that commit, and when I do a push in the future, my changes will not push to the remote branch.

I read git help, and I think the command I should use is git reset --hard HEAD. Is this correct?

Randall
  • 2,454
  • 1
  • 17
  • 21
hap497
  • 129,793
  • 42
  • 77
  • 91
  • 49
    I think this is **not** a duplicate of [Git undo last commit](http://stackoverflow.com/questions/927358/git-undo-last-commit) as it asks how to delete **any** commit from a branch. I also think non of the answers actually address this question. They all rewind the last commits, not `cherry-pick` and `delete` a single commit that may occurred a while ago. – Chris May 03 '15 at 18:06
  • 14
    @Chris, the answer with `git rebase -i HEAD~10` does address the question, as it does let you arbitrarily pick commits to delete. Git applies the commits in the range you specify one-by-one, ignoring commits you have removed from the log. I used this command today to get rid of the second and third most recent commits to my repo while keeping the top one. I agree that none of the other answers are satisfactory. – MST Jun 17 '15 at 21:07
  • @MST yes, I should have said, non of the options in the accepted answer address this question, but you are absolutely right - that command seems to work – Chris Jul 10 '15 at 12:43
  • I think `git reset --soft HEAD~1` is exactly what you need. In such case you will undo commit and save your work. `reset --hard` will remove commit completely. – sergpank May 18 '21 at 07:56

33 Answers33

4576

Careful: git reset --hard WILL DELETE YOUR WORKING DIRECTORY CHANGES. Be sure to stash any local changes you want to keep before running this command.

Assuming you are sitting on that commit, then this command will wack it...

git reset --hard HEAD~1

The HEAD~1 means the commit before head.

Or, you could look at the output of git log, find the commit id of the commit you want to back up to, and then do this:

git reset --hard <sha1-commit-id>

If you already pushed it, you will need to do a force push to get rid of it...

git push origin HEAD --force

However, if others may have pulled it, then you would be better off starting a new branch. Because when they pull, it will just merge it into their work, and you will get it pushed back up again.

If you already pushed, it may be better to use git revert, to create a "mirror image" commit that will undo the changes. However, both commits will be in the log.


FYI -- git reset --hard HEAD is great if you want to get rid of WORK IN PROGRESS. It will reset you back to the most recent commit, and erase all the changes in your working tree and index.


Lastly, if you need to find a commit that you "deleted", it is typically present in git reflog unless you have garbage collected your repository.

Arslan Ali
  • 16,294
  • 7
  • 51
  • 65
gahooa
  • 114,573
  • 12
  • 89
  • 95
  • 65
    `HEAD~1` or just `HEAD^`. If you pushed, you should use `git revert` instead. – Jakub Narębski Aug 27 '09 at 10:45
  • 15
    Obviously you can also use `HEAD~n` to "go back" `n` commits from your head. Maybe from this point you can interpreted `... --hard HEAD` also as `HEAD~0` => deleting work in progress. – nuala Jun 11 '12 at 08:05
  • @beamrider9 That is what `--hard` means. – Chad Aug 31 '12 at 17:13
  • 14
    @beamrider9 imho git rebase is almost always the better way to delete commits (as described in Greg Hewgill's answer) -- not least because rebase does in fact include a big warning that you will be deleting stuff 4realz. – Noah Sussman Oct 26 '12 at 06:39
  • 2
    maybe this should be modified to mention --soft ? – rogerdpack Dec 21 '12 at 18:45
  • 20
    this doesn't delete changes from the commit tree though. The OP asked for an already made commit. If you `reset --hard`, and check the `log --oneline --all`, the commits still remain in the tree. How do we delete these commits from tree? Thanks. – iGbanam Mar 17 '13 at 03:09
  • Thanks for the thorough documentation here. The only thing I'd add is that rebase typically is used to deal with multiple branches rather than deleting a single commit in a single branch. – Will Nielsen Jun 03 '13 at 18:01
  • 20
    use `reset --soft` to delete local commit WITHOUT reverting work in progress! –  Sep 24 '13 at 00:07
  • 6
    Glad I read the comments to learn that this answer doesn't actually answer the question, there should be NO leftovers in the repo "as if I didn't make that commit." – bradw2k Jan 16 '15 at 03:25
  • 1
    You sure deserve an upvote because I have looked this up atleast 5 times in the last year – Akshat Agarwal Jul 18 '15 at 06:50
  • 1
    Confirming that in Sept 2015 this worked for me `git reset --hard ` to make the last commit "like it never even happend" – Eric Hepperle - CodeSlayer2010 Sep 11 '15 at 22:39
  • I don't understand why everyone is recommending `git reset --hard ...` and then proceeds to explain how one should watch out for working directory changes etc. Well, why not use the more apt and less dangerous `git reset [--soft]` (i.e. soft or mixed reset) instead? – amn May 18 '17 at 08:16
  • 1
    Dropping the commit through a rebase is a less aggressive solution to achieve the same goal. See my answer for more details. – IliasT Jun 27 '17 at 06:35
  • Please correct me if I'm wrong: I always that `HEAD~1` means 'Go to the previous commit'. But the 'Go to' is a result of the command. `HEAD~1` just means 'previous commit'. The command `reset --hard HEAD~1` means Go to ` – Honey Sep 21 '17 at 17:21
  • 1
    ```HEAD``` is a reference to the currently checked out commit. ```HEAD^``` references it's parent. ```HEAD^^``` references it's grandparent. ```HEAD~N``` references it's Nth parent. If you look at ```git log``` you will see that ```HEAD~3``` is the 4th entry down. And yes, these can be used on any git operation that requires a commit as an argument. A branch, by the way, is just another reference to a commit :) – gahooa Sep 26 '17 at 00:00
  • 2
    You saved my life. – Mathiasfc Jul 09 '19 at 22:03
  • if I have unpushed commits and uncommitted changes, will `git reset --hard` delete my commits? – Daniel Springer Nov 01 '19 at 01:49
  • @DanielSpringer, `git reset --hard ` will reset your HEAD to the specified commit, and discard any changes in your index. Any working tree files that are untracked and have not been added to git will remain. You can use `git clean -df` to remove them, though, exercise with great care. – gahooa Nov 09 '19 at 22:37
  • What if I don’t specify a commit? Will unpushed commits be lost? – Daniel Springer Nov 10 '19 at 00:12
  • How can I dismiss uncommitted changes? The only way I know is `git reset --hard` – Daniel Springer Nov 15 '19 at 01:45
  • https://stackoverflow.com/a/32318688/2694784 is better as it shows how to remove a commit which is not on the top. – Karan Bansal Jul 02 '20 at 08:18
765

If you have not yet pushed the commit anywhere, you can use git rebase -i to remove that commit. First, find out how far back that commit is (approximately). Then do:

git rebase -i HEAD~N

The ~N means rebase the last N commits (N must be a number, for example HEAD~10). Then, you can edit the file that Git presents to you to delete the offending commit. On saving that file, Git will then rewrite all the following commits as if the one you deleted didn't exist.

The Git Book has a good section on rebasing with pictures and examples.

Be careful with this though, because if you change something that you have pushed elsewhere, another approach will be needed unless you are planning to do a force push.

James Ko
  • 25,479
  • 23
  • 92
  • 196
Greg Hewgill
  • 828,234
  • 170
  • 1,097
  • 1,237
  • 2
    Note: If you happen to have any --no-ff merges in that last batch of commits, rebase will butcher them :( This is mentioned under -p on [this page](https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html). The problem is, if you replace -i with -p, you no longer get that pop up with the choices for "edit this commit, sqush that one", etc etc. Anyone know the solution? – Bukov Apr 21 '13 at 00:20
  • Is this better than the "reset hard" answer as it won't delete the files, just the mistaken commit message? Because it appears to have deleted my files. If deleting the file is supposed to happen, please add that as a clear warning! – Darren Cook Nov 27 '13 at 03:11
  • 4
    What if you have pushed it? (just me using the remote repo) – Costa Jan 07 '15 at 06:02
  • 6
    @Costa you can use `push -f` to force the push and replace the remote branch with your local one. If it's just your own remote repo, no problem. The trouble starts if somebody else has fetched in the meantime. – Greg Hewgill Jan 07 '15 at 06:16
  • 3
    I added and committed a data file that was too big for GitHub (yeah, it probably shouldn't be in the source repo anyway; Oh well). When I tried to push, GitHub refused because of the too-large file. All I wanted to do was undo this one commit, while saving a few other unrelated commits that followed. The `git rebase -i HEAD~5` command was *exactly* what I needed to completely remove this commit from my local repo! Thanks! – aldo Feb 24 '15 at 18:07
  • 1
    @Bukov The [documentation](https://www.kernel.org/pub/software/scm/git/docs/git-rebase.html#_bugs) says you can use both `-i` and `-p`, but if you do, "Editing commits and rewording their commit messages should work fine, but attempts to reorder commits tend to produce counterintuitive results." I'm not sure how well deleting commits would work, but you could try it and then do a `reset --hard` to before the rebase (using the reflog) if it doesn't work out properly. – Max Nanasy Mar 04 '15 at 02:03
  • Or `git rebase -i 592d26e9131e0a5a9b6ada78ab1574688cbbf9b7^` while `592d26e9131e0a5a9b6ada78ab1574688cbbf9b7` is the id of an earliest commit you want to delete. – McKelvin Nov 26 '15 at 03:56
  • 1
    When it deletes the commit does it also delete the changes (like `--hard` in the original post) or does it leave them intact but uncommitted (c.f. `--soft`)? – dumbledad May 10 '16 at 11:28
  • 4
    @dumbledad: With `rebase -i`, the changes corresponding to the deleted commit are not preserved. – Greg Hewgill May 10 '16 at 17:43
571

Another possibility is one of my personal favorite commands:

git rebase -i <commit>~1

This will start the rebase in interactive mode -i at the point just before the commit you want to whack. The editor will start up listing all of the commits since then. Delete the line containing the commit you want to obliterate and save the file. Rebase will do the rest of the work, deleting only that commit, and replaying all of the others back into the log.

1800 INFORMATION
  • 119,313
  • 29
  • 152
  • 234
  • 4
    thx, btw if you run into any issues (like empty commits) you can use `git rebase --continue` – realgt Sep 28 '12 at 15:43
  • 13
    Even easier: `git rebase -i HEAD~1` – mmell Sep 10 '13 at 21:12
  • 3
    Wowzers. `git rebase -i HEAD~1` really cleaned the repo up a lot! It's hard to tell exactly what it did, but the whole thing looks a lot neater. A little alarming, actually. – Charles Wood Dec 02 '14 at 18:02
  • When a commit is empty, git rebase will display that line commented out (`#`). If you don't uncomment that line, git will delete the commit when rebasing. Deleting the empty commit is actually exactly what I was trying to do, but if you want to keep yours, un-comment out the line first. – Chris Middleton Apr 24 '15 at 22:16
  • 8
    I think it's worth noting that the commit is not obliterated, merely removed from the list. If you mess up, you can get the commit back using the [reflog](http://gitready.com/intermediate/2009/02/09/reflog-your-safety-net.html). – Zaz Apr 29 '15 at 00:11
  • 9
    Is deleting the line the same as d/drop? – Leo May 25 '16 at 18:37
  • @dragonmnl deleting or modifying pushed commits is something that I understand is not recommended – 1800 INFORMATION Feb 07 '17 at 02:13
  • I had merged instead of rebasing and my pull request showed other changes then mine. running git rebase -i HEAD~1 cleaned it up. Thanks to mmell – user373201 May 01 '19 at 15:33
  • First time ever I dared to use `rebase` and it worked smoothly. – Farzad Yousefzadeh Jan 08 '20 at 12:26
  • That _worked_ that is, I was able to remove a commit but then I just can't push the results so it's just completely useless. Maybe because I already pushed earlier? – Alexis Wilke Jun 11 '20 at 18:33
379

I'm appending this answer because I don't see why anyone who has just tried to commit work would want to delete all that work because of some mistake using Git!

If you want to keep your work and just 'undo' that commit command (you caught before pushing to repo):

git reset --soft HEAD~1

Do not use the --hard flag unless you want to destroy your work in progress since the last commit.

Rob
  • 4,678
  • 1
  • 20
  • 22
  • 6
    Here's an example of why: you do a small piece of work on a development server that you commit. Then it turns out that that server doesn't have outgoing HTTPS access, so you can't push the commit anywhere. Easiest to just pretend it never happened, and redo the patch from your local machine. – Steve Bennett Jan 03 '13 at 04:32
  • 2
    @KarthikBose there would always be the reflog. even after `git reset --hard HEAD~1` your previous latest commit would be available via reflog (until you expire it); see also here: http://gitready.com/intermediate/2009/02/09/reflog-your-safety-net.html – codeling Jun 06 '13 at 11:52
  • 1
    Maybe I'm using git wrong, but one situation I'd like the `--hard` option for is when I've got multiple remote branches and I pushed to the wrong branch. Say I've got a `master` branch and a `staging` branch, I do work on a local branch, but then accidentally merge and push into master, and then realize I did the wrong thing. I'd then want to restore master's HEAD to the second most recent commit **and** want to remove all trace of that faulty push from master, as it's not **supposed** to be in master – Goldentoa11 Jun 17 '13 at 15:12
  • 1
    you could just as easily do git commit --amend in this scenario which is way less confusing – UpAndAdam Jul 24 '13 at 22:26
  • 4
    Thanks. This answer should be ranked higher or included in the accepted answer. Deleting a commit != reverting a commit. – Alsciende Mar 05 '14 at 13:32
  • 2
    @RandolphCarter: you will still lose any uncommitted changes though. – naught101 Sep 01 '14 at 08:18
  • 9
    @Rob, one example is when you accidentally commit a file that contains a secret (e.g. a password) that should never be in source control. The local commit must be *destroyed*, not just undone, so it will never get pushed to the server. – Bob Meyers Nov 15 '16 at 15:51
  • This worked great! I did not want to undo everything, only a few folders in my last couple commits. HARD could have worked, but I would of had to save off all my changes that I wanted to keep and patch them in latter. SOFT removed the local commits. And "git reset HEAD -- ." was also necessary to remove staged changed. Then I could remove all the bad things manually, and everything else - my other changes - were left intact. – Gabe Halsmer Mar 21 '17 at 01:20
  • super important! tnx m8 – Li3ro Apr 24 '18 at 13:59
  • I think, this is a good option. – arango_86 Jan 13 '21 at 10:00
212

Removing an entire commit

git rebase -p --onto SHA^ SHA

Obviously replace "SHA" with the reference you want to get rid of. The "^" in that command is literal.

http://sethrobertson.github.io/GitFixUm/fixup.html#change_deep

Will Ediger
  • 873
  • 9
  • 16
raittes
  • 4,783
  • 2
  • 26
  • 25
  • 38
    how can I upvote more this answer??? the other solutions are just showing how to do it interactively or to remove the top commits. – ribamar Jan 12 '18 at 16:24
  • Thank you for this link! I was wondering, after running this, why do I still see the commit SHA in my git reflog? – bapors Feb 15 '18 at 11:03
  • Why do we need the `-p` here? – Serge Roussak Jun 26 '18 at 05:14
  • 6
    `-p, --preserve-merges` Recreate merge commits instead of flattening the history by replaying commits a merge commit introduces. Merge conflict resolutions or manual amendments to merge commits are not preserved. – raittes Jun 27 '18 at 18:31
  • 15
    It says, "replace SHA with the reference you want to get rid of" but the line has SHA in there twice. Here is what I did. git rebase -p --onto 5ca8832c120^ 5ca8832c120 But nothing changed. Am I supposed to use the same SHA twice? If not, then which is the SHA for the commit to be removed and what is the other SHA supposed to be? – Rubicksman May 14 '19 at 22:34
  • 1
    to be specific, this method removes ENTIRE commit, including files (not desired in my case) – goofology Jul 11 '19 at 20:16
  • 2
    @Rubicksman ^ must be escaped (^^) on windows (cmd window) - https://stackoverflow.com/questions/1955985/what-does-the-caret-character-mean – goofology Jul 11 '19 at 20:19
  • 1
    on mac: `git rebase --onto SHA~ SHA` – dimpiax Jan 09 '20 at 12:28
  • 3
    `-p` `[DEPRECATED: use --rebase-merges instead]` – SyedElec Feb 14 '20 at 17:49
68

Say we want to remove commits 2 & 4 from the repo.

commit 0 : b3d92c5
commit 1 : 2c6a45b
commit 2 : <any_hash>
commit 3 : 77b9b82
commit 4 : <any_hash>

Note: You need to have admin rights over the repo since you are using --hard and -f.

  • git checkout b3d92c5 Checkout the last usable commit.
  • git checkout -b repair Create a new branch to work on.
  • git cherry-pick 77b9b82 Run through commit 3.
  • git cherry-pick 2c6a45b Run through commit 1.
  • git checkout master Checkout master.
  • git reset --hard b3d92c5 Reset master to last usable commit.
  • git merge repair Merge our new branch onto master.
  • git push -f origin master Push master to the remote repo.
tk_
  • 13,042
  • 6
  • 71
  • 81
  • 1
    last step should be `git push -f origin master` there is no option `--hard` – vivex Jan 15 '18 at 04:55
  • 5
    I guess `commit 0` is older than `commit 1`. Please could you tell me why first run through `commit 3` (by cherry-pick) and then by `commit 1`? After checkout of `b3d92cd` (`commit 0`) I would expect cherry-pick `commit 1`, then `commit 3`. Thanks. – Jarek C Nov 05 '18 at 11:51
  • 1
    @JarekC I think the top-most commit is the newest commit here, unless I'm seeing something wrong... – Jeff Huijsmans Jan 22 '19 at 15:06
  • 1
    This is mostly right but kind of wrong. I just followed this process and had to tweak it a bit. Clarification: `commit 0` is the newest commit, `commit 4` is the oldest. Start by checking out `commit 5`, just before the commit that you don't want. Then `cherry-pick` `commit 3`, then `cherry-pick` `commit 1`, then do it for `commit 0`. Then checkout master and reset it to `commit 5` and follow the rest of the steps. – Joshua Swain Jan 07 '21 at 18:05
  • 1
    Good thorough and safe approach. Managing the changes on a separate branch means you can even do interactive rebasing on the `repair` branch and combine commits before merging back in to `master`. The only comment I have is that you can consolidate the first two steps: `git checkout -b repair b3d92c5` – camslice May 07 '21 at 11:45
53

If you didn't publish changes, to remove latest commit, you can do

$ git reset --hard HEAD^

(note that this would also remove all uncommitted changes; use with care).

If you already published to-be-deleted commit, use git revert

$ git revert HEAD
Jakub Narębski
  • 268,805
  • 58
  • 209
  • 228
  • That didn't work. When I git log, everything is still there, no matter why I do it just adds more commits. I wanna clean up the history. – Costa May 09 '14 at 14:42
  • @Costa: What didn't work (i.e. which version did you use), and how did you git log? – Jakub Narębski May 09 '14 at 14:44
  • I've tried almost everything on this Q&A. (I tried git revert HEAD, most recently) My git log: `tree = log --all --graph --format=format:'%C(bold blue)%h%C(reset) %C(dim black)%s%C(reset)%C(bold red)%d%C(reset) %C(green)by %an, %ar%C(reset)'` – Costa May 09 '14 at 14:46
  • @Costa: Note that with first version (using `git reset --hard HEAD^`) you "remove" commit only from current branch (actually move branch pointer), if there was some other branch this commit was on it would still be there. "Removing" commit with `git reset` just moves back branch pointer, making commit *dangling* and available for pruning... if not referenced by other ref (other branch, remote-tracking branch, or tag). Or did you use `git revert HEAD`? – Jakub Narębski May 09 '14 at 14:49
  • 1
    I just want to delete the commits (like as if they never existed). I went off on some weird coding adventure, with several new commits, and it all ended up being trash. How can I just erase those from my git log? – Costa May 09 '14 at 14:55
  • 2
    Holy crap something magically did exactly what I wanted.... which one of those commands did it?!!?! – Costa May 09 '14 at 14:57
48
git reset --hard commitId

git push <origin> <branch> --force

PS: CommitId refers the one which you want to revert back to

Community
  • 1
  • 1
sun34
  • 513
  • 4
  • 2
45

Forcefully Change History

Assuming you don't just want to delete the last commit, but you want to delete specific commits of the last n commits, go with:

git rebase -i HEAD~<number of commits to go back>, so git rebase -i HEAD~5 if you want to see the last five commits.

Then in the text editor change the word pick to drop next to every commit you would like to remove. Save and quit the editor. Voila!

Additively Change History

Try git revert <commit hash>. Revert will create a new commit that undoes the specified commit.

IliasT
  • 2,952
  • 1
  • 17
  • 22
  • `drop` keyword is not defined. To delete a commit just remove the whole line. – Shayan Salehian Dec 17 '18 at 22:40
  • 2
    For me drop was defined as a keyword, but doing a drop didn't seem to remove the commit from the history. Removing the line from the interactive rebase however did. – Adam Parkin Apr 23 '19 at 16:03
  • This is exactly what I needed. Works great; thanks! – diekunstderfuge Mar 06 '20 at 14:34
  • I deleted the line as suggested in several places: it didn't do anything. Replacing the word `pick` with `drop` did delete the commit. Note: the instructions are in the remarked-out section in the bottom portion of the text editor's contents. Using `git version 2.24.3 (Apple Git-128)` – leanne Aug 03 '20 at 22:04
31

If you want to fix up your latest commit, you can undo the commit, and unstage the files in it, by doing:

git reset HEAD~1

This will return your repository to its state before the git add commands that staged the files. Your changes will be in your working directory. HEAD~1 refers to the commit below the current tip of the branch.

If you want to uncommit N commits, but keep the code changes in your working directory:

git reset HEAD~N

If you want to get rid of your latest commit, and do not want to keep the code changes, you can do a "hard" reset.

git reset --hard HEAD~1

Likewise, if you want to discard the last N commits, and do not want to keep the code changes:

git reset --hard HEAD~N
Anurag-Sharma
  • 4,119
  • 5
  • 23
  • 37
  • I tried this and I got my latest commit removed but now when I push to the remote repository it says I have to pull before push. So I pulled and then pushed but when I pulled I again got the commit that I just removed because I pushed it before to remote. What should I do now? – an4s911 Aug 11 '20 at 14:28
28

[Quick Answer]

You have many alternatives, for example:

  • Alternative 1:

    git rebase -i <YourCommitId>~1
    

    Change YourCommitId for the number of the commit which you want to revert back to.

  • Alternative 2:

    git reset --hard YourCommitId
    git push <origin> <branch> --force
    

    Change YourCommitId for the number of the commit which you want to revert back to.

    I don't recommend this option because you can lost your work in progress.

  • Alternative 3:

    git reset --soft HEAD~1
    

    You can keep your work and only undo the commit.

Javier C.
  • 6,011
  • 4
  • 33
  • 46
23
git rebase -i HEAD~2

Here '2' is the number of commits you want to rebase.

'git rebase -i HEAD`

if you want to rebase all the commits.

Then you will be able to choose one of these options.

p, pick = use commit

r, reword = use commit, but edit the commit message

e, edit = use commit, but stop for amending

s, squash = use commit, but meld into previous commit

f, fixup = like "squash", but discard this commit's log message

x, exec = run command (the rest of the line) using shell

d, drop = remove commit

These lines can be re-ordered; they are executed from top to bottom. If you remove a line here THAT COMMIT WILL BE LOST. However, if you remove everything, the rebase will be aborted. Note that empty commits are commented out

You can simply remove that commit using option "d" or Removing a line that has your commit.

Siva Praveen
  • 1,257
  • 12
  • 18
17

To delete in local branch, use

git reset --hard HEAD~1

To delete in a remote branch, use

git push origin HEAD --force
thestar
  • 4,187
  • 2
  • 25
  • 22
13

Source: https://gist.github.com/sagarjethi/c07723b2f4fa74ad8bdf229166cf79d8

Delete the last commit

For example your last commit

git push origin +aa61ab32^:master

Now you want to delete this commit then an Easy way to do this following

Steps

  1. First reset the branch to the parent of the current commit

  2. Force-push it to the remote.

git reset HEAD^ --hard

git push origin -f

For particular commit, you want to reset is following

git reset bb676878^ --hard

git push origin -f
Sagar Jethi
  • 1,185
  • 11
  • 17
10

Here's another way to do this:

Checkout the branch you want to revert, then reset your local working copy back to the commit that you want to be the latest one on the remote server (everything after it will go bye-bye). To do this, in SourceTree I right-clicked on the and selected "Reset BRANCHNAME to this commit". I think the command line is:

git reset --hard COMMIT_ID

Since you just checked out your branch from remote, you're not going to have any local changes to worry about losing. But this would lose them if you did.

Then navigate to your repository's local directory and run this command:

git -c diff.mnemonicprefix=false -c core.quotepath=false \
push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME

This will erase all commits after the current one in your local repository but only for that one branch.

CommaToast
  • 9,468
  • 7
  • 46
  • 65
9

All the commands above restore the state of your work tree and index as they were before making the commit, but do not restore the state of the repository. If you look at it, the "removed" commit is not actually removed, it is simply not the one on the tip of the current branch.

I think that there are no means to remove a commit with porcelain commands. The only way is to remove it from the log and reflog and then to execute a git prune --expire -now.

Shog9
  • 146,212
  • 34
  • 221
  • 231
Angelo Borsotti
  • 315
  • 3
  • 5
  • 1
    The order in which answers are shown on StackOverflow is not fixed. Please do not refer to “All the commands above”. Make your own answer self-contained. – Pascal Cuoq Jan 16 '14 at 12:56
  • This answer isn't entirely correct. `git prune` [is actually one of the "porcelain" commands](https://www.kernel.org/pub/software/scm/git/docs/#_ancillary_commands). Also, it is rare that you would want to completely clear out your reflog (one use case is to remove sensitive info from your repo, but like I said, that's a rare use case). More often than not, you'll want to keep old commits around in the reflog, in case you need to recover data. See [Pro Git: 9.7 Git Internals - Maintenance and Data Recovery](http://git-scm.com/book/en/Git-Internals-Maintenance-and-Data-Recovery#Data-Recovery). –  May 14 '14 at 07:12
9

The mistake:

I git rebase -i --root'ed my branch, ignorantly thinking I could reword the first commit differing from the master (the GitHub for Windows default view is the comparison to master, hiding it's entirety).

I grew a Silicon Valley beard while 900+ commits loaded themselves into Sublime. Exiting with no changes, I charged my battery then proceeded to shave, as all 900+ individual commits nonchalantly rebased - resetting their commit times to now.

Determined to beat Git and preserve the original times, I deleted this local repository and re-cloned from the remote.

Now it had re-added a most recent unneeded commit to master I wished to remove, so proceeded like so.

Exhausting the options:

I didn't wish to git revert - it would create an additional commit, giving Git the upper hand.

git reset --hard HEAD did nothing, after checking the reflog, the last and only HEAD was the clone - Git wins.

To get the most recent SHA, I checked the remote repository on github.com - minor win.

After thinking git reset --hard <SHA> had worked, I updated another branch to master and 1... 2... poof! the commit was back - Git wins.

Checking back out to master, time to try git rebase -i <SHA>, then remove the line... to no avail, sad to say. "If you remove a line here THAT COMMIT WILL BE LOST". Ah...glossed over new feature troll the n00b in the 2.8.3 release notes.

The solution:

git rebase -i <SHA> then d, drop = remove commit.

To verify, I checked out to another branch, and voila - no hiding commit to fetch/pull from the master.

https://twitter.com/holman/status/706006896273063936

Good day to you.

Leo
  • 7,914
  • 2
  • 35
  • 46
8

If you want to keep the history, showing the commit and the revert, you should use:

git revert GIT_COMMIT_HASH

enter the message explaining why are you reverting and then:

git push  

When you issue git log you'll see both the "wrong" commit and revert log messages.

Paulo Fidalgo
  • 19,844
  • 7
  • 85
  • 108
7

If you just messed up your last commit (wrong message, forgot to add some changes) and want to fix it before pushing it to a public repo why not use:

git commit --amend -m "New message here"

If you have newly staged changes they'll be combined with the last commit (that you're trying to get rid of) and will replace that commit.

Of course if you amend a commit after you've pushed it, you're rewriting history so if you do that be sure to understand the implications.

You can also pass the '--no-edit' option instead of '-m' if you would prefer to use the previous commit's message.

Docs: http://git-scm.com/docs/git-commit.html

Pwnrar
  • 1,027
  • 12
  • 12
6

What I do usually when I commit and push (if anyone pushed his commit this solve the problem):

git reset --hard HEAD~1

git push -f origin

hope this help

Chris Sim
  • 3,584
  • 3
  • 26
  • 32
6

I have already pushed. Need to return some commits back remotly. Have tried many variations, but only this from Justin via git bush is working fine for me:

git reset --hard $GIT_COMMIT_HASH_HERE
git push origin HEAD --force
Serg Burlaka
  • 1,867
  • 19
  • 31
5

If you've already pushed, first find the commit you want to be at HEAD ($GIT_COMMIT_HASH_HERE), then run the following:

git reset --hard $GIT_COMMIT_HASH_HERE
git push origin HEAD --force

Then each place the repo has been cloned, run:

git reset --hard origin/master
Justin
  • 34,956
  • 68
  • 168
  • 266
5

Reset on local branch

git reset --hard HEAD~<Number of commit> So git reset --hard HEAD~3

Force push to origin

git push -f origin
Ashish Singh
  • 282
  • 2
  • 14
5
// display git commit log    
$ git log --pretty=oneline --abbrev-commit

// show last two commit and open in your default editor
// then delete second commit line and save it
$ git rebase -i HEAD~2

Reference: How to delete a commit in git, local and remote

Shajed
  • 497
  • 7
  • 13
4

git reset --hard HEAD~1
You will be now at previous head. Pull the branch. Push new code. Commit will be removed from git

  • Unless you have already pushed the changes. In that case hard reset will not clean up your remote. In that case rebase is the good option – c0der512 Mar 03 '20 at 21:58
3

Take backup of your code in to temp folder. Following command will reset same as server.

git reset --hard HEAD
git clean -f
git pull

If you want to keep your changes , and remove recent commits

git reset --soft HEAD^
git pull
Lava Sangeetham
  • 2,204
  • 2
  • 26
  • 42
2

delete local commit

As you can see on above image i want to delete revert"test change 2" commit(SHA1 ID: 015b5220c50e3dfbb1063f23789d92ae1d3481a2(you can get SHA1 ID by using gitk command in git bash)).

For that i can use(all below command work on local only. you need to push after delete):

  1. git reset --hard 515b5220c50e3dfbb1063f23789d92ae1d3481a2 //it back-up you to that commit (SHA1 ID of test change 4 commit is 515b5220c50e3dfbb1063f23789d92ae1d3481a2)
  2. git reset --hard HEAD~1 // it back-up you before one commit.
  3. git reset --hard HEAD^ // To remove the last commit from git

after delete:

after delete commit

ankit
  • 1,919
  • 19
  • 39
2

Here I just post one clear pipeline to do so

Step1: Use git log to get the commit ID.

git log

enter image description here

Step2: Use git reset to go back to the former version:

git reset --hard <your commit id>
Frank
  • 772
  • 3
  • 15
1

git reset --hard

git push origin HEAD --force

If one or more of the commits is tagged, delete the tag(s) first. Otherwise the tagged commit is not removed.

BillChan
  • 85
  • 1
  • 3
0

use git revert https://git-scm.com/docs/git-revert .It will revert all code then you can do next commit.Then head will point to that last commit. reverted commits never delete but it will not affect on you last commit.

0

In my case, my magic code for this pupose is this one:

git reset --hard @{u}

Test it and tell me. I have tried a few different ones, but this one was the only that helped me.

Mauro Bilotti
  • 3,823
  • 2
  • 30
  • 55
0

For me rebase did the trick

$ git rebase -i HEAD~98

# Delete everything except for the most recent commit on the shown editor caused by "rebase"

$ git push origin -f production-static

NOTE: After forcing the push to reduce my comments. I then pushed another set of files and then I tried pulled with the same "repository & branch" on another computer. Surprisingly there is no conflict. This became my way to reduce repository size while avoiding pull conflicts on my other locals that uses the same git

Dean Christian Armada
  • 5,376
  • 3
  • 43
  • 87
-1

Assuming you have not pushed to the remote repository, you could re-clone the repository. This has been my method of choice a few times.

zacharydl
  • 4,138
  • 1
  • 27
  • 23