Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove not-last commit in Git?

Tags:

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?

like image 424
Anders Martini Avatar asked Apr 08 '15 23:04

Anders Martini


People also ask

How do you delete a commit that is not the last?

Undoing the Changes of the "Middle" Commit There exists a safe way of deleting a commit in the middle of the history: using the git revert command. It adds a new commit, which undoes everything the middle commit has changed.


3 Answers

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!!

like image 57
gran_profaci Avatar answered Sep 30 '22 16:09

gran_profaci


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.
like image 37
Amnon Shochot Avatar answered Sep 30 '22 18:09

Amnon Shochot


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.

like image 43
Philipp Claßen Avatar answered Sep 30 '22 18:09

Philipp Claßen