Subject: Re: [RFC] Stgit - patch history / add extra parents

From: Catalin Marinas <[email-masked]>
Date: Tue, 23 Aug 2005 17:55:21 +0100

Daniel Barkalow <[email-masked]> wrote:
> One factor not mentioned there is that, as things move upstream, we often
> want to discard a lot of history; if someone commits constantly to deal
> with editor malfunction or something, we don't really want to take all of
> this junk into the project history when it is cleaned up and
> accepted.

That's true but Jan's proposal is to choose which commits to preserve
in the history via a 'freeze' command. That's a bit difficult to
implement in a clean way since the patches are floating on top of the
stack base and they change every time the base changes. It is possible
that a previous frozen state might no longer apply on top of a new
base.

> So the point is that there are things which are, in fact, parents, but we
> don't want to list them, because it's not desired information.

What's the definition of a parent in GIT terms? What are the
restriction for a commit object to be a parent? Can a parent be an
arbitrarily chosen commit?

> Probably the right thing is to have two views of the stack: the internal
> view, showing what actually happened, and the external view, showing what
> would have happened if the developers had done everything right the first
> time. When you make changes to the series, this adds to the internal view
> and entirely replaces the external view.

That's what I've been thinking. StGIT currently only implements the
external view.

An StGIT patch is a represented by a top and bottom commit
objects. The bottom one is the same as the parent of the top
commit. The patch is the diff between the top's tree id and the
bottom's tree id.

Jan's proposal is to allow a freeze command to save the current top
hash and later be used as a second parent for the newly generated
top. The problem I see with this approach is that (even for the
internal view you described) the newly generated top will have two
parents, new-bottom and old-top, but only the diff between new-top and
new-bottom is meaningful. The diff between new-top and old-top (as a
parent-child relation) wouldn't contain anything relevant to the patch
but all the new changes to the base of the stack.

Is the above an acceptable usage of the GIT DAG structure?

> I think that users will also want to discard the commits from the stack
> before rebasing in favor of the commits after, because (a) rebasing isn't
> all that interesting, especially if there's minimal merging, and (b)
> otherwise you'd get a ton of boring commits that obscure the interesting
> ones.

StGIT does this currently. The old commit is no longer available and
can be pruned (I still need to save the commits corresponding to the
unpushed patches since prune would remove those as well).

> I think that the best rule would be that, when you modify a patch, the
> previous version is the new version's parent, and when you rebase a
> series, you include as a parent any parent of the input that isn't also in
> the input (but never include the input itself as a parent of the output;
> the point of rebasing is to pretend that it was the newer mainline that
> you modified). This should mean that the internal history of a patch
> consists of the present version, based on each version that was replaced
> due to changing the patch rather than rebasing it.

Since you proposed this, my above usage of the DAG structure would be
fine then.

> Of course, there's an interesting situation with the commits earlier in a
> series from a patch that was changed not being ancestors of the newer
> versions of those patches (because they weren't interesting in the
> development of those patches) but accessible as the commits that an
> interesting patch was based on.
>
> A possible solution is just to consider the revision of any patch a
> significant event in the history of the whole stack, causing all of the
> patches to get a new retained version.

That's another idea to think about.

-- 
Catalin

P.S. I'll be away until next week and not able to follow-up the
discussions.