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')],
largefiles: put same 'action' object back in 'newglist'
The items we put in 'newglist' are always the same as what we found in
actions['g'], so let's just put the same item into the list instead of
creating a new one.
largefiles: don't unnecessarily sort merge action lists
The action lists returned from calculateupdates() (in merge.py) are
not required to be sorted. In fact, since they result from iteration
over the unordered manifest, they are unlikely to be sorted. Moreover,
some of the lists are appended to after they are returned from
manifestmerge(). The lists are instead sorted in
applyupdates(). Therefore, let's not sort the lists generated in
largefiles' overridecalculateupdates().
merge: don't treat 'diverge' and 'renamedelete' like actions
See earlier patch for motivation.
merge: move dr/rd warning messages out of applyupdates()
As preparation for making 'dr' and 'rd' actions no longer actions,
move the reporting from applyupdates() to its caller update(). This
way we won't have to pass additonal arguments to applyupdates() when
they are no longer actions. Also, the warnings are equally unrelated
to applyupdates() as they are to recordupdates(), as they don't result
in any changes to either the working copy or the dirstate.
See earlier patch for additional motivation.
merge: don't report progress for dr/rd actions
It is easier to reason about certain algorithms in terms of a
file->action mapping than the current action->list-of-files. Bid merge
is already written this way (but with a list of actions per file), and
largefiles' overridecalculateupdates() will also benefit. However,
that requires us to have at most one action per file. That requirement
is currently violated by 'dr' (divergent rename) and 'rd' (rename and
delete) actions, which can exist for the same file as some other
action.
These actions are only used for displaying warnings to the user; they
don't change anything in the working copy or the dirstate. In this
way, they are similar to the 'k' (keep) action. However, they are even
less action-like than 'k' is: 'k' at least describes what to do with
the file ("do nothing"), while 'dr' and 'rd' or only annotations for
files for which there may exist other, "real" actions.
As a first step towards separating these acitons out, stop including
them in the progress output, just like we already exclude the 'k'
action.
subrepo: add partial diff support for git subrepos
So far, git subrepositories were silently ignored for diffs.
This patch adds support for git subrepositories,
with the remark that --include and --exclude are not supported.
If --include or --exclude are used, the subrepo is ignored.
subrepo: extend git version check to 3 digits
This allows more flexibility when a version check is required.
Some git features are introduced in a version where only
the 3rd digit changes.
subrepo: move git version check into a separate method
This allows checking the git version in other methods,
instead of only being able to check if the version is ok or not.
rebase: show a note for updated mq patches
It deserves more than a debug message. Show a note like:
updating mq patch p0.patch to 5:
9ecc820b1737
The message could also refer to "qrefresh" instead. Same same.
rebase: show warning when rebase creates no changes to commit
Similar to graft:
note: rebase of 6:
eea13746799a created no changes to commit
rebase: show more useful status information while rebasing
Show status messages while rebasing, similar to what graft do:
rebasing 12:
2647734878ef "fork" (tip)
This gives more context for the user when resolving conflicts.
tests: make 'saved backup' globbing less narrow in rebase tests
Globbing the hash made it harder to maintain tests with run-tests -i when it
was so far by the generated test output.
The hashes are stable and we just need to add a (glob).
tests: stabilise mq rebase tests
Prepare for including hashes in output ... and less globbing make the tests
easier to update.
test-graft: use strip extension instead of mq extension
It only needs strip, no reason to load all of mq.