threads / bug / 8177

Opinions on bug fix organisation

Subject: Opinions on bug fix organisation

## tl;dr

8 messages between May 16, 2007 and May 18, 2007.

replies: 7people: 7as markdown or json

Andy Parkins· May 16, 2007, 10:38 UTC · lore
Hello,

This is not so much a question about git, but more about history organisation. I'm undecided on the best way to deal with bug fix history.

Imagine this situation:
 * -- * -- B -- * -- * -- *

"B" is a commit that introduced a feature and a bug, that bug is present forever more in history (which I think is good - history is history). I've pushed the repository to the rest of the developers in the meantime, so there is no editing "B" and doing some rebase magic.

Now, I want to make a commit that fixes that bug.  These are the options:
 * -- * -- B -- * -- * -- * -- F
 or
 * -- * -- B -- * -- * -- * -- M
            \                 /
             --------------- F

That is - just commit a fix or, commit the fix, "F", directly on "B" then merge that fix back to HEAD with "M".

I quite like option 2 because it records intent - i.e. "I wish I could have gone back and changed this revision, but I can't", but it makes a more complicated history.

What do people think?
Andy
-- 
Dr Andy Parkins, M Eng (hons), MIET
andyparkins@gmail.com
Brian Gernhardt· May 16, 2007, 14:46 UTC · re: Andy Parkins · lore

Re: Opinions on bug fix organisation

On May 16, 2007, at 6:38 AM, Andy Parkins wrote:
Show 10 quoted lines
> That is - just commit a fix or, commit the fix, "F", directly on  
> "B" then
> merge that fix back to HEAD with "M".
>
> I quite like option 2 because it records intent - i.e. "I wish I  
> could have
> gone back and changed this revision, but I can't", but it makes a more
> complicated history.
>
> What do people think?

I just encountered this myself with one of my repos. I'm developing solo so I could just rebase if I felt like it, but don't like developing that habit, so I'm probably going with the second one. But that's because of how I'm developing it. My master has undergone serious changes recently (since the bug commit), so I'm going back and checking out the bug commit to focus on that issue without anything else that's been changed since then.

My personal feeling is that the commit should reflect how the fix was developed. If it's simple fix that you simply wrote on top of the full branch, commit it that way. If you had to (or wanted to) go back and develop on top of the original commit, commit it that way. Usually I'll just commit on top of master, but if either I need to remove other complications from the fix or need to introduce the fix (but not everything else) into multiple branches, I'll do the merge.

~~ Brian
Junio C Hamano· May 16, 2007, 17:55 UTC · re: Andy Parkins · lore

Re: Opinions on bug fix organisation

Andy Parkins <andyparkins@gmail.com> writes:
Show 5 quoted lines
> I quite like option 2 because it records intent - i.e. "I wish I could have 
> gone back and changed this revision, but I can't", but it makes a more 
> complicated history.
>
> What do people think?

I think that largely depends on your taste and what other things you have between B and the tip when you contemplate on the fix.

If you ever have a forkpoint (e.g. maybe soon after B you had a tagged release, and maintenance track for that forked from it), then the latter is much more manageable in the long run. That is how 'master' and 'maint' in git.git are managed. An old bug is fixed as close to the introduction of bug as practical (so I would _not_ fork a fix on top of B itself, but apply fix to the tip of 'maint'), and then all newer development track that contain breakage B merges the fix from that branch (i.e. 'maint' is then merged into 'master' to propagate the fix forward).

The way 'next' and 'master' works in git.git looks a bit different from it, but you will realize that the idea is the same if you look at individual topic branches. Each topic is forked from 'master', gain its own commits and merged to 'next'. Its bugs may be discovered later while it still hasn't been merged to 'master'. I'd _never_ commit a fix to 'next' directly, but a fix goes to the tip of the topic branch that introduces the bug, and then merged to 'next'. When the topic is reasonably bug-free, it then is merged to 'master' -- at that point, the history of the topic has all the relevant fixes.

If you think of your straight single strand of pearls (the first picture) as a degenerated case that has a topic that includes B and ends with the tip, "merged" to 'master' in a fast forward fashion (i.e. the rightmost commit in the picture is the tip of the topic and at the same time the tip of the 'master'), then having a fix on top of the 'master' like in your first solution is perfectly fine -- it is in line with how topic branches in my repository gets fixed and how the fix is propagated to 'next' and then eventually to 'master'.

On the other hand, if your commits between B and the tip of your master contain enhancements and fixes to random issues (iow, it is not a degenerated merge of a single topic into 'master', but just a random set of development), I think your latter approach to have only the fix as a separate (temporary) topic and merge that to the tip is inconsistent with your current practice to begin with, and I do not see much merit in it by itself. If you prefer the latter solution (and I obviously do, as that is the way git.git repository is maintained), you would also want to have topic branches, where all the enhancements, advances _and_ fixes related to a single theme go to and then merged to the mainline. That's the history of a theme. Having branch and merge only for fixes but not for advancement may be "the history of a bug", but it probably would not buy you much by itself.

Andy Parkins· May 16, 2007, 21:20 UTC · re: Junio C Hamano · lore

Re: Opinions on bug fix organisation

On Wednesday 2007, May 16, Junio C Hamano wrote:
> I think that largely depends on your taste and what other things
> you have between B and the tip when you contemplate on the fix.

As always, thank you for the detailed response. I appreciate the thought that goes into answering these questions that flit into my mind :-)

Show 5 quoted lines
> is fixed as close to the introduction of bug as practical (so I
> would _not_ fork a fix on top of B itself, but apply fix to the
> tip of 'maint'), and then all newer development track that
> contain breakage B merges the fix from that branch (i.e. 'maint'
> is then merged into 'master' to propagate the fix forward).

The above method is almost a necessity when using git. If the bug fix is committed to master, there is no way to apply that same commit to the maint branch without also grabbing commits you don't want in maint.

> The way 'next' and 'master' works in git.git looks a bit
> different from it, but you will realize that the idea is the
> same if you look at individual topic branches.  Each topic is
> forked from 'master', gain its own commits and merged to 'next'.

I've noticed flows like that when looking at git history. I always think that it demonstrates the power of git's strong-on-branches stance because you can almost feel the story of the development without having to read any of the commits themselves. I wonder if other DVCSs encourage creation of such a strong narrative?

Show 6 quoted lines
> Its bugs may be discovered later while it still hasn't been
> merged to 'master'.  I'd _never_ commit a fix to 'next'
> directly, but a fix goes to the tip of the topic branch that
> introduces the bug, and then merged to 'next'.  When the topic
> is reasonably bug-free, it then is merged to 'master' -- at that
> point, the history of the topic has all the relevant fixes.

What is your preference when, for example, you have already merged a topic to next but then a bug fix appears?

 * -- * -- * -- M -- F         * -- * -- * -- M -- m (next)
               /        or                   /    /
    B -- * -- *                   B -- * -- * -- F (topic)

F is certainly most appropriate to be on the topic branch, but we create a perhaps excessively verbose extra merge, m.

Show 5 quoted lines
> just a random set of development), I think your latter approach
> to have only the fix as a separate (temporary) topic and merge
> that to the tip is inconsistent with your current practice to
> begin with, and I do not see much merit in it by itself.  If you
> prefer the latter solution (and I obviously do, as that is the

I'm not sure I've understood what you mean here. Which "latter" are you talking about - you've said that you find the latter inconsistent but also that you prefer the latter solution. I'm lost :-)

Show 6 quoted lines
> way git.git repository is maintained), you would also want to
> have topic branches, where all the enhancements, advances _and_
> fixes related to a single theme go to and then merged to the
> mainline.  That's the history of a theme.  Having branch and
> merge only for fixes but not for advancement may be "the history
> of a bug", but it probably would not buy you much by itself.

It's not so much a matter of it buying you something, it is more that when you find that bug fix commit in history you can see, by following the fix-branch back to its source, all the revisions that contained that bug at a glance; if you just commit on the end, you have to do the digging yourself, and hope that someone mentioned in the commit message which commit introduced the bug that that commit fixes.

The fact that git makes it so easy to branch and merge from a previous point is the thing that even makes this a possibility. Perhaps I'm spoilt now :-)

Andy
-- 
Dr Andy Parkins, M Eng (hons), MIET
andyparkins@gmail.com
Shawn O. Pearce· May 16, 2007, 21:38 UTC · re: Andy Parkins · lore

Re: Opinions on bug fix organisation

Andy Parkins <andyparkins@gmail.com> wrote:
Show 9 quoted lines
> What is your preference when, for example, you have already merged a 
> topic to next but then a bug fix appears?
> 
>  * -- * -- * -- M -- F         * -- * -- * -- M -- m (next)
>                /        or                   /    /
>     B -- * -- *                   B -- * -- * -- F (topic)
> 
> F is certainly most appropriate to be on the topic branch, but we create 
> a perhaps excessively verbose extra merge, m.

Look at the history of the next branch; the diagram on the right is exactly what Junio does. When topic finally graduates to master, only F is merged to master, making master's own history not show that "verbose extra merge" m. Or M really for that matter, as master gets its own M'.

-- 
Shawn.
Johannes Sixt· May 18, 2007, 08:11 UTC · re: Andy Parkins · lore

Re: Opinions on bug fix organisation

Andy Parkins wrote:
Show 9 quoted lines
> What is your preference when, for example, you have already merged a
> topic to next but then a bug fix appears?
> 
>  * -- * -- * -- M -- F         * -- * -- * -- M -- m (next)
>                /        or                   /    /
>     B -- * -- *                   B -- * -- * -- F (topic)
> 
> F is certainly most appropriate to be on the topic branch, but we create
> a perhaps excessively verbose extra merge, m.

It depends on whether the topic branch is "closed": A topic branch is "closed" after it is merged into all branches that it is intended to be merged into.

For example, in our setup we sometimes create topic branches off of 'maint' because we want to keep the option alive to merge it into 'maint', although for the time being it is only merged into 'master' (main development). If a bug fix appears, we have to add it to 'topic' and merge into 'master' again (your second example). 'topic' may never make it into 'maint', but this way we keep the option; hence, 'topic' is _not_ "closed", yet.

-- Hannes
Martin Langhoff· May 16, 2007, 21:51 UTC · re: Andy Parkins · lore

Re: Opinions on bug fix organisation

On 5/16/07, Andy Parkins <andyparkins@gmail.com> wrote:
> I quite like option 2 because it records intent - i.e. "I wish I could have
> gone back and changed this revision, but I can't", but it makes a more
> complicated history.

I prefer just letting history show what happened, rather than try to get too smart about it ;-) -- and use branches and merges for experimental or feature work. Once a feature or experimental branch is merged into master, further work happens on master (unless there are other reasons for it to be maintained).

Bugfixes are part of the life of the maint and master branches. Imagine your "option 2" being used to maintain git's maint branch. Some bugs live in the code for 6 months. The merge graph would be unreadable... and generally the project history would be really hard to make sense of.

Most "special" practices around branches kind-of work in the minimalistic case, but break down badly in real-life sized projects...

cheers,
martin
Jan Hudec· May 18, 2007, 19:50 UTC · re: Andy Parkins · lore

Re: Opinions on bug fix organisation

On Wed, May 16, 2007 at 11:38:28 +0100, Andy Parkins wrote:
Show 18 quoted lines
> Now, I want to make a commit that fixes that bug.  These are the options:
> 
>  * -- * -- B -- * -- * -- * -- F
> 
>  or
> 
>  * -- * -- B -- * -- * -- * -- M
>             \                 /
>              --------------- F
> 
> That is - just commit a fix or, commit the fix, "F", directly on "B" then 
> merge that fix back to HEAD with "M".
> 
> I quite like option 2 because it records intent - i.e. "I wish I could have 
> gone back and changed this revision, but I can't", but it makes a more 
> complicated history.
> 
> What do people think?
The big advantage of the later is, that if you have:
 * -- B -- * -- * -- M1
       \
        -- * -- * -- M2

You can merge the fix done on yet another branch into how many branches you need, so:

 * -- B -- * -- * ----- M1
       \               /
        -- * -- * ----/- M2
	 \           /  /
	  ----------F---

If you had the fix on one of the branches, you could only cherry-pick it to the other, but the history would not really reflect that.

-- 
						 Jan 'Bulb' Hudec <bulb@ucw.cz>

← back to recent threads