Commit Graph

558 Commits

Author SHA1 Message Date
Siddharth Agarwal
aaac3ed514 mergestate._resolve: store return code and action for each file
We're going to need this to compute (a) updated/merged/unresolved counts, and
(b) actions to perform on the dirstate.
2015-11-20 16:08:22 -08:00
Siddharth Agarwal
5d6cb7e78f mergestate.add: store absentfilectxes as nullhex
This is the most natural way to represent these files. We also need to make
sure we don't try to store these files in the merge store.
2015-11-14 00:07:11 -08:00
Siddharth Agarwal
328287680c mergestate._resolve: handle change/delete conflicts
We will represent a deleted file as 'nullhex' in the in-memory and on-disk
merge states. We need to be able to create absentfilectxes in that case, and
delete the file from disk rather than try to write it out.
2015-11-20 01:14:15 -08:00
Siddharth Agarwal
f5fc173bec merge.mergestate: compute dirstate action
In upcoming patches we're going to queue these actions up to be applied to the
dirstate at the end.
2015-11-19 10:50:02 -08:00
Siddharth Agarwal
4904ded295 filemerge: return whether the file was deleted
This is required for change/delete conflict resolution -- see previous patches
for more details.
2015-11-18 14:22:52 -08:00
Siddharth Agarwal
c5b488f2d2 mergestate: allow storing and retrieving change/delete conflicts
We introduce a new record type, 'C', to indicate change/delete conflicts. This
is a separate record type because older versions of Mercurial will not be able
to handle these conflicts.

We aren't actually storing any change/delete conflicts yet -- that will come in
future patches.
2015-11-18 15:46:45 -08:00
Siddharth Agarwal
4a78a436f9 mergestate: handle additional record types specially
This works around a bug in older Mercurial versions' handling of the v2 merge
state.

We also add a bunch of tests that make sure that
(1) we correctly abort when the merge state has an unsupported record type
(2) aborting the merge, rebase or histedit continues to work and clears out the
    merge state.
2015-11-18 15:46:45 -08:00
Siddharth Agarwal
a19a04c7f9 mergestate: move binary format documentation into _readrecordsv2
This is too low-level to be the top-level documentation for mergestate. We're
restricting the top-level documentation to only be about what consumers of the
mergestate and anyone extending it need to care about.
2015-11-18 16:39:30 -08:00
Siddharth Agarwal
0d7932e904 mergestate.commit: factor out making the list of records
Will aid in testing.
2015-11-17 14:23:26 -08:00
Siddharth Agarwal
9f1990c72b mergestate: move _read() call to read constructor
With this patch, mergestate.clean() will no longer abort when it encounters an
unsupported merge type. However we hold off on testing it until backwards
compatibility is in place.
2015-11-17 14:04:56 -08:00
Siddharth Agarwal
99a292eb8d mergestate: add a constructor that reads state from disk
At the moment it's the same as just creating a new mergestate, but we'll soon
move the _read call out of __init__ and in here.
2015-11-17 13:55:30 -08:00
Siddharth Agarwal
866f1a0d13 merge.applyupdates: switch to mergestate.clean()
See the previous patches for why we're doing this.
2015-11-17 17:04:53 -08:00
Siddharth Agarwal
7f86d75731 mergestate: add a constructor that sets up a clean merge state
Eventually, we'll move the read call out of the constructor. This will:
- avoid unnecessary reads when we're going to nuke the merge state anyway
- avoid raising an exception if there's an unsupported merge record

'clean' seems like a good name for it because I wanted to avoid anything with
the word 'new' in it, and 'reset' is more an action performed on a merge state
than a way to get a new merge state.

Thanks to Martin von Zweigbergk for feedback about naming this.
2015-11-17 17:00:54 -08:00
Siddharth Agarwal
a9244bf2d6 mergestate: raise structured exception for unsupported merge records
We're going to catch this exception in 'hg summary' to print a better error
message.

This code is pretty untested, so there are no changes to test output. In
upcoming patches we're going to test the output more thoroughly.
2015-11-17 14:11:52 -08:00
Siddharth Agarwal
c6faeb67e1 merge.applyupdates: don't return early if merge driver's conclude failed
Somewhat silly oversight -- this prevented the progress bar from being reset.
2015-11-15 22:45:20 -08:00
Siddharth Agarwal
5d41145967 merge: make 'cd' and 'dc' actions store the same arguments as 'm'
We're going to treat these conflicts similarly to merge conflicts, and this
change to the way we store things in memory makes future code a lot simpler.
2015-11-13 22:43:09 -08:00
Siddharth Agarwal
13a33ed9b5 merge: stop emptying out 'cd' and 'dc' actions
(1) These aren't currently read from anywhere, so emptying this out is
    pointless.
(2) These *will* be read from later in upcoming patches, and not emptying
    them out will be important then.
2015-11-13 14:24:22 -08:00
Martin von Zweigbergk
3d33120c8b merge: move messages about possible conflicts a litte earlier
I actually wanted to reduce the amount of code around the call to
applyupdates(), so I tried moving these warnings a little earlier, and
I think it makes the output make a little more sense (see changes to
test cases).
2015-11-12 13:14:03 -08:00
Siddharth Agarwal
b2610217fb merge.applyupdates: only attempt to merge files in mergeactions
This only makes a difference when a merge driver is active -- in that case we
don't want to try and merge all the files, just the ones still unresolved after
the merge driver's preprocess step is over.
2015-11-12 14:29:02 -08:00
Siddharth Agarwal
11e83e49ad merge.mergestate: update docstrings for preresolve and resolve
Add a docstring for preresolve, and update the one for resolve.
2015-11-04 23:44:51 -08: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
Pierre-Yves David
3ca3ce920a update: "deprecate" call to 'merge.update' without a destination
Now that all internal callers pre-compute and set a destination at a higher level
it feels like we can kill this API. This will allow us to simplify this
function. However I feel like this is a bit too central and critical to break
now. I'm adding a devel warning to let extension make catch this in the next
cycle.
2015-10-05 21:42:09 -07:00
Mads Kiilerich
b919454f81 merge: abort on file/directory case folding collisions (issue4892)
File/directory case folding collisions cannot be represented on case folding
systems and have to fail.

To detect this and abort early, utilize that for file/directory collisions, a
sorted list of case folded manifest names will have the colliding directory
right after the file.

(This could perhaps be optimized, but this way of doing it also has
directory/directory case folding in mind ... which however not is handled yet.)
2015-10-13 00:16:25 +02:00
Siddharth Agarwal
3b737ce486 merge.mergedriver: don't try resolving files marked driver-resolved
The driver is expected to take care of these.
2015-09-30 19:43:51 -07:00
Siddharth Agarwal
7cd68f9b50 merge.mergestate: add support for persisting driver-resolved files
A driver-resolved file is a file that's handled specially by the driver. A
common use case for this state would be autogenerated files, the generation of
which should happen only after all source conflicts are resolved.

This is done with an uppercase letter because older versions of Mercurial will
not know how to treat such files at all.
2015-09-28 18:34:06 -07:00
Siddharth Agarwal
5d14dbc5df merge.mergestate: add support for persisting a custom merge driver
A 'merge driver' is a coordinator for the overall merge process. It will be
able to control:

- tools for individual files, much like the merge-patterns configuration does
  today
- tools that can work across groups of files
- the ordering of file resolution
- resolution of automatically generated files
- adding and removing additional files to and from the dirstate

Since it is a critical part of the merge process, it really is part of the
merge state.

This is a lowercase character (i.e. optional) because ignoring this is fine for
older versions of Mercurial -- however, if there are any files that are
specially treated by the driver, we should abort. That will happen in upcoming
patches.

There is a potential security issue with storing the merge driver in the merge
state. See the inline comments for more details.
2015-09-30 21:42:52 -07:00
Pierre-Yves David
d22b16ba8c destupdate: also include bookmark related logic
For the same reason, we move the bookmark related update logic into the
'destupdate' function. This requires to extend the returns of the function to
include the bookmark that needs to move (more or less) and the bookmark to
activate at the end of the function. See function documentation for details on
this returns.
2015-09-29 01:03:26 -07:00
Siddharth Agarwal
c97c4cf7f6 merge.mergestate: perform all premerges before any merges (BC)
We perform all that we can non-interactively before prompting the user for input
via their merge tool. This allows for a maximally consistent state when the user
is first prompted.

The test output changes indicate the actual behavior change happening.
2015-10-11 21:56:39 -07:00
Siddharth Agarwal
8b2a429453 merge: introduce a preresolve function
The section of code that writes out the version of the file cached in the merge
state should only be run at preresolve time. This is so that if the premerge
keeps around conflict markers, those don't get overwritten before the main
merge.
2015-10-11 20:12:12 -07:00
Siddharth Agarwal
cbb558b9d7 merge.mergestate._resolve: also return completed status
We'll need this for a new 'preresolve' function we're adding.
2015-10-11 18:37:54 -07:00
Siddharth Agarwal
2826ed841f merge.mergestate: add a wrapper around resolve
The resolve function will be broken up into separate pre-resolve and resolve
steps.
2015-10-11 18:29:50 -07:00
Siddharth Agarwal
88da24240c filemerge: break overall filemerge into separate premerge and merge steps
This means that in ms.resolve we must call merge after calling premerge. This
doesn't yet mean that all premerges happen before any merges -- however, this
does get us closer to our goal.

The output differences are because we recompute the merge tool. The only
user-visible difference caused by this patch is that if the tool is missing
we'll print the warning twice. Not a huge deal, though.
2015-10-11 20:47:14 -07:00
Siddharth Agarwal
82f2aec334 filemerge: also return whether the merge is complete
In future patches, we'll pause merges after the premerge step. After the
premerge step we'll return complete = False.
2015-10-11 12:56:21 -07:00
Pierre-Yves David
30913031d4 error: get Abort from 'error' instead of 'util'
The home of 'Abort' is 'error' not 'util' however, a lot of code seems to be
confused about that and gives all the credit to 'util' instead of the
hardworking 'error'. In a spirit of equity, we break the cycle of injustice and
give back to 'error' the respect it deserves. And screw that 'util' poser.

For great justice.
2015-10-08 12:55:45 -07:00
Pierre-Yves David
a92a70c3bd merge: get the default update destination from the function
There is no value in using the revset instead of the extracted function.
2015-09-28 22:11:23 -07:00
Pierre-Yves David
24004c0b3e merge: drop special parent assignment in the obsolete case
We can safely drop this because the very same assignment is enforcement later in
the function. Dropping it will make it simpler to extract the default
destination logic in its own function.
2015-10-05 01:47:33 -07:00
Siddharth Agarwal
7c5424c31f merge.mergestate: factor out code to validate v1/v2 records
We're going to need this in another place in upcoming patches.
2015-09-30 21:22:31 -07:00
timeless@mozdev.org
bbe814936e merge: fix mergestate comment 2015-09-25 00:54:20 -04:00
Matt Mackall
b73f713c00 bidmerge: choose shortest list of diverge and rename/delete warnings
Slightly less arbitrary than choosing the first set.
2015-08-19 14:05:42 -05:00
Pierre-Yves David
182447758e update: move default destination into a revset
This is another step toward having "default" destination more clear and unified.
Not all the logic is there because some bookmark related computation happened
elsewhere. It will be moved later.

The function is private because as for the other ones, cleanup is needed before
we can proceed.
2015-09-18 17:23:10 -07:00