If you’re using Kiln’s branch repositories to separate development of different features and version, as we do at FogBugz, it can be hard to keep track of what repositories contain certain fixes and features. One of your developers might have an awesome new feature in her own branch, along with a bug fix that’s gone to QA. Plus, another developer just pushed a feature right to your release repository! How can you keep all this straight?
The Related Graph, new in Kiln 2.4, is designed to answer these questions. While the electric DAG shows you the relationship of changesets within a single repository, that doesn’t help much for showing the relationship of several related repositories. The Related Graph also shows a DAG, but it shows all the changesets in a set of related repositories. This means that every branch and other repository that shares history with the current repository is included — it’s the union of all those changesets. For large projects, this could get complicated, so Kiln simplifies the DAG by only showing the changesets that are a head in one or more repositories. All other changesets are collapsed into a single row. You can find the Related Graph by clicking the “Related” tab at the top of any repository, then clicking “Related”:
That sounds complicated, so let’s look at some more pictures!
First, let’s look at the simplest case: a single-headed repository with no branches.
(the repository I’m using here is jespern’s Piston for Django if you’d like to follow along at home)
It’s pretty straightforward: only the head is shown, and the other 264 changesets are collapsed into a single row. Now let’s push two changesets into the branch
issue117 of our
trunk repository to fix a bug:
Again, all the changesets except the two heads are collapsed. But why aren’t all the changesets collapsed into a single row? It’s because the Related Graph preserves the relationship of changesets to one another and to the repositories containing them. Remember that in the DAG, each changeset appears above its parents and other ancestors. So the ancestors of
trunks‘s head, “Fixed Resource.error_handler to include em_format.”, are the 16 changesets and 248 changesets below it. The head in
issue117 and the 1 changeset below that are not ancestors of
trunk‘s head, so they are not collapsed into one row. In the same way, the ancestors of
issue117‘s head are the 1 changeset and 248 changesets collapsed into two rows.
Put another way,
issue117 share the first 248 changesets of their history. At this point, the repositories diverge.
trunk has 17 changesets (16 collapsed + 1 head) that are not in
issue117 has 2 changesets (1 collapsed + 1 head) that are not in
trunk. You can confirm this by clicking
trunk‘s head to electrify it:
As expected, the ancestors of that changeset are the 264 collapse changesets; the changesets that are only in
issue117 are not included. Let’s merge the branch into
issue117 hasn’t changed (as we only pushed to
trunk‘s head is now a merge. Its old head (and a couple other changesets) have been collapsed into the “19 changesets” row (you can click that to see exactly what changesets are collapsed there, in beautiful electrified style). Since the branch has been merged into
issue117‘s head and it’s other changeset are now an ancestor of
trunk‘s head, just like you’d expect. At this point, you could delete
issue117, certain that all changesets in the branch have made it to another repository. Or, keep the branch around and you’ll always be able to come back to this graph and see exactly what changesets were initially in that branch — here, just the two changesets necessary to fix the bug. With Kiln, you never lose your history!
Let’s keep moving. Now, another developer has pushed his changes into another repository:
Much like before, you can see that
Rocca shares the first 248 changesets with
trunk, and then diverges for 3 changesets to its own head. But what if we push another head to
Whoa! What’s going on here?
Rocca now has another head, in addition to the one we saw in the last image. The new head, “adding jiaaro to authors”, is committed directly on top of
trunk‘s head, so there are no intervening changesets to collapse. It’s easy to see that
Rocca is a “more developed” branch than
trunk — it includes all of
trunk‘s changesets (and
issue117‘s, for that matter), plus 4 additional ones.
Now, we want to ship all of these changes, so we merge the two heads from
Rocca and push that to
The two heads in
Rocca are still marked as heads (by the green bubbles at the changesets), but they are both ancestors of the new head of
trunk. The merge itself has been collapsed into the “1 changeset” row near the top, but it’s still a merge – you can trace that its two parents are the two heads in
Rocca, just like you’d expect.
At the top of the page, you can see all the repositories that are included in the graph. Note that even though
Rocca is a central repository, it’s included because it shares history with
issue117. You can uncheck any that you don’t want to see:
Though the head in
issue117 is no longer shown, the changesets in
issue117 are still there, since it was merged into
trunk. You can see that the number of collapsed changesets in several of the rows have gone up to include the hidden changesets.
That covers all the bases for what the Related Graph can do. I’ll leave you with a more complicated example:
This is the sort of graph you’ll see for a more mature product, set up with a branch per version plus development branches for each developer. Here,
0-5 is the oldest repository, and all of its changes are included in every other repository. Working up the DAG, each versioned repository shares most or all of its history with later versions. The collapsed rows represent all of the development between versions. For example, click the “271 changesets” between
0-7-1 to see all the changes that were done for the 0.8, 0.8.1, and 0.8.2 releases. Tracking your product’s history has never been easier!
At the top of the graph, it diverges as developers do new work in the
devel repository and in their personal branches (
jon). A quick electrification reveals that Jon’s changes are based on
devel, including everything in the older versions; the only changes he’s missing are the three in Hugo’s branch and the two old ones in 0-6.
As the developers merge work back into
devel, that repository’s head will move further from
0-8. When the 0.9 release is made, the head for
0-9 will appear between
devel, and development will continue.
Understanding your code’s history requires looking across repositories to get the whole story. Kiln’s Related Graph helps you keep track of what changes are lingering in a developer’s personal branch or waiting to be pushed from a bugfix branch, and reveals the interconnected history of a large project. The shape of your project’s history is simplified, so you can understand your code base at a glance.