'How to copy commits from one branch to another?

I've got two branches from my master:

  • v2.1: (version 2) I've been working on for several months
  • wss: that I created yesterday to add one specific feature to my master (in production)

Is there a way to copy yesterday's commits from wss to v2.1?



Solution 1:[1]

Use

git cherry-pick <commit>

to apply <commit> to your current branch.

I myself would probably cross-check the commits I pick in gitk and cherry-pick them with right-clicks on the commit entry there instead.


If you want to go more automatic (with all its dangers) and assuming all commits since yesterday happened on wss you could generate the list of commits using git log (with --pretty suggested by Jefromi)

git log --reverse --since=yesterday --pretty=%H

so everything together assuming you use bash

for commit in $(git log --reverse --since=yesterday --pretty=%H);
do
    git cherry-pick $commit
done

If something goes wrong here (there is a lot of potential) you are in trouble since this works on the live checkout, so either do manual cherry-picks or use rebase like suggested by Jefromi.

Solution 2:[2]

git cherry-pick : Apply the changes introduced by some existing commits

Assume we have branch A with (X, Y, Z) commits. We need to add these commits to branch B. We are going to use the cherry-pick operations.

When we use cherry-pick, we should add commits on branch B in the same chronological order that the commits appear in Branch A.

cherry-pick does support a range of commits, but if you have merge commits in that range, it gets really complicated

git checkout B
git cherry-pick SHA-COMMIT-X
git cherry-pick SHA-COMMIT-Y
git cherry-pick SHA-COMMIT-Z

Example of workflow :

enter image description here

We can use cherry-pick with options

-e or --edit : With this option, git cherry-pick will let you edit the commit message prior to committing.

-n or --no-commit : Usually the command automatically creates a sequence of commits. This flag applies the changes necessary to cherry-pick each named commit to your working tree and the index, without making any commit. In addition, when this option is used, your index does not have to match the HEAD commit. The cherry-pick is done against the beginning state of your index.

Here an interesting article concerning cherry-pick.

Solution 3:[3]

Suppose I have committed changes to master branch. I will get the commit id (xyz) of the commit now. Then I have to go to the branch for which I need to push my commits.

Single commit id xyz

git checkout branch-name
git cherry-pick xyz
git push origin branch-name

Multiple commit id's xyz abc qwe

git checkout branch-name
git cherry-pick xyz abc qwe
git push origin branch-name

Solution 4:[4]

You could create a patch from the commits that you want to copy and apply the patch to the destination branch.

Solution 5:[5]

The answers already mentioned cover most of the stuff but one thing that seems to be missing is the --no-commit feature of cherry-picking.

Assume, you have more than one commits on the feature branch and you want to "merge" all of them into a single commit and put them on your main branch. In that case what you need to do is:

git checkout <branch-on-which-to-add-features>
git cherry-pick --no-commit <commit-hash>
git cherry-pick --no-commit <commit-hash>
.
.
.

And finally, once you have cherry-picked all the required features, you could do a final commit:

git commit -m "Some message for the merge commit"

Ideally, as @Cascabel mentioned, you should be using merge or rebase. But if you feel there's no other choice, you could get away with using cherry-picking.

Solution 6:[6]

Or if You are little less on the evangelist's side You can do a little ugly way I'm using. In deploy_template there are commits I want to copy on my master as branch deploy

git branch deploy deploy_template
git checkout deploy
git rebase master

This will create new branch deploy (I use -f to overwrite existing deploy branch) on deploy_template, then rebase this new branch onto master, leaving deploy_template untouched.

Solution 7:[7]

Here's another approach.

git checkout {SOURCE_BRANCH}               # switch to Source branch.
git checkout {COMMIT_HASH}                 # go back to the desired commit.
git checkout -b {temp_branch}              # create a new temporary branch from {COMMIT_HASH} snapshot.
git checkout {TARGET_BRANCH}               # switch to Target branch.
git merge {temp_branch}                    # merge code to your Target branch.
git branch -d {temp_branch}                # delete the temp branch.

Solution 8:[8]

The cherry-pick command can read the list of commits from the standard input.

The following command cherry-picks commits authored by the user John that exist in the "develop" branch but not in the "release" branch, and does so in the chronological order.

git log develop --not release --format=%H --reverse --author John | git cherry-pick --stdin

Solution 9:[9]

For the simple case of just copying the last commit from branch wss to v2.1, you can simply grab the commit id (git log --oneline | head -n 1) and do:

git checkout v2.1
git merge <commit>

Solution 10:[10]

It's safer to use built-in git gui for cherry-picking specific commits:

For ex: copy one commit from dev branch to main branch:

git checkout main
gitk --all

And then right-click on desired commit and select Cherry-pick this commit

enter image description here

gitk for Mac: Install gitk on Mac

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 JakeRobb
Solution 2 Shiridish
Solution 3 anilbey
Solution 4 Charles Ma
Solution 5 paradocslover
Solution 6 Petr Sykora
Solution 7 Muhammad Reda
Solution 8 Gebb
Solution 9 zeroimpl
Solution 10