Anders Martini
Anders Martini

Reputation: 948

How to remove not-last commit in Git?

I recently created a new branch, lets call it "branch1", which is based on another branch, lets call it "master". I then made a bunch of commits to branch1, and now I´ve realised that the first couple of commits was actually a mistake, The ones after those first few however are still great commits! So what I´m trying to do here is basically remove those first few commits, so that the ones after them basically gets rebased on master....how would one do this?

Upvotes: 17

Views: 12413

Answers (4)

vezenkov
vezenkov

Reputation: 4155

I'm generally a fan of git revert but when your commit is a delete one, the revert commit will re-add it and you will lose the history of that file before it. So in case you've done all those commits I'd create another branch - rebase all the commits on top of it, reset the wrong branch back to the commit before the wrong commits and then cherry pick the good commits from the top of the auxiliary branch.

Upvotes: 0

Philipp Claßen
Philipp Claßen

Reputation: 44009

Have you already pushed your changes? I assume that you did. In that case, I would recommend to get rid of the bad commits by using git revert. That is the safe choice.

The bad commits will still be visible in the history, but your colleagues will not run into problem when they have already pulled your changes.

If you have not yet pushed your changes, you have the option to rewrite the Git history, either by using git rebase -i or by git reset and recommitting.

Upvotes: 2

gran_profaci
gran_profaci

Reputation: 8473

Say this is your commit history from latest to earliest:

branch1

5XXXX Good Commit
4XXXX Good Commit
3XXXX Good Commit
2XXXX Bad Commit
1XXXX Bad Commit

So, say you want to get rid of only the code from 1XXXX and 2XXXXand don't really care if the commits stay or go. Thus, you can now do :

git revert 1XXXX This makes a new commit that has a message similar to reverts 1XXXX

then,

git revert 2XXXX This makes a new commit that has a message similar to reverts 2XXXX

You now have two new commits that revert 1XXXX and 2XXXX. Simply push them...

git push origin branch1

Thus, your commits will now be :

branch1

7XXXX Good Commit reverting bad commit 2XXXX
6XXXX Good Commit reverting bad commit 1XXXX
5XXXX Good Commit
4XXXX Good Commit
3XXXX Good Commit
2XXXX Bad Commit
1XXXX Bad Commit

If you want to get rid of the commits themselves, then you can do :

git rebase --interactive 1XXXX

Thus, on the same branch branch1, you now are doing a rebase to the first bad commit 1XXXX. You will now get a text editor come up that has something similar to :

pick 5XXXX Good Commit
pick 4XXXX Good Commit
pick 3XXXX Good Commit
pick 2XXXX Bad Commit
pick 1XXXX Bad Commit

Change the pick for the Bad Commits to squash.

pick 5XXXX Good Commit
pick 4XXXX Good Commit
pick 3XXXX Good Commit
squash 2XXXX Bad Commit
squash 1XXXX Bad Commit

Fix any merge conflicts if they come up and BOOM! 1XXXX and 2XXXX never existed!!

Upvotes: 27

Amnon Shochot
Amnon Shochot

Reputation: 9386

Your best option would probably be to use git revert (docs here) for the commits you want to cancel.

3 notes about it:

  1. This command allows you to revert specific commits, as opposed to git reset that will take you back until the point you're interested, potentially undoing all the commits along the way
  2. Each revert will be considered as a commit of its own, which means that your history may get cluttered with unwanted commits and reverts. However, before merging to the master branch you can squash your commits in branch1 by using git reset --soft <initial commit in branch1> and then recommitting all changes by git commit -m <your commit message>.
  3. To avoid merge conflicts it would be recommended to use it in the reverse order of the commits.

Upvotes: 5

Related Questions