gnu-arch-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnu-arch-users] Re: <<< conflict markers


From: Aaron Bentley
Subject: Re: [Gnu-arch-users] Re: <<< conflict markers
Date: Fri, 16 Apr 2004 15:34:17 -0400
User-agent: Mozilla Thunderbird 0.5 (X11/20040309)

Tom Lord wrote:
Instead, look at what "ancestry-following update" should mean.  Let's
suppose, though, that what we have is a situation like:


                       base-0           ; a tag or import revsision
                       patch-1
                       patch-2          ;\
                       ....             ; } all others are commit revisions
   my project tree --> patch-K          ;/
   is uptodate w/      ...
   patch-K             patch-N          ; a tag revsion of 
foo--bar--1.0--patch-Z
                       ...
                       patch-X          ; (commit revision)


What, exactly, should a hypothetically ancestry-based update do if I
run it in my project tree?  Should it do (the equivalent of):


        undo patch-K
        get --clobber patch-X
        redo


or:

        undo foo--bar--1.0
        get --clobber patch-X
        redo

(or, something else entirely?)   And, if the latter, does it matter if
I'm uptodate with foo--bar--1.0--patch-(Z-2) but
foo--bar--1.0--patch-(Z-1) is a tag revision?

My vote would go with "undo patch-K; get --clobber patch-X; redo". That's what I understand "update" to do; apply the changes I made to the latest version of the tree. That's the same behaviour as you'd get if the archive had been changed with replay --reverse and sync-tree.

And, to know that certain optimizations _don't_ apply, `update' will
have to get the revision type of each patch-K+1...patch-X.

So, both for predictability and performance, namespace-based update is
the way to go.   More complex merging needs should be handled by a
flexible `super-merge' command or by scripts.

But update is already ancestry-based, AFAICT. When I do update, it builds the latest revision, then applies the delta between my tree's revision and the latest revision to my tree. (It also does that undo-redo stuff, but I never have local changes when I do update.) Since build_revision follows ancestry, update is ancestry-based.

    > And personally, I'm lukewarm about mixing tags and commits.  But
    > I feel they should either be supported or forbidden.

I have a slightly different attitude:

~ Simple things should be easy.
~ Hard things should be possible.

Tagging into a commit-based branch, isn't just possible, it's easy. It's easier than tagging into a new branch (no need for make-archive) And it's non-reversible.

Yet on the other hand, some of my fellow Arch developers think that they don't have to test for the mixed-tags-and-commits case, because it's discouraged in the tutorial. So I rather suspect tla exhibits bugs (not just debatable behavour) for some commands when tag and commit are mixed.

I don't think we can let it stay like that. Either we say "yes, it's permitted", and provide some basic guarantees, or we say "no, we can't guarantee anything" and at least make it hard.

~ The operation of each subcommand should be easy to explain.
~ Operations should not be forbidden just because you can't see why
  someone would want to do it.

I think it's valid to forbid an operation because you expect that permitting it will lead to pathological behaviour. I wasn't suggesting forbidding it out of value judgements, and I'm willing to do either, as I hope my fixing the backbuilder demonstrates.

In fact, I think it would be quite handy to kill bad revisions by simply tagging their ancestor into the current version, so you get this:

patch-5 --commit---patch-6 (bad)      patch-7---commit---patch-8
    \                                /
     \---------------tag------------/

I prefer that approach, because it's more meaningful. It's very obvious that patch-6 has been disowned, and doesn't contribute to the ancestry. It's essentialy the "repent" command that someone jokingly suggested a while back, and it's a neat compromise between not changing history and deleting a revision.

However, replay --reverse and sync-tree are close enough to what I want. I'll use them instead if I can't trust tla's behaviour with mixed tags and commits.

If, following those principles, you wind up with something that
happens to be useful for revision control -- then, that's a win.  What
you wound up with is probably _very_ useful for revision control.

In this case, `update' (as it stands) makes a simple thing easy (while
other commands make harder merges possible).   It is easy to explain
what update does.

I've seen documentation that claims update replays revisions, but I've only ever seen it apply deltas. In my experience, then, it's ancestry-sensitive. Are there indeed cases in which it replays?



Update can be understood as any of a number of combinations like:

        undo + replay + redo
        what-changed + get + dopatch
        undo + delta-patch + redo
        get + delta-patch

At the risk of flogging a dead horse, the replay version will behave differently from the get and apply-delta versions wrt your patch-X and patch-K example.

etc.   I think that when users get how all these commands relate that
makes them more effective users.   Trying to hide a lot of black magic
in the guts of `update' is just going to create another generation of
users for whom revision control is a mysterious black-box.

As far as I see, update's already got the necessary magic. Please let me know if I'm missing something.

Aaron

--
Aaron Bentley
Director of Technology
Panometrics, Inc.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]