18

I accidentally committed to a wrong branch. The graph looks like this

----o--o-----o (master)
     \
      \
       A--B--C--D (feature)

I want to move C and D to master without the changes in A and B. I want the graph to look like this

----o--o-----o (master)
     \        \
      \        C--D (other_feature)
       \
        A--B (feature)

is this possible? and how to do it also on remote?

Changes in A and B are not going to be merged so I don't care if the commits will be lost

Zygro
  • 6,849
  • 11
  • 28
  • 43

2 Answers2

25

Warning: The following git commands will rewrite the history of the feature branch. git rebase and git reset are dangerous because it can wreak havoc for anyone else who is using the feature branch.

First create the branch other_feature at the same commit as feature.

git checkout -b other_feature feature

Rebase the previous two commits onto master.

git rebase --onto master HEAD~2

Checkout feature.

git checkout feature

Reset feature to the commit where you want it.

git reset --hard HEAD~2
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • 2
    Warning: This answer _rewrites_ the history of the `feature` branch. While this may be OK for this particular problem, this course of action should be taken with caution in general, because it can wreak havoc for anyone else who is using the `feature` branch. – Tim Biegeleisen Aug 22 '16 at 17:10
  • @TimBiegeleisen Thanks for the warning. I have edited my answer with similar wording. – Code-Apprentice Aug 22 '16 at 17:13
  • For me, `feature` branch was unchanged, while only last two commits were rebased, so commits A and B stayed the same at a first glance (C and D stayed too, but I used `reset --hard `). Maybe there is some difference that's not apparent but it looks fine now... – Zygro Aug 22 '16 at 17:14
  • @Zygro As far as the commit history is concerned, my answer will solve your problem. See the warning in Tim Biegeleisen's comment and at the top of my edited post for potential pitfalls from this approach. – Code-Apprentice Aug 22 '16 at 17:16
2

The following answer presumes that your feature branch is already published to the remote. I would just cherry pick commits C and D from the feature branch onto the master branch, and then revert these two commits on feature:

git checkout master
git checkout -b other_feature
git cherry-pick <SHA-1 for C>
git cherry-pick <SHA-1 for D>

git checkout feature
git revert <SHA-1 for C>
git revert <SHA-1 for D>
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360