Issue1011

Title Fetch should swap merge parents
Priority wish Status resolved
Superseder Nosy List abuehl, bos, djc, jglick, schickb
Assigned To bos Topics merge, surprise

Created on 2008-02-29.19:31:05 by jglick, last changed 2008-03-10.07:27:37 by djc.

Messages
msg5513 (view) Author: djc Date: 2008-03-10.07:27:37
In main, resolving.
msg5452 (view) Author: bos Date: 2008-03-05.17:45:38
Fixed in 0b6f12495276 in crew.
msg5440 (view) Author: jglick Date: 2008-02-29.19:53:06
Note that there was a recent discussion on the lists about a similar issue for
'hg backout --merge', which asks you to commit a merge whose apparent diff is
unrelated to the patch you are backing out. That case is rather simpler since it
is clear what the natural order of merge parents should be.
msg5439 (view) Author: jglick Date: 2008-02-29.19:31:03
In a team using a mostly centralized model - a bunch of people pushing to a
shared repository - the most straightforward workflow, using a single local
clone, is

edit files...
hg ci
hg fetch
hg push

Currently the fetch command runs with your own last changeset as first merge
parent and the shared repository's last changeset as second parent. If there are
no merge conflicts and you don't look at the result, it is OK. But to most
people's intuition, especially former users of a centralized VCS, this is
entirely backwards:

1. Looking at the changeset later (hg log, hgweb, ...) you will see someone
apparently committing changes to all kinds of files _except_ the ones they
actually work on, which is very misleading.

2. The notify extension will similarly send out mail "from" person A showing
numerous diffs made by people B...Z. (For hg.netbeans.org we work around this by
patching notify.py to simply not send mail for merge changesets at all.)

3. If the fetch command aborts - because there was some kind of merge conflict,
and either no merge tool was configured or it failed to mark the conflict
resolved - then you are left with an uncommitted merge, which probably just
needs some minor fixups to be OK to commit. But 'hg st' or 'hg di' on this will
show potentially hundreds of changes you never made, which is alarming - and
seems to lead novice Hg users to run 'hg revert', which is disastrously wrong.

Issue981 would ameliorate some of these problems, by giving people a way to see
the "real" change made by the merge (if any), but the fact remains that it feels
very uncomfortable to be "committing" other people's work.

Note that other workflow topologies do not necessarily suffer from this problem,
even if you are using fetch. For example, if you have an incoming repo, one or
more work repos, and an outgoing repo, you can

cd out
hg pull shared
hg up -C
hg fetch ../work
hg push shared

which will have your own work as second merge parent, not first. So simply
swapping the merge parents for fetch unconditionally - i.e. changing its
semantics from

hg pull
hg merge $newhead
hg ci

to

hg pull
hg up -C $newhead
hg merge $oldhead
hg ci

would have the wrong effect for people using this workflow.

Perhaps fetch should have a --reverse option to merge in the reverse order. Or
perhaps it could figure out the best order to merge. Maybe this would be
considered too magical, but one possible heuristic would be:

1. Compute common ancestor of old and new heads.

2. Collect changesets between ancestor and both heads.

3. If all changesets between ancestor and old head were committed by the
currently configured user, and at least some of the changesets between ancestor
and new head were not, then do a reverse merge.

4. Otherwise behave as now.

The effect would be that for people working in a simple centralized style, merge
changesets would look like people expect them to be: your last sequence of
patches folded into one (and, occasionally, updated for the new repo tip). I
think this would be more intuitive and less accident-prone.
History
Date User Action Args
2008-03-10 07:27:37djcsetstatus: testing -> resolved
nosy: + djc
messages: + msg5513
2008-03-05 17:45:40bossetstatus: chatting -> testing
nosy: bos, jglick, schickb, abuehl
messages: + msg5452
assignedto: bos
2008-03-01 06:30:37schickbsetnosy: + schickb
2008-02-29 20:57:06abuehlsetnosy: + abuehl
2008-02-29 19:53:06jglicksetstatus: unread -> chatting
nosy: bos, jglick
messages: + msg5440
2008-02-29 19:31:05jglickcreate