I've really not been paying a lot of attention to merge-tracking for
the last two months. It's obvious that it's causing a lot of stress;
we keep getting closer and closer, and then discover 'one more'
showstopper that involves a lot of work.
Today, however, I took a look at issue 2897 for the very first time,
along with Mark's explanation of the problem, and sort of did a "huh?"
I asked Danny Berlin to look as well, and we ended up having a nice
IRC chat with markphip, cmpilato, and jackr. In a nutshell: I think
it's sometimes too easy for a community to frame all problems in terms
of everything they've built -- to lose sight of the forest through the
trees. Here's a fresh suggestion from people who haven't been
heads-down on the implementation details.
The problem here is how to deal with long-lived feature branches that
are kept up-to-date with trunk, then eventually re-merged back to
trunk. In our simple example, we imagine a scenario where the user
merges /trunk:1-100 to the branch and gets some conflicts. She then
resolves the conflicts, and commits r101 to the branch. After a few
more branch commits, she merges back to trunk. What should our
merge-tracking feature do?
Mark (and others) have pointed out that the Big Problem here is "what
to do about r101". It contains all of the /trunk:1-100 changes and
*also* some branch-specific conflict-resolution. Our current
machinery either includes or excludes entire revisions, which poses a
dilemma. If we merge r101 back to trunk, we'll get 100 revisions of
repeated-merge errors. If we don't merge r101 back to trunk, then we
lose the critical conflict-resolution changes (which are likely needed
to make other branch-changes apply correctly to trunk.) Our current
code would include r101; when Kamesh is done with his issue-2897
branch, our code would exclude r101. Both behaviors are wrong... or
at least sub-optimal, and lead to problems for the user.
So what should a proper merge-tracking feature do? It should merge
*just the conflict resolution changes* back to trunk. In other words,
we need to stop treating revisions as atomic units -- the proper
solution is to apply just the "correct" part of the revision. As
DannyB explained in IRC, our merge code should take the r101 change,
*subtract* the /trunk:1-100 changes from it, and whatever's left over
is the correct patch to apply to the trunk.
Yes, this is hard, but it's correct. We'll need new APIs for this
sort of thing.
DannyB also pointed out that sometimes other version control systems
cheat in this area: that merging the branch to trunk causes an
"automatic" commit (even if there are conflicts!), and then the user's
conflict resolution changes are an extra commit on top of that. This
guarantees that the changes aren't blurred together into one revision.
This is possibility for us, if we don't want to go through the work of
I don't want to derail all the work Kamesh and Karl have been doing in
the branch, but I really feel like this is the Correct Solution -- and
it's going to involve a (little bit) of breaking of the walls we've
made for ourselves. :-)
To unsubscribe, e-mail: firstname.lastname@example.org
For additional commands, e-mail: email@example.com
Received on Wed Nov 28 22:46:28 2007