{"thread":{"id":"21921","subject":"Help: approach for rebasing to older commits after merging more recent commits","startedAt":"2009-12-09T20:04:26Z","lastAt":"2009-12-14T21:33:30Z","messageCount":3,"participants":["Jay Soffian","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"129659","messageId":"76718490912091204u3a4596fdi504005624d5a5bce@mail.gmail.com","threadId":"21921","inReplyTo":null,"subject":"Help: approach for rebasing to older commits after merging more recent commits","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-12-09T20:04:26Z","receivedAt":"2009-12-09T20:04:26Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"I have an interesting problem I'm not sure how best to tackle.\n\nA small development team is basing its product on an upstream git repo that is\nitself an svn clone. Currently the process looks like this:\n\nr1--r2--r3--r4--r5   upstream trunk   (git svn clone)\n \\       \\       \\\n  A---B---C---D---E  local trunk      (git clone of upstream)\n       \\     /\n        F---G        developerN trunk (git clones of local)\n\nSo local trunk has both daily merges from the local developers, as well as\nless periodic (typically weekly) merges from upstream trunk. The reason being\nthat it is necessary to remain on top of the upstream bleeding edge.\n\nThis works out okay, but there is a minor problem and a major problem.\n\nThe minor problem is that the local trunk is cluttered with the developerN\nmerges. That is easy to solve by having local developers rebase before pushing\nto local trunk. That would look like:\n\nr1--r2--r3--r4--r5            upstream trunk\n \\       \\       \\\n  A---B---C---D---E---F'---G'  local trunk\n\nThe major problem is that local trunk is also cluttered with merges from\nupstream. The is a problem because at some point in the future, upstream\nis going to declare some rN as being officially blessed. And we're going to\nwant to rewind any rN changes past that point.\n\nSo the question is, what's the best way to do this? Say r2 is blessed by\nupstream. The obvious thing to do (I think...) is:\n\n(local-trunk)$ git rebase -i r2\n\nremoving C and E from the pick list.\n\nBut, occassionally the merges from upstream require much conflict resolution.\nWould enabling rerere during merges help with the rebasing? I would want to\nreuse as much conflict resolution as possible.\n\nIs there a better approach altogether? Should we be doing something other\nthan merging to stay atop upstream?\n\nSuggestions/comments greatly appreciated.\n\nj.\n"},{"id":"129898","messageId":"76718490912141238k4ca1ba55jeff928efe875f020@mail.gmail.com","threadId":"21921","inReplyTo":"76718490912091204u3a4596fdi504005624d5a5bce@mail.gmail.com","subject":"Help: approach for rebasing to older commits after merging more recent commits","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-12-14T20:38:32Z","receivedAt":"2009-12-14T20:38:32Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"[He asks again...]\n\nI have an interesting problem I'm not sure how best to tackle.\n\nA small development team is basing its product on an upstream git repo that is\nitself an svn clone. Currently the process looks like this:\n\nr1--r2--r3--r4--r5   upstream trunk   (git svn clone)\n \\       \\       \\\n A---B---C---D---E  local trunk      (git clone of upstream)\n      \\     /\n       F---G        developerN trunk (git clones of local)\n\nSo local trunk has both daily merges from the local developers, as well as\nless periodic (typically weekly) merges from upstream trunk. The reason being\nthat it is necessary to remain on top of the upstream bleeding edge.\n\nThis works out okay, but there is a minor problem and a major problem.\n\nThe minor problem is that the local trunk is cluttered with the developerN\nmerges. That is easy to solve by having local developers rebase before pushing\nto local trunk. That would look like:\n\nr1--r2--r3--r4--r5            upstream trunk\n \\       \\       \\\n A---B---C---D---E---F'---G'  local trunk\n\nThe major problem is that local trunk is also cluttered with merges from\nupstream. The is a problem because at some point in the future, upstream\nis going to declare some rN as being officially blessed. And we're going to\nwant to rewind any rN changes past that point.\n\nSo the question is, what's the best way to do this? Say r2 is blessed by\nupstream. The obvious thing to do (I think...) is:\n\n(local-trunk)$ git rebase -i r2\n\nremoving C and E from the pick list.\n\nBut, occassionally the merges from upstream require much conflict resolution.\nWould enabling rerere during merges help with the rebasing? I would want to\nreuse as much conflict resolution as possible.\n\nIs there a better approach altogether? Should we be doing something other\nthan merging to stay atop upstream?\n\nSuggestions/comments greatly appreciated.\n\nj.\n"},{"id":"129906","messageId":"7vy6l5gs0l.fsf@alter.siamese.dyndns.org","threadId":"21921","inReplyTo":"76718490912141238k4ca1ba55jeff928efe875f020@mail.gmail.com","subject":"Re: Help: approach for rebasing to older commits after merging more recent commits","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-12-14T21:33:30Z","receivedAt":"2009-12-14T21:33:30Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jay Soffian <jaysoffian@gmail.com> writes:\n\n> [He asks again...]\n>\n> I have an interesting problem I'm not sure how best to tackle.\n>\n> A small development team is basing its product on an upstream git repo that is\n> itself an svn clone. Currently the process looks like this:\n>\n> r1--r2--r3--r4--r5   upstream trunk   (git svn clone)\n>  \\       \\       \\\n>  A---B---C---D---E  local trunk      (git clone of upstream)\n>       \\     /\n>        F---G        developerN trunk (git clones of local)\n>\n> So local trunk has both daily merges from the local developers, as well as\n> less periodic (typically weekly) merges from upstream trunk. The reason being\n> that it is necessary to remain on top of the upstream bleeding edge.\n>\n> This works out okay, but there is a minor problem and a major problem.\n>\n> The minor problem is that the local trunk is cluttered with the developerN\n> merges. That is easy to solve by having local developers rebase before pushing\n> to local trunk. That would look like:\n>\n> r1--r2--r3--r4--r5            upstream trunk\n>  \\       \\       \\\n>  A---B---C---D---E---F'---G'  local trunk\n>\n> The major problem is that local trunk is also cluttered with merges from\n> upstream. The is a problem because at some point in the future, upstream\n> is going to declare some rN as being officially blessed. And we're going to\n> want to rewind any rN changes past that point.\n>\n> So the question is, what's the best way to do this? Say r2 is blessed by\n> upstream.\n\nYou should re-think your earlier claim:\n\n    The reason being that it is necessary to remain on top of the upstream\n    bleeding edge.\n\nand then think about ways you can take advantage of the distributed nature\nof git, especially the topic branch workflow it supports well.\n\nThe key realization is this:\n\n    It is necessary to remain on top of the upstream\" does not mean \"all\n    of the new development done by my group must build _on top of_ the\n    upstream\" at all.\n\nfor one obvious reason: near the tip of the upstream is not necessarily\nwhat you want in your final product.  If the \"blessed\" point will be r2,\nyou won't want any topic to be based on r3 or later before forking your\nrelease branch that contains the upstream up to r2.\n\nYou _would_ want to remain as compatible as possible with upstream later\nthan r2 even if the \"blessed\" point _for this cycle_ is r2, so you would\nneed a daily integration testing branch that is rebuilt by merging all the\ntopics from your group _and_ upstream tip and run your tests there.  But\nonce you know which commit from the upstream side (r2 in your example)\nwill be the one your group will base your changes on and go into a pre-\nrelease mode, you will likely to want to have _another_ test integration\nbranch to merge all the topics from your group that have forked from a\ncommit before r2, on top of r2.  There _will_ be topics from some members\nwho unfortunately based their topic on commits newer than r2 and they need\nto adjust their work on r2 or older.  If they didn't depend on new API,\nnew features, or modified semantics r3 or later introduced, this rebase\nshould be trivial.  On the other hand, if they did depend on new things,\nthe project management needs to make a decision.  You may choose to\nkeep the topic out of your upcoming release (because it will depend on\nfeatures of upstream newer than the \"blassed\" upstream release your\nproduct will be based on), or you may choose to \"backport\" the upstream\nfeatures the topic needs without slurping all the new and unstable\nupstream features (e.g. if a topic based its work on a new feature\nimplemented in r5, but what r3 or r4 do are unnecessary for it, or any\nother topics in your product, you will cherry-pick r5 on top of r2 and\nthen rebase the topic on top of the result). \n\nIt also means that your group members try not to base their work on the\ndaily integration branch which is your 'master' branch current is, nor\nrebase their work on it before merging.  Instead, fork from a known good\nstate where the result of building on it and then merging that with the\ntip of the upstream and with other topics won't introduce excessive\nconflicts.\n\nThe project manager may want to establish and maintain a reasonable\nbaseline that:\n\n - merges from upstream trunk (but not its tip) only occasionally; Being\n   behind is perfectly fine and even preferable than being too hasty and\n   merging r3 and later into this branch.\n\n - merges from group members' topics _only_ after they are _fully_\n   completed _and_ you are sure that you want these topics in your next\n   release.\n\nand have group members fork from its tip.  I'd recommend using 'master'\nfor that.  Don't let random topics that are half-done (i.e. \"this doesn't\ndo what it should do, but it hopefully doesn't break other things\") merged\ninto this branch.\n\nThen every test cycle (once a day, or continuous, it doesn't matter)\ncreates a throw-away test branch to the tip of this branch, merges all the\ntopics that are still cooking and testable, and merges from the updated\nupstream.  This may need conflict resolution, and rerere will help here.\nAnd test the result.  That way you will ensure that you will be \"on top of\nthe bleeding edge\".\n\nWhen conflicts with the updated upstream become getting excessive, it is a\ngood sign that you would want to update the \"baseline\" (see above) with\n(an early part of) the upstream.\n\nIf conflicts between topics of your group members become excessive, it is\na sign that you are not partitioning the work correctly.  SCM is never a\nsubstitute for developer communication and you may need to have the\nmembers involved in the conflict talk with each other and resolve the\nconflict between themselves.  E.g. they may want to decide to merge their\nwork so far and build their topics upon a consolidated base.\n\nAnd that \"reasonable baseline\", as long as it won't overstep 'r2' in the\nend, will be directly the branch you cut your release from.  On the day\nyou decide to base your next product on r2, you will fork 'release' branch\nfrom the tip of 'master', and merge up to 'r2' from the upstream, and you\nhave your release with fully cooked topics.  If on the other hand you have\nalready merged from the upstream up to 'r5' to 'master', then you would\nneed to build a separate 'release' branch, forking from some commits in\n'master' before the branch merged commits later than 'r2' from the\nupstream.  Betweeen this fork-point and the tip of your 'master', there\nwill be some topics that have graduated to 'master'.  You need to examine\nthem and see if they merge to 'release' without dragging 'r3' and later in\nfrom the upstream, and make the management decision I mentioned 60 lines\nago.\n"}]}