largefiles: rewrite merge code using dictionary with entry per file
In overridecalculateupdates(), we currently only deal with conflicts
that result in a 'g' action for either the largefile or a standin. We
will soon want to deal cases with 'cd' and 'dc' actions here. It will
be easier to reason about such cases if we rewrite it using a dict
from filename to action.
A side-effect of this change is that the output can only have one
action per file (which should be a good change). Before this change,
when one of the tests in test-
issue3084 received this input (the 'a'
in the input was a result of 'cd' conflict resolved in favor of the
modified file):
'g': [('.hglf/f', ('',), 'remote created')],
'a': [('f', None, 'prompt keep')],
and the user chose to keep the local largefile, it produced this
output:
'g': [('.hglf/f', ('',), 'remote created')],
'r': [('f', None, 'replaced by standin')],
'a': [('f', None, 'prompt keep')],
Although 'a' actions are processed after 'r' actions by
recordupdates(), it still worked because 'a' actions have no effect on
merges (only on updates). After this change, the output is:
'g': [('.hglf/f', ('',), 'remote created')],
'r': [('f', None, 'replaced by standin')],
Similarly, there are several tests in test-largefiles-update that get
inputs like:
'a': [('.hglf/large2', None, 'prompt keep')],
'g': [('large2', ('',), 'remote created')],
and when the user chooses to keep the local largefile, they produce
this output:
'a': [('.hglf/large2', None, 'prompt keep'),
('.hglf/large2', None, 'keep standin')],
'lfmr': [('large2', None, 'forget non-standin largefile')],
In this case, it was not a merge but an update, so the 'a' action does
have an effect. However, since dirstate.add() is idempotent, it still
has no obserable effect.
After this change, the output is:
'a': [('.hglf/large2', None, 'keep standin')],
'lfmr': [('large2', None, 'forget non-standin largefile')],
#require killdaemons
$ hgserve() {
> hg serve -a localhost -p $HGPORT1 -d --pid-file=hg.pid \
> -E errors.log -v $@ > startup.log
> # Grepping hg serve stdout would hang on Windows
> grep -v 'listening at' startup.log
> cat hg.pid >> "$DAEMON_PIDS"
> }
$ hg init a
$ hg --encoding utf-8 -R a branch æ
marked working directory as branch \xc3\xa6 (esc)
(branches are permanent and global, did you want a bookmark?)
$ echo foo > a/foo
$ hg -R a ci -Am foo
adding foo
$ hgserve -R a --config web.push_ssl=False --config web.allow_push=* --encoding latin1
$ hg --encoding utf-8 clone http://localhost:$HGPORT1 b
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
updating to branch \xc3\xa6 (esc)
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg --encoding utf-8 -R b log
changeset: 0:867c11ce77b8
branch: \xc3\xa6 (esc)
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: foo
$ echo bar >> b/foo
$ hg -R b ci -m bar
$ hg --encoding utf-8 -R b push
pushing to http://localhost:$HGPORT1/
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files
$ hg -R a --encoding utf-8 log
changeset: 1:58e7c90d67cb
branch: \xc3\xa6 (esc)
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: bar
changeset: 0:867c11ce77b8
branch: \xc3\xa6 (esc)
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: foo
$ "$TESTDIR/killdaemons.py" hg.pid
verify 7e7d56fe4833 (encoding fallback in branchmap to maintain compatibility with 1.3.x)
$ cat <<EOF > oldhg
> import sys
> from mercurial import ui, hg, commands
>
> class StdoutWrapper(object):
> def __init__(self, stdout):
> self._file = stdout
>
> def write(self, data):
> if data == '47\n':
> # latin1 encoding is one %xx (3 bytes) shorter
> data = '44\n'
> elif data.startswith('%C3%A6 '):
> # translate to latin1 encoding
> data = '%%E6 %s' % data[7:]
> self._file.write(data)
>
> def __getattr__(self, name):
> return getattr(self._file, name)
>
> sys.stdout = StdoutWrapper(sys.stdout)
> sys.stderr = StdoutWrapper(sys.stderr)
>
> myui = ui.ui()
> repo = hg.repository(myui, 'a')
> commands.serve(myui, repo, stdio=True, cmdserver=False)
> EOF
$ echo baz >> b/foo
$ hg -R b ci -m baz
$ hg push -R b -e 'python oldhg' ssh://dummy/ --encoding latin1
pushing to ssh://dummy/
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files