Home > Net >  Git revert and cherry pick to omit middle commits?
Git revert and cherry pick to omit middle commits?

Time:04-12

I have the following commits on GitLab:

3fad532  Last commit   
3bnaj03  Fifth commit
vcn3ed5  Fourth commit xxx
aece15d  Third commit  xxx
385d65a  Second commit 
556cc58  First commit 

I want to remove the 3th and 4th commits and for this reason I think first revert to second commit via:

git revert 385d65a

And then apply cherry pick starting from 5th commit as:

git cherry-pick 3bnaj03 3fad532  

1. Is the approach above correct way to get the last commit by removing 3th and 4th commits?

2. Is there a better way for this scenario?

CodePudding user response:

I would say a far simpler way is to use an interactive rebase:

  • git rebase -i HEAD~6 (or to whatever commit you want to go from)
  • Remove the lines representing the commits you want to remove in the editor pop-up
  • Let the rebase do the rest automatically

CodePudding user response:

I want to remove the 3th and 4th commits and for this reason I think first revert to second commit ...

Git chose a bad English-language verb here. The word revert mostly means what you think it means, e.g., return to a former state. As the dictionary notes, in this sense, we tend to say "revert to". But that's not what git revert does or means in Git. In Git, git revert means to back out, and is used without the auxiliary verb.

Running:

git revert <hash>

tells Git: Find the commit whose hash ID I just gave you. Figure out what changed between that commit's parent—I promise that there's just the one parent commit—and that commit. Whatever changed, make another change to this current commit that undoes or backs out the previous change.

(To revert to—i.e., remove all the commits after—some particular commit, Git uses the verb git reset. This particular command is a very large and complicated command as it has multiple things it can reset. It's often the wrong choice unless you follow it up with some additional Git commands.)

As Jon Skeet answered, to literally remove the two commits you dislike, you would typically want git rebase -i. Note that this necessarily replaces all subsequent commits with new-and-improved different commits, with different hash IDs. For this reason, it's generally better to use the "new commit that backs out old commit" git revert command if you have already published these commits so that other people have them.

The exception to this rule ("don't replace published commits") occurs when you've arranged with those other people that it's OK to replace published commits. That way they won't be surprised to find that some commits that were there before are now gone, and if they have made their own additional commits that depend on the now-gone commits, they can use their private commits to make their own new-and-improved copies that add on to the rewound-and-rewritten branch, if necessary and appropriate.

If your code meets this exception (i.e., if it's OK to rebase), go ahead and use git rebase here. If not, consider using git revert twice, for the two commits you wish to undo. Git will add two more commits that back out the two commits you want backed out.

  • Related