[darcs-users] Darcs equivalent of force-pushing and branching
Ben Franksen
ben.franksen at online.de
Tue Sep 14 11:38:53 UTC 2021
Am 13.09.21 um 22:17 schrieb James Cook:
> On Fri, Sep 10, 2021 at 08:19:29PM +0900, Stephen J. Turnbull wrote:
>> All of this is obviously quite possible with Darcs. The problem is
>> getting the "accounting" right when separating the management of
>> *sets* of patches from the management of *histories*.
True, but this problem is already solved. In our code base there is no
explicit representation for "set of patches", we always treat them
internally as sequences. Two sequences may or may not be equivalent in
the sense that they represent "the same set of patches" (nominally
speaking i.e. "same set of patch identities"). Indeed, since we use
phantom types for the start and end context of any patch or sequence of
patches, any two sequences of the same type must be equivalent in this
sense. This has the notable consequence that none of our patch types
have a standard instance for (homegenous) equality, as that would be
trivial i.e. always return True. Instead, our two equality operators are
heterogeneous: they require (only) the start /or/ the end contexts to
coincide and (if comparison succeeds) return a proof of equality between
(the phantom types symbolizing) the two remaining contexts. This makes
the manipulation of sequences (re-arrangement, merging, etc) pretty easy
and safe, because almost all the mistakes you can make become type errors.
[The flip side is that we also make extensive use of laziness, including
unsafeInterleaveIO when reading patches from disk, which means that
semantically transparent changes can have devastating consequences for
performance or even lead to bugs when transfering patches (because we
may store too few or too many patch or inventory files).]
>> IIRC, in Darcs
>> the history is in the patches, which means a bit of tedious surgery on
>> data structures needs to be done.
>
> I'm not sure what you mean by "histories" as distinct from "sets of
> patches". Shouldn't a branch just be a set of patches?
Definitely.
It is /not/ true that in Darcs "the history is in the patches", quite
the opposite in fact: a patch by itself, as read from disk, makes no
sense without a context i.e. the set of patches preceding it. The
history is explicitly stored on disk, separately from the patches
themselves (in the form of "inventories"). To see that, you can look at
_darcs/hashed_inventory, which is a plain text file listing the patches
(since the last clean tag) in order from earliest to latest. For each
patch, it contains its PatchInfo (meta data) plus a sha256 hash of its
content /in this specific context/. It also contains a hash of the tree
corresponding to the "HEAD" (the recorded state, including the content
of all tracked files).
Technically seen, it would be a simple thing to allow multiple such
files to coexist in a repository, one of them being chosen as the
"current" one; IOW branches. Since each has its own tree hash,
calculating the diff between any two branch heads is cheap, as is
replacing the working tree with the recorded state of another branch
("checkout"). (Naturally, comparing or checkout of intermediate states
is more involved: for this we have to unapply patches from the end state.)
The only non-trivial problems on the way toward internal branches in
Darcs are (1) design and implementation of the UI and (2) maintaining
compatibility between repositories and Darcs versions.
Cheers
Ben
--
I would rather have questions that cannot be answered, than answers that
cannot be questioned. -- Richard Feynman
More information about the darcs-users
mailing list