[darcs-users] some questions about branching

Stephen J. Turnbull stephen at xemacs.org
Mon Apr 12 14:02:56 UTC 2010

Eric Kow writes:

 > I hope this three-month-late reply isn't a problem.

No, but I'll restrict myself to answer points I think I understand. :-)

 > That nervousness was why I was hoping we could get away with just
 > local branches.  Now I suppose that wouldn't actually be making
 > things that much simpler and that if we were going to do branching
 > at all, we might as well just go all the way.

What git has shown is that a fully distributed database of branches is
quite feasible and manageable.  I don't know how this can be applied
to Darcs, but as I wrote before, the distinction between branches
stored locally and those stored remotely is mostly bogus.

 > For more context, I later replied saying that the only thing I was
 > concerned about was opening up a can of UI worms, that adding all
 > the necessary concepts/distinctions/operations to support branches
 > may make Darcs more difficult to understand and use.

That's true.  But all of the DAG-based dVCSes have no trouble with the
remote/local distinction, which was the only thing I wanted to say.
Only the scheme of the URL used changes, and in the common "star"
topology with a shared mainline with a well-known URL, that well-known
URL is typically implicit (ie, you just say "$VCS pull" or "$VCS push"
rather than "$VCS pull $URL").

 > > The next level problem is that if your VCS supports colocated
 > > branches, you might commit to the "wrong" branch because you
 > > forgot which one you're in.  Fixing this is just a rebase (and
 > > maybe splitting the first patch).  Well, hey, isn't Darcs the
 > > world's best tool for rebasing, and no slouch at splitting up
 > > patches?  And note that this can surely happen without *remote*
 > > branches.
 > In the case of local branches, I think I'd agree that it's just a
 > question of pushing/pulling patches.
 > For remote branches, don't we run into the usual advice of not
 > performing git rebase (or darcs obliterate, or darcs amend) on
 > already-published work?

No!  That's where Darcs could have a real advantage in this field.  As
long as there are no (differences in the) dependencies, there is no
need for a rebase in Darcs; you just push or pull patches.  Of course
it *could* happen that there are dependencies, but in most cases of
mistaken commits there will be none.  On the other hand, in *all* of
the DAG-based VCSes, you can't even change a log message without
changing the identity of the whole branch and every commit following
the edit (the general statement of "the rebase problem").

 > About fast-forwards, reading
 >   http://marklodato.github.com/visual-git-guide/#merge
 > gives me the impression that a fast-forwards in Darcs is just the
 > case of pulling patches where "our" history is just a prefix of
 > "their" history

Yes, that would be a fast-forward.  However, in the case of Darcs, it
may be possible to define fast-forward more generally, as simply any
pull (or push) that causes no conflicts, ie where all dependencies of
all pulled patches are already present in the receiving repository.

 > > In other words, Darcs is only allowed to increase the number of
 > > branches in the target repo if the user specifies the branch to
 > > add *and* some kind of "new branch" option.
 > I'm a bit confused here.  What do fast-forwards have to do with the
 > number of branches?
 > In "remote operations are only permitted if they are fast
 > forwards", I understood something that you can only push patches on
 > to repositories whose history is a prefix of ours (like above, just
 > flipped).

Yes.  But you need to remember that "prefix" has a much stronger
meaning in DAG-based VCSes that it does in patch-based ones.

 > Whereas in the second sentence, I think you're talking about a UI
 > scheme to discourage branch proliferation.

I'm not sure what you mean by that.  The problem is this: Suppose you
and I have a common history A = (0, p1, ..., pn), and you commit q and
I commit q'.  In a DAG-based VCS, we now have the problem of managing
two different branches.  Commits q and q' necessarily have different
identities but the same parent; this is a branch.  At this point if
both commits are pushed to a common repository, there is a need to
decide which head, q or q', is the default head that will be pulled by
third parties accessing the common repository by its well-known URL.
There's no good way to do this automatically, and both you and I are
going to be under the impression that our commit is on the mainline.

This could be resolved by merging (creating a new commit that contains
both patches).  However, this is no better than preferring yours, or
preferring mine -- there's no guarantee the merge will succeed.  No
matter what resolution is chosen, somebody will be surprised, and
often displeased.  So DAG-based VCSes have all chosen the same
solution: no automatic merges in a remote repository.  All merges must
be explicitly requested and performed in a local repo.

In Darcs, if q and q' don't conflict, we can pull from each other and
the branches are once again identical and coherent.  And there is no
difference from either developers' point of view who commits and
pushes first; it's just a concurrent commit which Darcs will handle as
it does any concurrent commit to a related branch.

So it is my guess that the equivalent of "fast-forward" for Darcs is
"non-conflicting" which is a much weaker condition than fast-forward
in a DAG-based VCS.

 > > I can think of one use case where pulling a remote branch would
 > > be very useful.  That is the case where bootstrapping your
 > > project is very expensive.  The workflow here is to create a
 > > repository in one of the usual ways, and bootstrap it.  Now, if
 > > you want to test someone's changes, instead of cloning their
 > > branch (moderately to very expensive in a big tree) and
 > > bootstrapping (very expensive), you simply pull the delta to
 > > their branch into your "build&test" working tree and remake the
 > > changed files.
 > How would this be different from the current Darcs equivalent of
 > just pulling from a remote repository (as opposed to a branch
 > within that repository)?

There's not an issue of remote branching or not.  The remote branch
can be an ordinary Darcs repo, or it could be one of these
hypothetical "in-repo Darcs branches"; it doesn't matter.  It's
*local* branching that matters here.  The point is that the build
products from an earlier build remain.  You switch branches which
changes some of the source code but *not* the build products.  Those
build products which do not correspond to the new branch must be
rebuilt, but those which have not changed don't need it.

More information about the darcs-users mailing list