Commit Graph

612 Commits

Author SHA1 Message Date
Kostia Balytskyi
78766f7ff1 update: teach hg to override untracked dir with a tracked file on update
This is a fix to an old problem when Mercurial got confused by an
untracked folder with the same name as one of the files in a commit
hg was trying to update to. It is pretty safe to remove this folder if
it is empty. Backing up an empty folder seems to go against Mercurial's
"don't track dirs" philosophy.
2016-07-01 17:42:55 +02:00
Augie Fackler
ad67b99d20 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
All versions of Python we support or hope to support make the hash
functions available in the same way under the same name, so we may as
well drop the util forwards.
2016-06-10 00:12:33 -04:00
FUJIWARA Katsunori
390f95833b merge: make messages translatable
These messages have been overlooked by check-code, because they start
with non-alphabet character (' ').

Making these messages translatable seems reasonable, because all other
'ui.note()'-ed messages in calculateupdates() are already
translatable.

This is also a part of preparation for making "missing _() in ui
message" detection of check-code more exact.
2016-05-26 01:57:34 +09:00
timeless
a1cb3173a2 py3: convert to next() function
next(..) was introduced in py2.6 and .next() is not available in py3

https://docs.python.org/2/library/functions.html#next
2016-05-16 21:30:53 +00:00
Pierre-Yves David
f6e86ab7ff devel: officially deprecate update without destination
When we introduce the develwarning, we did not had an official deprecation API
and infrastructure. We can now officially deprecate the old way with a version
deadline.
2016-05-11 09:31:47 +02:00
Pierre-Yves David
6b9ad81f0e devel: use the new 'config' argument for the update develwarn 2016-05-08 10:43:41 +02:00
Simon Farnsworth
74ca86ac73 merge: save merge part labels for later reuse
We permit the caller of merge operations to supply labels for the merge
parts ("local", "other", and optionally "base"). These labels are used in
conflict markers to reduce confusion; however, the labels were not
persistent, so 'hg resolve' would lose the labels.

Store the labels in the mergestate.
2016-03-19 18:37:10 -07:00
Simon Farnsworth
ad7f9b0b86 merge: fix error message
Obvious copy-and-paste error
2016-02-26 19:13:10 +00:00
Martin von Zweigbergk
eb088b0b6d merge: use any() instead of for loop when checking for dirty subrepos
I think it's both simpler and clearer to use any() than the current
for loop.

While at it, also drop the call to sorted(), since it doesn't matter
which order we iterate over subrepos.
2016-02-23 10:59:25 -08:00
Gregory Szorc
a353815ec0 merge: perform background file closing in batchget
As 70dbbec70c4c demonstrated with stream clones, closing files on
background threads on Windows can yield a significant speedup
because closing files that have been created/appended to is slow
on Windows/NTFS.

Working directory updates can write thousands of files. Therefore it
is susceptible to excessive slowness on Windows due to slow file
closes.

This patch enables background file closing when performing working
directory file writes. The impact when performing an `hg up tip` on
mozilla-central (136,357 files) from an empty working directory is
significant:

Before: 535s (8:55)
After:  133s (2:13)
Delta: -402s (6:42)

That's a 4x speedup!

By comparison, that same machine can perform the same operation
in ~15s on Linux. So Windows went from ~35x to ~9x slower. Not bad
but there's still work to do.

As a reminder, background file closing is only activated on Windows
because it is only beneficial on that platform. So this patch
shouldn't change non-Windows behavior at all.

It's worth noting that non-Windows systems perform working directory
updates with multiple processes. Unfortunately, worker.py doesn't
yet support Windows. So, there is still plenty of room for making
working directory updates faster on Windows. Even if multiple
processes are used on Windows, I believe background file closing
will still provide a benefit, as individual processes will still
be slowed down by the file close bottleneck (assuming the I/O system
isn't saturated).
2016-02-20 15:54:09 -08:00
Gregory Szorc
5575f7b8a6 merge: indent code in batchget()
To make the next patch easier to read.
2016-02-20 15:27:11 -08:00
Durham Goode
b46992b939 checkunknown: audit path before checking if it's a file or link
Previously we would lstat the file to see if it was a file or a link before
attempting to process it. If the file happened to exist across a symlink, and if
that symlink was pointing to a network file system, that check could be very
expensive.

The new logic audit's the path to avoid symlinks before performing the lstat on
the file itself.

In our situation, this shaved 10 minutes off of certain hg updates.
300 files * (2 seconds - the network filesystem lookup time)
2016-02-11 17:23:10 -08:00
Siddharth Agarwal
66f60475b8 rebase: respect checkunknown and checkignored in more cases
checkunknown and checkignored are currently respected for updates and regular
merges, but not for certain kinds of rebases. To be precise, they aren't
respected for rebases when:

(1) we're rebasing while currently on the destination commit, and
(2) an untracked or ignored file F is currently in the working copy, and
(3) the same file F is in a source commit, and
(4) F has different contents in the source commit.

This happens because rebases set force to True when calling merge.update.
Setting force to True makes a lot of sense in general, but it turns out the
force option is overloaded: there's a deprecated '--force' option in merge that
allows you to merge in outstanding changes, including changes in untracked
files. We use the 'mergeforce' parameter to tell those two cases apart.

I think the behavior during rebases when checkunknown is 'abort' (the default)
is wrong -- we should abort on or overwrite differing untracked files, not try
to merge them in. However that currently breaks rebases by aborting in the
middle -- we need better handling for that case before we can change the
default.
2016-02-03 13:12:06 -08:00
Siddharth Agarwal
803f564a2a merge: tell _checkunknownfiles about whether this was merge --force
In an upcoming patch we'll have different behavior here for when 'merge
--force' is used as opposed to when other kinds of force operations are
performed, like rebases.
2016-02-01 20:28:32 -08:00
Siddharth Agarwal
fceebb99a4 merge: add missing doc for 'labels' parameter 2016-02-01 20:28:32 -08:00
Siddharth Agarwal
3386176013 merge: move abort/warn checks up to the top level of _checkunknownfiles
In upcoming patches, we're also going to do these checks when force is True.
2016-02-01 20:28:32 -08:00
Durham Goode
4834302703 merge: add file ancestor linknode to mergestate
During a merge, each file has a current commitnode+filenode, an other
commitnode+filenode, and an ancestor commitnode+filenode. The ancestor
commitnode is not stored though, and we rely on the ability for the filectx() to
look up the commitnode by using the filenode's linkrev. In alternative backends
(like remotefilelog), linkrevs may have restriction that prevent arbitrary
linkrev look up given a filenode.

This patch accounts for that by storing the ancestor commitnode in
the merge state so that it is available later at resolve time.

This results in some test changes because the ancestor commitnode we're using at
resolve time changes slightly. Before, we used the linkrev commit, which is the
earliest commit that introduced that particular filenode (which may not be the
latest common ancestor of the commits being merged). Now we use the latest
common ancestor of the merged commits as the commitnode. This is fine though,
because that commit contains the same filenode as the linkrev'd commit.
2016-02-05 10:22:14 -08:00
Durham Goode
791a4231ef merge: add state extras merge state data
In future commits we will want to store more data related to each file in the
merge state. This patch adds an optional record for storing a dictionary of
extras for each file.
2016-02-05 10:15:28 -08:00
Siddharth Agarwal
bfbbb007c7 merge: don't try to merge subrepos twice (issue4988)
In my patch series ending with rev c3f2eede6938 I switched most change/delete
conflicts to be handled at the resolve layer. .hgsubstate was the one file that
we weren't able to handle, so we kept the old code path around for it.

The old code path added .hgsubstate to one of the other lists as the user
specifies, including possibly the 'g' list.

Now since we did this check after converting the actions from being keyed by
file to being keyed by action type, there was nothing that actually removed
.hgsubstate from the 'cd' or 'dc' lists. This meant that the file would
eventually make its way into the 'mergeactions' list, now freshly augmented
with 'cd' and 'dc' actions.

We call subrepo.submerge for both 'g' actions and merge actions.

This means that if the resolution to an .hgsubstate change/delete conflict was
to add it to the 'g' list, subrepo.submerge would be called twice. It turns out
that this doesn't cause any adverse effects on Linux due to caching, but
apparently breaks on other operating systems including Windows.

The fix here moves this to before we convert the actions over. This ensures
that it .hgsubstate doesn't make its way into multiple lists.

The real fix here is going to be:
(1) move .hgsubstate conflict resolution into the resolve layer, and
(2) use a real data structure for the actions rather than shuffling data around
    between lists and dictionaries: we need a hash (or prefix-based) index by
    file and a list index by action type.

There's a very tiny behavior change here: collision detection on
case-insensitive systems will happen after this is resolved, not before. I think
this is the right change -- .hgsubstate could theoretically collide with other
files -- but in any case it makes no practical difference.

Thanks to Yuya Nishihara for investigating this.
2016-01-29 14:19:29 -08:00
Bryan O'Sullivan
ff05835c28 with: use context manager in merge update 2016-01-15 13:14:49 -08:00
Siddharth Agarwal
46071bce0e merge: split up checks for unknown and ignored files that differ
In some real-world cases it is preferable to allow overwriting ignored files
while continuing to abort on unknown files. This primarily happens when we're
replacing build artifacts (which are ignored) with checked in files, but
continuing to abort on differing files that aren't ignored.

We're redefining merge.checkunknown to only control the behavior for files
that aren't ignored. That's fine because this config was only very recently
introduced and has not made its way into any Mercurial releases yet.
2016-01-12 18:38:49 -08:00
Siddharth Agarwal
0914e3c659 merge: determine what untracked conflicts cause warns and aborts separately
This is written in a somewhat weird style, but it's designed for code reuse in
an upcoming patch.
2016-01-12 18:17:07 -08:00
Siddharth Agarwal
03971ff0e5 merge: factor out code to get checkunknown config
We're going to reuse this code shortly.
2016-01-12 18:12:35 -08:00
Siddharth Agarwal
093e742c00 merge: add options to warn or ignore on colliding unknown files
A 'colliding unknown file' is a file that meets all of the following
conditions:

- is untracked or ignored on disk
- is present in the changeset being merged or updated to
- has different contents

Previously, we would always abort whenever we saw such files. With this config
option we can choose to warn and back the unknown files up instead, or even
forgo the warning entirely and silently back the unknown files up.

Common use cases for this configuration include a large scale transition of
formerly ignored unknown files to tracked files. In some cases the files can be
given new names, but in other cases, external "convention over configuration"
constraints have determined that the file must retain the same name as before.
2016-01-02 03:11:52 -08:00
Siddharth Agarwal
027b946b48 batchget: add support for backing up files
We're going to use this in an upcoming feature.
2016-01-02 03:21:01 -08:00
Siddharth Agarwal
2584b69484 merge: add a new 'backup' argument to get actions
We're going to use this in an upcoming patch to back untracked files up when
they're replaced by tracked ones.
2016-01-02 03:02:57 -08:00
Siddharth Agarwal
54dd91b4db _checkunknownfiles: turn 'conflicts' into a set
We'll check for membership in this set in an upcoming patch.
2016-01-02 03:02:57 -08:00
Siddharth Agarwal
3e662143bb checkunknownfiles: make control flow clearer
In particular, make it clear that we only check for and abort on conflicts if
force is not true.
2016-01-02 03:02:57 -08:00
Siddharth Agarwal
6ff835640d _checkunknownfiles: rename 'aborts' to 'conflicts'
In upcoming patches we'll be able to do more useful things than aborting.
2016-01-02 03:02:57 -08:00
Matt Mackall
d7ec07e23e merge with stable 2016-01-02 02:13:56 +01:00
Siddharth Agarwal
a6934b01c3 merge: while checking for unknown files don't follow symlinks (issue5027)
Previously, we were using Python's native 'os.path.isfile' method which follows
symlinks. In this case, since we're operating on repo contents, we don't want
to follow symlinks.

There's a behaviour change here, as shown by the second part of the added test.
Consider a symlink 'f' pointing to a file containing 'abc'. If we try and
replace it with a file with contents 'abc', previously we would have let it
though. Now we don't. Although this breaks naive inspection with tools like
'cat' and 'diff', on balance I believe this is the right change.
2015-12-28 22:51:37 -08:00
Augie Fackler
1b827711c9 manifestmerge: have manifest do matching before diffing
This means that the diff code does less work, potentially
significantly less in the case of treemanifests. It also should ease
implementation with narrowed clone cases (such as narrowhg) when we
don't always have the entire set of treemanifest revlogs locally.

As far as I can tell, this codepath is currently only used by record,
so it'll probably die in the near future, and then narrowhg won't have
to worry about composing with some unknown matching system.
2015-12-14 20:57:21 -05:00
Augie Fackler
86f88ad861 merge: improve clarity of table in update docstring 2015-10-23 06:06:22 -04:00
Siddharth Agarwal
307771ef0d merge.applyupdates: call driverconclude after performing merge actions
This will be a chance for the merge driver to finish resolving or generating
any driver-resolved files.

As before, having a separate error state from 'unresolved' is too big a
refactoring for now, so we hack around it by setting unresolved to a positive
value when necessary.
2015-10-15 01:22:01 -07:00
Siddharth Agarwal
671581b397 merge.applyupdates: call driverpreprocess before starting merge actions
We also need to update our internal state to whatever state driverpreprocess
leaves it in.

Adding an error state separate from the unresolved count is too big a
refactoring for now, so we hack around it by setting it to a positive value to
indicate an error state.
2015-10-15 01:19:10 -07:00
Siddharth Agarwal
93aaae5f6a merge: add stubs for preprocess and conclude steps of merge driver
The exact semantics for what should happen (particularly with respect to error
handling) are still a bit hard to pin down, so I think it's better to
experiment with it as an extension for now. For now this stub will act as a
convenient point for extensions to hook on.
2015-10-15 01:17:29 -07:00
Siddharth Agarwal
fe759d6960 merge.mergestate: set merge driver state to 's' if there's none present
This allows mergestate.mdstate() to return 's' if there's nothing to be done on
the merge driver end.
2015-10-15 01:06:29 -07:00
Siddharth Agarwal
793db02056 merge.mergestate: only check for merge driver when property is accessed
Otherwise 'hg update --clean', 'hg rebase --abort' etc wouldn't work.
2015-10-15 01:04:46 -07:00
Siddharth Agarwal
f4dc777bce merge.mergestate: add a way to get the merge driver state
This will be useful to check what the status of the merge driver is.
2015-10-15 00:57:56 -07:00
Siddharth Agarwal
0eb994cb79 merge.mergestate: add a way to get the other side of the merge
It's surprising there was no API at all for this until now. In any case this
will be needed from custom merge drivers.
2015-10-15 00:49:07 -07:00
FUJIWARA Katsunori
75f4bab4a5 merge: make in-memory changes visible to external update hooks
c67339617276 (while 3.4 code-freeze) made all 'update' hooks run after
releasing wlock for visibility of in-memory dirstate changes. But this
breaks paired invocation of 'preupdate' and 'update' hooks.

For example, 'hg backout --merge' for TARGET revision, which isn't
parent of CURRENT, consists of steps below:

  1. update from CURRENT to TARGET
  2. commit BACKOUT revision, which backs TARGET out
  3. update from BACKOUT to CURRENT
  4. merge TARGET into CURRENT

Then, we expects hooks to run in the order below:

  - 'preupdate' on CURRENT for (1)
  - 'update'    on TARGET  for (1)
  - 'preupdate' on BACKOUT for (3)
  - 'update'    on CURRENT for (3)
  - 'preupdate' on TARGET  for (4)
  - 'update'    on CURRENT/TARGET for (4)

But hooks actually run in the order below:

  - 'preupdate' on CURRENT for (1)
  - 'preupdate' on BACKOUT for (3)
  - 'preupdate' on TARGET  for (4)
  - 'update'    on TARGET  for (1), but actually on CURRENT/TARGET
  - 'update'    on CURRENT for (3), but actually on CURRENT/TARGET
  - 'update'    on CURRENT for (4), but actually on CURRENT/TARGET

Root cause of the issue focused by c67339617276 is that external
'update' hook process can't view in-memory changes (especially, of
dirstate), because they aren't written out until the end of
transaction (or wlock).

Now, hooks can be invoked just after updating, because previous
patches made in-memory changes visible to external process.

This patch may break backward compatibility from the point of view of
"scheduling hook execution", but should be reasonable because 'update'
hooks had been executed in this order before 3.4.

This patch tests "hg backout" and "hg unshelve", because the former
activates the transaction before 'update' hook invocation, but the
former doesn't.
2015-10-17 01:15:34 +09:00
FUJIWARA Katsunori
106983607a dirstate: make dirstate.write() callers pass transaction object to it
Now, 'dirstate.write(tr)' delays writing in-memory changes out, if a
transaction is running.

This may cause treating this revision as "the first bad one" at
bisecting in some cases using external hook process inside transaction
scope, because some external hooks and editor process are still
invoked without HG_PENDING and pending changes aren't visible to them.

'dirstate.write()' callers below in localrepo.py explicitly use 'None'
as 'tr', because they can assume that no transaction is running:

  - just before starting transaction
  - at closing transaction, or
  - at unlocking wlock
2015-10-17 01:15:34 +09:00
Siddharth Agarwal
e65ca7df8c merge.mergestate: add a generator for driver-resolved files
Just like for unresolved files above, we need to be able to tell what files are
driver-resolved.
2015-10-14 15:01:07 -07:00
Augie Fackler
b184da51f2 merge: rework manifestmerge to use a matcher
This opens the door to working slightly more closely with the manifest
type and letting it optimize out some of the diff comparisons for us,
and also makes life significantly easier for narrowhg.
2015-12-14 20:47:22 -05:00
Augie Fackler
a84cc516e7 merge: restate calculateupdates in terms of a matcher
Once we get a matcher down into manifestmerge, we can make narrowhg
work more easily and potentially let manifest.match().diff() do less
work in manifestmerge.
2015-12-14 20:37:41 -05:00
Augie Fackler
0a19647501 merge: have merge.update use a matcher instead of partial fn
This is relatively rarely used functionality, but migrating this to a
matcher will make future work on narrow clones more feasible.
2015-12-14 18:54:03 -05:00
Martin von Zweigbergk
8e7f0fdda8 merge: refuse update/merge if there are unresolved conflicts (BC)
We currently allow updating and merging (with --force) when there are
unresolved merge conflicts, as long as there is only one parent of the
working copy. Even worse, when updating to another revision
(linearly), if one of the unresolved files (including any conflict
markers in the working copy) can now be merged cleanly with the target
revision, the file becomes marked as resolved.

While we could potentially allow updates that affect only files that
are not in the set of unresolved files, that's considerably more work,
and we don't have a use case for it anyway. Instead, let's keep it
simple and refuse any merge or update (without -C) when there are
unresolved conflicts.

Note that test-merge-local.t explicitly checks for conflict markers
that get carried over on update. It's unclear if that was intentional
or not, but it seems bad enough that we should forbid it. The simplest
way of fixing the test case is to leave the conflict markers in place
and just mark the files resolved, so let's just do that for now.
2015-12-07 20:43:24 -08:00
Andrew Halberstadt
f18899ffa6 merge.graft: add option to keep second parent
Currently merge.graft re-writes the dirstate so only a single
parent is kept. For some cases, like evolving a merge commit,
this behaviour is not desired. More specifically, this is
needed to fix issue4389.
2015-12-03 23:01:59 -05:00
Siddharth Agarwal
106338a190 merge: move almost all change/delete conflicts to resolve phase (BC) (API)
We have finally laid all the groundwork to make this happen.

The only change/delete conflicts that haven't been moved are .hgsubstate
conflicts. Those are trickier to deal with and well outside the scope of this
series.

We add comprehensive testing not just for the initial selections but also for
re-resolves and all possible dirstate transitions caused by merge tools. That
testing managed to shake out several bugs in the way we were handling dirstate
transitions.

The other test changes are because we now treat change/delete conflicts as
proper merges, and increment the 'merged' counter rather than the 'updated'
counter. I believe this is the right approach here.

For third-party extensions, if they're interacting with filemerge code they
might have to deal with an absentfilectx rather than a regular filectx.

Still to come:
- add a 'leave unresolved' option to merges
- change the default for non-interactive change/delete conflicts to be 'leave
  unresolved'
- add debug output to go alongside debug outputs for binary and symlink file
  merges
2015-11-25 14:25:33 -08:00
Siddharth Agarwal
ed64d46a37 merge.recordupdates: mark 'a' files as added unconditionally
See the previous patch for why we do this.
2015-11-24 15:26:51 -08:00