{"thread":{"id":"17030","subject":"Re: [PATCH v2] Add -ftabstop=WIDTH","startedAt":"2009-01-07T01:52:43Z","lastAt":"2009-01-07T01:52:43Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"99529","messageId":"7v4p0bevbo.fsf@gitster.siamese.dyndns.org","threadId":"17030","inReplyTo":"70318cbf0901061637l29837d14nfaa8a3106652b7e5@mail.gmail.com","subject":"Re: [PATCH v2] Add -ftabstop=WIDTH","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2009-01-07T01:52:43Z","receivedAt":"2009-01-07T01:52:43Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Christopher Li\" <sparse@chrisli.org> writes:\n\n> So here is my understanding of what you described. The 'pu' branch is\n> for highly experiment changes. The 'pu' branch can rewind and rewrite\n> the history. Once the patch merge to 'next', the history will not change\n> any more.  All update will stay as incremental changes.\n>\n> One question, does user suffer from conflict when then pull from the 'pu'\n> branch?\n\n[jc: I think this is going to the tangent for \"sparse\" list;\n redirecting to git@vger.kernel.org] \n\nI think they will, if they \"pull\", but:\n\n (1) They are upfront strongly discouraged from doing so by the way 'pu'\n     is advertised.  \"It is a collection of not yet even testable series,\n     and any patch in it can be dropped and replaced\".\n\n (2) They can instead 'fetch + rebase' the changes they made on top of\n     previous round of 'pu', instead of 'pull' (= 'fetch + merge') to\n     mitigate the pain.\n\nSuppose I have two un-ready topics A and B in pu, and you base your work\nX, Y, and Z on what was done by A (in other words, you are not interested\nin topic B at all).  Then suppose one of A or B is replaced by wildly\ndifferent versions, and 'pu' is rebuilt:\n\n                    X---Y---Z (private changes)\n                   /\n             A----B pu (old)\n            /\n           /              A'---B' pu (new)\n          /              /  \n     ----o----o----o----o\n\n        Fig. 1\n\nIf you pull, even if A was not the one that was replaced, the merge will\nhave severe conflicts from the changes involved in the other series\n(i.e. B).\n\nBut if A and A' did not change drastically in the meantime, rebasing X, Y,\nZ on top of the updated pu (i.e. B') would not conflict:\n\n\n                    X---Y---Z (private changes)\n                   /\n             A----B pu (old)     X'--Y'--Z' (private changes rebased)\n            /                   / \n           /              A'---B' pu (new)\n          /              /  \n     ----o----o----o----o\n\n        Fig. 2\n\nIn either case, if A (i.e. the work X, Y, Z were made on top of) was\nrewritten drastically to become A', neither rebase nor merge will be of\nhelp anyway, and it would not help if the new A' were recorded as an\nincremental change from A without rebasing/rewinding 'pu' itself, either.\n\nBut at least 'fetch + rebase' would avoid the issue when it is only the\nother topics in 'pu' that you are not interested in that were replaced or\nrewritten drastically.\n\nBy the way, I drew A and B as if they are single patches made _directly_\non pu, only for simplicity's sake.  In reality, all topics fork from more\nstable branches (maint or master), and the only commits you see on 'next'\nor 'pu' are merges.\n\nWhich means, even if we assume that you never rewind 'pu':\n\n> Here is an idea, I am just thinking it out loud.\n>\n> Given 'pu' branch like this, (each [ ] is a commit, A1 is a follow up\n> change for A0).\n>\n> 'pu' branch: [A0] - [B0] - [A1] - [C0] -[B1] -[A2]\n\n... the history of 'pu' won't look like this.\n\nIt would be more like this:\n\n           .-----[B0]----[B1]  ...  topic branch for B\n          /         \\       \\\n         /  ...--*---*---*---* ...  pu\n        /       /       /\n       /       [A0]---[A1]     ...  topic branch for A\n      /       /\n     o-------o----o master\n\n        Fig. 3\n\n    Side note: my 'next' never rewinds except for once every major\n    release, so the above \"repeated merge from topics into the branch\"\n    depicts how 'next' works pretty closely.\n\nOr, if you rebuild 'pu' every day, it would be more like\nthis one day, and;\n\n           .-----[B0]          ...  topic branch for B\n          /         \\        \n         /  ...--*---*         ...  pu\n        /       /        \n       /       [A0]            ...  topic branch for A\n      /       /\n     o-------o----o master\n\n        Fig. 4\n\nthe next day it would look like this:\n\n           .-----[B0]----[B1]  ...  topic branch for B\n          /                 \\\n         /          ...--*---* ...  pu\n        /               /\n       /       [A0]---[A1]     ...  topic branch for A\n      /       /\n     o-------o----o master\n\n        Fig. 5\n\nIn either case, unless a topic began with too many early issues and\nmistakes that requires a wholesale replacement, you can expect the\naccumulation of A0,A1,...,An to end up in a good shape eventually and then\nyou have a good incremental history you would want to preserve.\n\nAt that point, you can merge the tip of the branch (i.e. An) to master and\ndeclare victory.  'pu' or 'next' may have a messy history that would make\nanybody who looks at gitk output barf, but that is Ok.\n\n> We can have a temporary clean up branch fork from 'pu' looks like this:\n>\n> 'tmp_clean' branch: [A0 + A1 + A2] - [B0 + B1] - [C0]\n>\n>  'tmp_clean' and 'pu' will generate exactly the same tree. The\n> only different is the history path it take to get there.\n>\n> Then we can have 'pu' merge from 'tmp_clean', with zero text\n> changes. The only change is the change log and we tell git\n> that the merge is for history clean up. So when we launch\n> \"git log\", by default it will follow the \"tmp_clean\" path rather\n> than the original \"pu\" path.\n>\n> So it just provide \"alternative\" view of the history without introduce\n> real changes. When user pull from 'pu', it can automatically get the\n> cleanup version of the history without introduce conflicts.\n>\n> It seems it can have the best of both worlds. I am not sure weather\n> it is doable or worth while to do though.\n\nI do not think it is worth it, for two reasons:\n\n (1) That won't help the case where others based on their work on un-ready\n     changes in 'pu', as I described earlier, anyway.\n\n (2) If you do not have any work on top of the un-ready 'pu', in other\n     words, if you are just following along, then \"git checkout origin/pu\"\n     won't care if yesterday's pu and today's pu are not fast-forward\n     anyway.\n\nIf you rebuild 'pu' from scratch every day, without keeping many repeated\nmerges so far, it will give a pleasant read in \"gitk master..pu\" than\n'next' that never rewinds whose \"gitk master..next\" output is a disaster\n;-).\n\n\nThere is one trick my experienced users use, knowing how 'pu' is managed.\n\nIf today's 'pu' looked like Fig. 4 above, and you are interested in the\ntopic A, you can find the tip of that topic by looking at:\n\n        git log --first-parent master..pu\n\nIt is what was merged to the merge that is at the second from the tip of\n'pu' branch, i.e. \"pu^^2 == A0\".\n\nAnd you fork your own enhancement to that topic by forking from A0,\ncreating \"my-A\" branch.  Your own commits go to that branch.\n\nNext day you will find a history that is depicted in Fig. 5 and find the\ntip of topic A the same way.  It is at A1.\n\nThen you rebase \"my-A\" on top of A1 (or merge A1 to \"my-A\" branch).  You\nreally do not care about other uncooked garbage in 'pu', and you can\nignore them this way.\n\nIf you are working on more than one such \"topics started by others\", you\nwill have many my-A, my-B, ... branches.  You treat your 'master' branch\nas if it is my 'next', i.e. fork from the last major release, merging all\nof my-X branches, and employ the aggregated result for your own use.\n"}]}