Search code examples
gitrebase

How to remove a commit that shouldn't be a part of a branch due to branching too late after push?


I had a branch representing one set of changes that interacted with files XYZ. I decided to start working on another component of the project that interacted with files ABC (e.g. no mutually inclusive files). Mistakenly, I committed changes and then branched instead of stashing those changes so now work done to XYZ is accidentally included in the second branch. Unfortunately, I've already pushed the commits to remote version of this branch. I've tried to make a diagram below:

            /-G--H  # second branch
        /--E  # first branch
-A--B--C

What I meant to do is this:

        /--G--H # second branch
-A--B--C
        \--E # first branch

The second branch has already been pushed with git push -u origin second-branch


Solution

  • It's no problem to "move" the branch; checkout the second branch and rebase it, starting after E, onto commit C.

    So from this situation:

    * cb796d8 (HEAD -> second) H
    * 0bc85b6 G
    * d2c6ff8 (first) E
    * ba28890 (master) C
    * 41598db B
    * 625c73b A
    

    I just say

    git rebase --onto master first second
    

    and presto, I've got this:

    * a305755 (HEAD -> second) H
    * 18ebe9f G
    | * d2c6ff8 (first) E
    |/  
    * ba28890 (master) C
    * 41598db B
    * 625c73b A
    

    However, you will run into trouble when you try to push the result; you'll probably have to use force, because remotes don't like it when you attempt to change history, and if you are cooperating with others on these branches, you will have to warn them of what you're about to do.