The general idea in git is that you never delete a commit. You just leave them without a name. Commits that are neither named nor referenced by some other named commit, eventually go away on their own.
For example, suppose you started with:
$ git checkout my_work_branch
<do some editing>
$ git commit -m "attempt #1, so far so good"
<do more editing>
$ git commit -m "attempt #2, getting a little hazier"
<do more editing>
$ git commit -m "attempt #3, looking bleak now"
At this point git log --graph --decorate --pretty=oneline --abbrev-commit
might produce something like:
* d97de0e (HEAD, my_work_branch) attempt #3, looking bleak now
* 9a3efe3 attempt #2, getting a little hazier
* 9e80936 attempt #1, so far so good
* a1d6424 here's where you started
What you have now is that the branch named my_work_branch
(the name you gave earlier) "points to" commit d97de0e, which in turn points to 9a3efe3, which points to 9e80936, which points to a1d6424. (This is also where the special name HEAD points.)
You can move HEAD elsewhere with any old git checkout
. But, here's the thing: you can also move the name my_work_branch
to point to a1d6424 too:
$ git reset --hard a1d6424
or
$ git reset --hard HEAD~3 # use at most one of these
If you do this, you find that the name my_work_branch
has also been moved:
$ git rev-parse my_work_branch
a1d6424e5afcda475910084720c9aa26e3528618
The commits you added are still there:
$ git log d97de0e
will show it them to you:
$ git log --graph --decorate --pretty=oneline --abbrev-commit d79de0e
* d97de0e attempt #3, looking bleak now
* 9a3efe3 attempt #2, getting a little hazier
* 9e80936 attempt #1, so far so good
* a1d6424 (HEAD, my_work_branch) here's where you started
It's just that they no longer have any names, and if you do some work and git add
and git commit
it, that will be on a new branch named my_work_branch
. The old one, that has the three extra commits, is now a "junk" branch. (If you decide that despite the bleakness you want them back, you need only give them a name before they expire in roughly 3 months. You'll have to find or remember that number, d97de0e in the above example, somehow.)
Update: ah, you've pushed them and you want them gone from the remote repository.
You don't have to delete the remote branch. You can use git push -f
after doing the rewind (git reset --hard
) above. Just remember that anyone else who has fetched your pushed changes has them, and will continue to have them and can easily get confused by their presence. You'll have to alert any such people to beware of your "revoked" commits.