Assume we have a repository and 5 commits:
- commit 1
- commit 2
- commit 3
- commit 4
- commit 5
And now I realize commits 4 and 5 are a bad idea. I want to completely remove all changes committed in commit 4 and 5. How to do it?
Assume we have a repository and 5 commits:
And now I realize commits 4 and 5 are a bad idea. I want to completely remove all changes committed in commit 4 and 5. How to do it?
git revert commit_hash
It reverts given commit. Note that revert is another commit which discards changes from commit_hash, not removing given commit from repository.
I'd probably create a new branch from commit 3.
git checkout -b commit3
and then rebase master from that commit
http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html
of course, you are using topic branches to keep your dev branches separate until you know they are a good idea, right?
If commits 4 and 5 are in your repository only and haven't been pushed to or pulled by any other repository you can simply:
git reset --hard SHA1_HASH_OF_COMMIT_3
You can find out the SHA1 hash of a commit by using git log
or you could use more advanced naming techniques, see git help rev-parse
in particular the section 'SPECIFYING REVISIONS'.
Using this command will leave commits 4 and 5 unreachable from the tip of the branch. The commits will, however, not be lost as those commits are kept in the branch's reflog. You can use git reflog
to identify an unreachable commit. Restoring can then be done with another git reset --hard
. This page here describes it all pretty well.
It is recommended that you run git gc
on a regular basis; some commands also do this for you automatically. This essentially performs 'housekeeping' on the repository, such as "compressing file revisions (to reduce disk space and increase performance) and removing unreachable objects". Unreachable objects are pruned from the repository after (a default of) 30 days. This can be changed using the configuration option gc.reflogExpireUnreachable
.