I\'ve seen different posts on StackOverflow that explain cherry picking a bit, but the comments in their code aren\'t very specific as to what\'s a branch and what\'s a dire
You can use git checkout <from_branch> -- <files_to_bring>
.
I'd do this: git checkout dev -- tools/my-tool
Explanation: this tells git to replace/copy files from the branch dev
and the path tools/my-tool
to your current branch.
Here is the right way to cherry-pick commits from another branch for one folder:
git format-patch -k --stdout master...featureA -- tools/mytool | git am -3 -k
This will apply the patches to the "tools/mytool" files only, in order.
If you have a merge conflict on any commit, it will pause for you to fix it. git am --continue
will resume where it left off.
Note:
git checkout is about updating the working tree (and HEAD
if no path is specified, effectively switching branches)
git checkout [-p|--patch] [<tree-ish>] [--] <pathspec>...
When
<paths>
or--patch
are given,git checkout
does not switch branches.
It updates the named paths in the working tree from the index file or from a named<tree-ish>
(most often a commit). The<tree-ish>
argument can be used to specify a specific tree-ish (i.e. commit, tag or tree) to update the index for the given paths before updating the working tree.
Your git checkout dev -- tools/my-tool
updates a specific path, but it isn't a "merge" or a "git cherry-pick".
Jason Rudolph does a great job of summarising this scenario, and the accepted solution in this post:
https://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/
This is a good old question, and the above answers did a great job of answering it, but since I recently came across the issue, and his article stated it so concisely I thought I'd share it here.
To answer the original question about how to cherry-pick some directories (as commits instead of a brute-force checkout), this is possible. Imagine that featureA
has diverged from master
and you want to bring over the tools/my-tool
commits.
Assuming that you never made any commits that contain both stuff from
/tools/my-tool
and stuff from other directories
This will get you the list of commits to master
in tools/my-tool
(that are not already in featureA
), in reverse-chronological order:
git log --no-merges featureA...master tools/my-tool
To say it another way:
git log --no-merges source_branch...dest_branch my/firstpath my/secondpath [...]
To get just the commits you need in chronological order, you need to first reverse the order of the input lines (such as with tail -r
or tac
), then isolate the column for the commit hash (such as with cut
):
git log --format=oneline --no-merges featureA...master tools/my-tool \
| tail -r \
| cut -d " " -f 1
And to do the whole operation at once, do this:
git cherry-pick $(git log --format=oneline --no-merges featureA...master tools/my-tool | tail -r | cut -d " " -f 1)