{"thread":{"id":"37269","subject":"cherry picking and merge","startedAt":"2014-08-01T00:58:17Z","lastAt":"2014-08-21T17:58:07Z","messageCount":43,"participants":["Mike Stump","brian m. carlson","Jakub Narębski","Philip Oakley","Nico Williams","Jonathan Nieder","Sam Vilain","Junio C Hamano","Alex Davidson","Keller, Jacob E"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"247092","messageId":"51C01AAA-3CFB-4110-BAE9-7D04CA8EE53A@comcast.net","threadId":"37269","inReplyTo":null,"subject":"cherry picking and merge","fromName":"Mike Stump","fromEmail":"mikestump@comcast.net","sentAt":"2014-08-01T00:58:17Z","receivedAt":"2014-08-01T00:58:17Z","isPatch":false,"sender":{"key":"mikestump@comcast.net","avatar":null},"body":"Cherry picking doesn’t work as well as it should.  I was testing on git version 1.7.9.5.\n\nPut in a line in a file, call it:\n\nfirst version\n\nthen cherry pick this into your branch. Then update on master and transform that into:\n\nsecond version\n\nthen, merge that branch back to master.  Death in the form of conflicts.\n\nIn gcc land, I do this sort of thing all the time, and I need a merging subsystem to actually keep track of things.  I can manage this will diff and patch and it works flawlessly.  The point of using something better than diff and patch is for it to be better than diff and patch.\n\nI’d like for merge to merge in the work that has yet to be merged.  Not that, plus blindly try and apply or reapply cherry picked items."},{"id":"247093","messageId":"20140801024329.GA28914@vauxhall.crustytoothpaste.net","threadId":"37269","inReplyTo":"51C01AAA-3CFB-4110-BAE9-7D04CA8EE53A@comcast.net","subject":"Re: cherry picking and merge","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2014-08-01T02:43:29Z","receivedAt":"2014-08-01T02:43:29Z","isPatch":false,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Thu, Jul 31, 2014 at 05:58:17PM -0700, Mike Stump wrote:\n> Cherry picking doesn’t work as well as it should.  I was testing on\n> git version 1.7.9.5.\n> \n> Put in a line in a file, call it:\n> \n> first version\n> \n> then cherry pick this into your branch. Then update on master and transform that into:\n> \n> second version\n> \n> then, merge that branch back to master.  Death in the form of conflicts.\n> \n> In gcc land, I do this sort of thing all the time, and I need a\n> merging subsystem to actually keep track of things.  I can manage this\n> will diff and patch and it works flawlessly.  The point of using\n> something better than diff and patch is for it to be better than diff\n> and patch.\n> \n> I’d like for merge to merge in the work that has yet to be merged.\n> Not that, plus blindly try and apply or reapply cherry picked items.\n\nYou're not the first person to be surprised by the way merge works.\nFrom the git-merge manpage:\n\n  [This behavior] occurs because only the heads and the merge base are\n  considered when performing a merge, not the individual commits.\n\n(That was added after 1.7.9.5.)\n\nIf you want the behavior of applying multiple patches in a row, you want\nto use git rebase, not git merge.  Since rebase re-applies the patches\nof each of your commits on top of another branch, the identical change\nwon't cause conflicts.\n\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\n+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187\n"},{"id":"247103","messageId":"53DBBFE8.8060607@gmail.com","threadId":"37269","inReplyTo":"20140801024329.GA28914@vauxhall.crustytoothpaste.net","subject":"Re: cherry picking and merge","fromName":"Jakub Narębski","fromEmail":"jnareb@gmail.com","sentAt":"2014-08-01T16:27:20Z","receivedAt":"2014-08-01T16:27:20Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"W dniu 2014-08-01 04:43, brian m. carlson pisze:\n> On Thu, Jul 31, 2014 at 05:58:17PM -0700, Mike Stump wrote:\n\n>> Cherry picking doesn’t work as well as it should.  I was testing on\n>> git version 1.7.9.5.\n>>\n>> Put in a line in a file, call it:\n>>\n>> first version\n>>\n>> then cherry pick this into your branch. Then update on master and transform that into:\n>>\n>> second version\n>>\n>> then, merge that branch back to master.  Death in the form of conflicts.\n>>\n>> In gcc land, I do this sort of thing all the time, and I need a\n>> merging subsystem to actually keep track of things.  I can manage this\n>> will diff and patch and it works flawlessly.  The point of using\n>> something better than diff and patch is for it to be better than diff\n>> and patch.\n>>\n>> I’d like for merge to merge in the work that has yet to be merged.\n>> Not that, plus blindly try and apply or reapply cherry picked items.\n\nNote that you should try to avoid cherry-picking, as they do not\nleave trace in the graph of revisions.\n\nFor example if you are creating a bugfix, instead of putting it\ndirectly on maint, and then cherry-picking to master, it is better\nto create a separate feature branch for this fix (based at an early\nversion), and then merge said branch into maint, then into master.\nIt is described in blog post by Junio Hamano (which I cannot find now).\n\n> You're not the first person to be surprised by the way merge works.\n>  From the git-merge manpage:\n>\n>    [This behavior] occurs because only the heads and the merge base are\n>    considered when performing a merge, not the individual commits.\n>\n> (That was added after 1.7.9.5.)\n>\n> If you want the behavior of applying multiple patches in a row, you want\n> to use git rebase, not git merge.  Since rebase re-applies the patches\n> of each of your commits on top of another branch, the identical change\n> won't cause conflicts.\n\nThere is also git-imerge, third party tool that is intended to help\nmerging changes (and make it possible to do it in incremental way).\n\nHTH\n-- \nJakub Narębski\n"},{"id":"247106","messageId":"AC750A73-4FE9-4BCB-9A51-4DE28F2110A7@comcast.net","threadId":"37269","inReplyTo":"20140801024329.GA28914@vauxhall.crustytoothpaste.net","subject":"Re: cherry picking and merge","fromName":"Mike Stump","fromEmail":"mikestump@comcast.net","sentAt":"2014-08-01T16:56:51Z","receivedAt":"2014-08-01T16:56:51Z","isPatch":false,"sender":{"key":"mikestump@comcast.net","avatar":null},"body":"On Jul 31, 2014, at 7:43 PM, brian m. carlson <sandals@crustytoothpaste.net> wrote:\n> \n> You're not the first person to be surprised by the way merge works.\n\nI’m not the first, because the merge command is broken.  Once fixed, I would be happy to be the last.  Until then, the bug remains unfixed.  I’m sending the mail to petition for this bug to be fixed.\n\n> From the git-merge manage:\n> \n>  [This behavior] occurs because only the heads and the merge base are\n>  considered when performing a merge, not the individual commits.\n\nFrom:\n\ngoogle(”git merge”):\n\n> git-merge - Join two or more development histories together\n\nEither, the command should do as documented, or be fixed.  In that reference, there is no mention that merge will not merge.  There is no mention that merge isn’t the command I want to merge, but that I should use rebase.\n\nFurther, google(“git rebase”) says:\n\n> There is no difference in the end product of the integration,\n\nClearly, this is a lie.  There is a difference.\n\nNow, about rebase:\n\n> Do not rebase commits that you have pushed to a public repository.\n> \n> If you follow that guideline, you’ll be fine. If you don’t, people will hate you, and you’ll be scorned by friends and family.\n\n\nSince everything I do goes up and down into repositories and I don’t want my friends and family to scorn me, rebase isn’t the command I want to use.\n\nI want to use the simple, it works, named for the operation I want to perform, merge.  I’m a simple user, and the simple command I want to work.  You can name the old merge command, merge-mostly or merge-fast and the new one can be called merge.\n\n> (That was added after 1.7.9.5.)\n\nI don’t want bugs documented, I want them fixed.  I’m not reporting a doc bug, the doc is correct.\n\n> If you want the behavior of applying multiple patches in a row, you want\n> to use git rebase, not git merge.  Since rebase re-applies the patches\n> of each of your commits on top of another branch, the identical change\n> won't cause conflicts.\n\nBut, I don’t want the series of patches, I just want a simple,  merged feature X on trunk single commit that merge does.\n\nGiven branch B, master M, and cherry picked C, what I want merged is B-(M+C), not B-M.  The problem with B-M, is that when you do B += C (aka cherry pick from master onto your branch), then M += B-M (merge your branch into master), that C is then replicated.  This replication is wrong, always wrong, never right, incorrect, broken.  This is the bug I want fixed."},{"id":"247117","messageId":"5AF18A76-DD3B-4B9A-BF70-EFE4BB852C3D@comcast.net","threadId":"37269","inReplyTo":"53DBBFE8.8060607@gmail.com","subject":"Re: cherry picking and merge","fromName":"Mike Stump","fromEmail":"mikestump@comcast.net","sentAt":"2014-08-01T17:48:33Z","receivedAt":"2014-08-01T17:48:33Z","isPatch":false,"sender":{"key":"mikestump@comcast.net","avatar":null},"body":"On Aug 1, 2014, at 9:27 AM, Jakub Narębski <jnareb@gmail.com> wrote:\n> \n> Note that you should try to avoid cherry-picking, as they do not\n> leave trace in the graph of revisions.\n\nFine, then I want a new command to merge in a change into my branch from another branch and I want merge to account for the motion and not duplicate it when I merge that branch back into master.  Funny thing is, cherry and merge seem to be documented mostly to do exactly what I want.\n\n> For example if you are creating a bugfix, instead of putting it\n> directly on maint, and then cherry-picking to master, it is better\n> to create a separate feature branch for this fix\n\nYou’re assuming that I’m the author of master, I’m not, I’m merely a contributor.  This tail doesn’t wag that dog.  What that means is that I cannot change the world to work around a simple bug in git.\n\n> There is also git-imerge, third party tool that is intended to help\n> merging changes (and make it possible to do it in incremental way).\n\nThen remove git merge and replace it with git-imerge.  :-)  Anyway, I read that, and I can see some beauty of that that might be nice in complex merges.  The problem is, I want git merge to work.\n\n\nI was curious if svn handles this better the same or worse, and it did it just fine.  I know that a while ago, svn could not handle this, it would do what git does currently.  Apparently they figured out it was a bug and fixed it.  Have you guys figured out it is a bug yet?  The first step in solving a problem, is admitting you have a problem."},{"id":"247121","messageId":"4EA0D79811C348C6893039D315E6E190@PhilipOakley","threadId":"37269","inReplyTo":"5AF18A76-DD3B-4B9A-BF70-EFE4BB852C3D@comcast.net","subject":"Re: cherry picking and merge","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":"2014-08-01T18:57:04Z","receivedAt":"2014-08-01T18:57:04Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Mike Stump\" <mikestump@comcast.net>\n> On Aug 1, 2014, at 9:27 AM, Jakub Narębski <jnareb@gmail.com> wrote:\n>>\n>> Note that you should try to avoid cherry-picking, as they do not\n>> leave trace in the graph of revisions.\n>\n> Fine, then I want a new command to merge in a change into my branch \n> from another branch and I want merge to account for the motion and not \n> duplicate it when I merge that branch back into master.  Funny thing \n> is, cherry and merge seem to be documented mostly to do exactly what I \n> want.\n>\n>> For example if you are creating a bugfix, instead of putting it\n>> directly on maint, and then cherry-picking to master, it is better\n>> to create a separate feature branch for this fix\n>\n> You’re assuming that I’m the author of master, I’m not, I’m merely a \n> contributor.  This tail doesn’t wag that dog.  What that means is that \n> I cannot change the world to work around a simple bug in git.\n>\n>> There is also git-imerge, third party tool that is intended to help\n>> merging changes (and make it possible to do it in incremental way).\n>\n> Then remove git merge and replace it with git-imerge.  :-)  Anyway, I \n> read that, and I can see some beauty of that that might be nice in \n> complex merges.  The problem is, I want git merge to work.\n>\n>\n> I was curious if svn handles this better the same or worse, and it did \n> it just fine.  I know that a while ago, svn could not handle this, it \n> would do what git does currently.  Apparently they figured out it was \n> a bug and fixed it.  Have you guys figured out it is a bug yet?  The \n> first step in solving a problem, is admitting you have a problem.\n--\nBut that goes both ways, and is a philosophical issue about what is to \nbe expected in various cases. For some central control use styles, the \nideas behind _distributed_ version control are anathema and (Git) just \ngrinds away at the policies that are expected.\n\nThat said, Git doesn't claim to be perfect (and can't because of the \n'relativity' that comes with being distributed - truth has to give way \nto a web of trust). Also the artefacts that Git validates are at a \ndifferent level of abstraction i.e. the whole project as a commit, \nrather than just a few/one file at a time.\n\nIn your example (when generalised) the problem is deciding when, in the \nchange sequence, the cherry pick is to be backed out, especially if \nthere are conflicts in the change sequence that would need fixing \nanyway, and in a long change sequence that would be a lot of conflict \nfix-ups, hence the current choice of getting the merge conflicts all \nresolved in the one go.\n\nThe alternate case, mentioned/implied by Brian, is to use a rebase \n(probably after duplicating the branch so as to retain the original if \nrequired) so as to see each patch/changeset being applied, and doing \nany/many conflit resolutions as they appear, before finally doing any \nmerge of the new line of development back into the mainline (which again \npresumes your earlier resolutions don't cause more conflicts on that \nmerge). But do note that I've hidden the problem of deciding where the \nrebase start point should be, relative to the merge point, because \nthat's actually where the original problem is hidden (which bits merge \nwith what!)\n\ngit-imerge is a visual tool to show which bits merge cleanly with what \nbetween two change sequences.\n\nSelecting a compatible workflow is a problem of usage, rather than a \nproblem in Git. If Git has a problem, it's that it has too many ways of \ndoing things, leaving most of us with too much rope entangled round our \nneck.\n--\nPhilip\n"},{"id":"247123","messageId":"CANQwDwdKbmqLSLGsiyHTfGNZGfbeNZM3TN6Zk0G5G-8twRc_JQ@mail.gmail.com","threadId":"37269","inReplyTo":"CANQwDwc4YPdK+a0Oc-jWPTRyM5GiP-CMuRY1inxJY41GwUGBvQ@mail.gmail.com","subject":"Fwd: cherry picking and merge","fromName":"Jakub Narębski","fromEmail":"jnareb@gmail.com","sentAt":"2014-08-01T19:01:31Z","receivedAt":"2014-08-01T19:01:31Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"[sorry for duplicate sent as private mail; I forgot to turn off HTML\nwhen sending to the git mailing list]\n\nOn Fri, Aug 1, 2014 at 7:48 PM, Mike Stump <mikestump@comcast.net> wrote:\n[...]\n>\n> I was curious if svn handles this better the same or worse, and it did it just fine.  I know that a while ago, svn could not handle this, it would do what git does currently.  Apparently they figured out it was a bug and fixed it.  Have you guys figured out it is a bug yet?  The first step in solving a problem, is admitting you have a problem.\n\n\nIt can work in Subversion because Subversion stores information about\nwhat was merged in (and this includes cherry-picks, or whatever it is\nnamed in svn) in svn:mergeinfo property. Git does not track what was\nmerged in, instead it represent the history as the graph of revisions,\nand tracks merges (by storing that it came from two or more commits)\nand not merged-in information.\n\nWhen merging Git uses only what is being merged and its common\nancestor (3-point merge). It is simple, and simple works!!!\nUnfortunately, it does not see cherry-picked commits - it is invisible\nto merge as being on the chain from one of merged commits to the\ncommon ancestor.\n\nThe rebase command handles cherry-picked commits by detecting that the\nchange was already applied. I think that git-imerge does the same (but\nI have not used it myself).\n\nHave you tried git-imerge?\n\n-- \nJakub Narębski\n\n\n\n-- \nJakub Narebski\n"},{"id":"247127","messageId":"CAK3OfOipw+Tg4PF5HAr8tb204vt17EVn46Lm9VMuHW1299yP8A@mail.gmail.com","threadId":"37269","inReplyTo":"51C01AAA-3CFB-4110-BAE9-7D04CA8EE53A@comcast.net","subject":"cherry picking and merge","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-01T19:22:20Z","receivedAt":"2014-08-01T19:22:20Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Thursday, July 31, 2014, Mike Stump <mikestump@comcast.net> wrote:\n>\n> Cherry picking doesn’t work as well as it should.  I was testing on git version 1.7.9.5.\n>\n> Put in a line in a file, call it:\n>\n> first version\n>\n> then cherry pick this into your branch. Then update on master and transform that into:\n>\n> second version\n>\n> then, merge that branch back to master.  Death in the form of conflicts.\n\nThe problem is that cherry-picked commits lack the metadata that git\nmerge could use to avoid this spurious conflict report.  The reflog\nhas the metadata in question, but there's no guarantee that that\nreflog will be available where you do the merge.  (IMO this is another\nreason to want branches as objects, so such ancillary information can\nbe recorded somewhere, but in a way that can get dropped if desired\nand without changing commit hashes, but I digress.)\n\nIf you always rebase your commits on top of the upstream, then this\nproblem goes away.  You can't always rebase your commits on top of the\nupstream though, but wherever possible it's the best course of action\nfor this and other reasons.\n\nNico\n--\n"},{"id":"247131","messageId":"20140801200201.GS12427@google.com","threadId":"37269","inReplyTo":"51C01AAA-3CFB-4110-BAE9-7D04CA8EE53A@comcast.net","subject":"Re: cherry picking and merge","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2014-08-01T20:02:01Z","receivedAt":"2014-08-01T20:02:01Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi Mike,\n\nMike Stump wrote:\n\n> Cherry picking doesn’t work as well as it should.  I was testing on\n> git version 1.7.9.5.\n>\n> Put in a line in a file, call it:\n>\n> first version\n>\n> then cherry pick this into your branch. Then update on master and\n> transform that into:\n>\n> second version\n>\n> then, merge that branch back to master.  Death in the form of conflicts.\n\nDo you mean that \"git merge\" should be aware of what changes you have\nalready cherry-picked?\n\nIt isn't, and that's deliberate (\"git merge\" is designed to be simple\nas possible, though no more simple than that).  This way, if on a side\nbranch someone makes a change that would conflict with \"master\" and\nthen backs it out, then the branch can still merge cleanly.\n\nGenerally people do one of the following:\n\n * Use a merge-centric workflow.  Don't cherry-pick \"forward\" but\n   merge instead.  (Do use cherry-pick for backports when you forgot\n   to commit a fix on top of the oldest supported branch that would\n   need it.)  The gitworkflows(7) manpage has more details on how\n   this works.\n\n * Use a cherry-pick-centric workflow.  Never merge.  Notice when\n   you're trying to apply a patch you already applied and skip it.\n   (Others in the thread have covered this workflow a little.)\n\nEven in those workflows, it's possible to have conflicts due to\ngenuinely conflicting changes, even with no cherry-pick involved.  I\nfind the '[merge] conflictstyle = diff3' setting (see git-config(1))\nand git-rerere(1) to be helpful in making that less painful.\n\nHope that helps,\nJonathan\n"},{"id":"247134","messageId":"53DBF4C9.2090905@vilain.net","threadId":"37269","inReplyTo":"5AF18A76-DD3B-4B9A-BF70-EFE4BB852C3D@comcast.net","subject":"Re: cherry picking and merge","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2014-08-01T20:12:57Z","receivedAt":"2014-08-01T20:12:57Z","isPatch":false,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"On 08/01/2014 10:48 AM, Mike Stump wrote:\n>> There is also git-imerge, third party tool that is intended to help\n>> merging changes (and make it possible to do it in incremental way).\n> Then remove git merge and replace it with git-imerge.  :-)  Anyway, I read that, and I can see some beauty of that that might be nice in complex merges.  The problem is, I want git merge to work.\n\n\nGit merge has a notion of discrete \"merge strategies\".  The default,\n\"recursive\" merge strategy isn't completely oblivious to history; in the\nevent that the two branches don't have a single merge bases, it performs\n3-way merges (strangely enough) recursively, with the merge bases of the\nbranch you're trying to merge until it completes.  In general, this\nworks pretty well.  Some systems even simpler than that (eg, github's\ngreen merge button) work acceptably as well.\n\nThere's no particular reason that you couldn't implement a merge\nstrategy which works more like SVN's approach, which essentially does an\ninternal rebase and then commits the result.  The advantages of a rebase\nin this situation is that you get to eliminate changes which don't need\nto be applied, either because (in SVN's case), it had some\nmetadata/hearsay information that told it that it could skip that\nchange, or (in git's case), because it found content/facts that the\nchange already was applied on one side.\n\nHowever, there are corresponding disadvantages to this strategy.  It's\njust as easy to contrive a situation where this \"internal rebasing\"\ndoesn't do the right thing, even without cheating by getting the\nmetadata wrong.  And besides, there's already a way to do this: do an\nactual rebase.  You could also do a rebase, and then if, say, the\noriginal branch you're rebasing is published and you don't want to\nrewrite, then you can easily enough use squash merging, merge -s ours,\netc to make it look like the strategy you wanted was a built-in git\nmerge strategy.  Or, in the spirit of open source, you could contribute\nthe code required to make 'imerge' a built-in strategy.\n\n> I was curious if svn handles this better the same or worse, and it did it just fine.  I know that a while ago, svn could not handle this, it would do what git does currently.  Apparently they figured out it was a bug and fixed it.  Have you guys figured out it is a bug yet?  The first step in solving a problem, is admitting you have a problem.\n\nSo, I have to chuckle when I read this indignant comment.  There's a\nfunny story to the \"while ago\" you refer to.  This refers to the time\nperiod during which SVN was relevant; about versions 1.4 and earlier\n(being generous).  Back in those days, SVN projects for the most part\navoided merging, because it was so problematic and not tracked at all. \nAs one core SVN developer said to me, they found \"teams collaborate more\nclosely if they're all working on the same branch\".  Sure, you could do\nit, and I even know of a few communities who did, but by and large, it\nwas avoided.  Then, the new wave of version control systems including\nGit, bzr and Mercurial were cropping up, and their merges were actually\ngood enough that you could practically use them.\n\nThe SVN core team had to keep pace to match.  So, in 1.5 the \"merge\ntracking\" system, previously only supplied as a \"contrib\" script, became\ncore.  This is ironic, because the version control system which SVN\nimitated poorly--Perforce--had a very sophisticated, if\nover-complicated, merge tracking system which was also based on\nmetadata.  Per-branch, per-patch, per-file entries for whether or not a\npatch had been \"integrated\" into the target branch.  I can only guess\nthat the reason they didn't implement this in the original SVN version\nwas that it was something of a pain point for users in Perforce. \nPossibly something to do with the way that Perforce would store double\nentries for each merge (yes: two rows in a relational store, one\nrepresenting the mirror image of the other), and differentiated between\nmany different forms of \"integrated\" (ie, 2 rows and 4 states instead\nof, say, a single bit).  So the underlying data model wasn't as simple\nas it could have been, and this was reflected in the difficult to use\ncommand-line tools.  Plus, they were using BerkeleyDB for metadata\ninstead of the relational ISAM library, and debugging a rabbit's nest of\nmerge record as Perforce used would have been a nightmare.  They didn't\ngo there.  And besides, they found that often, detecting patches as\nalready applied based on content, like 'patch' did, worked.\n\nPrior to 1.5, the Perl community developed SVK, an offline version of\nSVN, and this had a far simpler model for merge tracking, more similar\nto git's: just tracking whole-branch merges rather than individual\nfiles, patches, and branches.  SVN eventually added two separate ways of\ntracking merges: either a per-file, per-branch, per-commit or a\nper-branch, per-commit model.\n\nAnyway, I'm not sure where I'm going with this, but I guess a little\nextra perspective would be useful!\n\nSam\n"},{"id":"247137","messageId":"20140801205040.GT12427@google.com","threadId":"37269","inReplyTo":"20140801200201.GS12427@google.com","subject":"Re: cherry picking and merge","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2014-08-01T20:50:40Z","receivedAt":"2014-08-01T20:50:40Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Jonathan Nieder wrote:\n\n> Do you mean that \"git merge\" should be aware of what changes you have\n> already cherry-picked?\n>\n> It isn't, and that's deliberate\n\nThat said, when today's \"git merge\" fails to resolve conflicts, it's\neasily possible that we could do better at resolving the merge by\nwalking through both sides and understanding what happened.\n\nThe detailed history lets you\n\n   i) Present conflicts in an easier to resolve way.\n\n      \"Patch #1 which tries to do X conflicted with patch #2 which\n      tries to do Y; please reconcile them\" can be less painful to\n      deal with than \"Something in this pile conflicted with something\n      in that pile\".\n\n  ii) Break a seeming conflict into pieces that can be automatically\n      resolved more easily.\n\n      X vs X'+Y may conflict where X' is a cherry-pick of X, if X and\n      Y touch the same code.  Meanwhile if we're lucky then X vs X'\n      will not conflict because they make the same change, and Y can\n      apply on top.\n\n iii) Handle cherry-picked changes in a *different* way.  For example,\n      if patch X was applied on one side and applied and then reverted\n      on the other side, this could show up as a conflict.  After all,\n      the two sides don't agree on whether patch X is a good change or\n      not.\n\nThese features have corresponding downsides:\n\n   i') (Speaking from experience of using git-imerge) Too many tiny\n       conflicts can sometimes be more painful to resolve than all the\n       conflicts at once.  When X, Y, Z, and W had various conflicts,\n       how to reconcile X and Y alone or Z and W alone are academic\n       questions that don't actually need to be answered to produce\n       the merge result.\n\n  ii') This kind of clean, broken-down merge can produce a \"clean\"\n       but wrong result.\n\n       For example, if the following sequence of events occured:\n\n         1. Build fancy new feature X on \"master\".\n\n\t 2. Cherry-pick X to the bugfixes-only branch \"maint\".\n\t    Whoops.\n\t 3. Correct the mistake: revert X on \"maint\".  Now \"maint\"\n\t    is bugfixes-only again!\n\n\t 4. Merge \"maint\" to \"master\".\n\n       Then a naive, 3-way merge will notice there is no change\n       on \"maint\" since it was last merged to master and the\n       merge will bring in no change (good).\n\n       And on the other hand a one-patch-at-a-time merge would\n       try to apply X (with no effect, since it's already applied)\n       and then try to apply the revert of X.  The net effect would\n       be to revert X from \"master\" (bad)!\n\n iii') See (ii').\n\ngit-imerge from https://github.com/mhagger/git-imerge can help with\n(i) and (ii) but not (iii).\n\nHoping that clarifies,\nJonathan\n"},{"id":"247138","messageId":"CAK3OfOhbJJqLB4yPbuJyufytxNUSBLzKF6axc4jeU7eAjvXtgA@mail.gmail.com","threadId":"37269","inReplyTo":"20140801205040.GT12427@google.com","subject":"Re: cherry picking and merge","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-01T20:55:23Z","receivedAt":"2014-08-01T20:55:23Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Fri, Aug 1, 2014 at 3:50 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Jonathan Nieder wrote:\n>\n>> Do you mean that \"git merge\" should be aware of what changes you have\n>> already cherry-picked?\n>>\n>> It isn't, and that's deliberate\n>\n> That said, when today's \"git merge\" fails to resolve conflicts, it's\n> easily possible that we could do better at resolving the merge by\n> walking through both sides and understanding what happened.\n\nIt would help if cherry-pick history where recorded somewhere (beyond\nthe reflog)...\n\nCherry-picks should record two parents, like merges.\n\n(Of course, it does no good to know about an unreachable parent, when\na commit with two parents is pushed to a repo that doesn't have one of\nthose parents, which can happen when topic branches aren't pushed\nupstream.)\n\nNico\n--\n"},{"id":"247141","messageId":"xmqq4mxvvqan.fsf@gitster.dls.corp.google.com","threadId":"37269","inReplyTo":"CAK3OfOhbJJqLB4yPbuJyufytxNUSBLzKF6axc4jeU7eAjvXtgA@mail.gmail.com","subject":"Re: cherry picking and merge","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-08-01T21:44:00Z","receivedAt":"2014-08-01T21:44:00Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nico Williams <nico@cryptonector.com> writes:\n\n> Cherry-picks should record two parents, like merges.\n\nNo.\n\nIt is OK to record where it came from, and we let you do so with the\n\"-x\" option.\n\nBut the \"where it came from\" commit is very different from being\nparent, which implies \"all the history behind it\".  The whole point\nof a cherry-pick is that you do not want to grab the changes behind\nthe commit you are cherry-picking and you want the _change_ the\ncherry-picked commit (and that commit alone) brings in.  It should\nnever record \"two parents, like merges.\"\n"},{"id":"247142","messageId":"CAK3OfOiLRpz7n7rCQZ7ixahoQyt=xywnDewtc+KCT_5LhYEC7A@mail.gmail.com","threadId":"37269","inReplyTo":"xmqq4mxvvqan.fsf@gitster.dls.corp.google.com","subject":"Re: cherry picking and merge","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-01T22:00:49Z","receivedAt":"2014-08-01T22:00:49Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Fri, Aug 1, 2014 at 4:44 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nico Williams <nico@cryptonector.com> writes:\n>\n>> Cherry-picks should record two parents, like merges.\n>\n> No.\n>\n> It is OK to record where it came from, and we let you do so with the\n> \"-x\" option.\n>\n> But the \"where it came from\" commit is very different from being\n> parent, which implies \"all the history behind it\".  The whole point\n> of a cherry-pick is that you do not want to grab the changes behind\n> the commit you are cherry-picking and you want the _change_ the\n> cherry-picked commit (and that commit alone) brings in.  It should\n> never record \"two parents, like merges.\"\n\nI didn't mean to imply all that.  s/parent/where it came from/, but -x\nedits the commit message, not the metadata...\n\nThe point remains: to do what the OP wants git merge would have to be\nable to notice that a given commit was cherry-picked from the other\nbranch, and what commit it was on that other branch, and right now the\nonly place where that information is available is in the reflog.\nRecording that metadata somewhere in the commit resulting from the\ncherry-pick would be better.\n\nNico\n--\n"},{"id":"247144","messageId":"xmqqtx5vuajz.fsf@gitster.dls.corp.google.com","threadId":"37269","inReplyTo":"CAK3OfOiLRpz7n7rCQZ7ixahoQyt=xywnDewtc+KCT_5LhYEC7A@mail.gmail.com","subject":"Re: cherry picking and merge","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-08-01T22:09:20Z","receivedAt":"2014-08-01T22:09:20Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nico Williams <nico@cryptonector.com> writes:\n\n> branch, and what commit it was on that other branch, and right now the\n> only place where that information is available is in the reflog.\n\n... or the line in \"-x\".\n\nWe do not add random unstructured cruft in the commit object\nheader.  Check the list archive.\n"},{"id":"247146","messageId":"FC00A4BB-6CB9-421D-83D6-4E1AFBB4CB3C@comcast.net","threadId":"37269","inReplyTo":"4EA0D79811C348C6893039D315E6E190@PhilipOakley","subject":"Re: cherry picking and merge","fromName":"Mike Stump","fromEmail":"mikestump@comcast.net","sentAt":"2014-08-01T22:10:35Z","receivedAt":"2014-08-01T22:10:35Z","isPatch":false,"sender":{"key":"mikestump@comcast.net","avatar":null},"body":"On Aug 1, 2014, at 11:57 AM, Philip Oakley <philipoakley@iee.org> wrote:\n> But that goes both ways, and is a philosophical issue about what is to be expected in various cases.\n\nThe problem is, users expect merge to merge.  There isn’t a user that expects it to scramble the source code, because the command is called merge, not scramble.  That word has semantics that were not invented by your project.  You cannot change the semantic of the word.  Merge has a nice mathematical definition.  Merge branch into master means, place into into master the work from that branch.  git already does this 99% correct, it is missing one corner case.\n\nThis is not a philosophical issue.  It is a definitional one.\n\n> For some central control use styles, the ideas behind _distributed_ version control are anathema and (Git) just grinds away at the policies that are expected.\n\nThis is irrelevant to the issue at hand.\n\n> That said, Git doesn't claim to be perfect\n\nAgain, irrelevant.\n\n> (and can't because\n\nDo you mean, and can’t be?  If so, you are wrong in the case at hand.  svn is an existence proof that you are wrong.\n\n> of the 'relativity' that comes with being distributed - truth has to give way to a web of trust). Also the artefacts that Git validates are at a different level of abstraction i.e. the whole project as a commit, rather than just a few/one file at a time.\n\nAh, so that gives me an idea.  [ pause ] If we try the cherry-pick as retroactively creating a feature branch, cherrying into that, then merge unconditionally so that no change happens that into trunk (thus killing those conflicts), and then git merge that feature branch into branch then it all works perfectly.  See, another existence proof that you are wrong, this time with git itself.\n\nIt was 13 lines of code, so, apparently, it is possible and easy to do, in git.  Now, we just want the cherry-pick to create a temporary cherry branch, cherry the pick into it, merge and drop into trunk and merge into branch…\n\nI tested with the below and it worked just fine.  Things to clean up, we want the meta data on the cherry on the merge commit, but, you get the idea.\n\nbranch=b\nmaster=master\nbase=$(git merge-base $branch $master)\ncherry=\"$1\"\n\ngit checkout -b cherry-$branch $base\ngit cherry-pick \"$cherry\"\ngit checkout $master\ngit merge -s ours cherry-$branch\ngit checkout $branch\ngit merge cherry-$branch\ngit branch -d cherry-$branch\ngit cherry-pick --strategy=ours --allow-empty \"$cherry\"\ngit commit --allow-empty\n\nI tested that with two cherries with further changes on master to ensure that it works for more than a single one, no problem.  Wow, even tried a merge of master back into b, and it worked just fine, no conflicts, yet, all the code was jammed up together nicely.\n\nSo, if you wish to continue your position, please explain why it can’t get this better, given the existence proof above of it working better in git.\n\n> In your example (when generalized)\n\nI’m not interested in other bugs that I didn’t state, in this email.  I don’t care about those.  Please don’t detract from fixing this issue, because you can identify other things that might not be perfect.  We attain perfection one step at a time.\n\n> the problem is deciding when, in the change sequence, the cherry pick is to be backed out, especially if there are conflicts in the change sequence that would need fixing anyway, and in a long change sequence that would be a lot of conflict fix-ups, hence the current choice of getting the merge conflicts all resolved in the one go.\n\nI have two possible conflict fixups in the above.  In my case (I have a specific patch in gcc-land i wanted to cherry), those fixups were trivial (no conflicts).  When they are trivial, I don’t care much that there were two of them.  When non-trivial, well, I’m resigned to the idea that I have to explain what is going on.\n\n> Selecting a compatible workflow is a problem of usage,\n\nNot when the workflow is mandated on you to work around trivial little bugs that can be fixed but for which the author’s don't even comprehend the bug.\n\n> rather than a problem in Git.\n"},{"id":"247145","messageId":"615C1C6F-4FE0-4A83-8DE6-837386D88A15@comcast.net","threadId":"37269","inReplyTo":"CAK3OfOipw+Tg4PF5HAr8tb204vt17EVn46Lm9VMuHW1299yP8A@mail.gmail.com","subject":"Re: cherry picking and merge","fromName":"Mike Stump","fromEmail":"mikestump@comcast.net","sentAt":"2014-08-01T22:13:33Z","receivedAt":"2014-08-01T22:13:33Z","isPatch":false,"sender":{"key":"mikestump@comcast.net","avatar":null},"body":"On Aug 1, 2014, at 12:22 PM, Nico Williams <nico@cryptonector.com> wrote:\n> If you always rebase\n\nI can’t use rebase unless you make rebase work with multiple users and pushing pulling."},{"id":"247147","messageId":"CAK3OfOgJRD1bOjdgHao4U3xZZaVEhr=YdFGdWGR1800K5=wkGw@mail.gmail.com","threadId":"37269","inReplyTo":"615C1C6F-4FE0-4A83-8DE6-837386D88A15@comcast.net","subject":"Re: cherry picking and merge","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-01T22:19:00Z","receivedAt":"2014-08-01T22:19:00Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Fri, Aug 1, 2014 at 5:13 PM, Mike Stump <mikestump@comcast.net> wrote:\n> On Aug 1, 2014, at 12:22 PM, Nico Williams <nico@cryptonector.com> wrote:\n>> If you always rebase\n>\n> I can’t use rebase unless you make rebase work with multiple users and pushing pulling.\n\nThat works now, and I do it all the time.  Have a single repo (\"the\ntruth\"), always rebase local commits on top of the latest upstream,\nalways do fast-forward pushes.  Done.\n"},{"id":"247148","messageId":"13DDD21A-F683-4116-9E07-F0D8AEF06A66@comcast.net","threadId":"37269","inReplyTo":"CANQwDwdKbmqLSLGsiyHTfGNZGfbeNZM3TN6Zk0G5G-8twRc_JQ@mail.gmail.com","subject":"Re: cherry picking and merge","fromName":"Mike Stump","fromEmail":"mikestump@comcast.net","sentAt":"2014-08-01T22:24:05Z","receivedAt":"2014-08-01T22:24:05Z","isPatch":false,"sender":{"key":"mikestump@comcast.net","avatar":null},"body":"On Aug 1, 2014, at 12:01 PM, Jakub Narębski <jnareb@gmail.com> wrote:\n> It can work in Subversion because Subversion stores information about\n> what was merged in (and this includes cherry-picks, or whatever it is\n> named in svn) in svn:mergeinfo property. Git does not track what was\n> merged in, instead it represent the history as the graph of revisions,\n> and tracks merges (by storing that it came from two or more commits)\n> and not merged-in information.\n\nSo, as a dumb user that just wants it to work, I am unsympathetic to the `but software is hard’ excuse.  I am aware that some bugs are harder to fix than others.  svn took a long time to fix this bug, but they did.  I can wait, the only question is, will it be a week, a month, a year, or a decade.\n\n> When merging Git uses only what is being merged and its common\n> ancestor (3-point merge). It is simple, and simple works!!!\n\nI gave a solution for git using branches and it works just fine.  It retains the simple 3-point merge as well.\n\n> Unfortunately, it does not see cherry-picked commits - it is invisible\n> to merge as being on the chain from one of merged commits to the\n> common ancestor.\n\nIm the solution that I sketched in my previous email, that information is then exposed so that the right merge happens.\n\n> The rebase command handles\n\nI can’t use rebase as it is unfriendly to coworkers.\n\n> cherry-picked commits by detecting that the\n> change was already applied. I think that git-imerge does the same (but\n> I have not used it myself).\n> \n> Have you tried git-imerge?\n\nNo, not yet.  I’m not as interested in using it, as I would like git itself to just work."},{"id":"247151","messageId":"05976673-8F8A-41FE-81C3-606CAA45BC52@comcast.net","threadId":"37269","inReplyTo":"20140801200201.GS12427@google.com","subject":"Re: cherry picking and merge","fromName":"Mike Stump","fromEmail":"mikestump@comcast.net","sentAt":"2014-08-01T22:35:28Z","receivedAt":"2014-08-01T22:35:28Z","isPatch":false,"sender":{"key":"mikestump@comcast.net","avatar":null},"body":"On Aug 1, 2014, at 1:02 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> \n> Do you mean that \"git merge\" should be aware of what changes you have\n> already cherry-picked?\n\nYes, it amounts to that.\n\n> It isn't, and that's deliberate\n\nDeliberate bugs are still bugs.  In time, users will either wear you down until you fix it, or they will move on to other systems that work better.\n\n> (\"git merge\" is designed to be simple as possible, though no more simple than that).\n\nI sketched a solution that retains a simple git merge…\n\n> This way, if on a side branch someone makes a change that would conflict with \"master\" and\n> then backs it out, then the branch can still merge cleanly.\n\nYeah, my solution doesn’t impinge upon that working nicely.  In it, I make cherry use scratch branches to record meta information so that the existing git merge just works.  git cherry is free to do the same.  Having a git cherry that fully interoperates with git merge, is a feature.\n\n> Even in those workflows, it's possible to have conflicts due to\n\n> genuinely conflicting changes, even with no cherry-pick involved.  I\n> find the '[merge] conflictstyle = diff3' setting (see git-config(1))\n> and git-rerere(1) to be helpful in making that less painful.\n\nI think those two should be the default, but it is easy enough to turn them on that it doesn’t matter much.  In my environment, I have both on."},{"id":"247153","messageId":"20140801224227.GU12427@google.com","threadId":"37269","inReplyTo":"05976673-8F8A-41FE-81C3-606CAA45BC52@comcast.net","subject":"Re: cherry picking and merge","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2014-08-01T22:42:27Z","receivedAt":"2014-08-01T22:42:27Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Mike Stump wrote:\n> On Aug 1, 2014, at 1:02 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n\n>> It isn't, and that's deliberate\n>\n> Deliberate bugs are still bugs.\n\nYes, you and I disagree about what the behavior should be.\n\nI actively prefer the current behavior over the one you proposed,\nunless I'm misunderstanding the one you proposed.  As I understand it,\nthere would be no way to undo the mistake of cherry-picking a change\nthat didn't belong on \"maint\".\n\nYou said that 3-way merge doesn't fit your idea of what a merge is.\nIt does fit mine.\n\nI'm even slightly against there being an option for the 'git cherry'\nbased thing.  I think it would be a support burden.  But if someone\nelse wants to do the work of implementing it, I wouldn't stop them\n(and would instead just help make sure the documentation is crystal\nclear).\n\nHoping that clarifies,\nJonathan\n"},{"id":"247154","messageId":"4E372CD5-33CA-4AF5-8647-F6BBC64BABA8@comcast.net","threadId":"37269","inReplyTo":"53DBF4C9.2090905@vilain.net","subject":"Re: cherry picking and merge","fromName":"Mike Stump","fromEmail":"mikestump@comcast.net","sentAt":"2014-08-01T23:06:10Z","receivedAt":"2014-08-01T23:06:10Z","isPatch":false,"sender":{"key":"mikestump@comcast.net","avatar":null},"body":"On Aug 1, 2014, at 1:12 PM, Sam Vilain <sam@vilain.net> wrote:\n> Git merge has a notion of discrete \"merge strategies”.\n\n> There's no particular reason that you couldn't implement a merge\n> strategy which works more like SVN's approach, which essentially does an\n> internal rebase and then commits the result.\n\nWell, being a simple user, wanting to do a simple thing, I want the default strategy to just work.  The expert that wants it to work faster, but less well, well, they can use a merge -s faster, or cherry-pick -s faster.\n\n> However, there are corresponding disadvantages to this strategy.  It's\n> just as easy to contrive a situation where this \"internal rebasing\"\n> doesn't do the right thing, even without cheating by getting the\n> metadata wrong.\n\nI sketched a solution using branches…  A large portion of the failures that happen when a cherry is remerged are gone.  I feel that benefit easily swamps the problem you sketched.\n\n> And besides, there's already a way to do this: do an actual rebase.\n\nOne problem is that rebase doesn’t work with co-workers nicely…  The other is that it isn’t spelled merge.  I am a simple user.\n\n>> I was curious if svn handles this better the same or worse, and it did it just fine.  I know that a while ago, svn could not handle this, it would do what git does currently.  Apparently they figured out it was a bug and fixed it.  Have you guys figured out it is a bug yet?  The first step in solving a problem, is admitting you have a problem.\n> \n> So, I have to chuckle when I read this indignant comment.\n\n:-)  Yeah, a chuckle, good.  Actually, no anger is involved.  I’d just like for git to work better in this regard."},{"id":"247157","messageId":"CAK3OfOiG8kzKYRUGZJW90t-DyjWf775MfMDxzin0gw94ATS7nw@mail.gmail.com","threadId":"37269","inReplyTo":"4E372CD5-33CA-4AF5-8647-F6BBC64BABA8@comcast.net","subject":"Re: cherry picking and merge","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-01T23:40:58Z","receivedAt":"2014-08-01T23:40:58Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Fri, Aug 1, 2014 at 6:06 PM, Mike Stump <mikestump@comcast.net> wrote:\n> On Aug 1, 2014, at 1:12 PM, Sam Vilain <sam@vilain.net> wrote:\n>> Git merge has a notion of discrete \"merge strategies”.\n>\n>> There's no particular reason that you couldn't implement a merge\n>> strategy which works more like SVN's approach, which essentially does an\n>> internal rebase and then commits the result.\n>\n> Well, being a simple user, wanting to do a simple thing, I want the default strategy to just work.  [...]\n\nDifferent users want different defaults.  You can't always have the\none you want.\n\nAs for rebase, I still don't understand why it doesn't work for you.\nYou didn't really explain.  Suppose we're right and it's the right\nsolution for you, then you might be ecstatic, but you gotta try it\nfirst.\n\nMy workflow is rebase-heavy.  It's long been so, and it was so before\ngit happened.  The only case where I can imagine not using a\nrebase-heavy workflow is where I have to track multiple forked\nupstreams and so I want to merge each into my branch.\n\nIf tracking multiple forked upstreams is not your case and yet rebase\ncan't work for you then I'd like to understand why.  Please help me\nunderstand your use case.  OTOH, if your use case is amenable to\nrebase, then I highly recommend that you try it.\n\n(I find that many users are allergic to rebasing.  Many people have\ntold me that rebase is lying, that history must be immutable, and so\non, all ignoring that: git users don't rebase published branches, and\nthat other VCSes tend to squash (therefore lose) history anyways when\npushing merges upstream.  But this all seems theological rather than\nrational.  It's true that I dislike merge commits, but that's a\ndifferent story; I'm not allergic to merging after all.)\n\nNico\n--\n"},{"id":"247159","messageId":"5EEA8572-291D-4D8C-A38A-E09E24E81A77@comcast.net","threadId":"37269","inReplyTo":"20140801205040.GT12427@google.com","subject":"Re: cherry picking and merge","fromName":"Mike Stump","fromEmail":"mikestump@comcast.net","sentAt":"2014-08-01T23:47:14Z","receivedAt":"2014-08-01T23:47:14Z","isPatch":false,"sender":{"key":"mikestump@comcast.net","avatar":null},"body":"On Aug 1, 2014, at 1:50 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> \n>       And on the other hand a one-patch-at-a-time merge would\n>       try to apply X (with no effect, since it's already applied)\n>       and then try to apply the revert of X.  The net effect would\n>       be to revert X from \"master\" (bad)!\n\nYeah, I appreciate that.  I know the type of user that would do that, and I understand why you would want to do that and even do that by default.\n\nHowever, as an expert user, I don’t need that particular type of hand holding given the cost of more conflicts and would like an option to let me to choose to have fewer conflicts when merging."},{"id":"247163","messageId":"BLU436-SMTP260FDB8DC4B2AC1F9132D10D1E40@phx.gbl","threadId":"37269","inReplyTo":"CAK3OfOiG8kzKYRUGZJW90t-DyjWf775MfMDxzin0gw94ATS7nw@mail.gmail.com","subject":"Re: cherry picking and merge","fromName":"Alex Davidson","fromEmail":"descenterace@hotmail.com","sentAt":"2014-08-02T00:18:11Z","receivedAt":"2014-08-02T00:18:11Z","isPatch":false,"sender":{"key":"descenterace@hotmail.com","avatar":null},"body":"On Fri, 2014-08-01 at 18:40 -0500, Nico Williams wrote:\n> On Fri, Aug 1, 2014 at 6:06 PM, Mike Stump <mikestump@comcast.net> wrote:\n> > On Aug 1, 2014, at 1:12 PM, Sam Vilain <sam@vilain.net> wrote:\n> >> Git merge has a notion of discrete \"merge strategies”.\n> >\n> >> There's no particular reason that you couldn't implement a merge\n> >> strategy which works more like SVN's approach, which essentially does an\n> >> internal rebase and then commits the result.\n> >\n> > Well, being a simple user, wanting to do a simple thing, I want the default strategy to just work.  [...]\n> \n> Different users want different defaults.  You can't always have the\n> one you want.\n\nOr to put it another way: one man's bug is another man's feature.\n\n> \n> As for rebase, I still don't understand why it doesn't work for you.\n> You didn't really explain.  Suppose we're right and it's the right\n> solution for you, then you might be ecstatic, but you gotta try it\n> first.\n> ...\n> Nico\n> --\n\nData point:\n\nWe've been using a rebase-centric workflow for a while at my current\nemployer. It's simple and generally straightforward for new development\non master.\n\nHowever we need to maintain multiple 'released' version branches which\nreceive hotfixes and (sadly) features from later development, and merges\nmake it much easier to visualise which releases have received specific\nfixes/shinies than cherry-picks do.\n\nIn a hybrid merge/rebase workflow it is convenient to have the option of\nmerges which yield rebase-like output. We have seen awkward merges\noutside of master, but I mostly see that as an indication that we\nshouldn't be mixing workflows so much, ie. hotfixing one thing with a\ncherry-pick and another with a merge (usually only happens when the\nbranch predates our use of merges).\n\nTL;DR: The option of a rebase-like merge would be a nice feature, but\nthe default system does not seem so onerous.\n\nAlex\n"},{"id":"247167","messageId":"FAC83E31AC1645EB83068122320F35AE@PhilipOakley","threadId":"37269","inReplyTo":"FC00A4BB-6CB9-421D-83D6-4E1AFBB4CB3C@comcast.net","subject":"Re: cherry picking and merge","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":"2014-08-02T10:39:08Z","receivedAt":"2014-08-02T10:39:08Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Mike Stump\" <mikestump@comcast.net>\nSent: Friday, August 01, 2014 11:10 PM\n> On Aug 1, 2014, at 11:57 AM, Philip Oakley <philipoakley@iee.org> \n> wrote:\n>> But that goes both ways, and is a philosophical issue about what is \n>> to be expected in various cases.\n>\n> The problem is, users expect merge to merge.  There isn’t a user that \n> expects it to scramble the source code, because the command is called \n> merge, not scramble.\n\nUnfortunately we are back at the problem af what 'merge' means. Git uses \na snapshot model, while most other version control systems uses a \nchangeset model (which has been used since before the Titanic was built \nfor various reasons [1]) for their storage. Thus most VCS users see \nmerge as the addition of a delta \"A + delta -> B\", while Git sees merge \nas the union of snapshots \"A + G -> Q\".\n\nThe cherry-pick and rebase methods determine the change deltas between \nadjacent snaphots (i.e. patches) and then apply that to a different \nsnapshot. In those cases we are not merging snapshots, rather applying \npatches (note my changed use of 'merge').\n\n>That word has semantics that were not invented by your project.  You \n>cannot change the semantic of the word.  Merge has a nice mathematical \n>definition.  Merge branch into master means, place into into master the \n>work from that branch.  git already does this 99% correct, it is \n>missing one corner case.\n>\n> This is not a philosophical issue.  It is a definitional one.\n>\n>> For some central control use styles, the ideas behind _distributed_ \n>> version control are anathema and (Git) just grinds away at the \n>> policies that are expected.\n>\n> This is irrelevant to the issue at hand.\n>\n>> That said, Git doesn't claim to be perfect\n>\n> Again, irrelevant.\n>\n>> (and can't because\n>\n> Do you mean, and can’t be?  If so, you are wrong in the case at hand. \n> svn is an existence proof that you are wrong.\n>\n>> of the 'relativity' that comes with being distributed - truth has to \n>> give way to a web of trust). Also the artefacts that Git validates \n>> are at a different level of abstraction i.e. the whole project as a \n>> commit, rather than just a few/one file at a time.\n>\n<snipped remainder because of time limitations>\n\n--\nPhilip\n\n[1] Way back when blueprints really were blue, and real drawing were on \nkaolin & linen drawing sheets with indian ink, the 'master' drawings \nwere the most prized items, that if damaged would stop production, so \nthere were many layers of drawing office controls to avoid touching it \n(e.g. tracers to copy drawings) and keep the master drawings pristine.\n\nFrom that, the ideas of Change requests, Change orders, Approved changes \netc. became the norm. It was the changes that were recorded. These \nprocesses are still in place today in most engineering companies and the \nmilitary, in fact anyone with real artefacts. These techniques were \ncopied into the computing world when it was young.\n\nThe big change has been that Computing has reduced the cost of \nproduction (duplication, replication) to zero, so now the problem is in \ntrying to validate and verify which alledged copy is actually the \n'master' - especially in a fully distributed environment, such as the \nmany different Linux distributions and applications. It was into this \ngap that Git steps, with the use of the sha1 to both validate the \nhistory chain and verify any specific snapshot. It doesn't get hung up \non what the change was, that can be determined easily after the fact by \na simple diff between adjacent snapshots, though having lots of small \nchanges and crisp commit messages does help.\n\nThat's the way I view it anyway. (When I first started work, they still \nhad blue prints, but had moved to microfiche and melinex (polyester) \ndrawing sheets, and the 8088 / IBM PC was new and powerful! I still work \nin engineering where the old VC model is ubiquitous)\n"},{"id":"247168","messageId":"40F24BA38E03454A9BA152F6AFDE56C4@PhilipOakley","threadId":"37269","inReplyTo":"13DDD21A-F683-4116-9E07-F0D8AEF06A66@comcast.net","subject":"Re: cherry picking and merge","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":"2014-08-02T11:44:51Z","receivedAt":"2014-08-02T11:44:51Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Mike Stump\" <mikestump@comcast.net>\nSent: Friday, August 01, 2014 11:24 PM\n> On Aug 1, 2014, at 12:01 PM, Jakub Narębski <jnareb@gmail.com> wrote:\n>> It can work in Subversion because Subversion stores information about\n>> what was merged in (and this includes cherry-picks, or whatever it is\n>> named in svn) in svn:mergeinfo property. Git does not track what was\n>> merged in, instead it represent the history as the graph of \n>> revisions,\n>> and tracks merges (by storing that it came from two or more commits)\n>> and not merged-in information.\n>\n> So, as a dumb user that just wants it to work, I am unsympathetic to \n> the `but software is hard’ excuse.  I am aware that some bugs are \n> harder to fix than others.  svn took a long time to fix this bug, but \n> they did.  I can wait, the only question is, will it be a week, a \n> month, a year, or a decade.\n>\n>> When merging Git uses only what is being merged and its common\n>> ancestor (3-point merge). It is simple, and simple works!!!\n>\n> I gave a solution for git using branches and it works just fine.  It \n> retains the simple 3-point merge as well.\n\nAt the moment there is no formal way for Git to record within the commit \nmetadata the inclusion of the cherry-picked diff (the 'merge' of the \nfix).\n\nThinking out of the box, the issue is that the commit parents list does \nnot have a formal mechanism to allow the recording that the 'merged' \nchange was the patch change from a specific commit fom somewhere else \n(which may be missing from the local repo).\n\nPerhaps it needs a style of merging-rebase where a second (last) parent \nis added but it isn't the straight <sha1>, but says 'patch-<sha1>', such \nthat readers with the capability could check if that <sha1> history is \npresent locally, and if so if it's correct, so that you can now 'track' \nyour fixes between releases, and (hopefully) older Gits don't barf on \nthat extra 'fake' parent. Somehow I suspect that older Git's would \nbarf.. (not enough time to create and test such a fake commit)\n\n>\n>> Unfortunately, it does not see cherry-picked commits - it is \n>> invisible\n>> to merge as being on the chain from one of merged commits to the\n>> common ancestor.\n>\n> Im the solution that I sketched in my previous email, that information \n> is then exposed so that the right merge happens.\n>\n>> The rebase command handles\n>\n> I can’t use rebase as it is unfriendly to coworkers.\n>\n>> cherry-picked commits by detecting that the\n>> change was already applied. I think that git-imerge does the same \n>> (but\n>> I have not used it myself).\n>>\n>> Have you tried git-imerge?\n>\n> No, not yet.  I’m not as interested in using it, as I would like git \n> itself to just work.\n\n--\nPhilip \n"},{"id":"247175","messageId":"7CCCA1CCC7F342FA9037AAFEDCEDB53F@PhilipOakley","threadId":"37269","inReplyTo":"FC00A4BB-6CB9-421D-83D6-4E1AFBB4CB3C@comcast.net","subject":"Re: cherry picking and merge","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":"2014-08-02T16:29:31Z","receivedAt":"2014-08-02T16:29:31Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Mike Stump\" <mikestump@comcast.net>\nSent: Friday, August 01, 2014 11:10 PM\n(part 2)\n> On Aug 1, 2014, at 11:57 AM, Philip Oakley <philipoakley@iee.org> \n> wrote:\n>> For some central control use styles, the ideas behind _distributed_ \n>> version control are anathema and (Git) just grinds away at the \n>> policies that are expected.\n> ...\n>> of the 'relativity' that comes with being distributed - truth has to \n>> give way to a web of trust). Also the artefacts that Git validates \n>> are at a different level of abstraction i.e. the whole project as a \n>> commit, rather than just a few/one file at a time.\n>\n> Ah, so that gives me an idea.  [ pause ] If we try the cherry-pick as \n> retroactively creating a feature branch, cherrying into that, then \n> merge unconditionally so that no change happens that into trunk (thus \n> killing those conflicts), and then git merge that feature branch into \n> branch then it all works perfectly.  See, another existence proof that \n> you are wrong, this time with git itself.\n>\n> It was 13 lines of code, so, apparently, it is possible and easy to \n> do, in git.  Now, we just want the cherry-pick to create a temporary \n> cherry branch, cherry the pick into it, merge and drop into trunk and \n> merge into branch…\n>\n> I tested with the below and it worked just fine.  Things to clean up, \n> we want the meta data on the cherry on the merge commit, but, you get \n> the idea.\n>\n\nI've annotated some of the bits to make sure we are on the same \nwavelength as to what this does...\n\n> branch=b\n> master=master\n> base=$(git merge-base $branch $master)\n\n> cherry=\"$1\"  # not quite sure where this commit is located relative to \n> either $branch or $master\n\n>\n# create a new branch, starting at base, for our cherry picked commit\n> git checkout -b cherry-$branch $base\n> git cherry-pick \"$cherry\" # which also commits onto our cherry pick \n> barnch\n\n> git checkout $master\n> git merge -s ours cherry-$branch # \"mark/remember\" the cherry branch, \n> its fix and it's base point, but don't actualy use it here on $master\n\n> git checkout $branch\n> git merge cherry-$branch # bring the 'fix' into $branch\n\n> git branch -d cherry-$branch # remove the fix branch that started at \n> $base - branches are ephemeral anyway.\n\n# still on $branch, which already has the change merged in (Git style) ?\n> git cherry-pick --strategy=ours --allow-empty \"$cherry\" # check its \n> all already included?\n> git commit --allow-empty\n>\n\nDoes my annotation match your understanding? It wasn't clear to me where \n$1 had been hiding previously, nor why the common fix didn't use a \n\"merge -s ours cherry-$branch\" in both cases - that maybe my \nmisunderstanding about how your workflow goes.\n\n> I tested that with two cherries with further changes on master to \n> ensure that it works for more than a single one, no problem.  Wow, \n> even tried a merge of master back into b, and it worked just fine, no \n> conflicts, yet, all the code was jammed up together nicely.\n>\n> So, if you wish to continue your position, please explain why it can’t \n> get this better, given the existence proof above of it working better \n> in git.\n>\n...\n> I have two possible conflict fixups in the above.  In my case (I have \n> a specific patch in gcc-land i wanted to cherry), those fixups were \n> trivial (no conflicts).  When they are trivial, I don’t care much that \n> there were two of them.  When non-trivial, well, I’m resigned to the \n> idea that I have to explain what is going on.\n>\n>> Selecting a compatible workflow is a problem of usage,\n>\n> Not when the workflow is mandated on you to work around trivial little \n> bugs that can be fixed but for which the author’s don't even \n> comprehend the bug.\n>\n>> rather than a problem in Git.\n> --\n\n\nPhilip. \n"},{"id":"247333","messageId":"53E24D07.9010105@gmail.com","threadId":"37269","inReplyTo":"40F24BA38E03454A9BA152F6AFDE56C4@PhilipOakley","subject":"Re: cherry picking and merge","fromName":"Jakub Narębski","fromEmail":"jnareb@gmail.com","sentAt":"2014-08-06T15:43:03Z","receivedAt":"2014-08-06T15:43:03Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Philip Oakley wrote:\n> From: \"Mike Stump\" <mikestump@comcast.net>\n> Sent: Friday, August 01, 2014 11:24 PM\n>> On Aug 1, 2014, at 12:01 PM, Jakub Narębski <jnareb@gmail.com> wrote:\n\n>>> It can work in Subversion because Subversion stores information about\n>>> what was merged in (and this includes cherry-picks, or whatever it is\n>>> named in svn) in svn:mergeinfo property. Git does not track what was\n>>> merged in, instead it represent the history as the graph of revisions,\n>>> and tracks merges (by storing that it came from two or more commits)\n>>> and not merged-in information.\n>>\n>> So, as a dumb user that just wants it to work, I am unsympathetic to\n>> the `but software is hard’ excuse.  I am aware that some bugs are\n>> harder to fix than others.  svn took a long time to fix this bug, but\n>> they did.  I can wait, the only question is, will it be a week, a\n>> month, a year, or a decade.\n\nHere Git and Subversion went in different directions, and use\ndifferent mechanisms (merge tracking vs merged-on tracking).\nBoth have their advantages and disadvantages.\n\ngit-merge (in the most usual case) depends only on three revisions:\nthe revision you merge into (current branch, ours), the revision\nyou are merging (merged branch, theirs), and merge base (common\nancestor).  We could have another merge strategy that examines\ncontents of revisions to handle cherry-picks and reverts... but\nit would be more complicated, and much slower.\n\n>>> When merging Git uses only what is being merged and its common\n>>> ancestor (3-point merge). It is simple, and simple works!!!\n>>\n>> I gave a solution for git using branches and it works just fine.  It\n>> retains the simple 3-point merge as well.\n\nIt works for this simple case, but I think it has unfortunate potential\nto go silently wrong.\n\nAlso, it prevents fully removing (commits, not only refs) the branch\nyou cherry-picked from.  The commit you cherry picked may no longer\nbe (or may no longer should be) in the repository.\n\n> At the moment there is no formal way for Git to record within the commit\n> metadata the inclusion of the cherry-picked diff (the 'merge' of the fix).\n>\n> Thinking out of the box, the issue is that the commit parents list does\n> not have a formal mechanism to allow the recording that the 'merged'\n> change was the patch change from a specific commit fom somewhere else\n> (which may be missing from the local repo).\n>\n> Perhaps it needs a style of merging-rebase where a second (last) parent\n> is added but it isn't the straight <sha1>, but says 'patch-<sha1>', such\n> that readers with the capability could check if that <sha1> history is\n> present locally, and if so if it's correct, so that you can now 'track'\n> your fixes between releases, and (hopefully) older Gits don't barf on\n> that extra 'fake' parent. Somehow I suspect that older Git's would\n> barf.. (not enough time to create and test such a fake commit).\n\nSometime ago there was long discussion about adding 'weak' references\nto commit object header.\n\nBeside the problem of backward compatibility, there was also the problem\nof semantics of said reference - what does it mean?  It should work as\nwell for cherry-picks, for interactive rebase (maybe?), and for reverts\n(which are also a problem).\n\nAlso, this could be avoided by using feature branches and merging\ninstead of committing to one branch and cherry-picking to other\nbranches. Also, git-rerere is your friend... sometimes.\n\n>>> Have you tried git-imerge?\n>>\n>> No, not yet.  I’m not as interested in using it, as I would like git\n>> itself to just work.\n\nMaybe this command would make it into git proper, though probably\nnot written in Python (there was once merge strategy written in Python,\nbut currently git does not depend on Python).\n\n-- \nJakub Narębski\n"},{"id":"247337","messageId":"53E25090.7010803@gmail.com","threadId":"37269","inReplyTo":"CAK3OfOhbJJqLB4yPbuJyufytxNUSBLzKF6axc4jeU7eAjvXtgA@mail.gmail.com","subject":"Re: cherry picking and merge","fromName":"Jakub Narębski","fromEmail":"jnareb@gmail.com","sentAt":"2014-08-06T15:58:08Z","receivedAt":"2014-08-06T15:58:08Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"W dniu 2014-08-01 22:55, Nico Williams pisze:\n> On Fri, Aug 1, 2014 at 3:50 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n>> Jonathan Nieder wrote:\n>>\n>>> Do you mean that \"git merge\" should be aware of what changes you have\n>>> already cherry-picked?\n>>>\n>>> It isn't, and that's deliberate\n>>\n>> That said, when today's \"git merge\" fails to resolve conflicts, it's\n>> easily possible that we could do better at resolving the merge by\n>> walking through both sides and understanding what happened.\n>\n> It would help if cherry-pick history where recorded somewhere (beyond\n> the reflog)...\n>\n> Cherry-picks should record two parents, like merges.\n>\n> (Of course, it does no good to know about an unreachable parent, when\n> a commit with two parents is pushed to a repo that doesn't have one of\n> those parents, which can happen when topic branches aren't pushed\n> upstream.)\n\nThere was (long time ago) a long thread about idea of adding some\nkind of 'weak' references (links), 'weakparent' that can be \nautomatically used by Git but do not pollute the commit message,\nand do not affect reachability calculations.  Ultimately it went\nnowhere (as you can see) - there were many problems.\n\nFor example: how it would work for reverts and rebases?\n\n-- \nJakub Narębski\n"},{"id":"247339","messageId":"CAK3OfOj4_ttmv6gQ4zkvG1tod9rUBMvLfwvtVVbbdttqZWcECA@mail.gmail.com","threadId":"37269","inReplyTo":"53E25090.7010803@gmail.com","subject":"Re: cherry picking and merge","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-06T16:26:50Z","receivedAt":"2014-08-06T16:26:50Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Wed, Aug 6, 2014 at 10:58 AM, Jakub Narębski <jnareb@gmail.com> wrote:\n> W dniu 2014-08-01 22:55, Nico Williams pisze:\n>> It would help if cherry-pick history where recorded somewhere (beyond\n>> the reflog)...\n>>\n>> Cherry-picks should record two parents, like merges.\n>>\n>> (Of course, it does no good to know about an unreachable parent, when\n>> a commit with two parents is pushed to a repo that doesn't have one of\n>> those parents, which can happen when topic branches aren't pushed\n>> upstream.)\n>\n> There was (long time ago) a long thread about idea of adding some\n> kind of 'weak' references (links), 'weakparent' that can be automatically\n> used by Git but do not pollute the commit message,\n> and do not affect reachability calculations.  Ultimately it went\n> nowhere (as you can see) - there were many problems.\n\nMy proposal was to put this sort of ancillary history info in a\n\"branch object\" (and that branches should be objects).  This would\nhave a number of benefits, not the least of which is that at push time\nyou can drop such ancillary history without having to alter the\ncommits being pushed.\n\n> For example: how it would work for reverts and rebases?\n\nReverts upstream?  The revert should record the commit hash of the\ncommit it reverts (but file-level reverts lose), so that this could be\nnoticed.\n\nRebases upstream?  Well, that shouldn't happen, but if it does then\nyou must rebase --onto and any cherry-picks of upstream rebased\ncommits lose their ties to those (but this can be detected).\n\nIn general recording more metadata (assuming there's not privacy\nissues to consider) can't hurt.  Using it might, but having the option\nto can also help.\n\nNico\n--\n"},{"id":"247352","messageId":"B8B80DE2-EC29-48FE-862F-D7A68DE6B243@comcast.net","threadId":"37269","inReplyTo":"53E24D07.9010105@gmail.com","subject":"Re: cherry picking and merge","fromName":"Mike Stump","fromEmail":"mikestump@comcast.net","sentAt":"2014-08-06T18:41:32Z","receivedAt":"2014-08-06T18:41:32Z","isPatch":false,"sender":{"key":"mikestump@comcast.net","avatar":null},"body":"On Aug 6, 2014, at 8:43 AM, Jakub Narębski <jnareb@gmail.com> wrote:\n>>> I gave a solution for git using branches and it works just fine.  It\n>>> retains the simple 3-point merge as well.\n> \n> It works for this simple case, but I think it has unfortunate potential\n> to go silently wrong.\n\nThat just means that you want to have two commands.  One for the people that when the remove a patch, they want it gone.  The other for people that when they remove a patch, they want it to magically reappear.  I’m of the former class of individuals.  Now, I would argue that that is the wrong solution of course.  See below for uncherry-pick.\n\nNow, if I needed a solution to the one problem that was mentioned, I would then request an uncherry-pick command to undo the cherry-pick.  The semantics of it are, the patch is removed from the tree, and when merged, that patch isn’t removed from the source.  See, we then retain the useful property that everything that should work does, and the system is predictable because it then does exactly what the user said to do.  Conceptually of course, it doesn’t have anything to do with cherry, if you merge a branch accidentally, and then remove it, and merge it, I think you still wind up with the work being removed.  Conceptually, it is just an undo a change, cherry, merge, file rename, whatever.\n\nNow, why is this preferable?  Because the advanced user gets to explain what they want to git, and then git does what they want.  It also works for beginning users, it does what they ask it to do.  If you are afraid you know better what command that they really wanted to use instead of the command they are using, you can prompt them and ask, did you mean this or that?  After 20 times being asked, it would get old and then even a new user would just issue the commands they want.  I’m not in favor of that, I’d prefer that the system just do what they tell it to do.\n\n> Also, it prevents fully removing (commits, not only refs) the branch\n> you cherry-picked from.  The commit you cherry picked may no longer\n> be (or may no longer should be) in the repository.\n\nI’m picking from trunk, when it goes, I go.  :-)\n\n> Also, this could be avoided by using feature branches and merging\n> instead of committing to one branch and cherry-picking to other\n> branches.\n\nIf the problem remains unfixed, at least the documentation should be changed to say cherry will mess up merge.  If you never merge, never a problem.  For me, I would read that, and say, well, trivially, cherry isn’t for me (til they fix the bug that causes it to mess up merges).  I can’t see anything on http://git-scm.com/docs/git-cherry-pick which says it will mess up merges."},{"id":"247356","messageId":"96B703A6-58B0-458A-8A2D-699EA8F1941B@comcast.net","threadId":"37269","inReplyTo":"CAK3OfOiG8kzKYRUGZJW90t-DyjWf775MfMDxzin0gw94ATS7nw@mail.gmail.com","subject":"Re: cherry picking and merge","fromName":"Mike Stump","fromEmail":"mikestump@comcast.net","sentAt":"2014-08-06T19:11:16Z","receivedAt":"2014-08-06T19:11:16Z","isPatch":false,"sender":{"key":"mikestump@comcast.net","avatar":null},"body":"On Aug 1, 2014, at 4:40 PM, Nico Williams <nico@cryptonector.com> wrote:\n> As for rebase, I still don't understand why it doesn't work for you.\n\nhttp://git-scm.com/docs/git-rebase says:\n\n  Rebasing (or any other form of rewriting) a branch that others have based work on is a bad idea\n\nIf you read stack-overflow, you will discover a ton of people that like doing this, and they get hammered because of it.  My use case fits exactly (as near as I can tell) the hammer case.\n\nIf you make a different command that isn’t guaranteed to screw me and my co-workers over, and tell us to use that, then I’d be happy to use it.  Bet the farm that it won’t bite you, just to be bitten isn’t what I want to try and recover from.\n\n> You didn't really explain.\n\nIf you say it will never bit you and then fix all the documentation to not say it will bite you…  I’d be happy to contemplate it again.  Now, I found the stack-overflow commentary first, and all the horrors of it, and all the nuances.  I carefully read what people were doing, how what I wanted to related to what they were doing, and it sure felt like I was in the, don’t go there camp.\n\n> Suppose we're right and it's the right solution for you, then you might be ecstatic, but you gotta try it\n> first.\n\nSo, I like to know if I’m driving off a cliff, before I do.  I’m the type of person that would rather know were the road goes, and merely avoid driving off the cliff.  When stack-overflow is littered with the bodies of people that thought it would be fun, I tend to just say, that’s not for me.\n\n> The only case where I can imagine not using a\n> rebase-heavy workflow is where I have to track multiple forked\n> upstreams and so I want to merge each into my branch.\n\nSo, sounds like I fit that use case and rebase could be my friend.  How do I square what you said and:\n\n  Rebasing (or any other form of rewriting) a branch that others have based work on is a bad idea\n\n?\n\nI want all old refs in old emails to work.  I want all refs in bugzilla to work.  I want to see the original dates of all the work.  I want git blame to report those artifacts in email and bugzilla.  I have coworkers that I push to, pull from (through a single sharing point, we call the master tree).  We work on gcc, we pull git gcc down to a local copy, then merge it into our tree.  I want to cherry pick changes from upstream.  I do work and push to our master, I pull work of coworkers from the master, my coworkers do the same.  Isn’t this the canonical open source use case?\n\n> (I find that many users are allergic to rebasing.  Many people have\n> told me that rebase is lying, that history must be immutable, and so\n> on, all ignoring that: git users don't rebase published branches,\n\nSo, when I push, and someone else pulls, is that published?  I thought it was."},{"id":"247358","messageId":"20140806194457.GD23449@localhost","threadId":"37269","inReplyTo":"96B703A6-58B0-458A-8A2D-699EA8F1941B@comcast.net","subject":"Rebase safely (Re: cherry picking and merge)","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-06T19:44:59Z","receivedAt":"2014-08-06T19:44:59Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Wed, Aug 06, 2014 at 12:11:16PM -0700, Mike Stump wrote:\n> On Aug 1, 2014, at 4:40 PM, Nico Williams <nico@cryptonector.com> wrote:\n> > As for rebase, I still don't understand why it doesn't work for you.\n> \n> http://git-scm.com/docs/git-rebase says:\n> \n>   Rebasing (or any other form of rewriting) a branch that others have\n>   based work on is a bad idea\n> \n> If you read stack-overflow, you will discover a ton of people that\n> like doing this, and they get hammered because of it.  My use case\n> fits exactly (as near as I can tell) the hammer case.\n\nIt's not a good idea to rebase a branch in a repo that others pull from.\n\nThere's nothing wrong with rebasing your patches on that same branch in\nyour clone as long as the end result is a fast forward merge when you\npush.\n\n    $ git clone https://..../blah\n    $ cd blah\n    $ <do some work>\n    $ git commit ...\n    $ git fetch origin\n--->$ git rebase origin/master\n    $ git push origin master\n\nThere's NOTHING wrong with that rebase.  It's perfectly safe because\nit's only in your *private* clone.\n\n(If later you publish that clone and expect people to track your master\nbranch, then rebase becomes problematic, but that's not something most\npeople ever do with their clones.)\n\nThe only use-case I've seen where a rebase-based workflow doesn't work\nis where you have multiple upstreams that you're following.  I.e., the\nupstream forked and you want to take some commits from one, some from\nthe other, or otherwise keep a merge of both.\n\n(Also, if an upstream is ever rebased you can usually recover on the\ndownstream side by rebasing with the --onto option, so it's not the end\nof the world.)\n\n> Now, I found the stack-overflow commentary first, and all the horrors\n> of it, and all the nuances.  I carefully read what people were doing,\n> how what I wanted to related to what they were doing, and it sure felt\n> like I was in the, don’t go there camp.\n\nA lot of people rant about rebase.  They're wrong.  They've distorted\nyour perspective.\n\n> So, I like to know if I’m driving off a cliff, before I do.  I’m the\n> [...]\n\nThere's just two simple rules to follow and you'll be safe:\n\n1) NEVER git push -f (--force) to a \"published\" repo/branch.\n\n   The upstream should enforce this with a receive hook.\n\n2) NEVER work directly in a published repo.  Instead work in a private\n   clone.  To help make sure of this, never publish a non-bare repo\n   (bare == has no workspace; non-bare == has a workspace).\n\nIf you ever do a rebase that produces results you're unhappy with you\ncan undo that rebase like so:\n\n - use git reflog to find the branch's previous HEAD commit\n - reset the branch to point to that commit\n\nIt really helps to think of git as a pile of commits arranged in a\nMerkle has tree.  Branches and tags are just symbolic names for specific\ncommits.  Rebase builds a new line of commits in the tree then it\nchanges the symbolic branch name's HEAD to point to the head of that new\nline of commits, BUT NOTHING IS LOST in the pile of commits that is the\nrepo, not until you git-prune(1) to remove commits not reachable from\nsymbolic names (branches and tags).\n\n> > The only case where I can imagine not using a\n> > rebase-heavy workflow is where I have to track multiple forked\n> > upstreams and so I want to merge each into my branch.\n> \n> So, sounds like I fit that use case and rebase could be my friend.\n\nExcellent.\n\n> How do I square what you said and:\n> \n>   Rebasing (or any other form of rewriting) a branch that others have\n>   based work on is a bad idea\n> \n> ?\n\nSee above.\n\n> I want all old refs in old emails to work.  I want all refs in\n\nThey will if you stick to the two rules I mention above.\n\n> bugzilla to work.  I want to see the original dates of all the work.\n\nDitto.\n\n> I want git blame to report those artifacts in email and bugzilla.  I\n> have coworkers that I push to, pull from (through a single sharing\n> point, we call the master tree).  We work on gcc, we pull git gcc down\n> to a local copy, then merge it into our tree.  I want to cherry pick\n> changes from upstream.  I do work and push to our master, I pull work\n> of coworkers from the master, my coworkers do the same.  Isn’t this\n> the canonical open source use case?\n\nThat means that you have/maintain an intermediate upstream, yes?\n\nThis is a bit trickier since once in a while that intermediate upstream\nand everyone downstream of it has to catch up with the real upstream.\n\nHere you have two options:\n\n - the intermediate diverges from the real upstream, and then you\n   merge/cherry-pick from the upstream as needed\n   \n   The intermediate's maintainer must still merge/rebase/cherry-pick\n   from the intermediate branch and onto a branch of the upstream in\n   order to push to the upstream.\n\nor\n\n - the intermediate occasionally rebases onto the upstream, and then the\n   repos downstream of the intermediate must also rebase with --onto.\n\n   In this case the intermediate's maintainer must tell the downstreams\n   what rebase command to execute.\n\n   This makes it easier to push from the intermediate to the upstream:\n   the intermediate's commits should always be on top of the upstream\n   (at rebase time) so it's easy to push them.\n\nThe latter is the workflow we used at Sun for decades for large\nprojects.  We followed that workflow long before git, first with\nTeamware, then later with Mercurial (even though Mercurial technically\nhad no support for rebasing at that time; we just made it work).\n\n(We always left symbolic names for the pre-rebase branch HEADs, mind\nyou, to make life easier for everyone.)\n\n> > (I find that many users are allergic to rebasing.  Many people have\n> > told me that rebase is lying, that history must be immutable, and so\n> > on, all ignoring that: git users don't rebase published branches,\n> \n> So, when I push, and someone else pulls, is that published?  I thought\n> it was.\n\nYes.  You shouldn't push -f.  As long as you don't there's no problem.\n\nNico\n-- \n"},{"id":"247362","messageId":"20140806201340.GF23449@localhost","threadId":"37269","inReplyTo":"20140806194457.GD23449@localhost","subject":"Re: Rebase safely (Re: cherry picking and merge)","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-06T20:13:46Z","receivedAt":"2014-08-06T20:13:46Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Wed, Aug 06, 2014 at 02:44:59PM -0500, Nico Williams wrote:\n> That means that you have/maintain an intermediate upstream, yes?\n> \n> This is a bit trickier since once in a while that intermediate upstream\n> and everyone downstream of it has to catch up with the real upstream.\n> \n> Here you have two options:\n> \n>  - the intermediate diverges from the real upstream, and then you\n>    merge/cherry-pick from the upstream as needed\n>    \n>    The intermediate's maintainer must still merge/rebase/cherry-pick\n>    from the intermediate branch and onto a branch of the upstream in\n>    order to push to the upstream.\n\nI should add something important here.\n\nRebasing makes life easier for the intermediate maintainer, and for any\nupstream maintainer who has to merge \"pull requests\" or patches sent in\nemail.  Rebasing puts the onus for merging on the contributor, exactly\nwhere it belongs!\n\n(Granted, for an e-mail based workflow one's patches might have made for\na fast-forward merge when sent but not when the upstream gets to them.\nWith long enough latency this gets painful.  Which is why I don't\nrecommend an e-mail based commit integration workflow.)\n\nNico\n-- \n"},{"id":"247376","messageId":"xmqqzjfhky3j.fsf@gitster.dls.corp.google.com","threadId":"37269","inReplyTo":"53E25090.7010803@gmail.com","subject":"Re: cherry picking and merge","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-08-06T23:16:48Z","receivedAt":"2014-08-06T23:16:48Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narębski <jnareb@gmail.com> writes:\n\n> There was (long time ago) a long thread about idea of adding some\n> kind of 'weak' references (links), 'weakparent' that can be\n> automatically used by Git but do not pollute the commit message,\n> and do not affect reachability calculations.  Ultimately it went\n> nowhere (as you can see) - there were many problems.\n>\n> For example: how it would work for reverts and rebases?\n\nPerhaps some digging in the list archive before typing is in order.\nThis may be a good starting point.\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/46770/focus=46799\n"},{"id":"247377","messageId":"xmqqvbq5kxwo.fsf@gitster.dls.corp.google.com","threadId":"37269","inReplyTo":"xmqqzjfhky3j.fsf@gitster.dls.corp.google.com","subject":"Re: cherry picking and merge","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-08-06T23:20:55Z","receivedAt":"2014-08-06T23:20:55Z","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> Jakub Narębski <jnareb@gmail.com> writes:\n>\n>> There was (long time ago) a long thread about idea of adding some\n>> kind of 'weak' references (links), 'weakparent' that can be\n>> automatically used by Git but do not pollute the commit message,\n>> and do not affect reachability calculations.  Ultimately it went\n>> nowhere (as you can see) - there were many problems.\n>>\n>> For example: how it would work for reverts and rebases?\n>\n> Perhaps some digging in the list archive before typing is in order.\n> This may be a good starting point.\n>\n> http://thread.gmane.org/gmane.comp.version-control.git/46770/focus=46799\n\nHere is another.\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/19126/focus=19149\n"},{"id":"247408","messageId":"20140807051129.GJ23449@localhost","threadId":"37269","inReplyTo":"A769B84E-42D1-44AC-B0A8-0F4E68AB71FB@comcast.net","subject":"Re: Rebase safely (Re: cherry picking and merge)","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-07T05:11:31Z","receivedAt":"2014-08-07T05:11:31Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Wed, Aug 06, 2014 at 05:38:43PM -0700, Mike Stump wrote:\n> Oh, wait, maybe I have misunderstood the prohibition.  I have:\n> \n>        upstream  <—— fsf\n>            |\n>             \\\n>              |\n>              v\n> Me  <—>   master  <—> coworker.\n\nThis looks a lot like what I meant about project repos.\n\n> Me is a git clone of master, coworker is a git clone of master.\n> Master is a bare repo on a shared server where we put all of our work.\n> upstream is a bare git repo of the fsf git tree for gcc.  fsf is a box\n\nYes, exactly.  We did used exactly this at Sun, with a rebase-only\nworkflow.  You won't believe it till you see it [below].\n\n> owned by other that hosts the gcc git repository.  I do a git pull fsf\n> in upstream from time to time, and a corresponding git merge fsf in Me\n> from time to time.  When I like my work I do a git push (to master\n> exclusively).  To go to upstream, we submit patches by hand, git is\n> not really involved.  I never pull into master from upstream (don’t\n> even think that’s possible since they are both bare).\n\nI see.  Hey, if that works for you...  You could, of course, merge or\ncherry-pick, or rebase your team's commits onto another copy of the FSF\n(upstream) master and then send those commits: sending commits is better\nthan sending diffs, IMO, mostly because you get to have some metadata\nand integrity protection, and because git can ensure lineage and so on.\n\nBut you could live purely with diff/patch, no question, and anywhere\nbetween that and making full use of a VCS' powers.\n\nHere now is what we did at Sun, mapped onto git, written as something of\na hardcopy to be more exact.\n\nRemember, this was what we did for _all_ of Solaris.  You can probably\nstill find docs from the OpenSolaris days describing how to do it with\nMercurial, so you can see I'm not lying.  Thousands of engineers,\nworking on many discrete projects, with a large OS broken up into a few\n\"consolidations\" (each with its own repo).\n\n(Here the \"project gate\" is the team repo, that I think you call\n\"master\" above.)\n\n$ # on a bi-weekly (or whatever's best) basis:\n$\n$ git clone $foo_project_gate foo\n$ cd foo\n$ git remote add upstream ...\n$ git fetch upstream\n$ git checkout $current_master\n$ new_snapshot=master-$(date +%Y-%m-%d)\n$ git checkout -b $new_snapshot\n$ git rebase upstream/master\n$ git push origin $new_snapshot\n$\n$ mutt -s \"PROJECT FOO: Rebase onto new master branch master-$(date +%Y-%m-%d)\" foo-engineers < /dev/null\n\nThen the engineers on this project do this (at their leisure):\n\n$ old_snapshot=<YYYY-mm-dd from current master branch>\n$ new_snapshot=<YYYY-mm-dd from new master branch>\n$ cd $my_foo_project_clone\n$ git fetch origin\n$ for topic_branch in ...; do\n    git checkout -b ${topic_branch%\"-${old_snapshot}\"}-$new_snapshot\n    git rebase --onto master-$new_snapshot master-$old_snapshot\n  done\n$\n$ # Ready to pick up where I left off!\n...\n\nEventually engineers integrate commits into the project gate:\n\n$ # I'm ready to push to the project gate!\n$\n$ git checkout some_topic_branch\n$\n$ # Note: no -f!\n$ git push origin HEAD:master-$current_snapshot\n...\n$ # yay\n\nEventually the project is ready to push its commits upstream:\n\n$ git clone $project_gate foo\n$ cd foo\n$ git remote add upstream ...\n$ git checkout master-$current_snapshot\n$ git push upstream HEAD:master\n\nIf you're not going to be sending all local commits upstream yet then\nyou can do an interactive rebase, put the commits you do want to send\nimmediately after the upstream's HEAD commit, all the others after, and\nsend just those.  If you do this you should create a new snapshot and\ntell your team members to git rebase --onto it.\n\nNote that we're always rebasing _new_ branches.  Never old ones.  The\nproject gate does plain rebases of those new branches.  Downstreams have\nto rebase --onto to \"recover\" (it works fine).\n\nThis is a very rebase-happy workflow.  It keeps as-yet-not-contributed\ncommits \"on top\" relative to the immediate upstream of any repo.  This\nmakes them easy to identify, and it keeps the author/date/subject\nmetadata.  Because you rebase often, you don't lag the upstream by much.\nBecause they are \"on top\" it's always fast-forward merge to push --\nyou're always \"merged\", with some lag, yes, but merged.  And the person\ndoing the merging is the owner of the repo (team members, project\ngatekeeper).\n\nIt's a bit more work each time you rebase than a merge-heavy workflow.\nBut it's also easier to contribute, and it's easier on each successive\nupstream's maintainers.\n\n(The upstream also kept \"snapshot\" branches.  Doing this has many good\nside effects, not the least of which is that git prune (and gc, which I\nknew about) doesn't go deleting the past of each rebase.)\n\n> > The only use-case I've seen where a rebase-based workflow doesn't work\n> \n> Well, and now mine, which I claim is a the canonical open source use\n> [...]\n\nNah.  Sun managed this for decades without a hitch, and for products\nmuch larger than GCC.  See above.\n\n(It's true that it's difficult to sell some people on this workflow,\nespecially when their previous experiences are with VCSes that look down\non rebase.  You don't have to buy it either.  However, it works very\nwell.)\n\n> I’m trying to envision how anyone could ever use rebase.  If you\n> can’t share your work, it isn’t work.\n\nDo some experiments based on the above hardcopy.  If that doesn't\nconvince you that it works, oh well, I'll have given it a good try.\n\nNico\n-- \n"},{"id":"247482","messageId":"3D5C75D8-69D5-449D-9B0A-1B147D711C51@comcast.net","threadId":"37269","inReplyTo":"A769B84E-42D1-44AC-B0A8-0F4E68AB71FB@comcast.net","subject":"Fwd: Rebase safely (Re: cherry picking and merge)","fromName":"Mike Stump","fromEmail":"mikestump@comcast.net","sentAt":"2014-08-08T16:23:47Z","receivedAt":"2014-08-08T16:23:47Z","isPatch":false,"sender":{"key":"mikestump@comcast.net","avatar":null},"body":"[ sorry for the dup ]\n\nBegin forwarded message:\n\nOn Aug 6, 2014, at 12:44 PM, Nico Williams <nico@cryptonector.com> wrote:\n> It's not a good idea to rebase a branch in a repo that others pull from.\n\nWell, so rebase is then out, as I don’t want to rebase _my_ tree, I want to rebase _the_ tree.  Recall, I don’t want to cherry pick for my tree, I want to cherry pick for the tree.\n\n[ reads rest of email ]\n\nOh, wait, maybe I have misunderstood the prohibition.  I have:\n\n       upstream  <—— fsf\n           |\n            \\\n             |\n             v\nMe  <—>   master  <—> coworker.\n\nMe is a git clone of master, coworker is a git clone of master.  Master is a bare repo on a shared server where we put all of our work.  upstream is a bare git repo of the fsf git tree for gcc.  fsf is a box owned by other that hosts the gcc git repository.  I do a git pull fsf in upstream from time to time, and a corresponding git merge fsf in Me from time to time.  When I like my work I do a git push (to master exclusively).  To go to upstream, we submit patches by hand, git is not really involved.  I never pull into master from upstream (don’t even think that’s possible since they are both bare).\n\nI read the prohibition as don’t rebase my branch called master on Me and push it to master on master as others then pull master from master.  Did I misunderstand?  Instead, the prohibition is you can use push/pull freely and you can have as many coworkers as you want, just don’t use push -f and don’t let anyone push/pull from your own private clone.\n\nI had envisions that the rebase of master on Me once pushed to master and then pull from master to coworker is the exact case that would screw us.\n\n> The only use-case I've seen where a rebase-based workflow doesn't work\n\nWell, and now mine, which I claim is a the canonical open source use case.  Can't use source, unless you import the source,  can’t be real unless you can change the source, once you do that, you then need to merge in newer sources, and if the company has or will have more than a single individual and these folks are ever to work together, then they need to share the source between them.\n\nI’m trying to envision how anyone could ever use rebase.  If you can’t share your work, it isn’t work.\n\n> is where you have multiple upstreams that you're following.\n\nI only have a single (for this repo) upstream.\n\n>> Now, I found the stack-overflow commentary first, and all the horrors\n>> of it, and all the nuances.  I carefully read what people were doing,\n>> how what I wanted to related to what they were doing, and it sure felt\n>> like I was in the, don’t go there camp.\n> \n> A lot of people rant about rebase.  They're wrong.  They've distorted\n> your perspective.\n\nWhat I saw were the people that screwed their world and were trying to recover.  It was a question, how do I recover, and what did I do wrong.  There was no rant.  Or, at least, I’m impervious to rants and don’t actually see them.  I deal in the cold hard facts and transform the rant into what happened, what they did wrong, and how to avoid doing it myself.\n\nNo, you’ve set my perspective, let me quote you:\n\n  It's not a good idea to rebase a branch in a repo that others pull from.\n\nthis matches the doc, matches the experience of users on stack overflow and matches what what I think is true.  You are free to correct that if I am wrong.\n\nI don’t know why you think my perspective is distorted.  Either, I can rebase all my patches, all my coworkers patches, and push those up to master and have all my coworkers pull from master and develop (meaning branches off master as well as patches to master) as normal, or I can’t.\n\n> There's just two simple rules to follow and you'll be safe:\n> \n> 1) NEVER git push -f (--force) to a \"published\" repo/branch.\n\nI can never use push -f.  That seems trivial.  git config --system receive.denyNonFastForwards true seems to be exactly what I would do to my master to enforce this rule.  This then seems to permanently be a non-issue.\n\n> 2) NEVER work directly in a published repo.  Instead work in a private\n>   clone.\n\nI only ever work in a private to me clone, so I’m safe.  The only published repo is a bare repo, which can’t be worked in by design, so, again, I think I’m perfectly safe.\n\nSo, if that is true, why do others write such things as (from http://ctoinsights.wordpress.com/2012/06/29/git-flow-with-rebase/):\n\n> The way to get the best of both worlds is to be explicit about when to use one versus the other. For us the simple rules to follow are:\n> \t• Rebase feature branches.\n> \t• Never rebase develop or master branch. (Always merge into develop and master.)\n> \t• Never rebase public branches.\nmaster is public, I want to rebase master.  This violates rule 3 above, but not any of your rules?\n\nI develop on master, thus violating rule 2.  This does’t violate any of your rules?\n\nI want to rebase master, thus, violating rule 1.  This doesn’t violate any of your rules?\n\nI violate every single rule, by his standard, I am screwed.\n\nhttp://blog.experimentalworks.net/2009/03/merge-vs-rebase-a-deep-dive-into-the-mysteries-of-revision-control/ says:\n\n> Never rebase branches or trees that you pulled. Only rebase local branches. \n\nI violate that.  This doesn’t violate ant of your rules?  I pull master rebase it, then push it.  master is not a local branch, or, more correctly, I have a local branch called master that is push to and pull from a bare repo that I’m calling master to/from a branch called master.  git diff origin/master master shows our work.\n\nTo me, a local branch is one call b, that doesn’t push or pull to any remote repo.\n\nLinus in https://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html said:\n\nBut never other peoples code. That's a \"destroy \nhistory\"\n\nThus violating his rule.  Recall why rebase was suggested.  I want to merge the upstream fsf tree into our tree (or our tree into a copy of the fsf tree) and instead of using merge, it was suggested to use rebase.  But I operate on our entire tree.  He further says:\n\n- You must never EVER destroy other peoples history. You must not rebase \n   commits other people did.\n\nI want to exactly rebase either the entire fsf tree onto mine, or mine on to the fsf tree.  Either result I am rebasing code I didn’t write, commits other than mine.  This violates his rule, not your?\n\nHe states:\n\n- Minor clarification to the rule: once you've published your history in \n   some public site, other people may be using it, and so now it's clearly \n   not your _private_ history any more.\n\nAnd I violate this rule, but it doesn’t violate any of your rules?\n\n>  To help make sure of this, never publish a non-bare repo\n>   (bare == has no workspace; non-bare == has a workspace).\n\nWe only have a bare repo (our master) and we only ever push/pull from it, so I’m safe.\n\n> It really helps to think of git as a pile of commits arranged in a\n> Merkle has tree.  Branches and tags are just symbolic names for specific\n> commits.  Rebase builds a new line of commits in the tree then it\n> changes the symbolic branch name's HEAD to point to the head of that new\n> line of commits, BUT NOTHING IS LOST in the pile of commits that is the\n> repo, not until you git-prune(1) to remove commits not reachable from\n> symbolic names (branches and tags).\n\nWrong, let me introduce you to git gc:\n\n       --prune=<date>\n           Prune loose objects older than date (default is 2 weeks ago, overridable by the config variable\n           gc.pruneExpire). --prune=all prunes loose objects regardless of their age. --prune is on by default.\n\nwhich, I run every now and then as we work on stuff that is more than 5 lines long.  I bring in 60,000 changes, I push, I git gc on the bare repo.\n\n>>> The only case where I can imagine not using a\n>>> rebase-heavy workflow is where I have to track multiple forked\n>>> upstreams and so I want to merge each into my branch.\n>> \n>> So, sounds like I fit that use case and rebase could be my friend.\n> \n> Excellent.\n\nI’m optimistic.\n\n>> How do I square what you said and:\n>> \n>>  Rebasing (or any other form of rewriting) a branch that others have\n>>  based work on is a bad idea\n>> \n>> ?\n> \n> See above.\n\nSo, rebasing will always work just fine, one just needs to never, ever use push -f and never ever share ones own private clone.  Sharing a bare repo that everyone works on (push/pull) is fine.  rebasing and pushing into it and others pulling from it will always just work fine.\n\nGosh, could you get the documentation to say that.  I’ve certainly been scared off even trying rebase.\n\nRebase should just say it always works perfectly (remove the warning entirely) and then burry into push -f, this option will destroy your world and put into it, the entire how it will screw it, how to recover from it, and then say in the clone documentation, you should never clone a none bare repo, because if you do, your world will end when you rebase.  In fact, I’ve make if a clone -f operation, and then fail the default is non-base, and then under clone -f explain this is a ver bad idea.\n\nArticles like http://stackoverflow.com/questions/457927/git-workflow-and-rebase-vs-merge-questions:\n\nReason #2: With rebase, there is no undo!\n\nmakes me nervous.\n\n>> I want all old refs in old emails to work.  I want all refs in\n> \n> They will if you stick to the two rules I mention above.\n\nAh, excellent.\n\n>> bugzilla to work.  I want to see the original dates of all the work.\n> \n> Ditto.\n\nAh, nice.\n\n>> I want git blame to report those artifacts in email and bugzilla.  I\n>> have coworkers that I push to, pull from (through a single sharing\n>> point, we call the master tree).  We work on gcc, we pull git gcc down\n>> to a local copy, then merge it into our tree.  I want to cherry pick\n>> changes from upstream.  I do work and push to our master, I pull work\n>> of coworkers from the master, my coworkers do the same.  Isn’t this\n>> the canonical open source use case?\n> \n> That means that you have/maintain an intermediate upstream, yes?\n\nYes.  I have upstream which is a virgin copy of the fsf in a bare repo.\n\nOur master only ever pulls from the upstream.\n\n> This is a bit trickier since once in a while that intermediate upstream\n> and everyone downstream of it has to catch up with the real upstream.\n> \n> Here you have two options:\n> \n> - the intermediate diverges from the real upstream, and then you\n>   merge/cherry-pick from the upstream as needed\n\nVirgin copy, it only can ever lag in time, no other way.  We can only pull or get work from our virgin copy, no other way.  To get a patch that just went in, I would like to pull from fsf into upstream, cherry-pick upstream into Me, push into master.  When I merge I same thing except I do a merge upstream.\n\n>   The intermediate's maintainer must still merge/rebase/cherry-pick\n>   from the intermediate branch and onto a branch of the upstream in\n>   order to push to the upstream.\n\nIt never pushes up, it is unidirectional.  The only direction down is pull the entire bare repo, everything, or nothing, that’s it.\n\n> (We always left symbolic names for the pre-rebase branch HEADs, mind\n> you, to make life easier for everyone.)\n> \n>>> (I find that many users are allergic to rebasing.  Many people have\n>>> told me that rebase is lying, that history must be immutable, and so\n>>> on, all ignoring that: git users don't rebase published branches,\n>> \n>> So, when I push, and someone else pulls, is that published?  I thought\n>> it was.\n> \n> Yes.  You shouldn't push -f.  As long as you don't there's no problem.\n\nSo, you would like to withdraw your statement, git users don't rebase published branches, and instead say, git users can rebase published branches and it all works flawlessly well, provided they stay away from non-bare shared repos and stay away from push -f?  The later statement doesn’t make be nervous at all.  Though, I would like an option like receive.denyNonFastForwards to turn off the ability to push/pull from a non-bare repo.\n\n\nSo, thinking about it some more, would references to the fsf git repo from the fsf bugzilla work in our tree once I rebase the fsf work on ours?  Remember, I do want those to work."},{"id":"247518","messageId":"894B9D26-F8C5-4C82-B04C-3B31094C2293@comcast.net","threadId":"37269","inReplyTo":"20140807051129.GJ23449@localhost","subject":"Re: Rebase safely (Re: cherry picking and merge)","fromName":"Mike Stump","fromEmail":"mikestump@comcast.net","sentAt":"2014-08-08T17:34:43Z","receivedAt":"2014-08-08T17:34:43Z","isPatch":false,"sender":{"key":"mikestump@comcast.net","avatar":null},"body":"On Aug 6, 2014, at 10:11 PM, Nico Williams <nico@cryptonector.com> wrote:\n> Nah.  Sun managed this for decades without a hitch, and for products\n> much larger than GCC.  See above.\n\nOk.  Ah, ok, perfect.  I see how that method of working would cure the cherry-pick and merge don’t work problem mentioned at the top of the thread.\n\n> Do some experiments based on the above hardcopy.  If that doesn't\n> convince you that it works, oh well, I'll have given it a good try.\n\nThank you for taking the time to diagram that as it appears to violate everyones how to use git guide.   I see the workflow does an onto, which was the ‘fix’ people talked about on stack overflow, and I see just how things would work.\n\nIf the old master branches are deleted and gc is run, then all the old references go away, and then the refs from email and bugzilla then don’t work.  Did you guys ever remove them and then prune (or gc)?\n\nNow, the biggest issue, if that is recognized as `fixing’ the cherry-pick problem, then certainly the problem is understood to be a problem.  If one recognized it as a problem, then one can envision cherry-pick and merge working together so that the problem doesn’t need fixing in the first place.  And, if it doesn’t need fixing, then the cost of the solution isn’t needed either.  The biggest problem with git, is that two features don’t work nicely together when they could; in this case, cherry-pick and merge).  Because they don’t, it makes it hard for people to predict what will happen when they use it.  This makes it more expensive to use and less suitable than a system that is more predictable.  You improve git, by fixing the problem and making the features work nicely together and making it predicable.\n\nI still favor fixing the underlying problem with cherry-pick and merge not working.  :-)  That said, I see how to work around the bug with rebase, if I need to.\n\nI wish the top google hit were your guide and I wish I never saw all the other pages…  I see now your position, and I see why all the guides are wrong, if you know just how to use rebase.  I wish the git documentation were improved to say as the first sentence under cherry-pick, this feature sucks and doesn’t really work well, it can cause excess merge conflicts.  rebase can be used to work around the bugs in cherry-pick for now.  And under rebase, instead of saying what it said now, that how one can can trivially and effortlessly use git, instead of saying, Do not rebase commits that you have pushed to a public repository which I now see is wrong."},{"id":"247522","messageId":"20140808182735.GC21575@localhost","threadId":"37269","inReplyTo":"894B9D26-F8C5-4C82-B04C-3B31094C2293@comcast.net","subject":"Re: Rebase safely (Re: cherry picking and merge)","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-08T18:27:36Z","receivedAt":"2014-08-08T18:27:36Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Fri, Aug 08, 2014 at 10:34:43AM -0700, Mike Stump wrote:\n> On Aug 6, 2014, at 10:11 PM, Nico Williams <nico@cryptonector.com> wrote:\n> > Nah.  Sun managed this for decades without a hitch, and for products\n> > much larger than GCC.  See above.\n> \n> Ok.  Ah, ok, perfect.  I see how that method of working would cure the\n> cherry-pick and merge don’t work problem mentioned at the top of the\n> thread.\n> \n> > Do some experiments based on the above hardcopy.  If that doesn't\n> > convince you that it works, oh well, I'll have given it a good try.\n> \n> Thank you for taking the time to diagram that as it appears to violate\n> everyones how to use git guide.   I see the workflow does an onto,\n> which was the ‘fix’ people talked about on stack overflow, and I see\n> just how things would work.\n\nThere's nothing scary about --onto.  You're saying \"figure out which are\nmy local commits (the ones on top of the previous upstream) and pick\nthem onto the new upstream\".\n\nWe only need to do it manually (though it can be scripted[*]) because\ngit doesn't track rebase history so that it can be done automatically.\n\n[*] And then there's Tony Finch's\n    https://git.csx.cam.ac.uk/x/ucs/git/git-repub.git , which is kinda\n    awesome!\n\n> If the old master branches are deleted and gc is run, then all the old\n> references go away, and then the refs from email and bugzilla then\n> don’t work.  Did you guys ever remove them and then prune (or gc)?\n\nProduct gates' repos and snapshots stuck around forever, though it was\nTeamware, and finding really old ones wasn't necessarily easy,\nparticularly since their names didn't always reflect product names.\n\nProminent project gate repos and their snapshots also stuck around\nforever.\n\nLesser project gate repos tended to be as ephemeral as the project.\n\n> Now, the biggest issue, if that is recognized as `fixing’ the\n> cherry-pick problem, then certainly the problem is understood to be a\n> problem.  If one recognized it as a problem, then one can envision\n\nNot really.  This isn't about git.  We followed a rebase-only workflow\nwith VCSes that nominally didn't support rebase.  We did it because it\nwas easier on everyone and kept history in the upstream clean.  We\ndidn't do it because git has issues when combining merge and\ncherry-pick.\n\n> cherry-pick and merge working together so that the problem doesn’t\n> need fixing in the first place.  And, if it doesn’t need fixing, then\n\nIf you buy into the Sun model then this is all a non-issue.  If you\ndon't then I think you have other problems (because I have bought into\nthe Sun model) :)\n\n> the cost of the solution isn’t needed either.  The biggest problem\n> with git, is that two features don’t work nicely together when they\n> [...]\n\nThe Sun model has no additional cost.  It moves costs around so that the\npeople dealing with conflicts are the downstreams, not the upstreams,\nand that's exactly as it should be.\n\n(Keep in mind that Solaris gates tended to have large numbers of commits\non any given day, so it was quite common that one would have to rebase\nmultiple times before successfully pushing.  For large projects with\nlong test cycles the gates would close to avoid the need to rebase and\nre-test.)\n\n> I still favor fixing the underlying problem with cherry-pick and merge\n> not working.  :-)  That said, I see how to work around the bug with\n> rebase, if I need to.\n\nIMO it could be done, but I can't help that.\n\n> I wish the top google hit were your guide and I wish I never saw all\n> the other pages…  I see now your position, and I see why all the\n\nMe too!  I should blog it.\n\n> guides are wrong, if you know just how to use rebase.  I wish the git\n> documentation were improved to say as the first sentence under\n\nThe Sun model is not the only way to use git though.\n\n> cherry-pick, this feature sucks and doesn’t really work well, it can\n> cause excess merge conflicts.  rebase can be used to work around the\n> bugs in cherry-pick for now.  And under rebase, instead of saying what\n> it said now, that how one can can trivially and effortlessly use git,\n> instead of saying, Do not rebase commits that you have pushed to a\n> public repository which I now see is wrong.\n\nI'm glad you understand the Sun model now.  You should evaluate its\napplicability to your use case on its own merits.  Don't use it just to\nworkaround a problem in git; use it because it's good, or don't use it\nbecause it doesn't fit your team's needs.\n\nNico\n-- \n"},{"id":"248069","messageId":"1408642561.20771.7.camel@jekeller-desk1.amr.corp.intel.com","threadId":"37269","inReplyTo":"AC750A73-4FE9-4BCB-9A51-4DE28F2110A7@comcast.net","subject":"Re: cherry picking and merge","fromName":"Keller, Jacob E","fromEmail":"jacob.e.keller@intel.com","sentAt":"2014-08-21T17:36:02Z","receivedAt":"2014-08-21T17:36:02Z","isPatch":false,"sender":{"key":"jacob.e.keller@intel.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Fri, 2014-08-01 at 09:56 -0700, Mike Stump wrote:\n> Since everything I do goes up and down into repositories and I don’t want my friends and family to scorn me, rebase isn’t the command I want to use.\n\nYou completely mis-understand what \"published\" means. Published history\nis history from which other people can pull right now.\n\nThat means it has to be in a publicly addressable repository (ie: just\nlike the remote that you are pulling from as upstream).\n\nrebasing commits which are already in the upstream is bad. Rebasing\ncommits which you have created locally is NOT bad. These commits would\nnot be published until you do a push.\n\nThis is the fundamental issue with rebase, and it is infact easy to\navoid mis-using, especially if you don't publish changes. The key is\nthat a commit isn't published until it's something someone else can\ndepend on.\n\nDoing \"git pull --rebase\" essentially doesn't ever get you into trouble.\n\nRegards,\nJake\n"},{"id":"248070","messageId":"1408643887.20771.8.camel@jekeller-desk1.amr.corp.intel.com","threadId":"37269","inReplyTo":"1408642561.20771.7.camel@jekeller-desk1.amr.corp.intel.com","subject":"Re: cherry picking and merge","fromName":"Keller, Jacob E","fromEmail":"jacob.e.keller@intel.com","sentAt":"2014-08-21T17:58:07Z","receivedAt":"2014-08-21T17:58:07Z","isPatch":false,"sender":{"key":"jacob.e.keller@intel.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Thu, 2014-08-21 at 17:36 +0000, Keller, Jacob E wrote:\n> On Fri, 2014-08-01 at 09:56 -0700, Mike Stump wrote:\n> > Since everything I do goes up and down into repositories and I don’t want my friends and family to scorn me, rebase isn’t the command I want to use.\n> \n> You completely mis-understand what \"published\" means. Published history\n> is history from which other people can pull right now.\n> \n> That means it has to be in a publicly addressable repository (ie: just\n> like the remote that you are pulling from as upstream).\n> \n> rebasing commits which are already in the upstream is bad. Rebasing\n> commits which you have created locally is NOT bad. These commits would\n> not be published until you do a push.\n> \n> This is the fundamental issue with rebase, and it is infact easy to\n> avoid mis-using, especially if you don't publish changes. The key is\n> that a commit isn't published until it's something someone else can\n> depend on.\n> \n> Doing \"git pull --rebase\" essentially doesn't ever get you into trouble.\n> \n> Regards,\n> Jake\n> \u0004�{.n�+�������+%��lzwm��b�맲��r��z\b��{ay�\u001dʇڙ�,j\u0007��f���h���z�\u001e�w���\f���j:+v���w�j�m����\u0007����zZ+�����ݢj\"��!�i\n\nPardon me. You can actually ignore this post. I read through more of the\nthread, and actually realize I completely misunderstood what your issue\nwas, and why rebase might not work.\n\nRegards,\nJake\n"}]}