Mercurial > hg
view tests/test-sparse-import.t @ 42406:f385ba70e4af
changelog: optionally store added and removed files in changeset extras
As mentioned in an earlier patch, copies._chain() is used a lot in the
changeset-centric version of pathcopies(). It is expensive because it
needs to look at the manifest in order to filter out copies whose
target file has since been removed. I want to store the sets of added
and removed files in the changeset in order to speed that up. This
patch does the writing part of that. It could easily be a separate
config, but it's currently tied to experimental.copies.write-to since
that's the only real use case (it will also make the {file_*} template
keywords faster, but I doubt that anyone cares enough about those to
write extra metadata for them).
The new information is stored in the changeset extras. Since they're
always subsets of the changeset's "files" list, they're stored as
indexes into that list. I've stored the indexes as stringified ints
separated by NUL bytes. The size of 00changelog.d for the hg repo
increased in size by 0.28% percent (compared to the size with only
copy information in the changesets, which in turn is 0.17% larger than
without copy information). We could store only the delta between the
indexes and we could store them in binary, but the chosen format is
more readable.
We could also have implemented this as a cache outside the
changelog. One advantage of doing it that way is that we would get the
speedups from the {file_*} template keywords also on old
repos. Another advantage is that it we can rewrite the cache if we
find a bug in how we calculate the set of files. A disadvantage is
that it would be more complex. Another is that it would surely use
more space. We already write the copy information to the changeset
extras, so it seems like a small step to also write these file sets.
Differential Revision: https://phab.mercurial-scm.org/D6416
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Tue, 14 May 2019 22:19:51 -0700 |
parents | 33d0859c37bd |
children | 5c2a4f37eace |
line wrap: on
line source
test sparse $ hg init myrepo $ cd myrepo $ cat >> $HGRCPATH <<EOF > [extensions] > sparse= > purge= > strip= > rebase= > EOF $ echo a > index.html $ echo x > data.py $ echo z > readme.txt $ cat > base.sparse <<EOF > [include] > *.sparse > EOF $ hg ci -Aqm 'initial' $ cat > webpage.sparse <<EOF > %include base.sparse > [include] > *.html > EOF $ hg ci -Aqm 'initial' Import a rules file against a 'blank' sparse profile $ cat > $TESTTMP/rules_to_import <<EOF > [include] > *.py > EOF $ hg debugsparse --import-rules $TESTTMP/rules_to_import $ ls data.py $ hg debugsparse --reset $ rm .hg/sparse $ cat > $TESTTMP/rules_to_import <<EOF > %include base.sparse > [include] > *.py > EOF $ hg debugsparse --import-rules $TESTTMP/rules_to_import $ ls base.sparse data.py webpage.sparse $ hg debugsparse --reset $ rm .hg/sparse Start against an existing profile; rules *already active* should be ignored $ hg debugsparse --enable-profile webpage.sparse $ hg debugsparse --include *.py $ cat > $TESTTMP/rules_to_import <<EOF > %include base.sparse > [include] > *.html > *.txt > [exclude] > *.py > EOF $ hg debugsparse --import-rules $TESTTMP/rules_to_import $ ls base.sparse index.html readme.txt webpage.sparse $ cat .hg/sparse %include webpage.sparse [include] *.py *.txt [exclude] *.py $ hg debugsparse --reset $ rm .hg/sparse Same tests, with -Tjson enabled to output summaries $ cat > $TESTTMP/rules_to_import <<EOF > [include] > *.py > EOF $ hg debugsparse --import-rules $TESTTMP/rules_to_import -Tjson [ { "exclude_rules_added": 0, "files_added": 0, "files_conflicting": 0, "files_dropped": 4, "include_rules_added": 1, "profiles_added": 0 } ] $ hg debugsparse --reset $ rm .hg/sparse $ cat > $TESTTMP/rules_to_import <<EOF > %include base.sparse > [include] > *.py > EOF $ hg debugsparse --import-rules $TESTTMP/rules_to_import -Tjson [ { "exclude_rules_added": 0, "files_added": 0, "files_conflicting": 0, "files_dropped": 2, "include_rules_added": 1, "profiles_added": 1 } ] $ hg debugsparse --reset $ rm .hg/sparse $ hg debugsparse --enable-profile webpage.sparse $ hg debugsparse --include *.py $ cat > $TESTTMP/rules_to_import <<EOF > %include base.sparse > [include] > *.html > *.txt > [exclude] > *.py > EOF $ hg debugsparse --import-rules $TESTTMP/rules_to_import -Tjson [ { "exclude_rules_added": 1, "files_added": 1, "files_conflicting": 0, "files_dropped": 1, "include_rules_added": 1, "profiles_added": 0 } ] If importing results in no new rules being added, no refresh should take place! $ cat > $TESTTMP/trap_sparse_refresh.py <<EOF > from mercurial import error, sparse > def extsetup(ui): > def abort_refresh(*args, **kwargs): > raise error.Abort('sparse._refresh called!') > sparse.refreshwdir = abort_refresh > EOF $ cat >> $HGRCPATH <<EOF > [extensions] > trap_sparse_refresh=$TESTTMP/trap_sparse_refresh.py > EOF $ cat > $TESTTMP/rules_to_import <<EOF > [include] > *.py > EOF $ hg debugsparse --import-rules $TESTTMP/rules_to_import If an exception is raised during refresh, restore the existing rules again. $ cat > $TESTTMP/rules_to_import <<EOF > [exclude] > *.html > EOF $ hg debugsparse --import-rules $TESTTMP/rules_to_import abort: sparse._refresh called! [255] $ cat .hg/sparse %include webpage.sparse [include] *.py *.txt [exclude] *.py