Subject: Re: bug?: stgit creates (unneccessary?) conflicts when pulling

From: Shawn Pearce <[email-masked]>
Date: Mon, 27 Feb 2006 17:26:00 -0500

Karl Hasselstr?m <[email-masked]> wrote:
> If I make a patch series where more than one patch touches the same
> line, I get a lot of merge errors when upstream has accepted them and
> I try to merge them back.
> 
> Suppose a line contained the string "0". Patch p1 changes that to "1",
> patch p2 further changes that to "2". Upstream accept the patches, and
> I later "stg pull" them. When reapplying p1 after the pull, stg
> generates a merge conflict since upstream changed the "0" to "2" and
> p1 changes the "0" to "1".

You should look at pg:

  http://www.spearce.org/2006/02/pg-version-0111-released.html

It has some of the features of StGIT and it (at least partially)
solves this problem.

Assume you had a patch stack of:

	PatchA : Change 0 to a 1
	PatchB : Change 1 to a 2
	PatchC : Change 2 to a 3

with each affecting the same line of the same file.

When pg grabs its (possibly remote) parent ("stg pull" aka pg-rebase)
we try to push down PatchA.  If PatchA fails to push cleanly we'll
pop it off and try to push PatchA + PatchB.  If that pushes cleanly
then we fold the content of PatchA into PatchB, effectively making
PatchA part of PatchB.  If PatchA + PatchB failed to push down
cleanly then we pop both and retry pushing PatchA + PatchB + PatchC.
If that pushes down cleanly then we make PatchA and PatchB officially
part of PatchC.

This required some ``hacks'' in pg-push.  Basically if we are
doing a non-fastforward push (as there are new commits we must
merge on top of) we run an external diff/patch to apply the change.
If that fails we reset the tree back to a clean state and try again.
Whenever patch rejects a hunk we examine the hunk to see if it is
already applied to the target file; if it is already applied we
skip the hunk.  If all hunks applied cleanly and/or are already
applied we accept the patch (or combination of patches) as merging
cleanly. Yea, its not very pretty.  But it works!

Where it falls down is if the upstream accepts all three of your
patches but then changes the line from a 3 to a 4.  pg won't look
at the GIT commit history to detect that the upstream accepted your
final change (PatchC) but then overwrite it with a newer change
(3->4).  I have thought about trying to implement this but the
current environment where I am using pg wouldn't benefit from it,
so it has not been high on my priority list.

-- 
Shawn.