- Oct 17, 2018
-
-
Gregory Szorc authored
This is somewhat hacky. For that I apologize. At the 4.8 Sprint, we decided we wanted to land support in wireprotov2 for doing a partial clone with changelog and manifestlog bootstrapped from a "stream clone" like primitive. This commit implements the client-side bits necessary to facilitate that. If the new server-side command for obtaining raw files data is available, we call it to get the raw files for the changelog and manifestlog. Then we fall through to an incremental pull. But when fetching files data, instead of using the list of a changesets and manifests that we fetched via the "changesetdata" command, we do a linear scan of the repo and resolve the changeset and manifest nodes along with the manifest linkrevs. Differential Revision: https://phab.mercurial-scm.org/D5135
-
- Oct 16, 2018
-
-
Gregory Szorc authored
Implementing shallow clone of the changelog is hard. We want the 4.8 release to have a fast implementation of partial clone in wireprotov2. In order to achieve fast, we can't use deltas for transferring changelog and manifestlog data. Per discussions at the 4.8 sprint, this commit implements a somwwhat hacky and likely-to-be-changed-drastically-or-dropped command in wireprotov2 that facilitates access to raw store files, namely the changelog and manifestlog. Using this command, clients can perform a "stream clone" of sorts for just the changelog and manifestlog. This will allow clients to fetch the changelog and manifest revlogs, stream them to disk (which should be fast), then follow up filesdata requests for files revision data for a particular changeset. Differential Revision: https://phab.mercurial-scm.org/D5134
-
Gregory Szorc authored
This will be needed in a future patch. Differential Revision: https://phab.mercurial-scm.org/D5133
-
- Sep 26, 2018
-
-
Gregory Szorc authored
pulloperation instances were recently taught to record file include and exclude patterns to facilitate narrow file transfer. Teaching the exchangev2 code to transfer a subset of files is as simple as constructing a narrow matcher from these patterns and filtering all seen file paths through it. Keep in mind that this change only influences file data: we're still fetching all changeset and manifest data. So, there's still a ton of "partial clone" to implement in exchangev2. On a personal note, I derive gratification that this feature requires very few lines of new code to implement. To test this, we implemented a minimal extension which allows us to specify --include/--exclude to clone. While the narrow extension provides these arguments, I explicitly wanted to test this functionality without the narrow extension enabled, as that extension monkeypatches various things and I want to isolate the behavior of core Mercurial. Differential Revision: https://phab.mercurial-scm.org/D5132
-
- Oct 09, 2018
-
-
Gregory Szorc authored
This commit provides an extension which uses SQLite to store file data (as opposed to revlogs). As the inline documentation describes, there are still several aspects to the extension that are incomplete. But it's a start. The extension does support basic clone, checkout, and commit workflows, which makes it suitable for simple use cases. One notable missing feature is support for "bundlerepos." This is probably responsible for the most test failures when the extension is activated as part of the test suite. All revision data is stored in SQLite. Data is stored as zstd compressed chunks (default if zstd is available), zlib compressed chunks (default if zstd is not available), or raw chunks (if configured or if a compressed delta is not smaller than the raw delta). This makes things very similar to revlogs. Unlike revlogs, the extension doesn't yet enforce a limit on delta chain length. This is an obvious limitation and should be addressed. This is somewhat mitigated by the use of zstd, which is much faster than zlib to decompress. There is a dedicated table for storing deltas. Deltas are stored by the SHA-1 hash of their uncompressed content. The "fileindex" table has columns that reference the delta for each revision and the base delta that delta should be applied against. A recursive SQL query is used to resolve the delta chain along with the delta data. By storing deltas by hash, we are able to de-duplicate delta storage! With revlogs, the same deltas in different revlogs would result in duplicate storage of that delta. In this scheme, inserting the duplicate delta is a no-op and delta chains simply reference the existing delta. When initially implementing this extension, I did not have content-indexed deltas and deltas could be duplicated across files (just like revlogs). When I implemented content-indexed deltas, the size of the SQLite database for a full clone of mozilla-unified dropped: before: 2,554,261,504 bytes after: 2,488,754,176 bytes Surprisingly, this is still larger than the bytes size of revlog files: revlog files: 2,104,861,230 bytes du -b: 2,254,381,614 I would have expected storage to be smaller since we're not limiting delta chain length and since we're using zstd instead of zlib. I suspect the SQLite indexes and per-column overhead account for the bulk of the differences. (Keep in mind that revlog uses a 64-byte packed struct for revision index data and deltas are stored without padding. Aside from the 12 unused bytes in the 32 byte node field, revlogs are pretty efficient.) Another source of overhead is file name storage. With revlogs, file names are stored in the filesystem. But with SQLite, we need to store file names in the database. This is roughly equivalent to the size of the fncache file, which for the mozilla-unified repository is ~34MB. Since the SQLite database isn't append-only and since delta chains can reference any delta, this opens some interesting possibilities. For example, we could store deltas in reverse, such that fulltexts are stored for newer revisions and deltas are applied to reconstruct older revisions. This is likely a more optimal storage strategy for version control, as new data tends to be more frequently accessed than old data. We would obviously need wire protocol support for transferring revision data from newest to oldest. And we would probably need some kind of mechanism for "re-encoding" stores. But it should be doable. This extension is very much experimental quality. There are a handful of features that don't work. It probably isn't suitable for day-to-day use. But it could be used in limited cases (e.g. read-only checkouts like in CI). And it is also a good proving ground for alternate storage backends. As we continue to define interfaces for all things storage, it will be useful to have a viable alternate storage backend to see how things shake out in practice. test-storage.py passes on Python 2 and introduces no new test failures on Python 3. Having the storage-level unit tests has proved to be insanely useful when developing this extension. Those tests caught numerous bugs during development and I'm convinced this style of testing is the way forward for ensuring alternate storage backends work as intended. Of course, test coverage isn't close to what it needs to be. But it is a start. And what coverage we have gives me confidence that basic store functionality is implemented properly. Differential Revision: https://phab.mercurial-scm.org/D4928
-
- Oct 16, 2018
-
-
Gregory Szorc authored
This function is super hacky and isn't correct 100% of the time. I'm going to need this functionality on a future non-revlog store. Let's copy things to storageutil so this code only exists once. Differential Revision: https://phab.mercurial-scm.org/D5118
-
- Sep 21, 2018
-
-
Matt Harbison authored
This is based on a patch by Gregory Szorc. I made small adjustments to clean up the messaging when the server has the extension enabled, but the client has it disabled (to prevent autoloading). Additionally, I added a second server capability to distinguish between the server having the extension enabled, and the server having LFS commits. This helps prevent unnecessary requirement propagation- the client shouldn't add a requirement that the server doesn't have, just because the server had the extension loaded. The TODO I had about advertising a capability when the server can natively serve up blobs isn't relevant anymore (we've had 2 releases that support this), so I dropped it. Currently, we lazily add the "lfs" requirement to a repo when we first encounter LFS data. Due to a pretxnchangegroup hook that looks for LFS data, this can happen at the end of clone. Now that we have more control over how repositories are created, we can do better. This commit adds a repo creation option to add the "lfs" requirement. hg.clone() sets this creation option if the remote peer is advertising lfs usage (as opposed to just support needed to push). So, what this change effectively does is have cloned repos automatically inherit the "lfs" requirement. Differential Revision: https://phab.mercurial-scm.org/D5130
-
- Oct 16, 2018
-
-
Gregory Szorc authored
As the comment in the test specifies, this was relying on storage backend implementation details. We switch to inserting a raw delta, skipping the regular insert path to ensure we have the desired outcome. This required implementing support for handling deltas in the revlog testing code. Differential Revision: https://phab.mercurial-scm.org/D5116
-
Gregory Szorc authored
addgroup() doesn't necessarily validate the hashes of each incoming revision. This is an optimization that allows delta group application to complete faster. The fact that revlog raises in this particular test is an implementation detail due to the way revlogs are testing multiple deltas. Differential Revision: https://phab.mercurial-scm.org/D5115
-
Gregory Szorc authored
test-storage.py manages to trigger this on Python 3. Differential Revision: https://phab.mercurial-scm.org/D5117
-
Gregory Szorc authored
This fixes a Python 3 breakage due to unknown key due to str/bytes type mismatch. # skip-blame just b'' literals Differential Revision: https://phab.mercurial-scm.org/D5114
-
Yuya Nishihara authored
# skip-blame just some b'' prefixes
-
Yuya Nishihara authored
Otherwise, things written to stdout.buffer would be interleaved.
-
Yuya Nishihara authored
-
Yuya Nishihara authored
-
Yuya Nishihara authored
-
Yuya Nishihara authored
# skip-blame just many b'' prefixes
-
Augie Fackler authored
-
- Aug 31, 2018
-
-
Martijn Pieters authored
There is absoluty no benefit in sorting a list that's being merged into a set on the next line. The changelog.ancestors() call later on also doesn't benefit from a sorted sequence of revs. Differential Revision: https://phab.mercurial-scm.org/D5111
-
- Oct 11, 2018
-
-
Boris Feld authored
We now have a valid no-op function. We no longer need the special case.
-
Boris Feld authored
We introduce a new "no-op" function to bear the documentation. In practice, the parsing step is skipping it so it is not even called. This will get fixed in the next changeset.
-
- Oct 16, 2018
-
-
Yuya Nishihara authored
Follow up for 47084b5ffd80.
-
- Oct 14, 2018
-
-
Martijn Pieters authored
Differential Revision: https://phab.mercurial-scm.org/D5105
-
Matt Harbison authored
-
- Oct 13, 2018
-
-
Augie Fackler authored
I suspect we should test this tool in isolation, but we don't yet. Oh well. Differential Revision: https://phab.mercurial-scm.org/D5061
-
- Oct 14, 2018
-
-
Augie Fackler authored
It turns out this behavior changed between versions of Python 3. Let's just always accept either size or sha1, and move on. Differential Revision: https://phab.mercurial-scm.org/D5104
-
Augie Fackler authored
Almost fixes test-keyword.t on Python 3, but leaves us with some extremely confusing failures at the end of the test that seem related to the command server? Differential Revision: https://phab.mercurial-scm.org/D5100
-
Augie Fackler authored
# skip-blame just a b prefix Differential Revision: https://phab.mercurial-scm.org/D5109
-
Augie Fackler authored
We should probably *not* use RuntimeError for this, but let's deal with that later, rather than as part of the Python 3 effort. Differential Revision: https://phab.mercurial-scm.org/D5108
-
- Oct 15, 2018
-
-
Georges Racinet authored
For now, we're duplicating it, but it would be probably a good idea to use a single one for the whole workspace (would have implications on the other crates as well)
-
- Oct 08, 2018
-
-
Georges Racinet authored
This changeset provides a Rust implementation of the iteration performed by lazyancestor.__contains__ It has the advantage over the Python iteration to use the 'seen' set encapsuled into the dedicated iterator (self._containsiter), rather than storing emitted items in another set (self._containsseen), and hence should reduce the memory footprint. Also, there's no need to convert intermediate emitted revisions back into Python integers. At this point, it would be tempting to implement the whole lazyancestor object in Rust, but that would lead to more C wrapping code (two objects) for little expected benefits.
-
- Oct 14, 2018
-
-
Matt Harbison authored
-
- Sep 27, 2018
-
-
Georges Racinet authored
We introduce a new class called 'rustlazyancestors' in the ancestors module, which is used only if parsers.rustlazyancestors does exist. The implementation of __contains__ stays unchanged, but is now backed by the Rust iterator. It would probably be a good candidate for further development, though, as it is mostly looping, and duplicates the 'seen' set. The Rust code could be further optimized, however it already gives rise to performance improvements: median timing from hg perfancestors: - on pypy: before: 0.077566s after: 0.016676s -79% - on mozilla central: before: 0.190037s after: 0.082225s -58% - on a private repository (about one million revisions): before: 0.567085s after: 0.108816s -80% - on another private repository (about 400 000 revisions): before: 1.440918s after: 0.290116s -80% median timing for hg perfbranchmap base - on pypy: before: 1.383413s after: 0.507993s -63% - on mozilla central: before: 2.821940s after: 1.258902s -55% - on a private repository (about one million revisions): before: 77.065076s after: 16.158475s -80% - on another private repository (about 401 000 revisions): before: 7.835503s after: 3.545331s -54%
-
- Oct 14, 2018
-
-
Mark Thomas authored
Differential Revision: https://phab.mercurial-scm.org/D5101
-
Mark Thomas authored
Differential Revision: https://phab.mercurial-scm.org/D5106
-
- Oct 12, 2018
-
-
Rodrigo Damazio Bovendorp authored
We previously used the '^' prefix to indicate that a command should be shown on the short list (shown for just "hg"), but that's a horrible hack, so I'm removing it. Differential Revision: https://phab.mercurial-scm.org/D5069
-
Rodrigo Damazio Bovendorp authored
Differential Revision: https://phab.mercurial-scm.org/D5068
-
- Oct 13, 2018
-
-
Rodrigo Damazio Bovendorp authored
I'm separating this into its own commit so people can bikeshed over the actual categorization (vs the support for categories). These categories are based on the help implementation we've been using internally at Google, and have had zero complaints. Differential Revision: https://phab.mercurial-scm.org/D5067
-
- Oct 12, 2018
-
-
Rodrigo Damazio Bovendorp authored
Differential Revision: https://phab.mercurial-scm.org/D5066
-
- Oct 13, 2018
-
-
Rodrigo Damazio Bovendorp authored
Differential Revision: https://phab.mercurial-scm.org/D5065
-