[darcs-users] Darcs equivalent of force-pushing and branching

Ben Franksen ben.franksen at online.de
Sat Oct 2 15:08:51 UTC 2021


Am 15.09.21 um 05:21 schrieb Stephen J. Turnbull:
> James Cook writes:
>   > > 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*.  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?
> 
> Apparently not, see Ben's response for accurate details.

It depends on what you mean with "patches". From a user perspective, it 
is indeed true that a branch is a set of patches. My response was about 
the implementation which has a different view.

The confusion arises because "patch" is a very broad term that covers 
many subtly different concepts and it depends on the context what is 
meant. By analogy, think of the term "number": it could mean natural 
number, integer, rational number, and so on up to complex and even 
hypercomplex numbers, all of which have common operations and properties 
(like a commutative addition), but differ in other aspects (like whether 
additive inverses exist).

Patches as seen by the user are "abstract" in the sense that they are 
actually equivalence classes of concrete patches (as stored in memory or 
on disk). A concrete patch consists of a sequence of primitive changes 
(possibly in conflicted form) together with meta-data (name, author, 
date, etc). The meta-data is the only part that is guaranteed to remain 
invariant under commutation and is therefore used to identify abstract 
patches. The implementation keeps track of the order of patches, 
restricting re-orderings according to what is allowed by the commutation 
laws. Thus, from the user perspective, any two sequences of patches are 
semantically the same (equivalent) if and only if their set of 
identifiers are the same.

In git things are simpler because it uses a more low-level approach: the 
user deals with commits and a commit is identified by a hash of its 
content, which includes the identifier (content hash) of its 
predecessor. This means the order is baked into the commits themselves, 
so there is no need to store it separately. You can manually re-order 
commits (using rebase), but there is no guarantee about equivalency and 
the re-ordered commits have different content and therefore different 
identities. Git has heuristics to guess when two different commits are 
meant to be "the same change", which allows for commands like 
cherry-pick to work well enough in practice. In contrast, Darcs never 
guesses and it guarantees equivalence, and thus lets you work with the 
more high-level concept of "abstract" patches, re-ordering the concrete 
patches automatically as needed. That said, the abstraction here is 
somewhat leaky, as the concrete order of patches can be observed (darcs 
log) and, to a certain extent, influenced by the user (darcs pull 
--reorder-patches, darcs optimize reorder).

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