Commit Graph

1547 Commits

Author SHA1 Message Date
Gregory Szorc
159c164568 scmutil: improve documentation of revset APIs
I can never remember the differences between the various revset
APIs. I can never remember that scmutil.revrange() is the one I
want to use from user-facing commands.

Add some documentation to clarify this.

While we're here, the argument name for revrange() is changed to
"specs" because that's what it actually is.
2016-06-25 19:12:20 -07:00
Martijn Pieters
d908f2c8dc scmutil: allow access to filecache descriptor on class
To make it easier to patch the wrapped function, make it possible to access the
filecache descriptor directly on the class (rather than have to use
ClassObject.__dict__['attributename']). Returning `self` when the first
argument to `__get__` is `None` makes the descriptor behave the same way
`property` objects do.
2016-06-17 20:06:09 +01:00
FUJIWARA Katsunori
dbfbc278c8 localrepo: make restoring from backup at rollback avoid ambiguity of file stat
Rollback of previous transaction restores contents of files below by
renaming from 'undo.*' file. If renaming keeps ctime, mtime and size
of a file, restoring is overlooked, and old contents cached before
restoring isn't invalidated as expected.

  - .hg/bookmarks
  - .hg/phaseroots

To avoid ambiguity of file stat at restoring, this patch invokes
vfs.rename() with checkambig=True.

BTW, .hg/dirstate is also restored at rollback. But it is restored by
dirstate.restorebackup(), and previous patch already made it invoke
vfs.rename() with checkambig=True.

This patch is a part of "Exact Cache Validation Plan":

    https://www.mercurial-scm.org/wiki/ExactCacheValidationPlan
2016-06-13 05:11:56 +09: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
Matt Mackall
204bd1271d merge with stable 2016-05-25 15:32:35 -05:00
Mateusz Kwapich
718300b2b4 localrepo: prevent executable-bit only changes from being lost on amend
If you have just executable-bit change and amend it twice it will vanish:

 * After the first amend the commit will have the proper executable bit set
   in manifest but it won't have the the file on the list of files in
   changelog.

 * The second amend will read the wrong list of files from changelog and it
   will copy the manifest entry from parent for this file.

 * Voila! The change is lost.

This change repairs the bug in localrepo causing this and adds a test for it.
2016-05-19 14:35:22 -07:00
Mateusz Kwapich
a7e298f9a4 localrepo: use dirstate savebackup instead of handling dirstate file manually
This is one step towards having dirstate manage its own storage. It will
be useful for the implementation of sql dirstate [1].

This introduced a small test change: now we always write the dirstate before
saving backup so in some cases where dirstate file didn't exist yet
savebackup can create it.

[1] https://www.mercurial-scm.org/wiki/SQLDirstatePlan
2016-05-11 14:18:52 -07:00
Mateusz Kwapich
70cc846630 localrepo: use dirstate restorebackup instead of copying dirstate manually
This is one step towards having dirstate manage its own storage. It will
be useful for the implementation of sqldirstate [1].

I'm deleting two of the dirstate.invalidate() calls in localrepo because
restorebackup method does that for us.

[1] https://www.mercurial-scm.org/wiki/SQLDirstatePlan
2016-05-13 13:30:08 -07:00
Pierre-Yves David
3b0e4dbcf2 transaction: turn lack of locking into a hard failure (API)
We have been warning about transactions without locks for about a year (and
three releases), third party extensions had a fair grace period to fix their
code, we are moving lack of locking to a hard failure in order to protect users
against repository corruption.
2016-05-05 16:20:53 +02:00
Augie Fackler
c5874833d2 localrepo: remove a couple of local type aliases
The local aliases are unused now, and were confusing mypy's type
checker.
2016-05-06 11:31:29 -04:00
Augie Fackler
8815201972 localrepo: jettison parents() method per deprecation policy (API) 2016-05-04 21:02:03 -04:00
timeless
109fcbc79e pycompat: switch to util.urlreq/util.urlerr for py3 compat 2016-04-06 23:22:12 +00:00
Mads Kiilerich
940d175900 localrepo: refactor prepushoutgoinghook to take a pushop
prepushoutgoinghook was introduced in 8dfcd476a7f7 and largefiles is the only
in-tree use of it. Refactor it to be more useful for other use cases in
largefiles.
2016-04-13 01:09:11 +02:00
timeless
ab5c7033f1 localrepo: drop force check from checkcommitpatterns
It was retained to make the code movement clearer
2016-04-06 18:08:38 +00:00
timeless
f2c255b594 localrepo: refactor commit argument check as checkcommitpatterns 2016-04-06 17:52:17 +00:00
Gregory Szorc
4370cf2fa4 localrepo: support background closing for wwrite()
So working copy update can pass it in.
2016-02-20 15:25:27 -08:00
Gregory Szorc
67e49ba640 localrepo: move new repo requirements into standalone function (API)
This patch extracts the code for determining requirements for a new
repo into a standalone function. By doing so, future code that will
perform an in-place repository upgrade (e.g. to generaldelta) can
examine the set of proposed new requirements and possibly take
additional actions (such as adding dotencode or fncache) when
performing the upgrade.

This patch is marked as API because _baserequirements (which was added
in 87e5a9d0fbb1 so extensions could override it) has been removed and
will presumably impact whatever extension it was added for. Consumers
should be able to monkeypatch the new function to achieve the same
functionality.

The "create" argument has been dropped because the function is only
called in one location and "create" is always true in that case.

While it makes logical sense for this code to be a method so extensions
can implement a custom repo class / method to override it, this won't
actually work. This is because requirements determination occurs during
localrepository.__init__ and this is before the "reposetup"
"callback" is fired. So, the only way for extensions to customize
requirements would be to overwrite localrepo.localrepository or to
monkeypatch a function on a module during extsetup(). Since we try to
keep localrepository small, we use a standalone function. There is
probably room to offer extensions a "hook" point to alter repository
creation. But that is scope bloat.
2016-02-15 13:20:20 -08:00
Gregory Szorc
3f113f8a93 localrepo: isolate requirements determination from side effects
In preparation for moving requirements determination to its own
function.
2016-02-15 13:19:07 -08:00
Gregory Szorc
0a03a6261d localrepo: use local variable for requirements assignment
A future patch will refactor requirements determination into a
standalone function. To prepare for this, refactor the requirements
code to assign to a local variable instead of to self.requirements.
2016-02-13 14:42:17 -08:00
Gregory Szorc
b16347f628 localrepo: don't reference transaction from hook closure (issue5043)
Before, the hook() closure (which is called as part of locking hooks)
would maintain a reference to a transaction instance (which should be
finalized by the time lock hooks are called). Because we accumulate
hook() instances when there are multiple transactions per lock, this
would result in holding references to the transaction instances which
would lead to higher memory utilization.

Creating a reference to the hook arguments dict minimizes the number
of objects that are kept alive until the lock release hook runs,
minimizing memory "leaks."
2016-01-17 14:14:15 -08:00
Bryan O'Sullivan
b5f5cce8ca with: use context manager in localrepo recover 2016-01-15 13:14:50 -08:00
Augie Fackler
a7381bb9d3 bmstore: add handling of the active bookmark
This further centralizes the handling of bookmark storage, and will
help get some lingering bookmarks business out of localrepo. Right
now, this change implies reading of the active bookmark to also imply
reading all bookmarks from disk - for users with many many bookmarks
this may be a measurable performance hit. In that case, we should
migrate bmstore to be able to lazy-read its properties from disk
rather than having to eagerly read them, but I decided to avoid doing
that to try and avoid some potentially complicated filecache decorator
issues.

This doesn't move the logic for writing the active bookmark into a
transaction, though that is probably the correct next step. Since the
API probably needs to morph a little more, I didn't bother marking
bookmarks.{activate,deactivate} as deprecated yet.
2015-11-11 21:18:02 -05:00
Gregory Szorc
4ccb8aa7b3 localrepo: use absolute_import 2015-12-23 12:30:14 -08:00
Pierre-Yves David
c33f182029 discovery: properly filter changeset in 'peer.known' (issue4982)
The 'peer.known' call (handled at the repository level) was applying its own
manual filtering (looking at phases) instead of relying on the repoview
mechanism. This led to the discovery finding more "common" node that
'getbundle' was willing to recognised. From there, bad things happen, issue4982
is a symptom of it. While situations like described in issue4982 can still
happen because of race conditions, fixing 'peer.known' is important for
consistency in all cases.

We update the code to use 'repoview' filtering. This lead to small changes in
the tests for exchanging obsolescence marker because the discovery yields
different results.

The test affected in 'test-obsolete-changeset-exchange.t' is a test for
issue4982 getting back to its expected state.
2015-12-02 16:12:15 -08:00
FUJIWARA Katsunori
18881f6953 commit: make commit acquire store lock before processing for consistency
If acquisition of wlock waits for another "hg commit" process to
release it, dirstate will refer newly committed revision after
acquisition of wlock.

At that time, '00changelog.i' on the filesystem contains this new
revision, but in-memory 'repo.changelog' doesn't, if it is cached
without store lock (slock) before updating by another "hg commit".

This makes validating parents at re-loading 'repo.dirstate' from
'.hg/dirstate' replace such new revision with 'nullid'. Then,
'localrepository.commit()' creates "orphan" revision (see issue4368
for detail).

ec817376a322 makes 'commands.commit()' acquire both wlock and slock
before processing to avoid this issue at "hg commit".

But similar issue can occur even after ec817376a322, if 3rd party
extension does:

  - refer 'repo.changelog' outside wlock scope, and
  - invoke 'repo.commit()' directly (instead of 'commands.commit()')

This patch makes 'commit()' acquire slock before processing, to refer
recent changelog at validating parents of 'repo.dirstate'.
2015-12-09 08:28:53 +09:00
Matt Mackall
0fe2dfc303 merge with stable 2015-12-07 18:06:13 -06:00
Pierre-Yves David
24b0212f4e localrepo: reinstate localrepo.parents with a deprecation warning
The function was dropped in d5d613de0f44. This API drop brokes three of my
extensions including some critical to my workflow like tortoisehg. Lets mark
this API for death and give people time to fix their code.
2015-12-05 23:14:49 -08:00
Siddharth Agarwal
bb5af1afc4 localrepo.commit: check all files for resolve state (issue4972)
Previously we were only checking modified files for their resolve state. But a
file might be unresolved yet not in the modified state. Handle all such cases
properly.
2015-11-30 16:31:28 -08:00
Pierre-Yves David
44f90da4f8 localrepo: add a second auditor without file system check
Auditors keeps a cache of audited paths. Therefore we cannot use the same
auditor for working copy and history operation. We create a new one without
file system check for this purposes.
2015-12-03 13:22:36 -08:00
Augie Fackler
840125d439 commands: inline definition of localrepo.parents() and drop the method (API)
localrepo.parents() has relatively few users, and most of those were
actually implicitly looking at the wctx, which is now made explicit
via repo[None].
2015-11-11 20:07:15 -05:00
Augie Fackler
1330ff6731 localrepo: document nodebookmarks 2015-11-11 20:02:05 -05:00
Augie Fackler
4e03270f68 localrepo: remove clone method by hoisting into hg.py
hg.py was the only remaining caller of localrepo.clone(), so it's time
to move some more behavior out of localrepo.
2015-11-11 19:47:49 -05:00
FUJIWARA Katsunori
f850c84e84 localrepo: discard objects in _filecache at transaction failure (issue4876)
'repo.invalidate()' deletes 'filecache'-ed properties by
'filecache.__delete__()' below via 'delattr(unfiltered, k)'. But
cached objects are still kept in 'repo._filecache'.

    def __delete__(self, obj):
        try:
            del obj.__dict__[self.name]
        except KeyError:
            raise AttributeError(self.name)

If 'repo' object is reused even after failure of command execution,
referring 'filecache'-ed property may reuse one kept in
'repo._filecache', even if reloading from a file is expected.

Executing command sequence on command server is a typical case of this
situation (e0a0f9ad3e4c also tried to fix this issue). For example:

  1. start a command execution

  2. 'changelog.delayupdate()' is invoked in a transaction scope

     This replaces own 'opener' by '_divertopener()' for additional
     accessing to '00changelog.i.a' (aka "pending file").

  3. transaction is aborted, and command (1) execution is ended

     After 'repo.invalidate()' at releasing store lock, changelog
     object above (= 'opener' of it is still replaced) is deleted from
     'repo.__dict__', but still kept in 'repo._filecache'.

  4. start next command execution with same 'repo'

  5. referring 'repo.changelog' may reuse changelog object kept in
     'repo._filecache' according to timestamp of '00changelog.i'

     '00changelog.i' is truncated at transaction failure (even though
     this truncation is unintentional one, as described later), and
     'st_mtime' of it is changed. But 'st_mtime' doesn't have enough
     resolution to always detect this truncation, and invalid
     changelog object kept in 'repo._filecache' is reused
     occasionally.

     Then, "No such file or directory" error occurs for
     '00changelog.i.a', which is already removed at (3).

This patch discards objects in '_filecache' other than dirstate at
transaction failure.

Changes in 'invalidate()' can't be simplified by 'self._filecache =
{}', because 'invalidate()' should keep dirstate in 'self._filecache'

'repo.invalidate()' at "hg qpush" failure is removed in this patch,
because now it is redundant.

This patch doesn't make 'repo.invalidate()' always discard objects in
'_filecache', because 'repo.invalidate()' is invoked also at unlocking
store lock.

  - "always discard objects in filecache at unlocking" may cause
    serious performance problem for subsequent procedures at normal
    execution

  - but it is impossible to "discard objects in filecache at unlocking
    only at failure", because 'releasefn' of lock can't know whether a
    lock scope is terminated normally or not

    BTW, using "with" statement described in PEP343 for lock may
    resolve this ?

After this patch, truncation of '00changelog.i' still occurs at
transaction failure, even though newly added revisions exist only in
'00changelog.i.a' and size of '00changelog.i' isn't changed by this
truncation.

Updating 'st_mtime' of '00changelog.i' implied by this redundant
truncation also affects cache behavior as described above.

This will be fixed by dropping '00changelog.i' at aborting from the
list of files to be truncated in transaction.
2015-10-24 18:58:57 +09:00
Mads Kiilerich
09567db49a spelling: trivial spell checking 2015-10-17 00:58:46 +02:00
Siddharth Agarwal
dedaa4b3f5 localrepo.commit: abort if merge driver's conclude step hasn't been run yet
This case also requires 'hg resolve --all' to be run before continuing.
2015-10-15 01:02:32 -07:00
FUJIWARA Katsunori
8f93d72f88 hook: centralize passing HG_PENDING to external hook process
This patch centralizes passing HG_PENDING to external hook process
into '_exthook()'. To make in-memory changes visible to external hook
process, this patch does:

  - write (or schedule to write) in-memory dirstate changes, and
  - set HG_PENDING environment variable, if:
    - a transaction is running, and
    - there are in-memory changes to be visible

This patch tests some commands with some hooks, because transaction
activity of a same hook differs from each other ("---": "not tested").

    ======== ========= ========= ============
    command  preupdate precommit pretxncommit
    ======== ========= ========= ============
    unshelve   o        ---       ---
    backout    x        ---       ---
    import     ---       o         o
    qrefresh   ---       x         o
    ======== ========= ========= ============

Each hooks are examined separately to prevent in-memory changes from
being visible to external process accidentally by side effect of hooks
previously invoked.
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
7164a1a80a localrepo.commit: disallow commit when driver-resolved files exist
This code will not currently be activated because there's no code to mark
files as driver-resolved in core. This point is also somewhat hard to plug into
from extensions.
2015-10-14 16:04:43 -07:00
Gregory Szorc
b8f3c3b570 localrepo: improve docstring for revset methods
revs() doesn't return a list. Also document what its arguments do.

Also clarify that set() is just a convenience wrapper around revs().
2015-11-21 11:07:30 -08:00
Laurent Charignon
85b8e6613d localrepo: put bookmark move following commit in one transaction
Before this patch, making a commit on a local repo could move a bookmark and
both operations would not be grouped as one transaction. This patch makes both
operations part of one transaction. This is necessary to switch to the new api
to save bookmarks repo._bookmarks.recordchange if we don't want to change the
current behavior of rollback.

Dirstate change happening after the commit is done is now part of the
transaction mentioned above. This leads to a change in the expected output of
several tests.

The change to test-fncache happens because both lock are now released in the
same finally clause. The lock release is made explicitly buggy in this test.
Previously releasing lock would crash triggering release of wlock that crashes
too. Now lock release crash does not directly result in the release of wlock.
Instead wlock is released at garbage collection time and the error raised at
that time "confuses" python.
2015-11-18 01:36:58 -08:00
Siddharth Agarwal
b5cb4f4050 localrepo.commit: switch to mergestate.read()
See previous patches for why we're doing this.
2015-11-17 13:58:50 -08:00
Siddharth Agarwal
7e0e958b67 localrepo: switch to mergestate.clean()
See the previous patches for why we're doing this.
2015-11-17 17:04:32 -08:00
Augie Fackler
a6bb3f0de9 localrepo: use cg?unpacker.apply() instead of changegroup.addchangegroup()
This is in localpeer, so it lives. Had it been in localrepo instead, I
would have tried to exterminate it.
2015-10-13 17:14:07 -04:00
FUJIWARA Katsunori
2ef2ab5d6d dirstate: make writing in-memory changes aware of transaction activity
This patch delays writing in-memory changes out, if transaction is
running.

'_getfsnow()' is defined as a function, to hook it easily for
ambiguous timestamp tests (see also fakedirstatewritetime.py)

'if tr:' code path in this patch is still disabled at this revision,
because there is no client invoking 'dirstate.write()' with repo
object.

BTW, this patch changes 'dirstate.invalidate()' semantics around
'dirstate.write()' in a transaction scope:

  before:
    with repo.transaction():
        dirstate.CHANGE('A')
        dirstate.write() # change for A is written out here
        dirstate.CHANGE('B')
        dirstate.invalidate() # discards only change for B

  after:
    with repo.transaction():
        dirstate.CHANGE('A')
        dirstate.write() # change for A is still kept in memory
        dirstate.CHANGE('B')
        dirstate.invalidate() # discards changes for A and B

Fortunately, there is no code path expecting the former, at least, in
Mercurial itself, because 'dirstateguard' was introduced to remove
such 'dirstate.invalidate()'.
2015-10-14 02:49:17 +09:00
FUJIWARA Katsunori
344e42ce00 localrepo: restore dirstate to one before rollbacking if not parent-gone
'localrepository.rollback()' explicilty restores dirstate, only if at
least one of current parents of the working directory is removed at
rollbacking (a.k.a "parent-gone").

After DirstateTransactionPlan, 'dirstate.write()' will cause marking
'.hg/dirstate' as a file to be restored at rollbacking.

    https://mercurial.selenic.com/wiki/DirstateTransactionPlan

Then, 'transaction.rollback()' restores '.hg/dirstate' regardless of
parents of the working directory at that time, and this causes
unexpected dirstate changes if not "parent-gone" (e.g.  "hg update" to
another branch after "hg commit" or so, then "hg rollback").

To avoid such situation, this patch restores dirstate to one before
rollbacking if not "parent-gone".

  before:
    b1. restore dirstate explicitly, if "parent-gone"

  after:
    a1. save dirstate before actual rollbacking via dirstateguard
    a2. restore dirstate via 'transaction.rollback()'
    a3. if "parent-gone"
        - discard backup (a1)
        - restore dirstate from 'undo.dirstate'
    a4. otherwise, restore dirstate from backup (a1)

Even though restoring dirstate at (a3) after (a2) seems redundant,
this patch keeps this existing code path, because:

  - it isn't ensured that 'dirstate.write()' was invoked at least once
    while transaction running

    If not, '.hg/dirstate' isn't restored at (a2).

    In addition to it, rude 3rd party extension invoking
    'dirstate.write()' without 'repo' while transaction running (see
    subsequent patches for detail) may break consistency of a file
    backup-ed by transaction.

  - this patch mainly focuses on changes for DirstateTransactionPlan

    Restoring dirstate at (a3) itself should be cheaper enough than
    rollbacking itself. Redundancy will be removed in next step.

Newly added test is almost meaningless at this point. It will be used
to detect regression while implementing delayed dirstate write out.
2015-10-13 12:25:43 -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
FUJIWARA Katsunori
45bfdb573e localrepo: execute appropriate actions for dirstate at releasing transaction
Before this patch, in-memory dirstate changes are still kept over a
transaction scope boundary regardless of the result of it.

For "all or nothing" policy of the transaction, in-memory dirstate
changes should be:

  - written out at successful closing a transaction, because
    subsequent 'dirstate.invalidate()' can lose them

  - discarded at failure of a transaction, because outer
    'wlock.release()' or so may write them out

To discard all changes in a transaction completely, this patch also
restores '.hg/dirstate' by '.hg/journal.dirstate' at failure, because
'transaction' itself does nothing for files related to '.hg/journal.*'
in such case (therefore, renaming in this patch is safe enough).

This is a part of preparations for "transactional dirstate". See also
the wiki page below for detail about it.

    https://mercurial.selenic.com/wiki/DirstateTransactionPlan

This patch also removes redundant 'dirstate.invalidate()' just before
aborting a transaction for shelve/unshelve.
2015-10-09 03:53:46 +09:00
Siddharth Agarwal
b91b05d624 localrepo: prevent wlock from being inherited when a transaction is running
Review feedback from Pierre-Yves David. A separate line of work is working to
ensure that dirstate writes are written to a separate 'pending' file while a
transaction is active. Lock inheritance currently conflicts with that, so dodge
the issue by simply preventing inheritance while a transaction is running.

Custom merge drivers aren't going to run inside a transaction, so this doesn't
affect that.
2015-10-06 13:19:05 -07:00
Siddharth Agarwal
faa305db27 localrepo: add a way to get the current wlock if it's held
This will be useful to pass around a reference to the lock to some functions
we're going to add to scmutil. We don't want those functions to live in
localrepo to avoid bloat.
2015-10-05 14:27:37 -07:00
Siddharth Agarwal
02ed78a388 localrepo: add a way to get the current lock if it's held
We'll use this in upcoming patches to return a reference to the wlock if it's
held.
2015-10-05 14:26:53 -07:00