Pending merges, non-integer revision numbers,...: documentation?

Matthew D. Fuller fullermd at
Sun Sep 9 02:18:48 BST 2007

On Sat, Sep 08, 2007 at 09:19:34PM +0200 I heard the voice of
Gonzalo HIGUERA DÍAZ, and lo! it spake thus:
> At this point, the concept of "subrevisions" seems interesting, but
> brings many questions to mind: What is the proper way to call them?
> How can they be created and converted back to regular revisions?
> What's the recommend way to use them? What are the differences
> between them and regular revisions and how might it affect the
> workflow

Well, there's not really such a thing as a "subrevision", and those
aren't "part of" that new commit you've made, really.  It looks that
way in the interface, but that's presentational.  It's really the
outcome of a merge, where you've re-combined branches that have

When you create local commits in your checkout, and have other commits
in the branch on your USB drive, what you actually end up with is two
branches have have diverged.  They're the same up to a point, but
differ past that:

       /        \
      /          \
     |            |
  (local 1)     (USB 1)
     |            |
  (local 2)     (USB 2)

  Your local     On USB
   checkout      branch

(hereafer, revisions specified like (l1) and (U2) for shorter

So, you have two separate lines of development that you need to bring
together.  You can't simply tack one onto the end of the other,
because that's not where it goes; the "parent" of (l1) is the last
(common) revision, so it can't go after (U2).  So, what needs to be
done is to create a new revision with two parents instead of the
normal 1, which brings those lines together:

       /        \
      /          \
     |            |
  (local 1)     (USB 1)
     |            |
  (local 2)     (USB 2)
     |            |
      \          /
       \        /
     (new revision)

Now, presenting that in a flat, linear-like form (which is what you
have to do, in a CLI 'log' output) presents some difficulties.  You
can't list them purely in geneological order, since the history is no
longer linear.

As long as revisions only have one parent (and one child), that works
fine, but now that you've split as above, you have a revision (the
last (common)) that has TWO children; it has two revisions that come
"right after it".  And you have a revision (the (new) one) that has
two parents; two revisions that come "right before it".

One way to do it is just to list out all the revisions in
chronological (or some similar) order, but that means that revisions
will be shown right before/after revisions that aren't necessarily
related to them.

The other is to somehow visually set apart diverged lines, which is
how bzr does it.  Your new revision has two ancestral lines; one is
represented by the normal log output; those revisions later on that
are flush on the left side.  The other is represented indented right
below it, and that history remains indented there until it reaches
back to a point where the two lines join.

(how bzr decides which line should be indented and which not is a
different question, but it is consistent)

They are not, however, "subrevisions"; they're full revisions the same
as any other.  If you looked at the history with a graphical tool
(like bzr-gtk's "viz"), you'd see the relationships in a perhaps
slightly more clear way.  You're a little more limited in what you can
display in a terminal, but I think the output in that case is still
excellent (if perhaps requiring a little more interpretation).

> (e.g.  how to uncommit a "subrevision" --which might simply not be a
> sensible thing to do--)?

Uncommitting isn't really a sensible thing to do, though not because
there's anything special about those revisions.  Rather, because you
can only uncommit the latest revision, and they aren't that; they're
older revisions.  And because of the way uncommit works, it'll
actually step backward along the 'left' path, so you won't quite get
back in the history through them that way either.

> So much confusion in my head makes me wondering how thick headed I
> am being (please excuse me for it), and whether I am confused becase
> "subrevision"/"pending merges" add a degree of complexity which
> right now to me seems wrong.

Well, realize that when you make local commits, you're basically
stepping out of the realm of "centralized" or "lockstep" development
with everything on a single linear history (CVS/SVN style), and
stepping into "distributed" development where history is a separating
and rejoining tree, just as if you used full independent branches that
you 'merge'd.  So, it adds complexity because what's being done is
more complex, and calls for a somewhat more nuanced mental model that
you need for purely linear development.

Of course, most people here would say that's a good thing   8-}

Matthew Fuller     (MF4839)   |  fullermd at
Systems/Network Administrator |
           On the Internet, nobody can hear you scream.

More information about the bazaar mailing list