[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Looming colocation [Was: Git mirrors]

From: Stephen J. Turnbull
Subject: Looming colocation [Was: Git mirrors]
Date: Tue, 18 Oct 2011 01:59:09 +0900

Alan Mackenzie writes:

 > Sorry if I'm a bit slow, but could you explain what a "colocated branch"
 > is, please?

"*A* colocated branch" doesn't really make sense; colocation is a
repository structure, not a branch property.  "Colocated branches" is
the way git normally operates: each repository contains a number of
branches which will be checked out in the same workspace at different
times.  To have two branches physically checked out at the same time,
you need to clone the repository (at least a whole branch).  In
Mercurial these are called "named branches".  Bazaar has an
experimental plugin called "coloc" which implements this (I think it's
about to become official in the next release or maybe in 2.6).

In the context of Mercurial or Bazaar, this is really just a way to
save space, and maybe a little bit of time, since you can compare
physically separate branches directly with "bzr diff $REMOTE_URL" or
get log information, etc.

In git, it plays two more important roles.  First, in git you can only
operate on branches (diff, merge, even log) when they are all present
in the same repository.[1]  Ie, colocation is fundamental to git's
design.  Second, in combination with refs (ie, a variable containing a
revision ID), it makes DAG manipulations like rebase potentially safe
and efficient (as long as you keep them within one repo).  Do you want
to do something dangerous with your master branch?  Just "git branch
saved-master master" (which is as cheap as "cp .git/refs/heads/master
.git/refs/heads/saved-master"), do it, and if something disastrous
happens, "git branch -f master saved-master" and you're back where you

It is possible to do this in bzr as well, but it's not documented, and
not part of the official UI.

 > Also, what is a "loom" in this context?

"loom" is an established but not so widely-used bzr plugin.  It allows
you to create a stack of groups of provisional changes which are
version-controlled (and so can be pulled into another branch; I think
push is inhibited for the same kinds of reasons that people prefer to
require that push be a fast-forward, but I'm not sure).

The idea is that you have a new feature you want to implement in CC
mode.  This requires some low-level infrastructure refactoring which
is generally useful.  So you create a "thread" called "refactor".  You
do the work, committing changes in coherent chunks as usual.  Now
you're ready to implement the feature.  So you create another thread
"on top of" refactor, called "feature".

OK, so midway through the implementation of feature, after a couple
more commits, you realize that you got refactor wrong.  Now you do
"down-thread", which pops off all the changes you made in feature so
far (but saves them).  This leaves you at the same state as when you'd
just finished refactor.  You fix the bug or add the extra feature,
then do "up-thread" which automatically restores the popped changes.
(This could result in a merge conflict, which you'd have to fix.)

I believe that loom keeps track of how much progress is made on each
thread, creating conceptual links that cross threads.  Thus you have
warp and woof being woven together, and the tool that manages such
weaving is, of course, a loom.

So this is like the famous "quilt" program, but the patches are
version controlled.  Another way to look at it, maybe, is a sort of
domesticated rebase.

Maybe Barry Warsaw will chime in, as I know he loves loom, and I've
never fully understood it or used it in anger.

[1]  This is actually true of hg and bzr, too.  The difference is that
git requires an explicit fetch (or pull) of the required branches in
advance, and then the reference to the fetched branch is durable -- if
you don't want that, you have to explicitly delete it.  In hg and bzr,
the fetch occurs implicitly as an internal step in diff or merge, and
the remote branch data is thrown away after a diff, or remains
implicitly in the internal DAG after a merge.  In a diff, it may be
possible to do a partial fetch, as well; I haven't thought about it
carefully.  But for a merge, obviously you have to fetch all of the
history and content data in order to incorporate it in the merged DAG.

It would be easy to emulate the hg/bzr style in git with a script.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]