Commit Graph

413 Commits

Author SHA1 Message Date
Mads Kiilerich
26a58ad0b7 merge: use ancestor filename from planning phase instead of filectx ancestor
test-merge-types.t changes a bit in flag merging. It relied on the
implementation detail that 100% identical revlog entries are reused. The revlog
reuse did that fctx.ancestor() saw an ancestor where there really not was one.
2014-02-25 20:30:08 +01:00
Matt Mackall
c9eb4517fa merge with stable 2014-04-01 15:11:19 -05:00
FUJIWARA Katsunori
01d8b27701 i18n: fix "% inside _()" problems
Before this patch, "contrib/check-code.py" can't detect these
problems, because the regexp pattern to detect "% inside _()" doesn't
suppose the case that the format string and "%" aren't placed in the
same line.

This patch replaces "\s" in that regexp pattern with "[ \t\n]" to
detect "% inside _()" problems in such case.

"[\s\n]" can't be used in this purpose, because "\s" is automatically
replaced with "[ \t]" by "_preparepats()" and "\s" in "[]" causes
nested "[]" unexpectedly.
2014-04-01 02:46:03 +09:00
FUJIWARA Katsunori
e0d81db88f merge: fix lack of "%s" in format string causing TypeError at runtime 2014-04-01 02:46:03 +09:00
Mads Kiilerich
6c40916e6d merge: audit the right destination file when merging with dir rename 2014-03-01 18:09:39 +01:00
Pierre-Yves David
3eab08d896 resolve: use "other" changeset from merge state (issue4163)
We can use the "other" data from the recorded merge state instead of inferring
what the other could be from working copy parent. This will allow resolve to
fulfil its duty even when the second parent have been dropped.

Most direct benefit is fixing a regression in backout.
2014-02-25 18:45:01 -08:00
Pierre-Yves David
f2a2751552 merge: add "other" file node in the merge state file
This data is mostly redundant with the "other" changeset node (+ other changeset
file path). However, more data never hurt.

The old format do not store it so this require some dancing to add and remove it
on demand.
2014-02-25 18:54:47 -08:00
Pierre-Yves David
49ce770140 merge: infer the "other" changeset when falling back to v1 format
When we have to fallback to the old version of the file, we infer the
"other" from current working directory parent. The same way it is currently done
in the resolve command. This is know to have shortcoming… but we cannot do
better from the data contained in the old file format. This is actually the
motivation to add this new file format.
2014-02-27 14:14:57 -08:00
Pierre-Yves David
15afb2ca0c merge: record the "other" node in merge state
We need to record the merge we were merging with. This solve multiple
bug with resolve when dropping the second parent after a merge. This
happen a lot when doing special merge (overriding the ancestor).
Backout, shelve, rebase, etc. can takes advantage of it.

This changeset just add the information in the merge state. We'll use it in the
resolve process in a later changeset.
2014-02-25 18:42:11 -08:00
Pierre-Yves David
b5e943e8cb merge: introduce new format for the state file
This new format will allow us to address common bugs while doing special merge
(graft, backout, rebase…) and record user choice during conflict resolution.

The format is open so we can add more record for future usage.

This file still store hexified version of node to help human willing to debug
it by hand. The overhead or oversize are not expected be an issue.

The old format is still used. It will be written to disk along side the newer
format. And at parse time we detect if the data from old version of the
mergestate are different from the one in the new version file. If its the same,
both have most likely be written at the same time and you can trust the extra
data from the new file. If it differs, the old file have been written by an
older version of mercurial that did not knew about the new file. In that case we
use the content of the old file.
2014-02-25 18:37:06 -08:00
Pierre-Yves David
01a482bed9 merge: change the merge state serialisation to use a record based logic
The format of the file is unchanged. But we are preparing a new file with a new
format that would be record based. So we change all the read/write logic to
handle a list of record until a very low level. This will allow simple plugging
of the new format in the current code.
2014-02-27 12:59:41 -08:00
Pierre-Yves David
2438827558 merge: move merge state file path into a constant
We are about to change the format. Having the file path in a single place make
it easier to update the filename for the new version.
2014-02-25 17:14:49 -08:00
Mads Kiilerich
5157505e94 merge: mark mergestate as dirty when resolve changes _state
Correctness - no visible difference so far.
2014-02-28 02:26:03 +01:00
Mads Kiilerich
4aef593d5a merge: don't overwrite file untracked after remove, abort with 'untracked files'
Merge could overwrite untracked files and cause data loss.

Instead we now handle the 'local side removed file and has untracked file
instead' case as the 'other side added file that local has untracked' case:

  FILE: untracked file exists
  abort: untracked files in working directory differ from files in requested revision

It could perhaps make sense to create .orig files when overwriting, either
instead of aborting or when overwriting anyway because of force ... but for now
we stay consistent with similar cases.
2014-02-10 00:43:54 +01:00
Pierre-Yves David
c559733782 merge: adds documentation to the mergestate class
Document most the new function involved in the new serialisation process (and a
few others).
2014-03-05 10:49:43 -08:00
Pierre-Yves David
2cdc06eb49 merge: add blank line between mergestate's method
This class is now too big to be a single big block of continuous text.
2014-03-05 10:22:43 -08:00
Mads Kiilerich
f6187cda8d merge: use the right ancestor when both sides copied the same file
The tests shows no real changes because of this ... but there must be some
weird corner cases where using the right ancestor for the merge planning is
better than using the wrong one.
2014-02-25 20:29:46 +01:00
Mads Kiilerich
24ed93fbb6 merge: handle create+delete prompts in calculateupdates
I would like to move it all the way to the interactive resolve state like
merges are ... but this is a first intermediate step.
2014-03-02 18:36:02 +01:00
Mads Kiilerich
23f515d5c2 merge: handle acceptremove of create+delete early in manifest merge 2014-02-28 02:26:03 +01:00
Augie Fackler
5b6342a4d8 merge with stable 2014-03-01 21:08:28 -05:00
Olle Lundberg
bee0a3e630 merge: fix spelling of length 2014-02-28 02:28:12 +01:00
Sean Farley
eb5399916a merge: consider successor changesets for a bare update
Previously, a bare update would ignore any successor changesets thus
potentially leaving you on an obsolete head. This happens commonly when there
is an old bookmark that hasn't been moved forward which is the motivating
reason for this patch series.

Now, we will check for successor changesets if two conditions hold: 1) we are
doing a bare update 2) *and* we are currently on an obsolete head.

If we are in this situation, then we calculate the branchtip of the successor
set and update to that changeset.

Tests coverage has been added.
2014-01-15 16:41:18 -06:00
Sean Farley
17f6cfcd6f merge: refactor initialization of variables in update
There is no code change here but this helps prepare for future commits that
will fix a bare update with obsolete markers.
2013-11-06 17:02:07 -06:00
Sean Farley
26332808a6 merge: update comment for future devs 2013-11-06 10:26:25 -06:00
Siddharth Agarwal
5fa78a0d83 merge: move forgets to the beginning of the action list
Forgets need to be in the beginning of the action list, same as removes. This
lets us avoid clashes in the dirstate where a directory is forgotten and a
file with the same name is added, or vice versa.
2013-11-06 10:20:18 -08:00
Mads Kiilerich
eabc047878 spelling: random spell checker fixes 2013-10-24 01:49:56 +08:00
Siddharth Agarwal
69eb5c00b0 merge: exit early during a no-op update (BC)
hg update . (or equivalents) are effectively no-ops in just about all
circumstances.  These sorts of updates can be especially common in a
bookmark-oriented workflow. This saves us a status check and a manifest
decompression, which means that on a repo with over 210,000 files, this brings
hg update . down from 2.5 seconds to 0.15.

There is one change in behavior: a file that was added, not committed, and then
deleted but not removed used to be removed from the dirstate. With this patch
it isn't. This is what causes the change in test-mq-qpush-exact.t. This seems
like it's enough of an edge case to not be worth handling.

The output of test-empty.t changes because those files are not yet created.
2013-10-01 17:43:54 -07:00
Siddharth Agarwal
c84868311c merge: standardize error message for dirty subrepo 2013-09-23 20:53:14 -07:00
Siddharth Agarwal
88c86521eb merge: standardize error message for dirty working dir 2013-09-23 20:50:51 -07:00
Siddharth Agarwal
663145e3f0 update: standardize error message for dirty update --check
This and following patches will standardize the error message for dirty working
directories to "uncommitted changes".
2013-09-23 20:33:02 -07:00
Siddharth Agarwal
7213ad0e07 update: improve error message for dirty non-linear update with rev 2013-09-23 20:08:52 -07:00
Siddharth Agarwal
ecd3be8cef update: add error message for dirty non-linear update with no rev
Previously, the error message for a dirty non-linear update was the same (and
relatively unhelpful) whether or not a rev was specified. This patch and an
upcoming one will introduce separate, more helpful hints.
2013-09-23 20:07:30 -07:00
Siddharth Agarwal
55e7463f51 update: improve error message for clean non-linear update 2013-09-23 17:43:33 -07:00
Matt Mackall
72d6ff963c update: add tracking of interrupted updates (issue3113)
This takes advantage of the new checkunfinished infrastructure
2013-07-25 00:33:28 -05:00
Bryan O'Sullivan
16cdb3e1a8 merge: add a files method to the mergestate class
This will be used in the upcoming shelve extension.
2013-06-03 17:20:37 -07:00
Matt Mackall
13d2a13ea6 ui: merge prompt text components into a singe string
This will help avoid problems with partial or mismatched translation
of the components.
2013-05-22 17:31:43 -05:00
Siddharth Agarwal
bc3c1061f7 manifestmerge: local unknown, remote created: don't traverse symlinks
To figure out what to do with locally unknown files, Mercurial attempts to read
them if they exist. When an attempt is made to read a file that exists but
traverses a symlink, Mercurial aborts.

With this patch, we first ensure that the file doesn't traverse a symlink
before opening it. This is fine because a file being "remote created" means the
symlink doesn't exist remotely, which means it will be deleted in the apply
phase.
2013-05-08 14:11:01 -07:00
FUJIWARA Katsunori
baa57a476c icasefs: rewrite case-folding collision detection (issue3452)
Before this patch, case-folding collision detection uses
"copies.pathcopies()" before "manifestmerge()", and is not aware of
renaming in some cases.

For example, in the case of issue3452, "copies.pathcopies()" can't
detect renaming, if the file is renamed at the revision before common
ancestor of merging. So, "hg merge" is aborted unexpectedly on case
insensitive filesystem.

This patch fully rewrites case-folding collision detection, and
relocate it into "manifestmerge()".

New implementation uses list of actions held in "actions" and
"prompts" to build provisional merged manifest up.

Provisional merged manifest should be correct, if actions required to
build merge result up in working directory are listed up in "actions"
and "prompts" correctly.

This patch checks case-folding collision still before prompting for
merge, to avoid aborting after some interactions with users. So, this
assumes that user would choose not "deleted" but "changed".

This patch also changes existing abort message, because sorting before
collision detection changes order of checked files.
2013-04-30 05:01:32 +09:00
FUJIWARA Katsunori
37ccfcc8ea merge: increase safety of parallel updating/removing on icasefs
"merge.applyupdates()" sorts "actions" in removal first order, and
"workeractions" derived from it should be also sorted.

If each actions in "workeractions" are executed in serial, this
sorting ensures that merging/updating process is collision free,
because updating the file in target context is always executed after
removing the existing file which causes case-folding collision against
the former.

In the other hand, if each actions are executed in parallel, updating
on a worker process may be executed before removing on another worker
process, because "worker.partition()" partitions list of actions
regardless of type of each actions.

This patch divides "workeractions" into removing and updating, and
executes the former first.

This patch still scans "actions"/"workeractions" some times for ease
of patch review, even though large list may cost much in this way.
(total cost should be as same as before)

This also changes some tests, because dividing "workeractions" affects
progress indication.
2013-04-29 15:58:15 +09:00
Pierre-Yves David
11445bce46 update: allow dirty update to foreground (successors)
Update to "foreground" are no longer seen as cross branch update. "Foreground"
are descendants or successors (or successors of descendants (or descendant of
successors (etc))). This allows to update with uncommited changes that get
automatically merged.

This changeset is a small step forward. We want to allow dirty update to
"background" (precursors) and takes obsolescence in account when finding the
default update destination. But those requires deeper changes and will comes in
later changesets.
2013-04-16 15:33:18 +02:00
Siddharth Agarwal
559322b2a6 manifestmerge: handle workdir removed, remote removed with flags
This can happen when a file with flags is removed or deleted in the working
directory and also not present in m2. The obvious solution is to add a
__delitem__ override to manifestdict that removes the file from flags if
necessary, but that has a significant performance cost in some cases, e.g.
hg status --rev rev1 --rev rev2 <file>.
2013-04-10 12:34:42 -07:00
Siddharth Agarwal
6857870aa1 manifestmerge: drop redundant flags calls 2013-03-24 16:56:25 -07:00
Siddharth Agarwal
65dea36afd manifestmerge: use dicthelpers.diff and join
This patch improves manifestmerge performance significantly.

In a repository with 170,000 files, the following results were observed on a
clean working directory. Revision '.' adds one file.

hg perfmergecalculate -r .
- before: 0.41 seconds
- after: 0.13 seconds

hg perfmergecalculate -r .^
- before: 0.53 seconds
- after: 0.24 seconds

Comparing against '.' is much faster than comparing against '.^' because with
'.', the wctx and p2 manifest strings have the same identity, so comparisons
are simply pointer equality. With '.^', the strings have different identities
so we need to perform memcmps.

Any operation that uses manifestmerge benefits.
- hg update . goes from 2.04 seconds to 1.75
- hg update .^ goes from 2.52 seconds to 2.25
- hg rebase -r . -d .~6 (involves 4 merges) goes from 11.8 seconds to 10.8
2013-03-25 17:41:06 -07:00
Siddharth Agarwal
b321ec2b67 manifestmerge: rename n to n1 and n2
An upcoming patch will combine the two loops into one, so it's important to
distinguish between nodes in m1 and nodes in m2.
2013-03-24 16:43:25 -07:00
Kevin Bullock
e1d6f97b9f applyupdates: assign variable before we try to use it (issue3855)
The variable 'fd' was getting used with a value left over from a prior
iteration, causing a KeyError: '.hgsubstate'.
2013-03-18 16:37:20 -05:00
Durham Goode
474ac2b31e rebase: fix --collapse when a file was added then removed
When a series of commits first adds a file and then removes it,
hg rebase --collapse prompts whether to keep the file or delete it. This is
due to it reusing the branch merge code. In a noninteractive terminal it
defaults to keeping the file, which results in a collapsed commit that is
has a file that should be deleted. This bug resulted in developers accidentally
commiting unintentional changes to our repo twice today, so it's fairly
important to get fixed.

This change allows rebase --collapse to tell the merge code to accept the
latest version every time without prompting.

Adds a test as well.
2013-03-15 11:23:29 -07:00
Siddharth Agarwal
ddf37d440b manifestmerge: fix order in which manifests are fetched
If the manifest of an earlier revision on the same delta chain is read before
that of a later revision, the revlog remembers that we parsed the earlier
revision and continues applying deltas from there onwards. If manifests are
parsed the other way round, we have to start over from the fulltext.

For a fresh clone of mozilla-central, updating from 29dd80c95b7d to its parent
aab96936a177 requires approximately 400 fewer zlib.decompress calls, which
results in a speedup from 1.10 seconds to 1.05.
2013-02-10 16:55:01 +00:00
Siddharth Agarwal
e15d936707 merge: run _forgetremoved after manifestmerge
_forgetremoved can trigger manifest construction, but we only want it to
happen after manifestmerge, so that our attempt to read the manifests in the
right order in an upcoming patch actually works.
2013-02-10 12:16:46 +00:00
Bryan O'Sullivan
7bc15afd4e merge: don't fiddle with name lookups or i18n in hot loops
We perform attribute dereferences and i18n lookups before looping.
2013-02-09 15:51:32 -08:00
Bryan O'Sullivan
9f400d1ba0 merge: apply non-interactive working dir updates in parallel
This has a big effect on the performance of working dir updates.

Here are the results of update from null to the given rev in several
repos, on a Linux 3.2 system with 32 cores running ext4, with the progress
extension enabled.

repo             rev           plain  parallel   speedup
hg               76a842fb67cc    0.9       0.3       3
mozilla-central  fe1600b22c77   42.8       7.7       5.5
linux-2.6        9ef4b770e069   31.4       4.9       6.4
2013-02-09 15:51:32 -08:00