configuring cherry-pick to always use -x?
Is there a configuration option to make cherry-pick always include the source commit hash in the new commit log message?
e.g., make "git cherry-pick" always behave like "git cherry-pick -x"?
My most frequent use case for cherry picking is between publicly visible branches.
I have the following configuration option set:
alias.cpx=cherry-pick -x
but I rarely remember to use it.
Quoted 2 lines · Adam Monsen
Is there a configuration option to make cherry-pick always include the source commit hash in the new commit log message?
Not currently, but before we go any further, could you please justify in what workflow it would make sense to use -x most of the time?
We used to add the "cherry-picked from" by default in the very early days, and stopped doing so for a reason, and also deliberately stayed away from adding such a configuration to actively discourage the use of -x without making the user thinking twice.
Quoted 2 lines · Junio C Hamano
could you please justify in what workflow it would make sense to use -x most of the time?
Sure. Summary: two long-lived publicly visible branches.
Details:
Mifos is what I'm usually working on lately. We have branches "master" and "f-release" both present in our public git repository called "head" (hosted at sf.net). master is the bleeding edge of development, f-release is a release maintenance branch recently created off the tip of master. I expect both to live on forever (even though commits to f-release will eventually cease).
Right after f-release was cut, we merged f-release to master every day or so to make sure bugfixes for f-release were also propagated to future releases. After a while, merging resulted in too many conflicts and we started cherry picking instead.
This process is described generally at
http://mifosforge.jira.com/wiki/display/MIFOS/Release+Branch+Merging+Policy
.
If the source commit is present in the log message of the new (cherry picked) commit, it's easy to (1) find the source commit (gitweb creates a hyperlink, for instance) and (2) know that, when viewing the log of master, a particular commit is also present on another branch. Right now I just keep reminding folks to use -x.
For (2), I generally assume that branch is a release branch, but come to think of it, it would be nice to know what branch a commit was cherry picked from. For example: "(cherry picked from BRANCHNAME commit c6e08938e352f3ec99a29a67dd192945d2bcf00d)" would be better than the current message generated by -x.
See also:
http://mifosforge.jira.com/wiki/display/MIFOS/Mifos+Version+Control+Guide
Adam Monsen venit, vidit, dixit 14.02.2011 22:50:
Quoted 14 lines
Quoted 2 lines · Junio C Hamano
could you please justify in what workflow it would make sense to use -x most of the time?
Sure. Summary: two long-lived publicly visible branches.
Details:
Mifos is what I'm usually working on lately. We have branches "master" and "f-release" both present in our public git repository called "head" (hosted at sf.net). master is the bleeding edge of development, f-release is a release maintenance branch recently created off the tip of master. I expect both to live on forever (even though commits to f-release will eventually cease).
Quoted 7 lines
Right after f-release was cut, we merged f-release to master every day or so to make sure bugfixes for f-release were also propagated to future releases. After a while, merging resulted in too many conflicts and we started cherry picking instead.
This process is described generally at
http://mifosforge.jira.com/wiki/display/MIFOS/Release+Branch+Merging+Policy
I don't quite understand how cherry picks could conflict less then merges if the release branch contains fixes only. Also, I don't think the advice to use "merge+revert" is a good one. All of this indicates a suboptimal use of branches. My impression is that "f-release" actually mixes release engineering and maintenance. Two possible remedies:
- Separate release engineering from maintenance and merge only the latter to master
- If you do want them on the same branch "f-release", you probably know beforehand which commits you don't want on master. You can fake-merge these ("merge -Xours") to master and merge the others, which is somewhat ugly but still better than cherry-picking everything. In some sense this is "manual rerere" whose results are shared (pushed) easily.(*)
Michael
(*) If that is cryptic, I mean something like:
git checkout master
git merge f-release
#be happy if it succeeds, identify problematic commit X if not; decide whether X belongs on master; if yes resolve, if not reset and:
git merge X^
git merge -Xours X
#back to start
Quoted 3 lines · Michael J Gruber
- If you do want them on the same branch "f-release", you probably know beforehand which commits you don't want on master. You can fake-merge these ("merge -Xours") to master and merge the others
For the record, I think that should be -sours.
I think it's just a typo but the difference is big --- -sours means "supersede by pretending to merge but actually keeping our version", while -Xours means "do a normal merge but be sloppy and favor our change when encountering adjacent or overlapping changes".
I suppose -Xours should have been named -Xfavor-ours, -Xsloppy-favoring-ours, or something similarly explicit.
Quoted 7 lines
git checkout master
git merge f-release
#be happy if it succeeds, identify problematic commit X if not; decide whether X belongs on master; if yes resolve, if not reset and:
git merge X^
git merge -Xours X
#back to start
Thanks for a nice example.
Jonathan
Jonathan Nieder venit, vidit, dixit 15.02.2011 10:18:
Quoted 6 lines
Quoted 3 lines · Michael J Gruber
- If you do want them on the same branch "f-release", you probably know beforehand which commits you don't want on master. You can fake-merge these ("merge -Xours") to master and merge the others
Quoted 6 lines
For the record, I think that should be -sours.
I think it's just a typo but the difference is big --- -sours means "supersede by pretending to merge but actually keeping our version", while -Xours means "do a normal merge but be sloppy and favor our change when encountering adjacent or overlapping changes".
Yes, sorry and thanks.
-Xours may still be useful to know for the OP, but for the complete fake-merge you need -sours. In fact, "-sours" has an awfully good mnemonic when used for fake-merging commits which you do not want to cherry-pick :)
Michael
release maintenance vs. release engineering (was: configuring cherry-pick to always use -x?)
In reply to Michael J GruberQuoted 2 lines · Michael J Gruber
I don't quite understand how cherry picks could conflict less then merges if the release branch contains fixes only.
The last time I experienced a painful merge from f-release to master, it was because some files had been culled from master but left extant on f-release. Not too hard to resolve, actually. But I really only needed one change pulled into master, and when I cherry picked instead of merging the whole branch, there were no conflicts, and master ended up containing exactly what I wanted.
Quoted 5 lines
My impression is that "f-release" actually
mixes release engineering and maintenance. Two possible remedies:- Separate release engineering from maintenance and merge only the latter to master
Ah, thank you! This is invaluable advice. I think I'll go with this option since mixing release engineering and maintenance is exactly what I'm doing. Hopefully it's worth the added complexity of having another public branch.
I pushed an example to https://github.com/meonkeys/releaseBranchDemo
that I'll share with my developers.
"git merge -sours" will definitely be something useful to add to the quiver too.
Quoted 5 lines · Michael J Gruber
- If you do want them on the same branch "f-release", you probably know beforehand which commits you don't want on master. You can fake-merge these ("merge -Xours") to master and merge the others, which is somewhat ugly but still better than cherry-picking everything. In some sense this is "manual rerere" whose results are shared (pushed) easily.(*)
I personally prefer cherry-pick, as the fake merge clutters mainline's history with the superseded commits.
It would be interesting to have a history simplification that given a merge M of parents A and B, ignored commits $(merge-base A B)..B where M is TREESAME to A. Hmm, that's effectively "git rev-list ." isn't it?
j.
Quoted 2 lines · Junio C Hamano
Not currently, but before we go any further, could you please justify in what workflow it would make sense to use -x most of the time?
In one of my repos, most of the time my cherry-picks are between two public branches. Perhaps a better enhancement would be something like:
branch.<name>.annotate_cherry_pick = {true, false}
which could be set to true for source branches that you wish to default to -x. Or, maybe it makes sense in cases where the source branch is a remote-tracking branch:
cherry_pick.annotate = {local, remote}
I'm not sure how good a remote-tracking branch is as an indicator of 'public branch', though, so I think explicitly configuring it per-branch makes more sense. I hesitate there only because we don't currently put remote-tracking branches in the branch section names.
j.
Hi Junio,
Quoted 11 lines · Junio C Hamano
Quoted 2 lines · Adam Monsen
Is there a configuration option to make cherry-pick always include the source commit hash in the new commit log message?
Not currently, but before we go any further, could you please justify in what workflow it would make sense to use -x most of the time?
We used to add the "cherry-picked from" by default in the very early days, and stopped doing so for a reason, and also deliberately stayed away from adding such a configuration to actively discourage the use of -x without making the user thinking twice.
Could you elaborate on the reason why -x is a bad idea?
Kind regards,
Signature · 6 lines
Ivan Kanis, Release Manager, Vision Objects,
Tel +33 2 28 01 84 44, Fax +33 2 40 25 89 20
http://www.visionobjects.com
We meet no Stranger, but Ourself.
-- Emily Dickinson Quoted 4 lines · Adam Monsen
Is there a configuration option to make cherry-pick always include the source commit hash in the new commit log message?
e.g., make "git cherry-pick" always behave like "git cherry-pick -x"?
Nope, but one would be appreciated. :-)
Quoted 8 lines
My most frequent use case for cherry picking is between publicly visible branches.
I have the following configuration option set:
alias.cpx=cherry-pick -x
but I rarely remember to use it.
It's worse than that. I like to keep the message generated after a cherry-pick conflict, but the original commit authorship. I have this, which I call recommit:
<snip>
#!/bin/sh
# Used after a cherry-pick conflicts to commit with the original
# authorship (commit -c) but keep the newly generated commit message # self=$(cd "$(dirname "$0")" && pwd -P)/$(basename "$0") . "$(git --exec-path)/git-sh-setup" require_work_tree cd_to_toplevel test -f .git/MERGE_MSG || die "No .git/MERGE_MSG"
if test "$GIT_EDITOR" = "$self"
then
cat .git/MERGE_MSG > .GIT/COMMIT_EDITMSG
exit 0
fi
if sha1=$(sed -ne \
's/^(cherry picked from commit \([a-f0-9]\{40\}\))$/\1/p' .git/MERGE_MSG)
then
export GIT_EDITOR="$self"
git commit -c $sha1
fi
</snip>
I've had it on my TODO list for a while now to:
1. add a config option to enable -x by default
2. improve the cherry-pick conflict UX. I was thinking of out CHERRY_HEAD on conflict and then adding a cherry-pick --continue option which acts like rebase --continue. CHERRY_HEAD is what was being picked at the time of conflict and can be used by the bash completion script for proper prompting, as well as obviously the --continue option.
j.
Quoted 8 lines · Jay Soffian
I've had it on my TODO list for a while now to:
...
2. improve the cherry-pick conflict UX. I was thinking of outCHERRY_HEADon conflict and then adding a cherry-pick --continue option which acts like rebase --continue.CHERRY_HEADis what was being picked at the time of conflict and can be used by the bash completion script for proper prompting, as well as obviously the --continue option.
Yes, we have so far only "use commit -c $that_one", which is an obvious and low hanging fruit for improvement. Thanks.