[darcs-users] Fwd: Darcs Problems

Ganesh Sittampalam ganesh at earth.li
Fri Mar 1 07:49:35 UTC 2013


On 01/03/2013 03:48, John Lato wrote:
> 
> Agreed.  This is a big part of my point, although in much clearer
> verbiage.  A clear history is very useful for determining the context of
> current work.  Git users value this history quite highly, as evidenced
> by the vast amount of time git users spend rebasing to clean up history,
> developing best practices for maintaining a clean history, etc.
>  Patch-oriented VCS's don't really have anything comparable.
> 
> I was thinking about a possible implementation a few days ago, and came
> up with this idea.  Darcs could add another special patch, which I'm
> calling a base patch.  A base patch would have the following properties:
> 
> 1.  Every patch applied after a base patch depends on the base patch.
> 2.  A base patch doesn't depend on anything, but it conflicts anywhere
> its dependents would conflict.

I think this will be difficult, because the set of dependents isn't a
fixed thing; if a new dependent patch comes along, it changes the
behaviour of the base patch, which could be arbitrarily far way in the
linear history.

> This would make a base patch act as essentially a starting point for a
> group of patches that logically work together (they're all based on the
> base patch).  I think you'd also need either a tag or another special
> patch to act as the other end of a base patch.
> 
> I think an equivalent statement is that a base patch doesn't commute
> with any of its dependents, but it does commute with any antecedent
> patches its dependents commute with.
> 
> What the base patch gives you is the ability to pick commits without
> their dependencies.  Suppose you have two branches, stable and dev, and
> you want to pick a patch 'hotfix' from dev to stable.  hotfix will most
> likely have several other dependencies in dev, but you don't want those.
>  You want to just take hotfix and fix any conflicts.  So you would do
> the following:
> make a new repo 'tmp-dev', which has everything in 'dev' except 'hotfix'
> apply a base patch
> pull hotfix
> from the stable repo, cherrypick tmp-dev's hotfix (which will also bring
> the base patch)
> 
> When trying to apply the base patch to the stable repo, the base patch
> will conflict everywhere hotfix's dependencies are unmet.  To resolve
> the conflicts, we first undo hotfix, then apply hotfix' (the new patch).
>  We don't actually touch the base patch when resolving conflicts, but
> after the resolution, the base patch's dependents have changed, so now
> it will only conflict where hotfix' would (since the original hotfix is
> undone).  At this point, the developer would apply a tag (or end-base)
> patch and it's done.

Could you explain this workflow a bit more - how does the base patch
help with dependencies? To pull the hotfix you are also pulling the
unwanted dependencies, and its those that you need to deal with.

> I haven't given too much thought to this, but there's probably
> substantial overlap with the darcs-rebase work that's been going on.
>  I'd appreciate it if someone who's familiar with that (Ganesh?) could
> comment on this.  If it's a good idea, maybe I could try to hack it up,
> or somebody else might be inspired to work on it.

With rebase, the workflow for grabbing the hotfix without its
dependencies is roughly:

pull hotfix (thus grabbing the dependencies too)
darcs rebase suspend <hotfix>
darcs obliterate <unwanted dependencies>
darcs rebase unsuspend <hotfix>
<resolve conflicts>
darcs amend-record <hotfix>.

The downside is that this gives you a patch with a new identity, with no
real relationship to the previous hotfix.


As far as tracking history goes in general, my feeling is that
conceptually tags are good enough to represent this, and the main thing
we need is good enough UI to make them usable for this purpose.

The basic idea is that each time you record a patch, you also create a
tag - let's call it a "history" tag. The history tag will depend on the
newly-recorded patch, and also the most recent previous tag, which will
typically be the history tag for the previous patch. Patches never
depend on tags unless you make them do so explicitly, so the patch
itself won't depend on any history tags by default.

What you end up with then is a chain of history tags, each depending on
the previous one and a single patch, that communicate a particular
ordering for the related patches, but don't actually enforce it, because
you can always pull without the tags.

If you want to see the context in which a particular patch was
originally written, it's represented by the history tag for that patch.
If you want to cherry pick it, just ignore the tags and get the patch
(if there aren't any problems with dependencies).

This approach is also something I see as the ideal way to track the
history of specific branches - e.g. production. In that case you would
tag each time you pull patches from development, so keeping a separate
record of "what was in production". I've also been pushing this idea on
Owen for the git bridge to encode the ordering of the git commits on the
darcs side.

This kind of approach is probably closer to the mercurial philosophy of
tracking the original context a change was made in, rather than
aggressively cleaning up with rebase. However the ability to use a
different sequence of tags to represent a different branch also lets you
encode later merges etc.

As you mentioned upthread, having a lot of tags cluttering the changelog
would be distracting, so we would need some way to hide history tags by
default.

Cheers,

Ganesh


More information about the darcs-users mailing list