{"thread":{"id":"20718","subject":"Git workflow: Managing topic branches.","startedAt":"2009-08-24T14:44:17Z","lastAt":"2009-08-25T07:07:37Z","messageCount":2,"participants":["Thomas Adam","Johannes Sixt"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"121642","messageId":"18071eea0908240744g359f8b1ey622259e89ac7592a@mail.gmail.com","threadId":"20718","inReplyTo":null,"subject":"Git workflow: Managing topic branches.","fromName":"Thomas Adam","fromEmail":"thomas.adam22@gmail.com","sentAt":"2009-08-24T14:44:17Z","receivedAt":"2009-08-24T14:44:17Z","isPatch":false,"sender":{"key":"thomas.adam22@gmail.com","avatar":"https://gravatar.com/avatar/137f9858bc6bfd5b2f743aefd988c81ce0cbd306248889df80e269519cfc8741?d=mp&s=160"},"body":"Hello all,\n\nI've a question regarding a specific workflow which we're currently using\nhere at work, but I am not convinced it's particularly brilliant -- and\nthere's a number of oddities about it which I'd like to discus -- perhaps\nwith a way of coming up with a new solution.\n\nWe have a work-flow such as this:\n\n\n         o---o---o---o--o--o (stable)\n        /\no---o---o---o---o---o---o  (master)\n     \\\n      o---o--o---o---o---o (featureA)\n\n\nMaster is where all our stable code lives after a release -- and also where\nbug-fixes for released code is put.  When we're working on a new feature,\nalmost all developers here will push (in this case) to \"featureA\" ---\neventually this branch will get merged into master, tagged and the code\nreleased.  Then a new branch, \"featureB\" is created off it, and process\ncontinues.  (Yes, we're using Git in a very CVS-like way, alas.)\n\nPeriodically though we need to release updates for our product.  This the\narea which is where my question lies about whether the workflow is good or\nnot.  Here's how we do that:\n\nWe have a branch called \"stable\" which contains all of our released code\nplus any updates release.  When we wish to create a new update, we create a\nnew branch off the tip of stable:\n\n\n                            o---o---o---o (updateN)\n                           /\n         o---o---o---o--o--o (stable)\n        /\no---o---o---o---o---o---o  (master)\n     \\\n      o---o--o---o---o---o (featureA)\n\n\nBecause bug-fixes happen on Master, we now want those fixes to appear on the\nupdateN branch so we can create a tarball from them (to release to our\ncustomers).  We're using \"git cherry\" to get a list of SHA1s that are\nrelevant between updateN and master, as in:\n\ngit cherry updateN master\n\n... and then manually deciding (based on it's \"+\"/\"-\" output whether that\nSHA1 needs to be used and then:\n\ngit cherry-pick SHA1\n\n... onto updateN as appropriate.  This branch is then pushed to our\n\"central\" server as a public branch, is checked out elsewhere on another\nmacine to build this update.  If that's successful, various other bits and\nbobs in terms of meta data is added into the commits onto the updateN branch\nand it is merged into stable:\n\n                            o---o---o---o (updateN)\n                           /            / <-- (merge updateN to stable)\n         o---o---o---o--o--o------------o (stable)\n        /\no---o---o---o---o---o---o  (master)\n     \\\n      o---o--o---o---o---o (featureA)\n\nThe \"stable\" branch is then merged into master so that when we create\nanother \"featureX\" branch, it's at a point where it's on a known set of\nreleased code.\n\nSo my questions:  I am not convinced this workflow is very elegant, or\nindeed a particularly good solution to what we're wanting to do.  Because\nthe cherry-picking that happens to the \"updateN\" branch happens from\n\"master\" which itself will have had several local topic-branches merged into\nit from other developers -- I've found \"git-cherry\" to give unreliable\nresults -- in some cases, the same two commits with the same data appear on\nthe \"updateN\" branch -- using git patch-id manually with processing on top\nof that seems to give a much shorter and succient set of SHA1s to\ncherry-pick.  (But this is kind of peripheral to my question).\n\nI am interested to know if this branch and merge scenario is the right one.\nI also don't believe we're using git-cherry in the right way to isolate the\ncorrect commits.  I have toyed with the idea of rebasing, but am hesitant on\nthis idea, and unsure if that would even be the right way to go --\nespecially seeing as all the branches mentioned are tracking branches.\n\nThe eventual aim of all of this is to try and automate building of these\nupdates -- but we sure as hell can't do that at the moment with our current\nworkflow.  If anyone has any suggestions on any of this, I'd appreciate it.\nIf I've not explained things adequately. shout and I'll try and clarify.\n\nThanks in advance,\n\nThomas Adam\n"},{"id":"121717","messageId":"4A938DB9.6030907@viscovery.net","threadId":"20718","inReplyTo":"18071eea0908240744g359f8b1ey622259e89ac7592a@mail.gmail.com","subject":"Re: Git workflow: Managing topic branches.","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2009-08-25T07:07:37Z","receivedAt":"2009-08-25T07:07:37Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Thomas Adam schrieb:\n> We have a work-flow such as this:\n> \n> \n>          o---o---o---o--o--o (stable)\n>         /\n> o---o---o---o---o---o---o  (master)\n>      \\\n>       o---o--o---o---o---o (featureA)\n> \n> \n> Master is where all our stable code lives after a release -- and also where\n> bug-fixes for released code is put.  When we're working on a new feature,\n> almost all developers here will push (in this case) to \"featureA\" ---\n> eventually this branch will get merged into master, tagged and the code\n> released.  Then a new branch, \"featureB\" is created off it, and process\n> continues.  (Yes, we're using Git in a very CVS-like way, alas.)\n> \n> Periodically though we need to release updates for our product.  This the\n> area which is where my question lies about whether the workflow is good or\n> not.  Here's how we do that:\n> \n> We have a branch called \"stable\" which contains all of our released code\n> plus any updates release.  When we wish to create a new update, we create a\n> new branch off the tip of stable:\n> \n> \n>                             o---o---o---o (updateN)\n>                            /\n>          o---o---o---o--o--o (stable)\n>         /\n> o---o---o---o---o---o---o  (master)\n>      \\\n>       o---o--o---o---o---o (featureA)\n> \n> \n> Because bug-fixes happen on Master, we now want those fixes to appear on the\n> updateN branch so we can create a tarball from them (to release to our\n> customers).  We're using \"git cherry\" to get a list of SHA1s that are\n> relevant between updateN and master, as in:\n> \n> git cherry updateN master\n> \n> ... and then manually deciding (based on it's \"+\"/\"-\" output whether that\n> SHA1 needs to be used and then:\n> \n> git cherry-pick SHA1\n> \n> ... onto updateN as appropriate.\n\nYour workflow looks quite reasonable except for this last part. You should\nmake your history look like this:\n\n          o--o--o--o--o         stable\n         /       \\     \\\n--o--B--o--o--o---o--o--o--o    master\n      \\\n       o--o--o--o--o--o         featureA\n\nInstead of cherry-picking commits onto updateN (or stable), your\ndevelopers should think which branches need the change that they are about\nto commit. If it is a serious bug-fix, then it should be enter the picture\non stable, not on master or feature branches. The important part is that\nbranch stable is merged into branch master (at least after each release,\nbut perhaps even more often).\n\nNow assume that your developer discovers a bug while she was developing on\nfeatureA that must go into stable. Previously you would have done it this\nway (I presume):\n\n--o--B--o--o--o---o--o--o--o--o    master\n     |   \\       /     /     /\n     |    o--o--o--o--o-----F'     stable\n      \\\n       o--o--o--o--o--o--F         featureA\n\nThat is, the fix F was committed on the feature branch and later was\ncherry-picked onto stable as F' and then merged into master. But she\nshould have done this instead:\n\n--o--B--o--o--o---o--o--o--o--o    master\n     |   \\       /     /     /\n     |    o--o--o--o--o-----o      stable\n     |\\                    /\n     | F------------------<        fixF\n      \\                    \\\n       o--o--o--o--o--o-----o      featureA\n\nThat is, fix F should go on its own bugfix-branch and that branch is\nmerged into stable as well as into featureA (but only if the fix is really\nneeded there); stable is in turn merged into master again. The new branch\ngrows from a commit that is in common to all the branches that need the\nfix. Since the fix is needed on featureA as well as on stable, the lastest\npossible branch point is B (where feature A was branch off of master/stable).\n\nSide note: An even better branch point would be the commit that introduced\nthe bug, which must have been B or a commit before it; otherwise the bug\nwould not have shown up during the development of featureA. This way you\ncould make the decision anytime later whether you want to merge the fix\ninto older releases as well.\n\n-- Hannes\n"}]}