How to git cherrypick all changes introduced in specific branch

佐手、 提交于 2019-12-03 04:34:47
CodeWizard

It seems that cherry-pick does what we want in terms of only getting changes from selected commits, but I would really like a way to cherry-pick all commits in a given branch at once, without having to look up the commit ids every time.


Using cherry-pick

git cherry-pick allows you to pick any commits you made in any branch to any other branch. In your case you can simply checkout master branch and then cherry-pick all the commits from any branch that you wish (cherry-pick supports ranges so you can specify start and end commit instead of listing all the commits).

This way you can control the way your commits will appear in the desired branch.

For example:

git cherry-pick ebe6942..905e279

# Find the range of commits you wish to re-add to your branch.
# then use cherry-pick to add them back to the branch
git cherry-pick start..end

# If you wish to include the start commit as well add the ^
# This will result in a cherry-pick of the start commit included as well 
git cherry-pick start^..end

How to find first commit of branch?

git log

 # print out the latest commit (first one) of the given branch
 git log  --oneline | tail -1

merge-base

Use the merge-base command to find where the branch was split from the original branch:

git merge-base A B

checkout your branch(target branch) and do

git cherry-pick -m 1 hashCode

If you want to cherry-pick all commits from branch dev.

Try:

git cherry-pick ..dev

Following from discussion in the accepted answer, here is a one-liner. It should not matter what branch you are currently on when you run this (presumably some non-default branch). This assumes that devel is the default branch, and that you want to cherry pick all commits from branch B, after it diverged from the devel branch.

git cherry-pick $(git log devel..B --pretty=format:"%h" | tail -1)^..$(git log B -n 1 --pretty=format:"%h")

The command syntax goes first..last, but we are using a variant here which is more like first-1^..last.

The command git log devel..B --pretty=format:"%h" | tail -1 gets the commit in the devel branch which is a parent of the first commit in the B branch. This is a little clunky, but the git merge-base command did not have the needed formatting options.

The command git log B -n 1 --pretty=format:"%h" just gets the last commit in that branch.

This will put your in an interactive cherry-pick context. So make sure to abort if it's not going well.

This should also work. We call the point of divergence between the HEAD (master in this case) and the branch and pass it to cherry-pick.

git merge-base origin/dev_single_doc_fit HEAD | xargs git cherry-pick {}..HEAD^

one more way with fast-forward.

The case:

you started newBranch, commited first commit and did reset Hard.

As a result you got empty newBranch, no that late commit and git tree is clean at the HEAD. You are at the branch newBranch (may check with git branch).

Here is two steps action:

  • get the list of commits in 'trash' by

git fsck --lost-found

  • commit the missed commit back to your branch with:

git cherry-pick --ff 43a7a2d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!