[issue1011] Fetch should swap merge parents

Jesse Glick mercurial-bugs at selenic.com
Fri Feb 29 13:31:05 CST 2008


New submission from Jesse Glick <jesse.glick at sun.com>:

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.

----------
messages: 5439
nosy: bos, jglick
priority: wish
status: unread
title: Fetch should swap merge parents
topic: merge, surprise

____________________________________________________
Mercurial issue tracker <mercurial-bugs at selenic.com>
<http://www.selenic.com/mercurial/bts/issue1011>
____________________________________________________



More information about the Mercurial-devel mailing list