35

I normally use the following git command to cherryppick a range of gerrits..no how do I exclude a couple gerrits in between.. can the below command be modified or is there one where we can pick a range of gerrits and exclude the ones we want..

git cherrypick fromgerritSHA1..togerritSHA1
user
  • 86,916
  • 18
  • 197
  • 190
carte blanche
  • 10,796
  • 14
  • 46
  • 65
  • Similar: [How to cherry pick a range of commits and merge into another branch?](http://stackoverflow.com/q/1994463/55075) – kenorb Mar 19 '15 at 17:22

3 Answers3

62

You can specify multiple ranges:

git cherry-pick A..B C..D E..F

or even specific commits:

git cherry-pick A B C D E F

If you have lots of commits you want to exclude, it might be easier to do something like this (sort of like a poor man's git rebase -i for git cherry-pick):

git log --pretty=oneline A..F | tac > tempfile.txt
< edit tempfile.txt to remove the commits you don't want >
git cherry-pick $(awk '{print $1}' tempfile.txt)

Edit: Added recommendation to tac the log, since git cherry-pick wants to see the commits in the opposite order from what git log produces (could also use git log --reverse ...).

twalberg
  • 59,951
  • 11
  • 89
  • 84
  • For some reason the lines that I get in tempfile.txt needs to be reversed. git log will present all the commits from newest to oldest while using git cherry pick you would like to apply these commits from oldest to newest. Did you miss it or that wasn't that a problem in your case? – Konrad Szałwiński Apr 17 '14 at 07:33
  • 1
    @KonradSzałwiński You're right... forgot about that bit. Linux has a convenient utility called `tac` to reverse the order of lines - I'll edit that in... – twalberg Apr 17 '14 at 10:59
  • 1
    Thanks for updating the solution. Unfortunately with Windows there is no 'tac' command so at that time I had to use an online tool to reverse the lines. Thanks for pointing out that with git log --reverse. – Konrad Szałwiński Apr 17 '14 at 17:03
  • Do you also happen to know if there is a way to preserve original dates of creation of the commits we cherry-pick? – Konrad Szałwiński Apr 18 '14 at 08:19
  • @KonradSzałwiński I'm not sure there is a way to do that. I know there are some environment variables you can use to explicitly set the dates when doing a `git commit`, but I don't know if they are consulted during `cherry-pick` or `rebase`-like operations... – twalberg Apr 18 '14 at 13:40
  • 1
    When do ranges you have to specify A^..B to get A included. – 0andriy Aug 11 '15 at 11:42
3

Not sure if you can pull individual commits out of a range abcdef..123456. Git range syntax is explained in the docs for gitrevisions, and it doesn't look like it works that way. Still, there's another way to get what you want using only the range hashes and the ones to exclude.

Assuming the two hashes in range fromgerritSHA1..togerritSHA1 that you don't want are skiphash1 and skiphash2, try:

$ git rev-list --reverse fromgerritSHA1..togerritSHA1 | grep -vE 'skiphash1|skiphash2' | git cherry-pick --stdin

git rev-list --reverse fromgerritSHA1..togerritSHA1 prints out commit hashes in range fromgerritSHA1..togerritSHA1, one line at a time. --reverse is needed to list the hashes in the correct order for the cherry-pick.

grep -vE 'skiphash1|skiphash2' removes the two hashes you don't want from the list. You can add more hashes to skip, just separate them with |.

Finally, the list of only the commit hashes you want is passed to git cherry-pick --stdin.

Rob Bajorek
  • 6,382
  • 7
  • 44
  • 51
1

If you got problem during cherry-pick like below, try to choose starting hash one before than your original attempt was.

git cherry-pick a005efa..1ece685
[temp_4454kjerer3233 3520dd4] 3. xxx.
 1 file changed, 9 insertions(+)
[temp_4454kjerer3233 791cec5] 4. xxx.
 3 files changed, 19 insertions(+)
[temp_4454kjerer3233 2e95364] 5. xxx.
 2 files changed, 21 insertions(+)
[temp_4454kjerer3233 59e38b9] 6. xxx.
 3 files changed, 61 insertions(+)
error: could not apply a3b0c6b... 7. xxx.
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
János
  • 32,867
  • 38
  • 193
  • 353