How to move certain commits to be based on another branch in git?

GitCommitPatch

Git Problem Overview


The situation:

  • master is at X
  • quickfix1 is at X + 2 commits

Such that:

o-o-X (master HEAD)
     \
      q1a--q1b (quickfix1 HEAD)

Then I started working on quickfix2, but by accident took quickfix1 as the source branch to copy, not the master. Now quickfix2 is at X + 2 commits + 2 relevant commits.

o-o-X (master HEAD)
     \
      q1a--q1b (quickfix1 HEAD)
              \
               q2a--q2b (quickfix2 HEAD)

Now I want to have a branch with quickfix2, but without the 2 commits that belong to quickfix1.

      q2a'--q2b' (quickfix2 HEAD)
     /
o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)

I tried to create a patch from a certain revision in quickfix2, but the patch doesn't preserve the commit history. Is there a way to save my commit history, but have a branch without changes in quickfix1?

Git Solutions


Solution 1 - Git

This is a classic case of rebase --onto:

 # let's go to current master (X, where quickfix2 should begin)
 git checkout master

 # replay every commit *after* quickfix1 up to quickfix2 HEAD.
 git rebase --onto master quickfix1 quickfix2 

So you should go from

o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)
              \
               q2a--q2b (quickfix2 HEAD)

to:

      q2a'--q2b' (new quickfix2 HEAD)
     /
o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)

This is best done on a clean working tree.
See git config --global rebase.autostash true, especially after Git 2.10.

Solution 2 - Git

You can use git cherry-pick to just pick the commit that you want to copy over.

Probably the best way is to create the branch out of master, then in that branch use git cherry-pick on the 2 commits from quickfix2 that you want.

Solution 3 - Git

The simplest thing you can do is cherry picking a range. It does the same as the rebase --onto but is easier for the eyes :)

git cherry-pick quickfix1..quickfix2

Solution 4 - Git

I believe it's:

git checkout master
git checkout -b good_quickfix2
git cherry-pick quickfix2^
git cherry-pick quickfix2

Solution 5 - Git

// on your branch that holds the commit you want to pass
$ git log
// copy the commit hash found
$ git checkout [branch that will copy the commit]
$ git reset --hard [hash of the commit you want to copy from the other branch]
// remove the [brackets]

Other more useful commands here with explanation: Git Guide

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlex YarmulaView Question on Stackoverflow
Solution 1 - GitVonCView Answer on Stackoverflow
Solution 2 - GitDJ.View Answer on Stackoverflow
Solution 3 - GitChristophView Answer on Stackoverflow
Solution 4 - GitMatthew FlaschenView Answer on Stackoverflow
Solution 5 - GitGopherView Answer on Stackoverflow