{"thread":{"id":"28648","subject":"Symmetric of rebase / more intelligent cherry-pick","startedAt":"2011-10-11T15:54:44Z","lastAt":"2011-10-11T22:23:03Z","messageCount":4,"participants":["Lionel Elie Mamane","Junio C Hamano","Jonathan Nieder"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"177375","messageId":"20111011155444.GB14417@capsaicin.mamane.lu","threadId":"28648","inReplyTo":null,"subject":"Symmetric of rebase / more intelligent cherry-pick","fromName":"Lionel Elie Mamane","fromEmail":"lionel@mamane.lu","sentAt":"2011-10-11T15:54:44Z","receivedAt":"2011-10-11T15:54:44Z","isPatch":false,"sender":{"key":"lionel@mamane.lu","avatar":null},"body":"Hi,\n\nI was thinking about a sort of symmetric to rebase, a kind of\n\"intelligent\" mass cherry-pick. For the sake of example let's call it\n\"basere\", although a better name would have to be found.\n\nWhile\n git rebase UPSTREAM\nmoves the *current* branch (and any commit in it, but not in UPSTREAM)\non top of UPSTREAM,\n git basere UPSTREAM\nwould \"cherry-pick\" all commits in UPSTREAM that are not in HEAD to\nthe current branch.\n\ngit cherry-pick ..UPSTREAM\n*nearly* does what I want, except that it lacks rebase's intelligence\nof skipping commits that do the same textual changes as a commit\nalready in the current branch. So maybe it should be an option to\ncherry-pick rather than a new command? E.g. --skip-same? What about\nmaking it cherry-picks *default* behaviour?\n\nWhy do I think it is useful? Take the case of a developer following\ntwo different origins A and B, and B uses rebase (not merge) to\nintegrate changes from A, but not as often as one would like. A could\nfor example be the \"official\" tree (e.g. linux Linus tree), and B a\nfeature branch of a developer that is meant to eventually go into A\n\"cleanly\" at some future time and A's policy is that one has to rebase\nbefore sending a merge request. Then another developer wants to keep\nup with changes from *both* A and B. So, the situation could look\nlike:\n\n      A---A---A remotes/A/master\n     /\nX---X---B0---B1---L master\n     \\\n      B0---B1---B2--B3 remotes/B/master\n\nSo one does \"git rebase remotes/A/master master\" and one gets\n\n      A---A---A---B0---B1---L master\n     /\nX---X\n     \\\n      B0---B1---B2--B3 remotes/B/master\n\nI'd like to go to the situation:\n\n      A---A---A---B0---B1---L---B2--B3 master\n     /\nX---X\n     \\\n      B0---B1---B2--B3 remotes/B/master\n\nWithout having to manually find the cutoff point \"B2\"\n(or worse, if the history is more messy than that, as in:\n\n      A---A---A---B1---L master\n     /\nX---X\n     \\\n      B0---B1---B2--B3 remotes/B/master\n)\n\n\nThe best way I have found to do that is:\n\ngit fetch B\ngit checkout --no-track -b TMP remotes/B/master\ngit rebase master\ngit checkout master\ngit merge --ff-only TMP\ngit branch -d TMP\n\nor less commands but more messy/fragile (and more work for git):\n\ngit fetch B\ngit tag TMP\ngit rebase remotes/B/master\ngit rebase TMP\ngit tag -d TMP\n\nbut that is rather onerous for something that should be just one\ncommand.\n\n\nSo what are your thoughts on that?\n\n - Good idea? Would you take a patch that does something like that?\n\n - Should it be cherry-picks's default behaviour?\n\n - An option to cherry-pick?\n\n - A new command? What name? Maybe \"multi-cherry-pick\"?\n\n - An option to rebase, e.g. \"--pull\" or \"--incoming\" or \"--here\"?\n   (\"--pull\" is probably too confusing wrt to \"git pull\"; people will\n    have trouble remembering which is which between \"git pull\n    --rebase\" and \"git rebase --pull\"...)\n\n-- \nLionel\n"},{"id":"177393","messageId":"7v8vorfhhu.fsf@alter.siamese.dyndns.org","threadId":"28648","inReplyTo":"20111011155444.GB14417@capsaicin.mamane.lu","subject":"Re: Symmetric of rebase / more intelligent cherry-pick","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-10-11T19:36:13Z","receivedAt":"2011-10-11T19:36:13Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lionel Elie Mamane <lionel@mamane.lu> writes:\n\n> git cherry-pick ..UPSTREAM\n> *nearly* does what I want, except that it lacks rebase's intelligence\n> of skipping commits that do the same textual changes as a commit\n> already in the current branch.\n\nI think in the longer term \"--ignore-if-in-upstream\" that is known only to\nformat-patch, which is the true source the intelligence of rebase you\nobserved comes from, should be factored out into a helper function that\ncan be used to filter output from get_revision() in other commands, or\nperhaps get_revision() itself might want to learn it.\n\nI say \"or perhaps might\" above, because I do not think the general\nrevision traversal machinery used by the log family (which cherry-pick's\nmulti-pick option relies on) has enough information to decide what the\ncaller means by \"upstream\" at the point setup_revisions() is called.\n"},{"id":"177400","messageId":"7vty7fdxql.fsf@alter.siamese.dyndns.org","threadId":"28648","inReplyTo":"7v8vorfhhu.fsf@alter.siamese.dyndns.org","subject":"Re: Symmetric of rebase / more intelligent cherry-pick","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-10-11T21:28:18Z","receivedAt":"2011-10-11T21:28:18Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Lionel Elie Mamane <lionel@mamane.lu> writes:\n>\n>> git cherry-pick ..UPSTREAM\n>> *nearly* does what I want, except that it lacks rebase's intelligence\n>> of skipping commits that do the same textual changes as a commit\n>> already in the current branch.\n>\n> I think in the longer term \"--ignore-if-in-upstream\" that is known only to\n> format-patch, which is the true source the intelligence of rebase you\n> observed comes from, should be factored out into a helper function that\n> can be used to filter output from get_revision() in other commands, or\n> perhaps get_revision() itself might want to learn it.\n\nWe actually have half of that filtering in \"--cherry-pick\" that was\nintroduced in d7a17ca (git-log --cherry-pick A...B, 2007-04-09).\n\nPerhaps the recent cherry-pick that allows multiple commits to be picked\nshould use that option (i.e. a \"log --cherry-pick --right-only ..@{u}\"\nequivalent) when coming up with which commits to apply?\n"},{"id":"177404","messageId":"20111011222138.GA3768@elie.hsd1.il.comcast.net","threadId":"28648","inReplyTo":"7vty7fdxql.fsf@alter.siamese.dyndns.org","subject":"Re: Symmetric of rebase / more intelligent cherry-pick","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2011-10-11T22:23:03Z","receivedAt":"2011-10-11T22:23:03Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Junio C Hamano wrote:\n\n> We actually have half of that filtering in \"--cherry-pick\" that was\n> introduced in d7a17ca (git-log --cherry-pick A...B, 2007-04-09).\n>\n> Perhaps the recent cherry-pick that allows multiple commits to be picked\n> should use that option (i.e. a \"log --cherry-pick --right-only ..@{u}\"\n> equivalent) when coming up with which commits to apply?\n\nNo UI ideas from me, but I have a script like this sitting in $HOME/bin:\n\n base=$1 topic=$2\n\n git rev-list $base..HEAD |\n git diff-tree -s --pretty=raw --stdin |\n sed -ne 's/(cherry picked from commit \\([0-9a-f]*\\))/\\1/p' |\n xargs git cherry-pick -x -s \\\n   --cherry-pick --right-only --no-merges HEAD...$topic \\\n   --not $base\n"}]}