Is there any easy way to cherry pick a _range_ of commits from some other
branch to the current branch, instead of just one?I thought maybe git-rebase could be coerced to do this somehow, but I
couldn't figure a way. [Using git-rebase would be nice because of all the
useful tools it provides, e.g., the --abort, --continue, and -i options.]Thanks,
-Miles
--
P.S. All information contained in the above letter is false,
for reasons of military security.
--
git format-patch --full-index --binary --stdout <range...> | git am -3
This will not work if you want to pick a list, not a range, of
commits.
--
Doesn't "--no-walk" + list commits individually work?
So it _should_ be possible to pick a list of commits too. Although I think
that git format-patch will reverse the order.Linus
--
Or "git show --pretty=email $commit1 $commit2" ... piped to "am"?
--
Or make git show write shell commands.
I often have commits that later need to be cherry-picked into other
branches. For these, I use a commit message that starts with the name of the
branch, like "implement-foo: make foo barfy". Later when I want to do the
cherry-picking, I use this:git log t/whatever..master --reverse --pretty=tformat:'git cherry-pick %h #
%s' | sed 's/^\([^:]*\) \([^:]*\):/git checkout \2 \&\& \1/'giving me output like:
git checkout implement-foo && git cherry-pick 90ce727 # make foo barfy
git checkout ...... and I'm ready for cut'n'paste.
Michael
--
noris network AG - Deutschherrnstraße 15-19 - D-90429 Nürnberg -
Tel +49-911-9352-0 - Fax +49-911-9352-100
http://www.noris.de - The IT-Outsourcing CompanyVorstand: Ingo Kraupa (Vorsitzender), Joachim Astel, Hansjochen Klenk -
Vorsitzender des Aufsichtsrats: Stefan Schnabel - AG Nürnberg HRB 17689
--
Does not work if there are ranges given :-/
It'd be very nice to have: git show #c1..$c2 $c3 $c4 $c5..$c6--
Yeah, we've very fundamentally never supported that. Not for show, but
also not for anything else (ie "gitk a..b c..d" does _not_ give you two
ranges).It's easy to see why once you understand what 'a..b' really means (ie it
just expands to '^a' and 'b'), and how it's not really a "range" operation
as much as a set operation that interacts with all the other arguments
too. But unless you're very aware of that, it can be surprising.Linus
--
Oh, I am. But it is just so convenient to have range support for
commands which just show commits. Besides, git-show just errors out,
instead of producing the commits like git-log does.--
Hi,
Have fun implementing the support, and then explaining to users why this
shows only one commit:git show HEAD^..HEAD HEAD~10
Ciao,
Dscho
--
I find what Alex says somewhat silly because show is always "no walk", and
range by definition means you need to walk.But when you give that command line, Alex could also change the command to
show the HEAD and HEAD~10, by changing the way series of range parameters
are evaluated by the revision parsing machinery. You take HEAD^..HEAD and
come up with one set (that has only one commit, HEAD), you take the next
parameter HEAD~10 and come up with another set (that also has only one
commit, HEAD~10, because show does not walk), then you take union.I personally do not want to see that happen, though. The way multiple
"ranges" that come from separate command line parameters combine using set
operator semantics is so useful to do something like...git log ko/master..master ^maint
which is my way to ask "Which commits on master are the ones that I
haven't pushed out? By the way, I have pushed out maint already so I do
not want to see anything that is already in maint", where ko/master tracks
what I pushed out to the public repository at k.org; this query is used to
see if I can still rewrite commits when I find typo/thinko in them.--
Hi,
Exactly one of my use cases, since we do not have ko/master,maint..master.
Ciao,
Dscho
--
for cs in HEAD^..HEAD HEAD~10; do
case "$cs"; in
*..*)
git format-patch --stdout "$cs"
;;
*)
git show --pretty=email "$cs"
;;
esac
doneAt least, this is what I have in mind and how I expect it to work.
--
Hi,
That is not the way git-show is implemented (it uses setup_revisions() to
check for validity and to parse the arguments), and I cannot think of any
way to make this work without ugly workarounds.Ciao,
Dscho--
Would it be possible to add "range" support to a subset of commands by
using a git-range wrapper?Hypothetical, pie-in-the-sky idea:
git range HEAD^..HEAD HEAD~10 -- show --pretty=email
git range HEAD^..HEAD HEAD~10 -- log
git range HEAD^..HEAD HEAD~10 -- cherry-pickWhich would call the given command for each of the commits found in all
the specified ranges and lists. git-range could have an internal list
of supported git subcommands that it would massage the parameter lists for.I find this both elegant and ugly at the same time. :-)
- Chris
--
It would be better to just extend the SHA-1 arithmetic. We could do it, no
problem. It's just a SMOP.For example, right now the arithmetic is entirely "flat", with no
precedence, no nesting, nothing but a single level of set operations. We
could extend it to be hierarchical.So we _could_ do something like
git log {a..b} {c..d ^e}
and just declare that { $args } is a self-contained "subset", and
effectively becomes the same thing as "$(git rev-list $args)" but with
magic no-walking semantics (ie all walking is done only _within_ the { },
not between different groups.You literally _can_ do it right now that way:
git log --no-walk $(git rev-list HEAD~5..HEAD~3) $(git rev-list HEAD~1..)
actually works, but that will hit argument size limits on many platforms
really quickly.So we could make a '{ }' in the argument space basically do a SHA1
expansion of the range inside, and imply --no-walk. It's _not_ entirely
trivial, because we'd need to handle the fact that object flags are
sticky, and clear them in between invocations of multiple ranges, but it's
not _fundmanetally_ difficult. It's just that somebody would need to do
it.Linus
--
Le Friday 14 November 2008 17:11:41 Linus Torvalds, vous avez écrit :
I don't know if you really meant this, but entering SHA1s as is at a shell
prompt may have dangerous side effects... If not right now, then in (some not
so distant time in) the future. Consider this (I use bash 3.2, maintained by
Gentoo):$ echo {a..c}
a b cWho knows if some day they won't have the idea of, say,
extending "{aeb32ca..ee23ff1}" to, well... You see what I mean.--
Francis Galiegue
ONE2TEAM
Ingénieur système
Mob : +33 (0) 6 83 87 78 75
Tel : +33 (0) 1 78 94 55 52
fge@one2team.com
40 avenue Raymond Poincaré
75116 Paris
--
Wouldn't you lose the nice streaming output (iow short latency)?
--
Oh, absolutely. So the '{x}' format would be not be a replacement for
non-{} format - it would be an addition to.But it's no different from 'a..b' in that sense: anything that sets
'revs->limited' automatically forces a synchronous revision walk. So you'd
be crazy to dogitk {HEAD}
because
(a) there would be no point
(b) it indeed loses the streaming data and would become synchronous.but if you already do
gitk a..b
then you're _already_ doing a revision limiter and forcing the revision
walk to be synchronous, so there would be no interactivity downside
between 'a..b' and '{a..b}'.Linus
--
Btw, the biggest problem (I think) is actually non-simple ranges and just
the _syntax_ of these things.It's entirely reasonable to want to group a more complex expression than
just a single range. IOW, something likegitk {..origin/pu ^origin/next} {HEAD~5..HEAD~2}
to show a union of what is in 'pu' but not master or next, and the
symmetrical difference of the current merge. It's a perfectly sensible
thing to do. And we _can_ do it right now, just with a nasty syntax:gitk --no-walk $(git rev-list ..origin/pu ^origin/next) $(git rev-list HEAD~5..HEAD~2)
actually works. But look again at how nasty it is to parse the '{x}'
version, because the '{..}' thing now spans multiple arguments.Linus
--
That would probably be a job that parseopt could take care of. to some
degree.Also { } is a poor choice as it's an expansion thingy for many shells.
zsh even refuses ` { a.. b } ` as an argument, pretending there is a
syntax error at the closing brace. [ ] looks like a safer choice, it's
used for shells supporting arrays, but only when stuck after an
identifier which won't be our case ever, so we would be probably safe.--=20
=C2=B7O=C2=B7 Pierre Habouzit
=C2=B7=C2=B7O madcoder@debia=
n.org
OOO http://www.madism.org
Hi,
Well, do not forget the case
git log ^HEAD^ {HEAD^..HEAD} $BLUB
Ciao,
Dscho--
Hi,
This is not really well defined is it? What about
git range HEAD -- log makefile
Where should it insert the "HEAD" argument?
Besides, I do not like how this muddies the semantics: if git range as you
proposed it became part of Git, people _would_ get confused why "git range
HEAD^..HEAD HEAD~10" interprets the range _differently_ from "git log
HEAD^..HEAD HEAD~10".Ciao,
Dscho--
Incidentally, the reason I like a rebase-based solution is that many
of the rebase features like -i, --abort, and --continue (after
conflict resolution) are very nice for the multi-cherry-pick case too,
and I'm already very familiar with their operation from using rebase.[git-am seems to have some similar features, but I don't know how well
they work.]-Miles
--
Do not taunt Happy Fun Ball.
--
They work well.
--
Rebase is exactly what you want. Given something like this:
o--o--o--A--B--C--o--o--X
\
o--o--Dwhere you want A, B, C to go on top of D:
$ git checkout -b newbranch C
$ git rebase --onto D ^Anewbranch will have <...> --D--A--B--C
Hope that helps,
Deskin Miller
--
... and then you can merge newbranch into the existing branch that
references D, fast-forwarding the branch. And then newbranch can be
deleted.If you don't want to use a temporary branch, you can also do (while on
the branch onto which you want to cherry-pick):git reset --hard C
git rebase --onto ORIG_HEAD A^Which should get you the same result, without using a temporary branch.
Björn
--
Is that safe...? Doesn't git-rebase also set ORIG_HEAD?
-Miles
--
Twice, adv. Once too often.
--
One of the first things rebase does is validating and resolving its
arguments. And that's happening before any actions that would touch
ORIG_HEAD. Though I'm not sure if it's always been like that.Björn
--
Ah, I see.
Hmm, I guess using rebase --abort isn't a very good idea in this case
though... :-/Kind of a shame, since it's nice being to just abort the whole operation
if it turns out you did something wrong and aren't sure how to recover.Thanks,
-Miles
--
Kilt, n. A costume sometimes worn by Scotchmen [sic] in America and Americans
in Scotland.
--
Why not? I mean, ok, you end up at C, and not where you have been before
the reset --hard, but there's the reflog to help you get back to
whatever previous state of the branch it is that you want.Björn
--
I just mean it's not a trivial way to get back to the state before the
multi-cherry-pick -- you need to know the details of what's going on,
and handle the rest of the cleanup manually.So, for instance, if you were to package up the above commands in a
shell script, the abort issue is one of those rough edges which would
prevent it from being as convenient as a real git command. [A
hypothetical extension of the cherry-pick command to handle multiple
commits would presumably offer a "cherry-pick --abort" option that did
everything magically.]-Miles
--
Do not taunt Happy Fun Ball.
--
| Andrew Morton | Re: Linux 2.6.21-rc4 |
| Andrew Morton | -mm merge plans for 2.6.23 |
| Greg KH | [GIT PATCH] driver core patches against 2.6.24 |
| Balbir Singh | Re: [RFC][PATCH 2/7] RSS controller core |
git: | |
| Gerrit Renker | [PATCH 15/37] dccp: Set per-connection CCIDs via socket options |
| David Miller | [GIT]: Networking |
| Andreas Henriksson | [PATCH 06/12] Remove bogus reference to tc-filters(8) from tc(8) manpage. |
| Jarek Poplawski | Re: [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
