Commit Graph

127 Commits

Author SHA1 Message Date
FUJIWARA Katsunori
49079a5fce repair: open a file with checkambig=True to avoid file stat ambiguity
Before this patch, if steps below occurs at "the same time in sec",
all of mtime, ctime and size are same between (1) and (3).

  1. append data to revlog-style file (and close transaction)
  2. discard appended data by truncation of strip
  3. append same size but different data to revlog-style file again

Therefore, cache validation doesn't work after (3) as expected.

To avoid such file stat ambiguity around truncation, this patch opens
a file with checkambig=True.

This patch also introduces "with" statement style, to ensure immediate
invocation of close() after truncation, because closing file is the
only trigger to check (and get rid of) file stat ambiguity.

This is a part of ExactCacheValidationPlan.

    https://www.mercurial-scm.org/wiki/ExactCacheValidationPlan
2016-09-22 21:52:00 +09:00
Martin von Zweigbergk
e3fc1041dc strip: don't use "full" and "partial" to describe bundles
The partial bundle is not a subset of the full bundle, and the full
bundle is not full in any way that i see. The most obvious
interpretation of "full" I can think of is that it has all commits
back to the null revision, but that is not what the "full" bundle
is. The "full" bundle is simply a backup of what the user asked us to
strip (unless --no-backup). The "partial" bundle contains the
revisions we temporarily stripped because they had higher revision
numbers that some commit that the user asked us to strip.

The "full" bundle is already called "backup" in the code, so let's use
that in user-facing messages too. Let's call the "partial" bundle
"temporary" in the code.
2016-09-19 09:14:35 -07:00
Martin von Zweigbergk
fe544b2a62 strip: clarify that user action is required to recover temp bundle
If strip fails when applying the temporary bundle, the commits in the
temporary bundle have not yet been applied, so the user will almost
definitely want to apply the bundle. We should be more clear to the
user about that than our current "partial bundle stored in...".

Note that we will probably not be able to recover it automatically,
since whatever made it fail (e.g. a hook) will most likely make it
fail again. We need to give control back to the user to fix the
problem before trying again.
2016-09-19 09:14:32 -07:00
Martin von Zweigbergk
c435ce4f96 strip: report both bundle files in case of exception (issue5368)
If strip fails while recovering the temporary bundle (e.g. because a
hook fails), we tell the user only about the backup bundle, not about
the temporary bundle. Since the user did not ask to strip the commits
in the temporary bundle, that's the more important bundle to mention,
so let's do that (and also mention the backup bundle as usual).
2016-09-15 09:45:29 -07:00
Martin von Zweigbergk
19513cd917 strip: simplify some repeated conditions
We check "if saveheads or savebases" in several places to see if we
should or have created a bundle of the changesets to apply after
truncating the revlogs. One of the conditions is actually just "if
saveheads", but since there can't be savebases without saveheads, that
is effectively the same condition. It seems simpler to check only once
and from then on see if we created the file.
2016-09-15 10:18:56 -07:00
Augie Fackler
cc39e93327 repair: build dirlogs using manifest, rather than repo shortcut method
As before, this was rarely used, so let's get rid of the convenience method.
2016-08-05 13:01:01 -04:00
Martin von Zweigbergk
82a5e7d944 treemanifests: actually strip directory manifests
Stripping has only partly worked since f41815302d49 (repair: use cg3
for treemanifests, 2016-01-19): the bundle seems to have been created
correctly, but revlog entries in subdirectory revlogs were not
stripped. This meant that e.g. "hg verify" would fail after stripping
in a tree manifest repo.

To find the revisions to strip, we simply iterate over all directories
in the repo (included in store.datafiles()). This is inefficient for
stripping few commits, but efficient for stripping many commits. To
optimize for stripping few commits, we could instead walk the tree
from the root and find modified subdirectories, just like we do in the
changegroup code. I'm leaving that for another day.
2016-06-30 13:06:19 -07: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
Laurent Charignon
94c489ecf6 strip: invalidate phase cache after stripping changeset (issue5235)
When we remove a changeset from the changelog, the phase cache must be
invalidated, otherwise it could refer to changesets that are no longer in the
repo.

To reproduce the failure, I created an extension querying the phase cache after
the strip transaction is over.

To do that, I stripped two commits with a bookmark on one of them to force
another transaction (we open a transaction for moving bookmarks)
after the strip transaction.

Without the fix in this patch, the test leads to a stacktrace showing the issue:
      repair.strip(ui, repo, revs, backup)
    File "/Users/lcharignon/facebook-hg-rpms/hg-crew/mercurial/repair.py", line 205, in strip
      tr.close()
    File "/Users/lcharignon/facebook-hg-rpms/hg-crew/mercurial/transaction.py", line 44, in _active
      return func(self, *args, **kwds)
    File "/Users/lcharignon/facebook-hg-rpms/hg-crew/mercurial/transaction.py", line 490, in close
      self._postclosecallback[cat](self)
    File "$TESTTMP/crashstrip2.py", line 4, in test
      [repo.changelog.node(r) for r in repo.revs("not public()")]
    File "/Users/lcharignon/facebook-hg-rpms/hg-crew/mercurial/changelog.py", line 337, in node
      return super(changelog, self).node(rev)
    File "/Users/lcharignon/facebook-hg-rpms/hg-crew/mercurial/revlog.py", line 377, in node
      return self.index[rev][7]
  IndexError: revlog index out of range

The situation was encountered in inhibit (evolve's repo) where we would crash
following the volatile set invalidation submitted by Augie in
cbc52a99d057d11790cf5011e877c6f698bf57bf. Before his patch the issue was masked
as we were not accessing the phasecache after stripping a revision.

This bug uncovered another but in histedit (see explanation in issue5235).
I changed the histedit test accordingly to avoid fixing two things at once.
2016-05-12 06:13:59 -07:00
Kostia Balytskyi
47727221bc obsstore: move delete function from obsstore class to repair module
Since one of the original patches was accepted already and people on the
mailing list still have suggestions as to how this should be improved, I'm
implementing those suggestions in the following patches (this and the ones that
might follow).
2016-04-12 04:06:50 -07:00
Martin von Zweigbergk
4cc86f7b27 bundle: move writebundle() from changegroup.py to bundle2.py (API)
writebundle() writes a bundle2 bundle or a plain changegroup1. Imagine
away the "2" in "bundle2.py" for a moment and this change should makes
sense. The bundle wraps the changegroup, so it makes sense that it
knows about it. Another sign that this is correct is that the delayed
import of bundle2 in changegroup goes away.

I'll leave it for another time to remove the "2" in "bundle2.py"
(alternatively, extract a new bundle.py from it).
2016-03-28 14:41:29 -07:00
Anton Shestakov
e4ad4cc290 repair: specify unit for ui.progress in rebuildfncache() 2016-03-11 20:44:40 +08:00
Anton Shestakov
9c0d085179 repair: use 'rebuilding' progress topic in rebuildfncache() 2016-03-11 20:39:29 +08:00
Martin von Zweigbergk
d7ef7dd40a treemanifest: fix debugrebuildfncache
When I taught debugrebuildfncache about dirlogs in ebe9dacc63ba
(treemanifests: fix streaming clone, 2016-02-04), I added a
last-minute "if 'treemanifest' in repo" guard. That should have been
checking for "... in repo.requirements". Fix that and add tests for
it.
2016-02-07 21:44:38 -08:00
Martin von Zweigbergk
e50c296659 treemanifests: fix streaming clone
Similar to the previous patch, the .hg/store/meta/ directory does not
get copied when when using "hg clone --uncompressed". Fix by including
"meta/" in store.datafiles(). This seems safe to do, as there are only
a few users of this method. "hg manifest" already filters the paths by
"data/" prefix. The calls from largefiles also seem safe. The use in
verify needs updating to prevent it from mistaking dirlogs for
orphaned filelogs. That change is included in this patch.

Since the dirlogs will now be in the fncache when using fncachestore,
let's also update debugrebuildfncache(). That will also allow any
existing treemanifest repos to get their dirlogs into the fncache.

Also update test-treemanifest.t to use an a directory name that
requires dot-encoding and uppercase-encoding so we test that the path
encoding works.
2016-02-04 08:34:07 -08:00
Martin von Zweigbergk
857d2206c3 repair: use cg3 for treemanifests
The newly created helper changegroup.safeversion() knows to pick
version 03 if the repo uses treemanifests, so just using that means we
pick the right changegroup version.
2016-01-19 15:38:24 -08:00
Bryan O'Sullivan
541db2c882 with: use context manager for transaction in strip 2016-01-15 13:14:49 -08:00
Bryan O'Sullivan
8bfeb98530 with: use context manager for transaction in strip 2016-01-15 13:14:49 -08:00
Bryan O'Sullivan
da377129a6 with: use context manager in rebuildfncache 2016-01-15 13:14:49 -08:00
Bryan O'Sullivan
155e1de602 with: use context manager in rebuildfncache again 2016-01-15 13:14:49 -08:00
Laurent Charignon
0a74ada9c5 repair: improves documentation of strip regarding locks
This patch adds a comment making it clear that we should hold a lock before
calling repair.strip. The wording is the same than what we have for
obsolete.createmarkers
2015-12-29 10:21:39 -08:00
Laurent Charignon
56e13fa832 repair: use bookmarks.recordchange instead of bookmarks.write
Before this patch we were using the deprecated bookmarks.write api. This
patch replaces the call to bookmarks.write by a call to bookmarks.recordchange.
We move the bookmark code above the code removing the undo file because with
bookmarks.recordchange we have to create a transaction that would create an
undo file.
2015-11-30 16:38:29 -08:00
Pierre-Yves David
0089eccb8e strip: pass source and url to bundle2 processing
Restoring from a 'bundle2' was missing this data.
2015-10-20 16:01:33 +02:00
Augie Fackler
5888f3afd8 repair: use cg?unpacker.apply() instead of changegroup.addchangegroup() 2015-10-13 17:12:46 -04:00
Ryan McElroy
61f504197f strip: factor out revset calculation for strip -B
This will allow reusing it in evolve and overriding it in other extensions.
2015-10-09 14:48:59 -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
316994e165 strip: compress bundle2 backup using BZ
Storing uncompressed bundle on disk would be a regression. Strip backup using
bundle2 are now compressed when requested.
2015-09-29 14:42:03 -07:00
Pierre-Yves David
124ee320a0 strip: use bundle2 + cg2 by default when repository use general delta
The bundle10 format (plain changegroup-01) does not support general delta and
result into expensive delta re-computation when stripping. If the repository is
general delta, we store backups as bundle20 containing a changegroup-02 payload.

We remove the experimental feature related to strip backup bundle format because
this achieve the same goal in a leaner way. Removing the experimental option is
fine, that is why it experimental in the first place.

Compression of these bundles are coming in later changesets.
2015-09-29 13:16:51 -07:00
Matt Mackall
dc3c45835d merge with stable 2015-08-12 17:01:50 -05:00
Pierre-Yves David
618daeb9ac strip: use the 'finally: tr.release' pattern during stripping
The previous code, was calling 'abort' in all exception cases. This was wrong
when an exception was raised by post-close callback on the transaction. Calling
'abort' on an already closed transaction resulted in a error, shadowing the
original error.

We now use the same pattern as everywhere else. 'tr.release()' will abort the
transaction if we escape the scope without closing it. We add a test to make
sure we do not regress.
2015-08-08 14:50:03 -07:00
Wagner Bruna
f6ce8ccc47 repair: fix typo in warning message 2015-07-26 09:28:52 -03:00
Matt Mackall
c8d98cbf34 bundle2: fix type of experimental option 2015-06-25 17:56:06 -05:00
Gregory Szorc
a34c01ff2d repair: use absolute_import 2015-08-08 19:50:48 -07:00
Gregory Szorc
5380dea2a7 global: mass rewrite to use modern exception syntax
Python 2.6 introduced the "except type as instance" syntax, replacing
the "except type, instance" syntax that came before. Python 3 dropped
support for the latter syntax. Since we no longer support Python 2.4 or
2.5, we have no need to continue supporting the "except type, instance".

This patch mass rewrites the exception syntax to be Python 2.6+ and
Python 3 compatible.

This patch was produced by running `2to3 -f except -w -n .`.
2015-06-23 22:20:08 -07:00
Gregory Szorc
8f8cc06067 repair: add functionality to rebuild fncache
Currently, there is no way to recover from a missing or corrupt fncache
file in place (a clone is required). For certain use cases such as
servers and with large repositories, an in-place repair may be
desirable. This patch adds functionality for in-place repair of the
fncache.

The `hg debugrebuildfncache` command is introduced. It ensures the
fncache is up to date by reconstructing the fncache from all seen files
encountered during a brute force traversal of the repository's entire
history.

The command will add missing entries and will prune excess ones.

Currently, the command no-ops unless the repository has the fncache
requirement. The command could later grow the ability to "upgrade" an
existing repository to be fncache enabled, if desired.

When testing this patch on a local clone of the Firefox repository, it
removed a bunch of entries. Investigation revealed that removed entries
belonged to empty (0 byte size) .i filelogs. The functionality for
pruning fncache of stripped revlogs was introduced in 93ba76bfbe8a, so
the presence of these entries likely predates this feature.
2015-06-22 09:59:48 -07:00
Pierre-Yves David
401e1dc20d bundle2: use bundle2 by default
All the test change have been isolated and validated. We have free to turn on
bundle2 as the default exchange protocol.

"To reach a port we must set sail –
Sail, not tie at anchor
Sail, not drift."
2015-02-06 17:41:24 +00:00
Yuya Nishihara
33719fba6e repair: use _hexlist() to build revset expression from binary nodes
_hexlist() should be efficient than _list().
2015-05-24 14:34:12 +09:00
Pierre-Yves David
c0b7b3f795 repair: forbid strip from inside a transaction
Stripping inside a transaction will (at best) crash or (at worst)
result in very unexpected results. We explicitly forbid it early.
2015-05-23 21:18:47 -07:00
FUJIWARA Katsunori
79a47e0eeb repair: avoid string concatenation by + operator
String concatenation by "+" operator causes failure of extracting
messages to be translated.

Python automatically concatenates strings separated by whitespaces
into one string.
2015-04-25 23:44:53 +09:00
Pierre-Yves David
af7d20b000 bundle2: rename format, parts and config to final names
It is finally time to freeze the bundle2 format! To do so we:
- rename HG2Y to HG20,
- drop "b2x:" prefix from all part names,
- rename capability to "bundle2-exp" to "bundle2"
- rename the hook flag from 'bundle2-exp' to 'bundle2'
2015-04-09 16:25:48 -04:00
Mike Edgar
d7e989d6f9 repair: define explicit local variable, don't reuse a comprehension variable
The node ID used in strip bundle names is currently taken as the last
iterated value in a list comprehension found much earlier in the function.
This change makes the node selection more explicit at the cost of redundancy.
2015-03-10 16:25:10 -04:00
Eric Sumner
a01d77c360 repair: setup hookargs when processing bundle2s
addchangegroup() modifies its behavior based on the transaction source.
This is incorrect for bundle2 repair files, causing rebases to abort when this
option is enabled.

This diff specifies the source type in the way recommended by comments in
bundle2.py and adds a test to ensure that rebases with the experimental option
work successfully.
2015-02-20 13:55:01 -08:00
Eric Sumner
fa1eb17d62 repair._bundle: fix traceback for bad config value
On IRC, rom1dep reported a traceback[1] from setting
experimental.strip-bundle2-version to True. This diff catches
unexpected values and falls back to the non-experimental bundle1
implementation after issuing a warning.

[1] http://gist.tamytro.org/_admin/gists/qXcdQLwtApgy6e3NwWgl
2015-01-21 15:54:52 -08:00
Eric Sumner
e2ad8ed688 repair: add experimental option to write bundle2 files
This adds an experimental option 'strip-bundle2-version' which causes backup
bundles to use bundle2 formatting.  Especially for generaldelta repositories,
this should provide significant performance gains for any operation that needs
to write a backup.
2015-01-15 16:51:13 -08:00
Eric Sumner
7cbcf9bdca changegroup.writebundle: provide ui
The next diff will add support for writing bundle2 files to writebundle, but
the bundle2 generator wants access to a ui object.  This changes the signature
and callsites to pass one in.
2015-01-15 14:39:41 -08:00
Angel Ezquerra
6e49f7def8 localrepo: remove all external users of localrepo.sopener
This change touches every module in which repository.sopener was being used, and
changes it for the equivalent repository.svfs.

It should now be possible to remove localrepo.sopener.
2015-01-11 00:25:54 +01:00
Durham Goode
2591767a70 bundles: do not overwrite existing backup bundles (BC)
Previously, a backup bundle could overwrite an existing bundle and cause user
data loss. For instance, if you have A<-B<-C and strip B, it produces backup
bundle B-backup.hg. If you then hg pull -r B B-backup.hg and strip it again, it
overwrites the existing B-backup.hg and C is lost.

The fix is to add a hash of all the nodes inside that bundle to the filename.
Fixed up existing tests and added a new test in test-strip.t
2015-01-09 10:52:14 -08:00
Pierre-Yves David
bbcfd63a3a repair: use first instead of direct indexing
This makes it compatible with all smartset classes.
2014-10-07 00:09:50 -07:00
Jordi Gutiérrez Hermoso
465e05be10 strip: remove -b/--backup codepaths
cset 21b4faf3787e has removed this option. This commit just tidies the
code that was associated to it. It also fixes the internal calls to
the strip() function.

Before this change, any function that thought it would want as a final
safety to keep a partial backup bundle (bundling changes not linearly
related to the current change being stripped), had to explicitly pass
a backup="strip" option. With this change, these backups are always
kept in case of an exception and always removed if there is no
exception. Only full backups can be specified with backup=True or no
full backups with backup=False.
2014-07-24 15:06:08 -04:00
Pierre-Yves David
c9703fe999 bundle2: add a ui argument to readbundle
The bundle2 unbundler needs a ui argument. We are now passing this information
to `readbundle`.
2014-04-14 15:45:30 -04:00