threads / discuss / 22325

cherry picking several patches at once

Subject: cherry picking several patches at once

## tl;dr

7 messages between Jan 21, 2010 and Jan 24, 2010.

replies: 6people: 4as markdown or json

Felipe Balbi· Jan 21, 2010, 16:11 UTC · lore
Hi,

I wonder if it's possible to cherry several patches at once ? Can't find anything on any docs, but something like:

$ git cherry-pick <commit_id_start>..<commit_id_end> -- \
	/path/to/directory

I want to do that because I keep patches to the musb driver (on linux kernel) based on top of linus' mainline tree and on top of internal tree.

The internal tree is outdated (not following mainline), but the musb driver is basically in sync, so cherry picking works, but it's a bit painful when I have to pick patches from community and manually cherry-pick to the other branch based on my internal tree.

If there's a way (besides git rebase --onto) to do that I would very much like to know.

Another thing that would be nice to have, is to pass the HEAD to which we want to cherry-pick, so we can cherry-pick to not-checked-out branches. Something like:

$ git cherry-pick <commit_id> <my_branch_name>
and combining both, of course:
$ git cherry-pick <commit_id_start>..<commit_id_end> \
	<my_branch_name> -- /path/to/directory
-- 
balbi
Felipe Contreras· Jan 22, 2010, 23:57 UTC · re: Felipe Balbi · lore

Re: cherry picking several patches at once

Heippa,
On Thu, Jan 21, 2010 at 6:11 PM, Felipe Balbi <me@felipebalbi.com> wrote:
Show 17 quoted lines
> I wonder if it's possible to cherry several patches at once ?
> Can't find anything on any docs, but something like:
>
> $ git cherry-pick <commit_id_start>..<commit_id_end> -- \
>        /path/to/directory
>
> I want to do that because I keep patches to the musb driver (on linux
> kernel) based on top of linus' mainline tree and on top of internal
> tree.
>
> The internal tree is outdated (not following mainline), but the musb
> driver is basically in sync, so cherry picking works, but it's a bit
> painful when I have to pick patches from community and manually
> cherry-pick to the other branch based on my internal tree.
>
> If there's a way (besides git rebase --onto) to do that I would very
> much like to know.

Have you tried something like: git format-patch old-base --full-diff -- /path git am -3 *.patch

> Another thing that would be nice to have, is to pass the HEAD to which
> we want to cherry-pick, so we can cherry-pick to not-checked-out
> branches.

I think that would not be possible because of the challenges when dealing with conflicts.

Cheers.
-- 
Felipe Contreras
Marc Weber· Jan 23, 2010, 00:24 UTC · re: Felipe Contreras · lore

Re: cherry picking several patches at once

Hi,

I like both ideas. I fact I had both my self. Cherry-picking a range can be implemented using a simple shell script. So that is not that important.

> I think that would not be possible because of the challenges when
> dealing with conflicts.

If cherry-picking to a not checkout branch causes conflicts it could be rejected. It's that simple.

The use case is: You have many topic-branches. Of course you develop on the big temporary merge. However you want to push your changes to the topic branches. You may be working on multiple topics at the same time. Some of the topics may quick hacks to make a porject work on your system such as patching shebang lines, change PHP require lines etc.

Currently you have to git checkout topic1; git cherry-pick big-merge git checkout topic2; git cherry-pick big-merge~2 git checkout big-merge

compare this to

git cherry-push HEAD topic1 git cherry-push HEAD~2 topic2

not much typing.
Very often there are no conflicts and you know that there are none.

If you have conflicts you can still fallback going the slow way. Maybe the command could behave this way:

git cherry-push-checkout-on-failure hash other-branch

I'd be very happy about such a git cherry-push-checkout-on-failure command. I'm not sure whether the command should be renamed. I did so for fun.

Marc Weber
Sverre Rabbelier· Jan 23, 2010, 11:17 UTC · re: Marc Weber · lore

Re: cherry picking several patches at once

Heya,
On Sat, Jan 23, 2010 at 01:24, Marc Weber <marco-oweber@gmx.de> wrote:
> git cherry-push-checkout-on-failure hash other-branch

Heh, I could use that exact command myself, as I use the exact workflow you described :).

-- 
Cheers,

Sverre Rabbelier
Felipe Balbi· Jan 24, 2010, 10:52 UTC · re: Felipe Contreras · lore

Re: cherry picking several patches at once

Hi,
On Sat, 2010-01-23 at 01:57 +0200, Felipe Contreras wrote:
> Have you tried something like:
> git format-patch old-base --full-diff -- /path
> git am -3 *.patch

yes, sure that can be done, but the idea is to avoid having format-patch, switch branches and git am those patches ;-)

> I think that would not be possible because of the challenges when
> dealing with conflicts.

there shouldn't be any. I have the same driver internally and publicly and would be cherry-picking only the patches for that particular driver.

-- 
balbi
Felipe Contreras· Jan 24, 2010, 13:10 UTC · re: Felipe Balbi · lore

Re: cherry picking several patches at once

On Sun, Jan 24, 2010 at 12:52 PM, Felipe Balbi <me@felipebalbi.com> wrote:
Show 7 quoted lines
> On Sat, 2010-01-23 at 01:57 +0200, Felipe Contreras wrote:
>> Have you tried something like:
>> git format-patch old-base --full-diff -- /path
>> git am -3 *.patch
>
> yes, sure that can be done, but the idea is to avoid having
> format-patch, switch branches and git am those patches ;-)

When you do a 'git rebase' you are also doing a format-patch/am, but that happens inside the script; you can write a script that does what you want in a way that you wouldn't notice it: save the old branch, git stash, switch to new branch, generate the patches, apply the patches, switch back to the old branch, git stash pop.

Show 5 quoted lines
>> I think that would not be possible because of the challenges when
>> dealing with conflicts.
>
> there shouldn't be any. I have the same driver internally and publicly
> and would be cherry-picking only the patches for that particular driver.

Ok, in that case we would just need a cherry-pick that can commit to a separate branch, however I don't think git internals allow that kind of thing.

-- 
Felipe Contreras
Marc Weber· Jan 24, 2010, 15:31 UTC · re: Felipe Contreras · lore

Re: cherry picking several patches at once

> Ok, in that case we would just need a cherry-pick that can commit to a
> separate branch, however I don't think git internals allow that kind
> of thing.
Which is the best way to implement this git-cherry-push command?
# naive implementation (BASH function):
gitCherryPush(){
  # start a subshell so that failures don't quit your shell because of
  # set -e
  (
  set -e
  local branch=$(cat .git/HEAD |  sed 's@ref: refs/heads/\(.*\)@\1@')
  local otherBranch=$1; shift
  commits="$(
    for range in "$@"; do
      local HAS_DOTS=${range%%*..*}
      # add -1 if commit is not a range
      git rev-list --reverse ${HAS_DOTS:+-1} "$range"
    done
  )"
  echo "checking out other branch"
  git checkout "$otherBranch"
  echo "$commits" | while read c; do
    git cherry-pick "$c" || {
      echo "cherry-picking $c failed. fix it, exit 1 to abort. Starting subshell now"
      $SHELL || [ "$?" != 1] || return
    }
  done
  echo "checking out original branch $branch"
  git checkout $branch
  )
}
zsh completion:
compdef _gitCherryPush gitCherryPush
_gitCherryPush(){
  typeset -A opt_args
  _arguments -S \
   ':branch to which to move commit range:__git_branch_names' \
   ':branch to which to move commit range:__git_commit_ranges2'
}

Example usage (push last 5 commits) gitCherryPush branch-to-push-to HEAD~4 HEAD~4..HEAD

Can I checkout the other branch without touching the working copy? I don't think so because cherry-pick will fail operating if working directory is not clean, correct?

Is something like this worth comitting to the main repo?
Marc Weber

← back to recent threads