{"thread":{"id":"14280","subject":"Cherry picking instead of merges.","startedAt":"2008-07-03T18:26:50Z","lastAt":"2008-07-04T16:47:49Z","messageCount":13,"participants":["David Brown","Alex Riesen","Avery Pennarun","Linus Torvalds","Samuel Tardieu","Björn Steinbrink","Johannes Sixt"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"82139","messageId":"20080703182650.GA11166@old.davidb.org","threadId":"14280","inReplyTo":null,"subject":"Cherry picking instead of merges.","fromName":"David Brown","fromEmail":"git@davidb.org","sentAt":"2008-07-03T18:26:50Z","receivedAt":"2008-07-03T18:26:50Z","isPatch":false,"sender":{"key":"git@davidb.org","avatar":"https://gravatar.com/avatar/94c86a2938470a74c2eac5e2b69afc0871f79a660295c02219597aba8cb101c1?d=mp&s=160"},"body":"We have a branch coming from \"company B\" who is also doing development on\nthe same tree as us.  We would like to do regular merges with them, but\nunfortunately, there are quite a few changes in between.\n\nFirst we tried a git-merge and resolved the conflicts.  The problem here is\nthat the resultant code didn't work.  git-bisect wasn't very useful because\nthe intermediate versions don't have resolved conflicts.\n\nYesterday, one developer cherry picked company B's changes into a branch.\nIt appears he resolved the conflicts for each commit, which should make\nbisecting easier.\n\nThe problem is that we now have very divergent history.\n\nAny advice on how to make use of how he resolved conflicts in order to\nmerge company B's changes in using git-merge.  I could always use the\n\"ours\" strategy to just kind of force the merge, so at least future merges\nwould work, but it'd kind of be nice to have the proper history.\n\nThere are about 110 commits in question.\n\nThanks,\nDavid Brown\n"},{"id":"82151","messageId":"20080703201354.GA3546@steel.home","threadId":"14280","inReplyTo":"20080703182650.GA11166@old.davidb.org","subject":"Re: Cherry picking instead of merges.","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2008-07-03T20:13:54Z","receivedAt":"2008-07-03T20:13:54Z","isPatch":false,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"David Brown, Thu, Jul 03, 2008 20:26:50 +0200:\n> Yesterday, one developer cherry picked company B's changes into a branch.\n> It appears he resolved the conflicts for each commit, which should make\n> bisecting easier.\n>\n> The problem is that we now have very divergent history.\n\n...and have absolutely no idea on what were the changes of the company\nB were made.\n\n> Any advice on how to make use of how he resolved conflicts in order to\n> merge company B's changes in using git-merge. ...\n\nLet that developer do the merge next time? Or let the B do a merge\nwith a commonly accepted base?\n"},{"id":"82152","messageId":"32541b130807031315j3d9b7d77y277e3cb994ab0964@mail.gmail.com","threadId":"14280","inReplyTo":"20080703182650.GA11166@old.davidb.org","subject":"Re: Cherry picking instead of merges.","fromName":"Avery Pennarun","fromEmail":"apenwarr@gmail.com","sentAt":"2008-07-03T20:15:22Z","receivedAt":"2008-07-03T20:15:22Z","isPatch":false,"sender":{"key":"apenwarr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/20592?v=4"},"body":"On 7/3/08, David Brown <git@davidb.org> wrote:\n>  First we tried a git-merge and resolved the conflicts.  The problem here is\n>  that the resultant code didn't work.  git-bisect wasn't very useful because\n>  the intermediate versions don't have resolved conflicts.\n>\n>  Yesterday, one developer cherry picked company B's changes into a branch.\n>  It appears he resolved the conflicts for each commit, which should make\n>  bisecting easier.\n>\n>  The problem is that we now have very divergent history.\n>\n>  Any advice on how to make use of how he resolved conflicts in order to\n>  merge company B's changes in using git-merge.  [...]\n\nUnfortunately, since your mismerged branches are already published,\nrewriting history would cause a lot of pain for everyone.  It would be\nbetter to avoid doing that entirely.  However, I can see why you'd\nwant to do that in order to make future git-bisect easier.\n\nBasically, if you're going to try to fix the git-bisect intermediate\nversions, you're going to have to rewrite history anyway; in which\ncase, why not just make your developer's cherry-picked branch the\nofficial one?  Then your problems are solved, other than getting all\nyour developers onto the new history.\n\nAlternatively, if you just want to fix your main development tree so\nthat it's \"correct\", then you could do this:\n\n- Go to a point in time where both branches (main and developer) have\nexactly the same set of patches: that is, your company + company B.\nThe exact history (ie. commit ids) will look different, because the\ntwo branches took different paths to get there, but the code *should*\nhave been identical at those two times, since you have the same set of\npatches.  Call the two points X and Y.\n\n- X (on the main branch) is actually different from Y (on your\ndeveloper's branch) because someone mis-resolved the conflicts on X.\nHowever, the only difference between X and Y should be the mis-merge.\nThus:\n\n- git diff X..Y >fix-mis-merge.patch\n\n- git checkout HEAD\n\n- git apply fix-mis-merge.patch\n\nThis will apply the correct conflict resolution to the tip of your\nnewest branch.  All the revisions between X and HEAD will still be\nbroken, but that's usually better than trying to rewrite history and\npretend the broken revisions never existed.  You can always use \"git\nbisect skip\" for cases like that.\n\nHave fun,\n\nAvery\n"},{"id":"82156","messageId":"20080703205329.GA17923@old.davidb.org","threadId":"14280","inReplyTo":"32541b130807031315j3d9b7d77y277e3cb994ab0964@mail.gmail.com","subject":"Re: Cherry picking instead of merges.","fromName":"David Brown","fromEmail":"git@davidb.org","sentAt":"2008-07-03T20:53:29Z","receivedAt":"2008-07-03T20:53:29Z","isPatch":false,"sender":{"key":"git@davidb.org","avatar":"https://gravatar.com/avatar/94c86a2938470a74c2eac5e2b69afc0871f79a660295c02219597aba8cb101c1?d=mp&s=160"},"body":"On Thu, Jul 03, 2008 at 04:15:22PM -0400, Avery Pennarun wrote:\n\n>Unfortunately, since your mismerged branches are already published,\n>rewriting history would cause a lot of pain for everyone.  It would be\n>better to avoid doing that entirely.  However, I can see why you'd\n>want to do that in order to make future git-bisect easier.\n\nIt's only sitting in a private developer's branch.  I want to do the merge\nproperly, but I'm just trying to figure out how to get the conflict\nresolution out of his work.\n\n>Basically, if you're going to try to fix the git-bisect intermediate\n>versions, you're going to have to rewrite history anyway; in which\n>case, why not just make your developer's cherry-picked branch the\n>official one?  Then your problems are solved, other than getting all\n>your developers onto the new history.\n\nOnce we start cherry picking the changes from Company B, we have a\ndifferent set of changes from them, and future merges will get harder and\nharder.\n\n>This will apply the correct conflict resolution to the tip of your\n>newest branch.  All the revisions between X and HEAD will still be\n>broken, but that's usually better than trying to rewrite history and\n>pretend the broken revisions never existed.  You can always use \"git\n>bisect skip\" for cases like that.\n\nExcept we already know that the broken change is inside of the broken\nrevisions.\n\nIt turns out that things are more messed up than I thought.  This developer\nhad done a 'git push' with some manual refs and pushed what was supposed to\nbe a merge into an unmerged branch.\n\nI've spoken with all of the developers who use this tree, and everyone\nagrees that rewinding the tree is the best way to go.  Now just time to\ntrudge forward and learn.\n\nBut, it makes for a good new rule: no cherry-picking other people's\nchanges.\n\nDavid\n"},{"id":"82161","messageId":"2008-07-03-23-18-40+trackit+sam@rfc1149.net","threadId":"14280","inReplyTo":"20080703205329.GA17923@old.davidb.org","subject":"Re: Cherry picking instead of merges.","fromName":"Samuel Tardieu","fromEmail":"sam@rfc1149.net","sentAt":"2008-07-03T21:18:40Z","receivedAt":"2008-07-03T21:18:40Z","isPatch":false,"sender":{"key":"sam@rfc1149.net","avatar":"https://avatars.githubusercontent.com/u/44656?v=4"},"body":">>>>> \"David\" == David Brown <git@davidb.org> writes:\n\nDavid> It's only sitting in a private developer's branch.  I want to\nDavid> do the merge properly, but I'm just trying to figure out how to\nDavid> get the conflict resolution out of his work.\n\nWhy don't you create a commit which has both your (A) and company B\nbranch head (B) as parent with the same content as the private\ndeveloper's branch (P) which contains the succesful merge?\n\nSomething like that: (totally untested)\n\n% git checkout A\n% git merge --no-commit -s ours B\n% git checkout P .\n% git commit -a\n"},{"id":"82159","messageId":"alpine.LFD.1.10.0807031403380.2815@woody.linux-foundation.org","threadId":"14280","inReplyTo":"20080703182650.GA11166@old.davidb.org","subject":"Re: Cherry picking instead of merges.","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2008-07-03T21:18:53Z","receivedAt":"2008-07-03T21:18:53Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 3 Jul 2008, David Brown wrote:\n> \n> First we tried a git-merge and resolved the conflicts.  The problem here is\n> that the resultant code didn't work.  git-bisect wasn't very useful because\n> the intermediate versions don't have resolved conflicts.\n> \n> Yesterday, one developer cherry picked company B's changes into a branch.\n> It appears he resolved the conflicts for each commit, which should make\n> bisecting easier.\n\nWhat I would suggest is actually a stupid combination of the two. The \nadvantage and disadvantage of the cherry-picking is:\n\n - the cherry-picking obviously gave you the end result you wanted, and is \n   bisectable at a per-commit level (ie each cherry-pick was a \n   \"micro-merge\", and if there was a merge problem, it would show up \n   exactly in _that_ one)\n\nBUT\n\n - the cherry-picking doesn't help future merges, since the history is \n   disjoint, and as such it will always diverge and just cause more and \n   more problems down the road to keep on doing this.\n\nso what I would suggest is\n\n - generate the *state* of the tree by cherry-picking each commit one by \n   one, and verify that state.\n\n - but then do a merge that picks that one state as the merge result \n   (this is all assuming you cherry-picked every single commit, of \n   course!)\n\nThe latter thing is really easy to do. Just do the merge, and ignore the \nconflicts that happen entirely, because you then just use the tree from \nthe temporary cherry-picking branch\n\n\t# Try to merge the other branch ..\n\tgit merge otherbranch\n\n\t# .. but ignore conflicts entirely by then\n\t# setting the index and checked-out state to\n\t# the known-good end result\n\tgit read-tree -u --reset cherry-picked-branch\n\n\t# .. and commit that instead\n\tgit commit\n\n\t# and you can now remove the cherry-picked branch\n\t# that was only used for the tree\n\tgit branch -D cherry-picked-branch\n\nto actually commit that merge and get rid of the temporary cherry-picking \nbranch.\n\n(Of course, if the merge actually doesn't generate any conflicts, and thus \ncommits it, but doesn't actually _work_, then that \"git commit\" needs to \nbe a \"git commit --amend\" instead, in order to actually replace the merge \ncommit rather than add a fixup commit afterwards)\n\nEnd result: you have a nice merge with nice history that actually \nconverges at a common point, but you effectively did the merge resolution \none commit at a time with cherry-picking (or \"git rebase\", which is \nobviously just a convenient shorthand for cherry-picking everything).\n\nThis actually has a few other advantages too: \"git show --cc\" on that \nmerge will also show the conflicts the way they got resolved, so you \nactually end up with some useful information this way too.\n\n\t\t\tLinus\n"},{"id":"82169","messageId":"20080703223949.GA23092@old.davidb.org","threadId":"14280","inReplyTo":"alpine.LFD.1.10.0807031403380.2815@woody.linux-foundation.org","subject":"Re: Cherry picking instead of merges.","fromName":"David Brown","fromEmail":"git@davidb.org","sentAt":"2008-07-03T22:39:49Z","receivedAt":"2008-07-03T22:39:49Z","isPatch":false,"sender":{"key":"git@davidb.org","avatar":"https://gravatar.com/avatar/94c86a2938470a74c2eac5e2b69afc0871f79a660295c02219597aba8cb101c1?d=mp&s=160"},"body":"On Thu, Jul 03, 2008 at 02:18:53PM -0700, Linus Torvalds wrote:\n\n>End result: you have a nice merge with nice history that actually \n>converges at a common point, but you effectively did the merge resolution \n>one commit at a time with cherry-picking (or \"git rebase\", which is \n>obviously just a convenient shorthand for cherry-picking everything).\n\nI'm still not clear how the one-commit-at-a-time resolution gets recorded\nanywhere (except in the cherry-picking branch).\n\nIt seems to be that I would need to do multiple merges, one at each point\nwhere there is a conflict that I had to resolved.  I would remember this as\nI did each cherry picked change, but after the fact, I would have to\ncompare the cherry picked change with the one it came from, and figure out\nwhere conflicts had to be resolved.\n\nThanks,\nDavid\n"},{"id":"82181","messageId":"20080704001003.GA19053@atjola.homenet","threadId":"14280","inReplyTo":"20080703223949.GA23092@old.davidb.org","subject":"Re: Cherry picking instead of merges.","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2008-07-04T00:10:03Z","receivedAt":"2008-07-04T00:10:03Z","isPatch":false,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2008.07.03 15:39:49 -0700, David Brown wrote:\n> On Thu, Jul 03, 2008 at 02:18:53PM -0700, Linus Torvalds wrote:\n>\n>> End result: you have a nice merge with nice history that actually\n>> converges at a common point, but you effectively did the merge\n>> resolution one commit at a time with cherry-picking (or \"git rebase\",\n>> which is obviously just a convenient shorthand for cherry-picking\n>> everything).\n>\n> I'm still not clear how the one-commit-at-a-time resolution gets\n> recorded anywhere (except in the cherry-picking branch).\n\nThey don't get recorded. Git does not store how merges happened in some\ndiffs or whatever, it just stores the end result. So what Linus\nsuggested was to reuse the end result that you already have to create\nthe merge commit.\n\nSay you have 5 commits like this:\n\n  A---B---C\n   \\\n    D---E\n\nNow there are two ways to get the changes from D and E ontop of C. The\nfirst one is cherry-picking, which leads to:\n\n  A---B---C---D'---E'\n   \\\n    D---E\n\nThe other one is merging:\n\n  A---B---C---M\n   \\         /\n    D---E---/\n\nOf course, you should end up with the same tree either way. It's just a\ndifferent way of getting towards that final state. So commit E' and\ncommit M, while different commits, would point to the same tree object.\n\nNow if you want to create that merge commit M, and already have E' (like\nyou do, as you already did all those cherry-picks), you can use what\nLinus suggested. You start the merge, ignore any conflicts and just tell\ngit to use the tree that E' is pointing to instead.\n\nBjörn\n"},{"id":"82186","messageId":"alpine.LFD.1.10.0807031735330.2815@woody.linux-foundation.org","threadId":"14280","inReplyTo":"20080703223949.GA23092@old.davidb.org","subject":"Re: Cherry picking instead of merges.","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2008-07-04T00:39:44Z","receivedAt":"2008-07-04T00:39:44Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 3 Jul 2008, David Brown wrote:\n> \n> I'm still not clear how the one-commit-at-a-time resolution gets recorded\n> anywhere (except in the cherry-picking branch).\n\nFor merges, the _only_ thing that matters from a \"resolution\" standpoint \nis that the history joins together. And it doesn't matter if it joins \ntogether fifty times or once - only the last point is relevant, since that \nbecomes the last point of shared state.\n\n> It seems to be that I would need to do multiple merges, one at each point\n> where there is a conflict that I had to resolved.  I would remember this as\n> I did each cherry picked change, but after the fact, I would have to\n> compare the cherry picked change with the one it came from, and figure out\n> where conflicts had to be resolved.\n\nNo, because you simply don't care. You only care about the final result. \nWith a single merge, there is only a single merge-point, and a single \nresult. The advantage of doing the cherry-pick is just that it splits the \ndecision on how to merge up into many smaller decisions (that is often the \n_dis_advantage of cherry-picking too - it often makes for more work, even \nif the individual work may be simpler).\n\nBut once you've done all the small cherry-pick decisions, you'd only make \none final merge that takes that final result as-is. Any future work will \nthen know about the fact that you have a new common base point.\n\n\t\tLinus\n"},{"id":"82198","messageId":"20080704044032.GA4445@old.davidb.org","threadId":"14280","inReplyTo":"20080704001003.GA19053@atjola.homenet","subject":"Re: Cherry picking instead of merges.","fromName":"David Brown","fromEmail":"git@davidb.org","sentAt":"2008-07-04T04:40:32Z","receivedAt":"2008-07-04T04:40:32Z","isPatch":false,"sender":{"key":"git@davidb.org","avatar":"https://gravatar.com/avatar/94c86a2938470a74c2eac5e2b69afc0871f79a660295c02219597aba8cb101c1?d=mp&s=160"},"body":"On Fri, Jul 04, 2008 at 02:10:03AM +0200, Björn Steinbrink wrote:\n\n>The other one is merging:\n>\n>  A---B---C---M\n>   \\         /\n>    D---E---/\n>\n>Of course, you should end up with the same tree either way. It's just a\n>different way of getting towards that final state. So commit E' and\n>commit M, while different commits, would point to the same tree object.\n\nOk.  I guess I need to explain a little further.  The advice I've gotten is\ngood, BTW.\n\nAfter we've resolved the merge and committed it, we've then discovered that\nit doesn't work.  However, there are around 100 commits on both branches of\nthe merges and it would be nice to come up with some way of doing something\nlike a bisect.\n\nThe trick is that the branch being merged in doesn't actually work on our\nplatform, so I can't just test the alternate branch.\n\nBut, git-bisect isn't being all that helpful here.  The problem is that the\nonly conflicts we resolved is how the two trees were put together.  Picking\npoints in the middle seem to generate lots of similar, but not quite the\nsame conflicts.\n\nA cherry-picked tree would allow for an easy bisect, since all of the\nintermediary versions would work.  If I somehow knew magical points within\nthe other tree I could do some number of merges and the bisect would still\nwork.  I suppose I could do the merges one at a time, but it would make the\nhistory rather verbose.\n\nThanks,\nDavid\n"},{"id":"82199","messageId":"alpine.LFD.1.10.0807032221190.2815@woody.linux-foundation.org","threadId":"14280","inReplyTo":"20080704044032.GA4445@old.davidb.org","subject":"Re: Cherry picking instead of merges.","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2008-07-04T05:30:32Z","receivedAt":"2008-07-04T05:30:32Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 3 Jul 2008, David Brown wrote:\n> \n> A cherry-picked tree would allow for an easy bisect, since all of the\n> intermediary versions would work.  If I somehow knew magical points within\n> the other tree I could do some number of merges and the bisect would still\n> work.  I suppose I could do the merges one at a time, but it would make the\n> history rather verbose.\n\nWhy do you want to worry so much about bisecting the merge?\n\nYou should basically expect that normally, a merge doesn't cause new bugs \nin itself. And if it does, the most common case is a fairly obvious \nmismerge (we've had a number of those in the kernel, but they weren't all \nthat mysterious). So _planning_ for a subtle bisection failure sounds a \nbit strange and counter-productive.\n\nSo don't plan for it, and don't make it a primary issue for your workflow. \n\nThen, *after* you have a merge, and the unlucky thing happens where the \nmerge is actually the thing that introduces the bug, and it's not obvious \nwhat the exact interaction is, and bisection didn't help you pinpoint it \n(because it really was the merge), *that* is when you might then choose to \nre-do the rebase in a temporary branch, and then bisect that re-linearized \nhistory. \n\nSo basically:\n\n - keep the history clean and obvious\n\n - make it fairly straightforward and don't worry about the unlikely case.\n\n - don't do something painful just because bad things _can_ happen (they \n   can happen regardless of what you do)\n\n - because in the unlikely situation that bad things happen, you can \n   always then go back and do things the other way around and pinpoint \n   where the fault is that way.\n\nIOW, let's say that you really do bisect things down to a merge and cannot \nsee what the fault in that merge is, you can literally do\n\n\t# create a test-branch with the 'remote' side of the merge\n\tgit checkout -b test-branch merge^2\n\n\t# rebase that remote side on top of the local side\n\tgit rebase merge^\n\nand now you've linearized the merge temporarily just to be able to bisect \nin that temporary branch what the bad interaction is. But once you've \nbisected it, the temporary branch is again just junk - there's no real \nvalue in saving it, because once you know _why_ the bug happened, you're \njust better off going back to the original history and just fixing it (and \ndocumenting the bug through the fix, rather than by addign extra-ugly \nhistory).\n\n\t\tLinus\n"},{"id":"82201","messageId":"486DC4F2.70608@viscovery.net","threadId":"14280","inReplyTo":"alpine.LFD.1.10.0807032221190.2815@woody.linux-foundation.org","subject":"Re: Cherry picking instead of merges.","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-07-04T06:36:34Z","receivedAt":"2008-07-04T06:36:34Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Linus Torvalds schrieb:\n> IOW, let's say that you really do bisect things down to a merge and cannot \n> see what the fault in that merge is, you can literally do\n> \n> \t# create a test-branch with the 'remote' side of the merge\n> \tgit checkout -b test-branch merge^2\n> \n> \t# rebase that remote side on top of the local side\n> \tgit rebase merge^\n> \n> and now you've linearized the merge temporarily just to be able to bisect \n> in that temporary branch what the bad interaction is. But once you've \n> bisected it, the temporary branch is again just junk - there's no real \n> value in saving it, because once you know _why_ the bug happened, you're \n> just better off going back to the original history and just fixing it (and \n> documenting the bug through the fix, rather than by addign extra-ugly \n> history).\n\nFWIW, the same thing in different words is written in section\n\n\"Why bisecting merge commits can be harder than bisecting linear history\"\n\nof Documentation/user-manual.txt.\n\n-- Hannes\n"},{"id":"82241","messageId":"alpine.LFD.1.10.0807040939150.2815@woody.linux-foundation.org","threadId":"14280","inReplyTo":"486DC4F2.70608@viscovery.net","subject":"Re: Cherry picking instead of merges.","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2008-07-04T16:47:49Z","receivedAt":"2008-07-04T16:47:49Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 4 Jul 2008, Johannes Sixt wrote:\n> \n> FWIW, the same thing in different words is written in section\n> \n> \"Why bisecting merge commits can be harder than bisecting linear history\"\n> \n> of Documentation/user-manual.txt.\n\nI don't think that's the same thign at all.\n\nThat section basically says \"just keep things linear\". Which I very much \ndisagree with. Trying to keep things linear just doesn't work if you work \ntogether with other people - since you have to rewrite history.\n\nSo my argument was the exact _reverse_. Don't try to keep things linear, \nbecause it doesn't _work_ right. Do the merges. They will very seldom \ncause subtle merge problems (non-subtle ones are much more common, but \ntrivial to handle), and they will mean that you can work effectively \ntogethr with other people.\n\nAnd then, _if_ you have a merge that you really cannot figure out why it \nbreaks, at that point you can _temporarily_ linearize the git history \nafter-the-fact just as easily as you would ever have done before-the-fact.\n\nIn other words: linearization throws away real and useful information. You \ncan always linearize afterwards for bisection purposes or whatever, but \nyou can never _un_linearize because you've thrown away the information.\n\nSo it's much better to just do merges and keep the history, and then there \nare ways to rewrite the history later if you really need it.\n\nThat said - I think it's good practice and perfectly sane to do things \nlike git-rebase to rewrite the history in a _private_ tree that contains \nonly your own modifications and has never been public (where \"applied \nemailed patches from others\" still counts as your own work).\n\nThe \"don't linearize\" mantra really only is about commits that have ever \nbeen in anybody elses repository (and whether they _came_ from there, or \nwhether they came from you but were public to others is immaterial).\n\n\t\t\tLinus\n"}]}