{"thread":{"id":"8177","subject":"Opinions on bug fix organisation","startedAt":"2007-05-16T10:38:28Z","lastAt":"2007-05-18T19:50:00Z","messageCount":8,"participants":["Andy Parkins","Brian Gernhardt","Junio C Hamano","Shawn O. Pearce","Martin Langhoff","Johannes Sixt","Jan Hudec"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"42305","messageId":"200705161138.30134.andyparkins@gmail.com","threadId":"8177","inReplyTo":null,"subject":"Opinions on bug fix organisation","fromName":"Andy Parkins","fromEmail":"andyparkins@gmail.com","sentAt":"2007-05-16T10:38:28Z","receivedAt":"2007-05-16T10:38:28Z","isPatch":false,"sender":{"key":"andyparkins@gmail.com","avatar":null},"body":"Hello,\n\nThis is not so much a question about git, but more about history organisation.  \nI'm undecided on the best way to deal with bug fix history.\n\nImagine this situation:\n\n * -- * -- B -- * -- * -- *\n\n\"B\" is a commit that introduced a feature and a bug, that bug is present \nforever more in history (which I think is good - history is history).  I've \npushed the repository to the rest of the developers in the meantime, so there \nis no editing \"B\" and doing some rebase magic.\n\nNow, I want to make a commit that fixes that bug.  These are the options:\n\n * -- * -- B -- * -- * -- * -- F\n\n or\n\n * -- * -- B -- * -- * -- * -- M\n            \\                 /\n             --------------- F\n\nThat is - just commit a fix or, commit the fix, \"F\", directly on \"B\" then \nmerge that fix back to HEAD with \"M\".\n\nI quite like option 2 because it records intent - i.e. \"I wish I could have \ngone back and changed this revision, but I can't\", but it makes a more \ncomplicated history.\n\nWhat do people think?\n\n\n\nAndy\n\n-- \nDr Andy Parkins, M Eng (hons), MIET\nandyparkins@gmail.com\n"},{"id":"42316","messageId":"5C14809D-14D9-4FC9-B8D5-FDBFDA89A369@silverinsanity.com","threadId":"8177","inReplyTo":"200705161138.30134.andyparkins@gmail.com","subject":"Re: Opinions on bug fix organisation","fromName":"Brian Gernhardt","fromEmail":"benji@silverinsanity.com","sentAt":"2007-05-16T14:46:00Z","receivedAt":"2007-05-16T14:46:00Z","isPatch":false,"sender":{"key":"benji@silverinsanity.com","avatar":"https://gravatar.com/avatar/e06c101dbc25c68114d859b4a9ec7cf8a2c52fd2b0270ef0eac0e2e63ff22311?d=mp&s=160"},"body":"\nOn May 16, 2007, at 6:38 AM, Andy Parkins wrote:\n\n> That is - just commit a fix or, commit the fix, \"F\", directly on  \n> \"B\" then\n> merge that fix back to HEAD with \"M\".\n>\n> I quite like option 2 because it records intent - i.e. \"I wish I  \n> could have\n> gone back and changed this revision, but I can't\", but it makes a more\n> complicated history.\n>\n> What do people think?\n\nI just encountered this myself with one of my repos.  I'm developing  \nsolo so I could just rebase if I felt like it, but don't like  \ndeveloping that habit, so I'm probably going with the second one.   \nBut that's because of how I'm developing it.  My master has undergone  \nserious changes recently (since the bug commit), so I'm going back  \nand checking out the bug commit to focus on that issue without  \nanything else that's been changed since then.\n\nMy personal feeling is that the commit should reflect how the fix was  \ndeveloped.  If it's simple fix that you simply wrote on top of the  \nfull branch, commit it that way.  If you had to (or wanted to) go  \nback and develop on top of the original commit, commit it that way.   \nUsually I'll just commit on top of master, but if either I need to  \nremove other complications from the fix or need to introduce the fix  \n(but not everything else) into multiple branches, I'll do the merge.\n\n~~ Brian\n"},{"id":"42320","messageId":"7v1whgfybe.fsf@assigned-by-dhcp.cox.net","threadId":"8177","inReplyTo":"200705161138.30134.andyparkins@gmail.com","subject":"Re: Opinions on bug fix organisation","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-16T17:55:17Z","receivedAt":"2007-05-16T17:55:17Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Andy Parkins <andyparkins@gmail.com> writes:\n\n> I quite like option 2 because it records intent - i.e. \"I wish I could have \n> gone back and changed this revision, but I can't\", but it makes a more \n> complicated history.\n>\n> What do people think?\n\nI think that largely depends on your taste and what other things\nyou have between B and the tip when you contemplate on the fix.\n\nIf you ever have a forkpoint (e.g. maybe soon after B you had a\ntagged release, and maintenance track for that forked from it),\nthen the latter is much more manageable in the long run.  That\nis how 'master' and 'maint' in git.git are managed.  An old bug\nis fixed as close to the introduction of bug as practical (so I\nwould _not_ fork a fix on top of B itself, but apply fix to the\ntip of 'maint'), and then all newer development track that\ncontain breakage B merges the fix from that branch (i.e. 'maint'\nis then merged into 'master' to propagate the fix forward).\n\nThe way 'next' and 'master' works in git.git looks a bit\ndifferent from it, but you will realize that the idea is the\nsame if you look at individual topic branches.  Each topic is\nforked from 'master', gain its own commits and merged to 'next'.\nIts bugs may be discovered later while it still hasn't been\nmerged to 'master'.  I'd _never_ commit a fix to 'next'\ndirectly, but a fix goes to the tip of the topic branch that\nintroduces the bug, and then merged to 'next'.  When the topic\nis reasonably bug-free, it then is merged to 'master' -- at that\npoint, the history of the topic has all the relevant fixes.\n\nIf you think of your straight single strand of pearls (the first\npicture) as a degenerated case that has a topic that includes B\nand ends with the tip, \"merged\" to 'master' in a fast forward\nfashion (i.e. the rightmost commit in the picture is the tip of\nthe topic and at the same time the tip of the 'master'), then\nhaving a fix on top of the 'master' like in your first solution\nis perfectly fine -- it is in line with how topic branches in my\nrepository gets fixed and how the fix is propagated to 'next'\nand then eventually to 'master'.\n\nOn the other hand, if your commits between B and the tip of your\nmaster contain enhancements and fixes to random issues (iow, it\nis not a degenerated merge of a single topic into 'master', but\njust a random set of development), I think your latter approach\nto have only the fix as a separate (temporary) topic and merge\nthat to the tip is inconsistent with your current practice to\nbegin with, and I do not see much merit in it by itself.  If you\nprefer the latter solution (and I obviously do, as that is the\nway git.git repository is maintained), you would also want to\nhave topic branches, where all the enhancements, advances _and_\nfixes related to a single theme go to and then merged to the\nmainline.  That's the history of a theme.  Having branch and\nmerge only for fixes but not for advancement may be \"the history\nof a bug\", but it probably would not buy you much by itself.\n"},{"id":"42331","messageId":"200705162220.15417.andyparkins@gmail.com","threadId":"8177","inReplyTo":"7v1whgfybe.fsf@assigned-by-dhcp.cox.net","subject":"Re: Opinions on bug fix organisation","fromName":"Andy Parkins","fromEmail":"andyparkins@gmail.com","sentAt":"2007-05-16T21:20:13Z","receivedAt":"2007-05-16T21:20:13Z","isPatch":false,"sender":{"key":"andyparkins@gmail.com","avatar":null},"body":"On Wednesday 2007, May 16, Junio C Hamano wrote:\n\n> I think that largely depends on your taste and what other things\n> you have between B and the tip when you contemplate on the fix.\n\nAs always, thank you for the detailed response.  I appreciate the \nthought that goes into answering these questions that flit into my \nmind :-)\n\n> is fixed as close to the introduction of bug as practical (so I\n> would _not_ fork a fix on top of B itself, but apply fix to the\n> tip of 'maint'), and then all newer development track that\n> contain breakage B merges the fix from that branch (i.e. 'maint'\n> is then merged into 'master' to propagate the fix forward).\n\nThe above method is almost a necessity when using git.  If the bug fix \nis committed to master, there is no way to apply that same commit to \nthe maint branch without also grabbing commits you don't want in maint.\n\n> The way 'next' and 'master' works in git.git looks a bit\n> different from it, but you will realize that the idea is the\n> same if you look at individual topic branches.  Each topic is\n> forked from 'master', gain its own commits and merged to 'next'.\n\nI've noticed flows like that when looking at git history.  I always \nthink that it demonstrates the power of git's strong-on-branches stance \nbecause you can almost feel the story of the development without having \nto read any of the commits themselves.  I wonder if other DVCSs \nencourage creation of such a strong narrative?\n\n> Its bugs may be discovered later while it still hasn't been\n> merged to 'master'.  I'd _never_ commit a fix to 'next'\n> directly, but a fix goes to the tip of the topic branch that\n> introduces the bug, and then merged to 'next'.  When the topic\n> is reasonably bug-free, it then is merged to 'master' -- at that\n> point, the history of the topic has all the relevant fixes.\n\nWhat is your preference when, for example, you have already merged a \ntopic to next but then a bug fix appears?\n\n * -- * -- * -- M -- F         * -- * -- * -- M -- m (next)\n               /        or                   /    /\n    B -- * -- *                   B -- * -- * -- F (topic)\n\nF is certainly most appropriate to be on the topic branch, but we create \na perhaps excessively verbose extra merge, m.\n\n> just a random set of development), I think your latter approach\n> to have only the fix as a separate (temporary) topic and merge\n> that to the tip is inconsistent with your current practice to\n> begin with, and I do not see much merit in it by itself.  If you\n> prefer the latter solution (and I obviously do, as that is the\n\nI'm not sure I've understood what you mean here.  Which \"latter\" are you \ntalking about - you've said that you find the latter inconsistent but \nalso that you prefer the latter solution.  I'm lost :-)\n\n> way git.git repository is maintained), you would also want to\n> have topic branches, where all the enhancements, advances _and_\n> fixes related to a single theme go to and then merged to the\n> mainline.  That's the history of a theme.  Having branch and\n> merge only for fixes but not for advancement may be \"the history\n> of a bug\", but it probably would not buy you much by itself.\n\nIt's not so much a matter of it buying you something, it is more that \nwhen you find that bug fix commit in history you can see, by following \nthe fix-branch back to its source, all the revisions that contained \nthat bug at a glance; if you just commit on the end, you have to do the \ndigging yourself, and hope that someone mentioned in the commit message \nwhich commit introduced the bug that that commit fixes.\n\nThe fact that git makes it so easy to branch and merge from a previous \npoint is the thing that even makes this a possibility.  Perhaps I'm \nspoilt now :-)\n\n\nAndy\n-- \nDr Andy Parkins, M Eng (hons), MIET\nandyparkins@gmail.com\n"},{"id":"42333","messageId":"20070516213819.GT3141@spearce.org","threadId":"8177","inReplyTo":"200705162220.15417.andyparkins@gmail.com","subject":"Re: Opinions on bug fix organisation","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-05-16T21:38:19Z","receivedAt":"2007-05-16T21:38:19Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Andy Parkins <andyparkins@gmail.com> wrote:\n> What is your preference when, for example, you have already merged a \n> topic to next but then a bug fix appears?\n> \n>  * -- * -- * -- M -- F         * -- * -- * -- M -- m (next)\n>                /        or                   /    /\n>     B -- * -- *                   B -- * -- * -- F (topic)\n> \n> F is certainly most appropriate to be on the topic branch, but we create \n> a perhaps excessively verbose extra merge, m.\n\nLook at the history of the next branch; the diagram on the right is\nexactly what Junio does.  When topic finally graduates to master,\nonly F is merged to master, making master's own history not show\nthat \"verbose extra merge\" m.  Or M really for that matter, as\nmaster gets its own M'.\n\n-- \nShawn.\n"},{"id":"42336","messageId":"46a038f90705161451v3bf2c04agb95c03f14f236e76@mail.gmail.com","threadId":"8177","inReplyTo":"200705161138.30134.andyparkins@gmail.com","subject":"Re: Opinions on bug fix organisation","fromName":"Martin Langhoff","fromEmail":"martin.langhoff@gmail.com","sentAt":"2007-05-16T21:51:55Z","receivedAt":"2007-05-16T21:51:55Z","isPatch":false,"sender":{"key":"martin.langhoff@gmail.com","avatar":"https://gravatar.com/avatar/1e3f311b6c4c15836501901ca58f8c0b0667246488084ba524d8bc9867e22fd9?d=mp&s=160"},"body":"On 5/16/07, Andy Parkins <andyparkins@gmail.com> wrote:\n> I quite like option 2 because it records intent - i.e. \"I wish I could have\n> gone back and changed this revision, but I can't\", but it makes a more\n> complicated history.\n\nI prefer just letting history show what happened, rather than try to\nget too smart about it ;-) -- and use branches and merges for\nexperimental or feature work. Once a feature or experimental branch is\nmerged into master, further work happens on master (unless there are\nother reasons for it to be maintained).\n\nBugfixes are part of the life of the maint and master branches.\nImagine your \"option 2\" being used to maintain git's maint branch.\nSome bugs live in the code for 6 months. The merge graph would be\nunreadable... and generally the project history would be really hard\nto make sense of.\n\nMost \"special\" practices around branches kind-of work in the\nminimalistic case, but break down badly in real-life sized projects...\n\ncheers,\n\n\nmartin\n"},{"id":"42453","messageId":"464D5FC0.3BBF977F@eudaptics.com","threadId":"8177","inReplyTo":"200705162220.15417.andyparkins@gmail.com","subject":"Re: Opinions on bug fix organisation","fromName":"Johannes Sixt","fromEmail":"j.sixt@eudaptics.com","sentAt":"2007-05-18T08:11:44Z","receivedAt":"2007-05-18T08:11:44Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Andy Parkins wrote:\n> What is your preference when, for example, you have already merged a\n> topic to next but then a bug fix appears?\n> \n>  * -- * -- * -- M -- F         * -- * -- * -- M -- m (next)\n>                /        or                   /    /\n>     B -- * -- *                   B -- * -- * -- F (topic)\n> \n> F is certainly most appropriate to be on the topic branch, but we create\n> a perhaps excessively verbose extra merge, m.\n\nIt depends on whether the topic branch is \"closed\": A topic branch is\n\"closed\" after it is merged into all branches that it is intended to be\nmerged into.\n\nFor example, in our setup we sometimes create topic branches off of\n'maint' because we want to keep the option alive to merge it into\n'maint', although for the time being it is only merged into 'master'\n(main development). If a bug fix appears, we have to add it to 'topic'\nand merge into 'master' again (your second example). 'topic' may never\nmake it into 'maint', but this way we keep the option; hence, 'topic' is\n_not_ \"closed\", yet.\n\n-- Hannes\n"},{"id":"42530","messageId":"20070518195000.GC3327@efreet.light.src","threadId":"8177","inReplyTo":"200705161138.30134.andyparkins@gmail.com","subject":"Re: Opinions on bug fix organisation","fromName":"Jan Hudec","fromEmail":"bulb@ucw.cz","sentAt":"2007-05-18T19:50:00Z","receivedAt":"2007-05-18T19:50:00Z","isPatch":false,"sender":{"key":"bulb@ucw.cz","avatar":null},"body":"On Wed, May 16, 2007 at 11:38:28 +0100, Andy Parkins wrote:\n> Now, I want to make a commit that fixes that bug.  These are the options:\n> \n>  * -- * -- B -- * -- * -- * -- F\n> \n>  or\n> \n>  * -- * -- B -- * -- * -- * -- M\n>             \\                 /\n>              --------------- F\n> \n> That is - just commit a fix or, commit the fix, \"F\", directly on \"B\" then \n> merge that fix back to HEAD with \"M\".\n> \n> I quite like option 2 because it records intent - i.e. \"I wish I could have \n> gone back and changed this revision, but I can't\", but it makes a more \n> complicated history.\n> \n> What do people think?\n\nThe big advantage of the later is, that if you have:\n\n * -- B -- * -- * -- M1\n       \\\n        -- * -- * -- M2\n\nYou can merge the fix done on yet another branch into how many branches you\nneed, so:\n\n * -- B -- * -- * ----- M1\n       \\               /\n        -- * -- * ----/- M2\n\t \\           /  /\n\t  ----------F---\n\nIf you had the fix on one of the branches, you could only cherry-pick it to\nthe other, but the history would not really reflect that.\n\n-- \n\t\t\t\t\t\t Jan 'Bulb' Hudec <bulb@ucw.cz>\n"}]}