[darcs-users] Darcs in kernel-like development model

Stephen J. Turnbull stephen at xemacs.org
Wed Feb 6 00:01:55 UTC 2008


John Goerzen writes:

 > I'd like to get some feedback from all of you on best practices for
 > Darcs in what a lot of people call the kernel development model (used
 > for the Linux kernel).

Unfortunately, I don't see how to adapt Darcs to this usage.  As far
as I can see Darcs is a very happy choice for what Archies call the
"star topology", but does not work well in the face of chaotic
processes like lk.  I have some comments about your discussion that
may be useful, though.

[snip good description -- probably pretty common knowledge as well ]

 > People use various tools to do this.  Patch queue management tools
 > like quilt or Mercurial's mq are common.  Others use git with frequent
 > use of its rebase feature, or Mercurial with transplant.

Note that rebase (and I would guess "transplant" -- why do the
Mercurial people insist on breaking the common idiom so often?) are
logically equivalent to quilt and mq.  Also a superset of Arch's
update (dunno if bzr preserved the update vs. replay distinction),
where "pull" in most VCSes approximates Arch's "replay".

I'm not sure what you're saying next.  A slight gloss makes clear what
I think it is:

 > So if we [try to] model this workflow on a DVCS like Mercurial or
 > Git [without transplant/rebase], here's what we wind up with. [...]
 > You have a complete history, but not a final, complete patch of
 > each logical feature.  That model doesn't work [in the Linux kernel
 > workflow].

Is that OK?

 > So what people do is use git rebase or hg transplant.  When a new
 > upstream version comes out, you use rebase/transplant to extract
 > all your local patches against the previous upstream and re-apply
 > them against the new upstream.  If there are conflicts, you stop to
 > fix them for the individual patch, then resume.  Later you
 > presumably throw away your former local development branch.

Well put.  But you forget that "presumably" later.

 > Now, this model works well for private repos.  In both git and hg, it
 > is difficult to use -- though not impossible -- if you are sharing
 > repos with others.

Actually, it's not difficult at all (in principle!)  It just requires
a bit of discipline about which branches you expose and how.  Much of
this discipline can be automated (I haven't done so yet, though I
suspect that many lkml denizens have; cf. comments about reflog,
below).

 > That seems similar to using amend-record in darcs.

Maybe.  But amend-record actually destroys history, whereas the only
command in git and Mercurial combined that does so is git-gc.

 > Now, how would we accomplish this in Darcs?  As far as I know, Darcs
 > has no equivolent of rebase.

AIUI, Darcs doesn't have rebase in theory, because a darcs repo
doesn't try to impose a complete DAG based on "ancestry".  Instead
there's a theoretically more accurate notion of "dependency".  (It's
possible that a Darcs analog of rebase could be based on reordering in
the dependency graph, but I suspect it would be much more painful to
use, since it would inherently involve conflict resolution.  Also,
it's not clear to me from following darcs-devel with its two-line
patches followed by 2000 lines of dependencies that in practice the
notion of dependency actually used isn't pragmatically equivalent to
ancestry.)

 > While it does have amend-record and similar unrecord types of
 > features, it does not have a way to arbitrarily merge two patches
 > back in the history -- at least not a convenient way.

Worse yet, Darcs is ahistoric.  That's what it means to say that there
is no complete ancestry DAG.

But I don't understand what you're asking for here.  Specifically,
what's missing from "patch < PATCH-A && patch < PATCH-B && darcs record"?

 > Is there some nice feature of Darcs that lets us avoid some of the
 > pitfalls of the approach that uses rebase or transplant, such as:
 > 
 >  * Loss of development history due to having to throw out old branches

This is a common misconception about how rebase works.  No history is
ever lost (unless the user calls git-gc *explicitly*, and AFAIK in
Mercurial there is no such thing as garbage collection).  Besides
git-gc, the only history-destroying commands in git are git reset
--hard and git checkout (which wipe out any unrecorded changes in the
workspace, and so are only "locally" history-destroying).  Note that
the effects of git-gc are mitigated to the extent that the objects
destroyed have already been copied elsewhere!

If you want to preserve *convenient* access to the rebase history of a
branch, this shell function DTRTs:

function git-tag-then-rebase () {
  UPSTREAM=$1
  BRANCH=$2
  ONTO=$3
  # I think git-branch DTRTs here
  if test -z "$BRANCH"; then BRANCH=`git branch`; fi
  if test -z "$ONTO"; then ONTO=$UPSTREAM; fi
  git tag $BRANCH-`date +%Y-%m-%d.%H;%M%S` $BRANCH
  git rebase --onto=$ONTO $UPSTREAM 
}

And here's how to read that history:

function git-branch-rebase-history () {
  BRANCH=$1
  ls .git/refs/tags/${BRANCH}*
}

In fact I suspect git's recently introduced reflog capability may
address the same issue in a different way.

I don't see how to translate the notion of a self-contained line of
development, which is imperfectly modeled by git-rebase, to current
Darcs with its rapidly proliferating dependencies.

 >  * Inconvenience of sharing repos with others (note that
 >    any use of darcs amend-record, unrecord, etc. will fail on this,
 >    though won't necessarily be worse than git/hg)

They are worse, because AIUI they do destroy history.


More information about the darcs-users mailing list