From 419e3a3e23c7b42f70504f2d0edc3ee72636892a Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Thu, 21 Mar 2024 23:15:19 +0100 Subject: [PATCH] Import mercurial_6.7.1.orig.tar.gz [dgit import orig mercurial_6.7.1.orig.tar.gz] --- .arcconfig | 7 + .clang-format | 13 + .editorconfig | 21 + .gitattributes | 2 + .gitlab/merge_request_templates/Default.md | 18 + .hgignore | 82 + .hgsigs | 260 + .hgtags | 276 + .jshintrc | 11 + CONTRIBUTING | 13 + CONTRIBUTORS | 41 + COPYING | 339 + MANIFEST.in | 2313 + Makefile | 307 + PKG-INFO | 29 + README.rst | 30 + contrib/Makefile.python | 76 + contrib/all-revsets.txt | 159 + contrib/asv.conf.json | 13 + contrib/automation/README.rst | 258 + contrib/automation/automation.py | 74 + contrib/automation/hgautomation/__init__.py | 57 + contrib/automation/hgautomation/aws.py | 1330 + contrib/automation/hgautomation/cli.py | 551 + contrib/automation/hgautomation/linux.py | 602 + contrib/automation/hgautomation/pypi.py | 21 + contrib/automation/hgautomation/ssh.py | 72 + contrib/automation/hgautomation/try_server.py | 99 + contrib/automation/hgautomation/windows.py | 542 + contrib/automation/hgautomation/winrm.py | 87 + .../automation/linux-requirements-py3.5.txt | 194 + contrib/automation/linux-requirements-py3.txt | 306 + contrib/automation/linux-requirements.txt.in | 17 + contrib/automation/requirements.txt | 267 + contrib/automation/requirements.txt.in | 4 + contrib/base-revsets.txt | 52 + contrib/bash_completion | 659 + contrib/bdiff-torture.py | 107 + contrib/benchmarks/__init__.py | 124 + contrib/benchmarks/perf.py | 29 + contrib/benchmarks/revset.py | 56 + contrib/byteify-strings.py | 338 + contrib/casesmash.py | 40 + contrib/catapipe.py | 120 + contrib/check-code.py | 1083 + contrib/check-commit | 114 + contrib/check-config.py | 190 + contrib/check-py3-compat.py | 92 + contrib/check-pytype.sh | 133 + contrib/chg/Makefile | 43 + contrib/chg/README | 40 + contrib/chg/chg.1 | 41 + contrib/chg/chg.c | 560 + contrib/chg/hgclient.c | 656 + contrib/chg/hgclient.h | 30 + contrib/chg/procutil.c | 275 + contrib/chg/procutil.h | 21 + contrib/chg/util.c | 222 + contrib/chg/util.h | 35 + contrib/clang-format-ignorelist | 12 + contrib/debugcmdserver.py | 50 + contrib/debugshell.py | 64 + contrib/docker/apache-server/Dockerfile | 23 + contrib/docker/apache-server/README.rst | 144 + contrib/docker/apache-server/entrypoint.sh | 80 + contrib/docker/apache-server/hgwebconfig | 6 + contrib/docker/apache-server/vhost.conf | 24 + contrib/docker/pytype/Dockerfile | 14 + contrib/docker/pytype/entrypoint.sh | 8 + contrib/docker/pytype/recipe.sh | 28 + contrib/dumprevlog | 59 + contrib/editmerge | 58 + contrib/editmergeps.bat | 2 + contrib/editmergeps.ps1 | 78 + contrib/examples/fix.hgrc | 14 + contrib/fuzz/FuzzedDataProvider.h | 368 + contrib/fuzz/Makefile | 139 + contrib/fuzz/README.rst | 26 + contrib/fuzz/bdiff.cc | 39 + contrib/fuzz/dirs.cc | 55 + contrib/fuzz/dirs_corpus.py | 27 + contrib/fuzz/dirstate.cc | 47 + contrib/fuzz/dirstate_corpus.py | 15 + contrib/fuzz/fm1readmarkers.cc | 59 + contrib/fuzz/fm1readmarkers_corpus.py | 36 + contrib/fuzz/fncache.cc | 69 + contrib/fuzz/fuzzutil.h | 37 + contrib/fuzz/jsonescapeu8fast.cc | 55 + contrib/fuzz/manifest.cc | 72 + contrib/fuzz/manifest_corpus.py | 36 + contrib/fuzz/mpatch.cc | 114 + contrib/fuzz/mpatch_corpus.py | 369 + contrib/fuzz/pyutil.cc | 76 + contrib/fuzz/pyutil.h | 15 + contrib/fuzz/revlog.cc | 61 + contrib/fuzz/revlog_corpus.py | 23 + contrib/fuzz/standalone_fuzz_target_runner.cc | 45 + contrib/fuzz/xdiff.cc | 58 + contrib/genosxversion.py | 140 + contrib/heptapod-ci.yml | 165 + contrib/hg-ssh | 117 + contrib/hg-test-mode.el | 97 + contrib/hgclient.py | 162 + contrib/hgk | 4155 ++ contrib/hgperf | 112 + contrib/hgsh/Makefile | 13 + contrib/hgsh/hgsh.c | 438 + contrib/hgweb.fcgi | 19 + contrib/hgweb.wsgi | 15 + contrib/import-checker.py | 770 + contrib/install-windows-dependencies.ps1 | 204 + contrib/logo-droplets.svg | 5 + contrib/memory.py | 35 + contrib/mercurial.el | 1293 + contrib/merge-lists/Cargo.lock | 695 + contrib/merge-lists/Cargo.toml | 21 + contrib/merge-lists/src/main.rs | 300 + contrib/merge-lists/tests/test-merge-lists.rs | 204 + contrib/mq.el | 417 + contrib/nix/flake.lock | 94 + contrib/nix/flake.nix | 177 + contrib/openvms/build.com | 422 + contrib/openvms/vms/hgeditor.com | 12 + contrib/openvms/vms/hgmerge.com | 76 + contrib/openvms/vms/logicals.com | 20 + contrib/openvms/vms/setup.com | 7 + contrib/openvms/vms/startup.com | 12 + contrib/openvms/vms/stmlf.fdl | 7 + contrib/packaging/Makefile | 136 + contrib/packaging/build-linux-wheels.sh | 34 + contrib/packaging/builddeb | 115 + contrib/packaging/buildrpm | 172 + contrib/packaging/debian/cacerts.rc | 5 + contrib/packaging/debian/changelog | 5 + contrib/packaging/debian/compat | 1 + contrib/packaging/debian/control | 43 + contrib/packaging/debian/copyright | 27 + contrib/packaging/debian/default-tools.rc | 5 + contrib/packaging/debian/hgkpath.rc | 2 + contrib/packaging/debian/rules | 101 + contrib/packaging/docker/debian.template | 16 + contrib/packaging/docker/fedora.template | 15 + contrib/packaging/docker/rhel7 | 20 + contrib/packaging/docker/rhel8 | 21 + contrib/packaging/docker/rhel9 | 25 + contrib/packaging/docker/ubuntu.template | 21 + contrib/packaging/dockerdeb | 46 + contrib/packaging/dockerrpm | 55 + contrib/packaging/hg-docker | 129 + contrib/packaging/hgpackaging/__init__.py | 0 contrib/packaging/hgpackaging/cli.py | 154 + contrib/packaging/hgpackaging/downloads.py | 141 + contrib/packaging/hgpackaging/inno.py | 154 + contrib/packaging/hgpackaging/pyoxidizer.py | 173 + contrib/packaging/hgpackaging/util.py | 190 + contrib/packaging/hgpackaging/wix.py | 96 + contrib/packaging/inno/mercurial.iss | 82 + contrib/packaging/inno/modpath.iss | 175 + contrib/packaging/inno/readme.rst | 44 + .../packaging/linux-wheel-centos5-blacklist | 3 + contrib/packaging/macosx/Readme.html | 37 + contrib/packaging/macosx/Welcome.html | 20 + contrib/packaging/macosx/distribution.xml | 19 + contrib/packaging/mercurial.spec | 167 + contrib/packaging/packagelib.sh | 43 + contrib/packaging/packaging.py | 74 + contrib/packaging/requirements-macos.txt | 38 + contrib/packaging/requirements-macos.txt.in | 22 + .../packaging/requirements-windows-py3.txt | 344 + contrib/packaging/requirements-windows.txt.in | 23 + contrib/packaging/requirements.txt | 68 + contrib/packaging/requirements.txt.in | 5 + contrib/packaging/wix/COPYING.rtf | Bin 0 -> 1792 bytes contrib/packaging/wix/defines.wxi | 9 + contrib/packaging/wix/guids.wxi | 12 + contrib/packaging/wix/mercurial.wxs | 136 + contrib/packaging/wix/readme.rst | 57 + contrib/perf-utils/compare-discovery-case | 227 + contrib/perf-utils/discovery-helper.sh | 107 + contrib/perf-utils/perf-revlog-write-plot.py | 125 + contrib/perf-utils/search-discovery-case | 214 + contrib/perf-utils/subsetmaker.py | 202 + contrib/perf.py | 4651 ++ contrib/phab-clean.py | 92 + contrib/phab-refresh-stack.sh | 47 + contrib/plan9/9diff | 42 + contrib/plan9/9mail | 26 + contrib/plan9/README | 39 + contrib/plan9/hgrc.d/9diff.rc | 7 + contrib/plan9/hgrc.d/9mail.rc | 4 + contrib/plan9/hgrc.d/factotum.rc | 4 + contrib/plan9/mkfile | 37 + contrib/plan9/proto | 24 + contrib/pull_logger.py | 141 + contrib/pylintrc | 313 + contrib/python-hook-examples.py | 26 + contrib/python-zstandard/LICENSE | 27 + contrib/python-zstandard/MANIFEST.in | 9 + contrib/python-zstandard/NEWS.rst | 721 + contrib/python-zstandard/README.rst | 1602 + contrib/python-zstandard/c-ext/bufferutil.c | 792 + .../c-ext/compressionchunker.c | 360 + .../python-zstandard/c-ext/compressiondict.c | 411 + .../c-ext/compressionparams.c | 572 + .../c-ext/compressionreader.c | 818 + .../c-ext/compressionwriter.c | 372 + contrib/python-zstandard/c-ext/compressobj.c | 256 + contrib/python-zstandard/c-ext/compressor.c | 1670 + .../c-ext/compressoriterator.c | 235 + contrib/python-zstandard/c-ext/constants.c | 110 + .../c-ext/decompressionreader.c | 781 + .../c-ext/decompressionwriter.c | 295 + .../python-zstandard/c-ext/decompressobj.c | 202 + contrib/python-zstandard/c-ext/decompressor.c | 1822 + .../c-ext/decompressoriterator.c | 249 + contrib/python-zstandard/c-ext/frameparams.c | 138 + .../python-zstandard/c-ext/python-zstandard.h | 360 + contrib/python-zstandard/make_cffi.py | 238 + contrib/python-zstandard/setup.py | 119 + contrib/python-zstandard/setup_zstd.py | 218 + contrib/python-zstandard/tests/__init__.py | 0 contrib/python-zstandard/tests/common.py | 203 + .../tests/test_buffer_util.py | 153 + .../python-zstandard/tests/test_compressor.py | 1803 + .../tests/test_compressor_fuzzing.py | 884 + .../tests/test_data_structures.py | 255 + .../tests/test_data_structures_fuzzing.py | 121 + .../tests/test_decompressor.py | 1714 + .../tests/test_decompressor_fuzzing.py | 593 + .../tests/test_estimate_sizes.py | 15 + .../tests/test_module_attributes.py | 68 + .../tests/test_train_dictionary.py | 102 + .../python-zstandard/zstandard/__init__.py | 74 + contrib/python-zstandard/zstandard/cffi.py | 2768 + contrib/python-zstandard/zstd.c | 344 + contrib/python-zstandard/zstd/COPYING | 339 + contrib/python-zstandard/zstd/LICENSE | 30 + .../python-zstandard/zstd/common/bitstream.h | 460 + .../python-zstandard/zstd/common/compiler.h | 159 + contrib/python-zstandard/zstd/common/cpu.h | 215 + contrib/python-zstandard/zstd/common/debug.c | 44 + contrib/python-zstandard/zstd/common/debug.h | 134 + .../zstd/common/entropy_common.c | 236 + .../zstd/common/error_private.c | 54 + .../zstd/common/error_private.h | 76 + contrib/python-zstandard/zstd/common/fse.h | 708 + .../zstd/common/fse_decompress.c | 311 + contrib/python-zstandard/zstd/common/huf.h | 358 + contrib/python-zstandard/zstd/common/mem.h | 453 + contrib/python-zstandard/zstd/common/pool.c | 344 + contrib/python-zstandard/zstd/common/pool.h | 84 + .../zstd/common/pythoncapi_compat.h | 283 + .../python-zstandard/zstd/common/threading.c | 120 + .../python-zstandard/zstd/common/threading.h | 154 + contrib/python-zstandard/zstd/common/xxhash.c | 882 + contrib/python-zstandard/zstd/common/xxhash.h | 305 + .../zstd/common/zstd_common.c | 83 + .../zstd/common/zstd_errors.h | 93 + .../zstd/common/zstd_internal.h | 350 + .../zstd/compress/fse_compress.c | 721 + contrib/python-zstandard/zstd/compress/hist.c | 203 + contrib/python-zstandard/zstd/compress/hist.h | 95 + .../zstd/compress/huf_compress.c | 798 + .../zstd/compress/zstd_compress.c | 4103 ++ .../zstd/compress/zstd_compress_internal.h | 1003 + .../zstd/compress/zstd_compress_literals.c | 154 + .../zstd/compress/zstd_compress_literals.h | 29 + .../zstd/compress/zstd_compress_sequences.c | 415 + .../zstd/compress/zstd_compress_sequences.h | 47 + .../zstd/compress/zstd_cwksp.h | 535 + .../zstd/compress/zstd_double_fast.c | 518 + .../zstd/compress/zstd_double_fast.h | 38 + .../zstd/compress/zstd_fast.c | 484 + .../zstd/compress/zstd_fast.h | 37 + .../zstd/compress/zstd_lazy.c | 1115 + .../zstd/compress/zstd_lazy.h | 67 + .../python-zstandard/zstd/compress/zstd_ldm.c | 597 + .../python-zstandard/zstd/compress/zstd_ldm.h | 105 + .../python-zstandard/zstd/compress/zstd_opt.c | 1246 + .../python-zstandard/zstd/compress/zstd_opt.h | 56 + .../zstd/compress/zstdmt_compress.c | 2116 + .../zstd/compress/zstdmt_compress.h | 192 + .../zstd/decompress/huf_decompress.c | 1234 + .../zstd/decompress/zstd_ddict.c | 240 + .../zstd/decompress/zstd_ddict.h | 44 + .../zstd/decompress/zstd_decompress.c | 1769 + .../zstd/decompress/zstd_decompress_block.c | 1323 + .../zstd/decompress/zstd_decompress_block.h | 59 + .../decompress/zstd_decompress_internal.h | 175 + .../python-zstandard/zstd/deprecated/zbuff.h | 214 + .../zstd/deprecated/zbuff_common.c | 26 + .../zstd/deprecated/zbuff_compress.c | 147 + .../zstd/deprecated/zbuff_decompress.c | 75 + .../python-zstandard/zstd/dictBuilder/cover.c | 1236 + .../python-zstandard/zstd/dictBuilder/cover.h | 147 + .../zstd/dictBuilder/divsufsort.c | 1913 + .../zstd/dictBuilder/divsufsort.h | 67 + .../zstd/dictBuilder/fastcover.c | 747 + .../python-zstandard/zstd/dictBuilder/zdict.c | 1111 + .../python-zstandard/zstd/dictBuilder/zdict.h | 282 + contrib/python-zstandard/zstd/zstd.h | 2049 + contrib/python3-ratchet.py | 161 + contrib/python3-whitelist | 786 + contrib/relnotes | 207 + contrib/revsetbenchmarks.py | 388 + contrib/setup-pytype.sh | 33 + contrib/showstack.py | 30 + contrib/simplemerge | 140 + contrib/synthrepo.py | 564 + contrib/tcsh_completion | 50 + contrib/tcsh_completion_build.sh | 74 + contrib/testparseutil.py | 657 + contrib/undumprevlog | 56 + contrib/vagrant/README.md | 4 + contrib/vagrant/Vagrantfile | 13 + contrib/vagrant/provision.sh | 10 + contrib/vagrant/run-tests.sh | 13 + contrib/vim/HGAnnotate.vim | 27 + contrib/vim/hg-menu.vim | 93 + contrib/vim/hgcommand.vim | 1703 + contrib/vim/hgtest.vim | 42 + contrib/vim/patchreview.txt | 97 + contrib/vim/patchreview.vim | 868 + contrib/win32/ReadMe.html | 161 + contrib/win32/buildlocal.bat | 9 + contrib/win32/hg.bat | 21 + contrib/win32/hgwebdir_wsgi.py | 139 + contrib/win32/mercurial.ico | Bin 0 -> 2238 bytes contrib/win32/mercurial.ini | 97 + contrib/win32/postinstall.txt | 9 + contrib/xml.rnc | 41 + contrib/zsh_completion | 1325 + doc/Makefile | 55 + doc/README | 11 + doc/check-seclevel.py | 242 + doc/docchecker | 83 + doc/gendoc.py | 345 + doc/hg-ssh.8 | 86 + doc/hg-ssh.8.html | 91 + doc/hg.1 | 19503 +++++++ doc/hg.1.html | 15773 ++++++ doc/hgignore.5 | 164 + doc/hgignore.5.html | 141 + doc/hgmanpage.py | 1144 + doc/hgrc.5 | 4279 ++ doc/hgrc.5.html | 3154 ++ doc/runrst | 68 + doc/style.css | 309 + hg | 59 + hgdemandimport/__init__.py | 86 + hgdemandimport/demandimportpy3.py | 178 + hgdemandimport/tracing.py | 61 + hgeditor | 56 + hgext/__init__.py | 3 + hgext/absorb.py | 1162 + hgext/acl.py | 488 + hgext/amend.py | 75 + hgext/automv.py | 127 + hgext/beautifygraph.py | 107 + hgext/blackbox.py | 211 + hgext/bookflow.py | 125 + hgext/bugzilla.py | 1251 + hgext/censor.py | 143 + hgext/children.py | 83 + hgext/churn.py | 262 + hgext/clonebundles.py | 1090 + hgext/closehead.py | 91 + hgext/commitextras.py | 87 + hgext/convert/__init__.py | 602 + hgext/convert/bzr.py | 346 + hgext/convert/common.py | 576 + hgext/convert/convcmd.py | 692 + hgext/convert/cvs.py | 331 + hgext/convert/cvsps.py | 1071 + hgext/convert/darcs.py | 223 + hgext/convert/filemap.py | 497 + hgext/convert/git.py | 531 + hgext/convert/gnuarch.py | 377 + hgext/convert/hg.py | 735 + hgext/convert/monotone.py | 411 + hgext/convert/p4.py | 402 + hgext/convert/subversion.py | 1730 + hgext/convert/transport.py | 157 + hgext/eol.py | 480 + hgext/extdiff.py | 803 + hgext/factotum.py | 160 + hgext/fastannotate/__init__.py | 173 + hgext/fastannotate/commands.py | 356 + hgext/fastannotate/context.py | 858 + hgext/fastannotate/error.py | 14 + hgext/fastannotate/formatter.py | 176 + hgext/fastannotate/protocol.py | 262 + hgext/fastannotate/revmap.py | 259 + hgext/fastannotate/support.py | 135 + hgext/fastexport.py | 216 + hgext/fetch.py | 195 + hgext/fix.py | 959 + hgext/fsmonitor/__init__.py | 1016 + hgext/fsmonitor/pywatchman/__init__.py | 1200 + hgext/fsmonitor/pywatchman/bser.c | 1268 + hgext/fsmonitor/pywatchman/capabilities.py | 72 + hgext/fsmonitor/pywatchman/compat.py | 53 + hgext/fsmonitor/pywatchman/encoding.py | 72 + hgext/fsmonitor/pywatchman/load.py | 106 + hgext/fsmonitor/pywatchman/pybser.py | 564 + hgext/fsmonitor/state.py | 148 + hgext/fsmonitor/watchmanclient.py | 128 + hgext/git/TODO.md | 30 + hgext/git/__init__.py | 352 + hgext/git/dirstate.py | 395 + hgext/git/gitlog.py | 570 + hgext/git/gitutil.py | 48 + hgext/git/index.py | 359 + hgext/git/manifest.py | 368 + hgext/githelp.py | 1269 + hgext/gpg.py | 389 + hgext/graphlog.py | 124 + hgext/hgk.py | 385 + hgext/highlight/__init__.py | 108 + hgext/highlight/highlight.py | 100 + hgext/histedit.py | 2679 + hgext/hooklib/__init__.py | 25 + hgext/hooklib/changeset_obsoleted.py | 146 + hgext/hooklib/changeset_published.py | 138 + hgext/hooklib/enforce_draft_commits.py | 44 + hgext/hooklib/reject_merge_commits.py | 44 + hgext/hooklib/reject_new_heads.py | 40 + hgext/journal.py | 606 + hgext/keyword.py | 893 + hgext/largefiles/CONTRIBUTORS | 4 + hgext/largefiles/__init__.py | 200 + hgext/largefiles/basestore.py | 182 + hgext/largefiles/lfcommands.py | 673 + hgext/largefiles/lfutil.py | 823 + hgext/largefiles/localstore.py | 72 + hgext/largefiles/overrides.py | 1924 + hgext/largefiles/proto.py | 217 + hgext/largefiles/remotestore.py | 153 + hgext/largefiles/reposetup.py | 474 + hgext/largefiles/storefactory.py | 95 + hgext/largefiles/wirestore.py | 51 + hgext/lfs/TODO.rst | 192 + hgext/lfs/__init__.py | 446 + hgext/lfs/blobstore.py | 788 + hgext/lfs/pointer.py | 88 + hgext/lfs/wireprotolfsserver.py | 368 + hgext/lfs/wrapper.py | 540 + hgext/logtoprocess.py | 82 + hgext/mq.py | 4301 ++ hgext/narrow/TODO.rst | 21 + hgext/narrow/__init__.py | 77 + hgext/narrow/narrowbundle2.py | 345 + hgext/narrow/narrowcommands.py | 697 + hgext/narrow/narrowdirstate.py | 75 + hgext/narrow/narrowrepo.py | 28 + hgext/narrow/narrowtemplates.py | 51 + hgext/narrow/narrowwirepeer.py | 182 + hgext/notify.py | 658 + hgext/pager.py | 82 + hgext/patchbomb.py | 1007 + hgext/phabricator.py | 2402 + hgext/purge.py | 39 + hgext/rebase.py | 2281 + hgext/record.py | 174 + hgext/releasenotes.py | 720 + hgext/relink.py | 212 + hgext/remotefilelog/README.md | 111 + hgext/remotefilelog/__init__.py | 1259 + hgext/remotefilelog/basepack.py | 548 + hgext/remotefilelog/basestore.py | 449 + hgext/remotefilelog/connectionpool.py | 86 + hgext/remotefilelog/constants.py | 41 + hgext/remotefilelog/contentstore.py | 395 + hgext/remotefilelog/datapack.py | 473 + hgext/remotefilelog/debugcommands.py | 480 + hgext/remotefilelog/fileserverclient.py | 670 + hgext/remotefilelog/historypack.py | 572 + hgext/remotefilelog/metadatastore.py | 165 + hgext/remotefilelog/remotefilectx.py | 527 + hgext/remotefilelog/remotefilelog.py | 473 + hgext/remotefilelog/remotefilelogserver.py | 446 + hgext/remotefilelog/repack.py | 906 + hgext/remotefilelog/shallowbundle.py | 337 + hgext/remotefilelog/shallowrepo.py | 349 + hgext/remotefilelog/shallowstore.py | 17 + hgext/remotefilelog/shallowutil.py | 540 + hgext/remotefilelog/shallowverifier.py | 18 + hgext/remotenames.py | 437 + hgext/schemes.py | 175 + hgext/share.py | 231 + hgext/show.py | 529 + hgext/sparse.py | 389 + hgext/split.py | 202 + hgext/sqlitestore.py | 1348 + hgext/strip.py | 21 + hgext/transplant.py | 929 + hgext/uncommit.py | 323 + hgext/win32mbcs.py | 221 + hgext/win32text.py | 248 + hgext/zeroconf/Zeroconf.py | 1890 + hgext/zeroconf/__init__.py | 242 + hgext3rd/__init__.py | 4 + hgweb.cgi | 19 + i18n/check-translation.py | 270 + i18n/da.po | 18328 +++++++ i18n/de.po | 24246 +++++++++ i18n/el.po | 9665 ++++ i18n/fr.po | 11432 +++++ i18n/hggettext | 170 + i18n/it.po | 14231 ++++++ i18n/ja.po | 39911 +++++++++++++++ i18n/polib.LICENSE | 19 + i18n/polib.py | 1954 + i18n/posplit | 93 + i18n/pt_BR.po | 42639 ++++++++++++++++ i18n/ro.po | 16116 ++++++ i18n/ru.po | 28705 +++++++++++ i18n/sv.po | 20115 ++++++++ i18n/zh_CN.po | 10448 ++++ i18n/zh_TW.po | 12929 +++++ mercurial.egg-info/PKG-INFO | 29 + mercurial.egg-info/SOURCES.txt | 2318 + mercurial.egg-info/dependency_links.txt | 1 + mercurial.egg-info/top_level.txt | 4 + mercurial/__init__.py | 12 + mercurial/__main__.py | 12 + mercurial/__version__.py | 2 + mercurial/admin/__init__.py | 0 mercurial/admin/chainsaw.py | 226 + mercurial/admin/verify.py | 341 + mercurial/admin_commands.py | 50 + mercurial/ancestor.py | 393 + mercurial/archival.py | 367 + mercurial/bdiff.c | 345 + mercurial/bdiff.h | 23 + mercurial/bitmanipulation.h | 77 + mercurial/bookmarks.py | 1119 + mercurial/branchmap.py | 931 + mercurial/bundle2.py | 2670 + mercurial/bundlecaches.py | 562 + mercurial/bundlerepo.py | 758 + mercurial/cacheutil.py | 21 + mercurial/cext/__init__.py | 0 mercurial/cext/base85.c | 192 + mercurial/cext/base85.pyi | 6 + mercurial/cext/bdiff.c | 348 + mercurial/cext/bdiff.pyi | 12 + mercurial/cext/charencode.c | 404 + mercurial/cext/charencode.h | 61 + mercurial/cext/dirs.c | 326 + mercurial/cext/manifest.c | 999 + mercurial/cext/mpatch.c | 203 + mercurial/cext/mpatch.pyi | 10 + mercurial/cext/osutil.c | 1262 + mercurial/cext/osutil.pyi | 26 + mercurial/cext/parsers.c | 1261 + mercurial/cext/parsers.pyi | 82 + mercurial/cext/pathencode.c | 802 + mercurial/cext/py.typed | 1 + mercurial/cext/revlog.c | 3497 ++ mercurial/cext/revlog.h | 17 + mercurial/cext/util.h | 81 + mercurial/cffi/__init__.py | 0 mercurial/cffi/bdiff.py | 88 + mercurial/cffi/bdiffbuild.py | 34 + mercurial/cffi/mpatch.py | 50 + mercurial/cffi/mpatchbuild.py | 38 + mercurial/cffi/osutil.py | 114 + mercurial/cffi/osutilbuild.py | 106 + mercurial/changegroup.py | 2441 + mercurial/changelog.py | 507 + mercurial/chgserver.py | 761 + mercurial/cmdutil.py | 4137 ++ mercurial/color.py | 566 + mercurial/commands.py | 8104 +++ mercurial/commandserver.py | 738 + mercurial/commit.py | 551 + mercurial/compat.h | 58 + mercurial/config.py | 261 + mercurial/configitems.py | 214 + mercurial/configitems.toml | 2947 ++ mercurial/context.py | 3145 ++ mercurial/copies.py | 1307 + mercurial/crecord.py | 2131 + mercurial/dagop.py | 1141 + mercurial/dagparser.py | 515 + mercurial/debugcommands.py | 4775 ++ mercurial/defaultrc/__init__.py | 0 mercurial/defaultrc/mergetools.rc | 168 + mercurial/destutil.py | 495 + mercurial/diffhelper.py | 81 + mercurial/diffutil.py | 190 + mercurial/dirstate.py | 1825 + mercurial/dirstatemap.py | 849 + mercurial/dirstateutils/__init__.py | 0 mercurial/dirstateutils/docket.py | 70 + mercurial/dirstateutils/timestamp.py | 127 + mercurial/dirstateutils/v2.py | 421 + mercurial/discovery.py | 619 + mercurial/dispatch.py | 1388 + mercurial/dummycert.pem | 56 + mercurial/encoding.py | 718 + mercurial/error.py | 691 + mercurial/exchange.py | 2892 ++ mercurial/exewrapper.c | 169 + mercurial/extensions.py | 1007 + mercurial/exthelper.py | 338 + mercurial/fancyopts.py | 390 + mercurial/filelog.py | 313 + mercurial/filemerge.py | 1320 + mercurial/fileset.py | 617 + mercurial/filesetlang.py | 350 + mercurial/formatter.py | 870 + mercurial/graphmod.py | 515 + mercurial/grep.py | 221 + mercurial/hbisect.py | 338 + mercurial/help.py | 1230 + mercurial/helptext/__init__.py | 0 mercurial/helptext/bundlespec.txt | 121 + mercurial/helptext/color.txt | 150 + mercurial/helptext/common.txt | 8 + mercurial/helptext/config.txt | 3463 ++ mercurial/helptext/dates.txt | 39 + mercurial/helptext/deprecated.txt | 30 + mercurial/helptext/diffs.txt | 29 + mercurial/helptext/environment.txt | 124 + mercurial/helptext/evolution.txt | 56 + mercurial/helptext/extensions.txt | 35 + mercurial/helptext/filesets.txt | 79 + mercurial/helptext/flags.txt | 106 + mercurial/helptext/glossary.txt | 413 + mercurial/helptext/hg-ssh.8.txt | 71 + mercurial/helptext/hg.1.txt | 119 + mercurial/helptext/hgignore.5.txt | 34 + mercurial/helptext/hgignore.txt | 103 + mercurial/helptext/hgrc.5.txt | 41 + mercurial/helptext/hgweb.txt | 86 + mercurial/helptext/internals/__init__.py | 0 mercurial/helptext/internals/bid-merge.txt | 115 + mercurial/helptext/internals/bundle2.txt | 677 + mercurial/helptext/internals/bundles.txt | 93 + mercurial/helptext/internals/cbor.txt | 130 + mercurial/helptext/internals/censor.txt | 22 + mercurial/helptext/internals/changegroups.txt | 229 + mercurial/helptext/internals/config.txt | 109 + mercurial/helptext/internals/dirstate-v2.txt | 624 + mercurial/helptext/internals/extensions.txt | 377 + mercurial/helptext/internals/linelog.txt | 302 + mercurial/helptext/internals/mergestate.txt | 68 + mercurial/helptext/internals/requirements.txt | 172 + mercurial/helptext/internals/revlogs.txt | 313 + mercurial/helptext/internals/wireprotocol.txt | 1163 + .../helptext/internals/wireprotocolrpc.txt | 740 + .../helptext/internals/wireprotocolv2.txt | 724 + mercurial/helptext/merge-tools.txt | 109 + mercurial/helptext/pager.txt | 43 + mercurial/helptext/patterns.txt | 93 + mercurial/helptext/phases.txt | 100 + mercurial/helptext/revisions.txt | 223 + mercurial/helptext/rust.txt | 99 + mercurial/helptext/scripting.txt | 210 + mercurial/helptext/subrepos.txt | 171 + mercurial/helptext/templates.txt | 215 + mercurial/helptext/urls.txt | 76 + mercurial/hg.py | 1680 + mercurial/hgweb/__init__.py | 126 + mercurial/hgweb/common.py | 306 + mercurial/hgweb/hgweb_mod.py | 525 + mercurial/hgweb/hgwebdir_mod.py | 593 + mercurial/hgweb/request.py | 628 + mercurial/hgweb/server.py | 423 + mercurial/hgweb/webcommands.py | 1597 + mercurial/hgweb/webutil.py | 942 + mercurial/hgweb/wsgicgi.py | 93 + mercurial/hgweb/wsgiheaders.py | 184 + mercurial/hook.py | 370 + mercurial/httpconnection.py | 138 + mercurial/httppeer.py | 670 + mercurial/i18n.py | 124 + mercurial/interfaces/__init__.py | 0 mercurial/interfaces/dirstate.py | 219 + mercurial/interfaces/repository.py | 2072 + mercurial/interfaces/util.py | 37 + mercurial/keepalive.py | 857 + mercurial/linelog.py | 466 + mercurial/localrepo.py | 4038 ++ mercurial/lock.py | 408 + mercurial/logcmdutil.py | 1328 + mercurial/logexchange.py | 167 + mercurial/loggingutil.py | 142 + mercurial/lsprof.py | 135 + mercurial/lsprofcalltree.py | 95 + mercurial/mail.py | 533 + mercurial/manifest.py | 2381 + mercurial/match.py | 1703 + mercurial/mdiff.py | 555 + mercurial/merge.py | 2513 + mercurial/mergestate.py | 910 + mercurial/mergeutil.py | 18 + mercurial/metadata.py | 907 + mercurial/minifileset.py | 101 + mercurial/minirst.py | 899 + mercurial/mpatch.c | 393 + mercurial/mpatch.h | 26 + mercurial/namespaces.py | 242 + mercurial/narrowspec.py | 392 + mercurial/node.py | 60 + mercurial/obsolete.py | 1155 + mercurial/obsutil.py | 1047 + mercurial/parser.py | 745 + mercurial/patch.py | 3256 ++ mercurial/pathutil.py | 387 + mercurial/phases.py | 1223 + mercurial/policy.py | 151 + mercurial/posix.py | 809 + mercurial/profiling.py | 288 + mercurial/progress.py | 295 + mercurial/pure/__init__.py | 0 mercurial/pure/base85.py | 87 + mercurial/pure/bdiff.py | 108 + mercurial/pure/charencode.py | 86 + mercurial/pure/mpatch.py | 143 + mercurial/pure/osutil.py | 206 + mercurial/pure/parsers.py | 979 + mercurial/pushkey.py | 70 + mercurial/pvec.py | 226 + mercurial/pycompat.py | 495 + mercurial/pythoncapi_compat.h | 283 + mercurial/rcutil.py | 118 + mercurial/registrar.py | 563 + mercurial/repair.py | 571 + mercurial/repocache.py | 139 + mercurial/repoview.py | 486 + mercurial/requirements.py | 125 + mercurial/revlog.py | 4078 ++ mercurial/revlogutils/__init__.py | 82 + mercurial/revlogutils/concurrency_checker.py | 38 + mercurial/revlogutils/constants.py | 318 + mercurial/revlogutils/debug.py | 943 + mercurial/revlogutils/deltas.py | 1884 + mercurial/revlogutils/docket.py | 430 + mercurial/revlogutils/flagutil.py | 198 + mercurial/revlogutils/nodemap.py | 670 + mercurial/revlogutils/randomaccessfile.py | 234 + mercurial/revlogutils/revlogv0.py | 139 + mercurial/revlogutils/rewrite.py | 884 + mercurial/revlogutils/sidedata.py | 174 + mercurial/revset.py | 2874 ++ mercurial/revsetlang.py | 940 + mercurial/rewriteutil.py | 271 + mercurial/scmposix.py | 103 + mercurial/scmutil.py | 2358 + mercurial/scmwindows.py | 117 + mercurial/server.py | 237 + mercurial/setdiscovery.py | 526 + mercurial/shelve.py | 1247 + mercurial/similar.py | 131 + mercurial/simplemerge.py | 533 + mercurial/smartset.py | 1141 + mercurial/sparse.py | 856 + mercurial/sshpeer.py | 709 + mercurial/sslutil.py | 924 + mercurial/stabletailgraph/__init__.py | 0 mercurial/stabletailgraph/stabletailsort.py | 172 + mercurial/stack.py | 22 + mercurial/state.py | 383 + mercurial/statichttprepo.py | 271 + mercurial/statprof.py | 1097 + mercurial/store.py | 1220 + mercurial/streamclone.py | 1172 + mercurial/strip.py | 280 + mercurial/subrepo.py | 2124 + mercurial/subrepoutil.py | 544 + mercurial/tagmerge.py | 272 + mercurial/tags.py | 936 + mercurial/templatefilters.py | 559 + mercurial/templatefuncs.py | 920 + mercurial/templatekw.py | 1031 + mercurial/templater.py | 1163 + mercurial/templates/__init__.py | 0 mercurial/templates/atom/__init__.py | 0 mercurial/templates/atom/bookmarkentry.tmpl | 8 + mercurial/templates/atom/bookmarks.tmpl | 11 + mercurial/templates/atom/branchentry.tmpl | 8 + mercurial/templates/atom/branches.tmpl | 11 + mercurial/templates/atom/changelog.tmpl | 10 + mercurial/templates/atom/changelogentry.tmpl | 43 + mercurial/templates/atom/error.tmpl | 17 + mercurial/templates/atom/filelog.tmpl | 8 + mercurial/templates/atom/header.tmpl | 2 + mercurial/templates/atom/map | 18 + mercurial/templates/atom/tagentry.tmpl | 8 + mercurial/templates/atom/tags.tmpl | 11 + mercurial/templates/coal/__init__.py | 0 mercurial/templates/coal/header.tmpl | 8 + mercurial/templates/coal/map | 2 + mercurial/templates/gitweb/__init__.py | 0 mercurial/templates/gitweb/bookmarks.tmpl | 35 + mercurial/templates/gitweb/branches.tmpl | 35 + mercurial/templates/gitweb/changelog.tmpl | 38 + .../templates/gitweb/changelogentry.tmpl | 16 + mercurial/templates/gitweb/changeset.tmpl | 62 + mercurial/templates/gitweb/error.tmpl | 37 + mercurial/templates/gitweb/fileannotate.tmpl | 85 + .../templates/gitweb/filecomparison.tmpl | 75 + mercurial/templates/gitweb/filediff.tmpl | 56 + mercurial/templates/gitweb/filelog.tmpl | 52 + mercurial/templates/gitweb/filerevision.tmpl | 77 + mercurial/templates/gitweb/footer.tmpl | 11 + mercurial/templates/gitweb/graph.tmpl | 70 + mercurial/templates/gitweb/graphentry.tmpl | 9 + mercurial/templates/gitweb/header.tmpl | 8 + mercurial/templates/gitweb/help.tmpl | 36 + mercurial/templates/gitweb/helptopics.tmpl | 50 + mercurial/templates/gitweb/index.tmpl | 26 + mercurial/templates/gitweb/manifest.tmpl | 38 + mercurial/templates/gitweb/map | 383 + mercurial/templates/gitweb/notfound.tmpl | 18 + mercurial/templates/gitweb/search.tmpl | 35 + mercurial/templates/gitweb/shortlog.tmpl | 55 + mercurial/templates/gitweb/summary.tmpl | 62 + mercurial/templates/gitweb/tags.tmpl | 35 + mercurial/templates/json/__init__.py | 0 mercurial/templates/json/changelist.tmpl | 5 + mercurial/templates/json/graph.tmpl | 5 + mercurial/templates/json/map | 252 + mercurial/templates/map-cmdline.bisect | 15 + mercurial/templates/map-cmdline.changelog | 18 + mercurial/templates/map-cmdline.compact | 31 + mercurial/templates/map-cmdline.default | 91 + mercurial/templates/map-cmdline.phases | 5 + mercurial/templates/map-cmdline.show | 25 + mercurial/templates/map-cmdline.status | 21 + mercurial/templates/map-cmdline.xml | 21 + mercurial/templates/monoblue/__init__.py | 0 mercurial/templates/monoblue/bookmarks.tmpl | 32 + mercurial/templates/monoblue/branches.tmpl | 32 + mercurial/templates/monoblue/changelog.tmpl | 37 + .../templates/monoblue/changelogentry.tmpl | 11 + mercurial/templates/monoblue/changeset.tmpl | 67 + mercurial/templates/monoblue/error.tmpl | 30 + .../templates/monoblue/fileannotate.tmpl | 61 + .../templates/monoblue/filecomparison.tmpl | 67 + mercurial/templates/monoblue/filediff.tmpl | 52 + mercurial/templates/monoblue/filelog.tmpl | 46 + .../templates/monoblue/filerevision.tmpl | 61 + mercurial/templates/monoblue/footer.tmpl | 17 + mercurial/templates/monoblue/graph.tmpl | 65 + mercurial/templates/monoblue/graphentry.tmpl | 9 + mercurial/templates/monoblue/header.tmpl | 7 + mercurial/templates/monoblue/help.tmpl | 32 + mercurial/templates/monoblue/helptopics.tmpl | 46 + mercurial/templates/monoblue/index.tmpl | 34 + mercurial/templates/monoblue/manifest.tmpl | 41 + mercurial/templates/monoblue/map | 318 + mercurial/templates/monoblue/notfound.tmpl | 32 + mercurial/templates/monoblue/search.tmpl | 31 + mercurial/templates/monoblue/shortlog.tmpl | 53 + mercurial/templates/monoblue/summary.tmpl | 71 + mercurial/templates/monoblue/tags.tmpl | 32 + mercurial/templates/paper/__init__.py | 0 mercurial/templates/paper/bookmarks.tmpl | 53 + mercurial/templates/paper/branches.tmpl | 53 + mercurial/templates/paper/changeset.tmpl | 95 + mercurial/templates/paper/diffstat.tmpl | 8 + mercurial/templates/paper/error.tmpl | 42 + mercurial/templates/paper/fileannotate.tmpl | 95 + mercurial/templates/paper/filecomparison.tmpl | 90 + mercurial/templates/paper/filediff.tmpl | 77 + mercurial/templates/paper/filelog.tmpl | 83 + mercurial/templates/paper/filelogentry.tmpl | 9 + mercurial/templates/paper/filerevision.tmpl | 83 + mercurial/templates/paper/footer.tmpl | 4 + mercurial/templates/paper/graph.tmpl | 89 + mercurial/templates/paper/graphentry.tmpl | 9 + mercurial/templates/paper/header.tmpl | 7 + mercurial/templates/paper/help.tmpl | 34 + mercurial/templates/paper/helptopics.tmpl | 48 + mercurial/templates/paper/index.tmpl | 31 + mercurial/templates/paper/manifest.tmpl | 56 + mercurial/templates/paper/map | 292 + mercurial/templates/paper/notfound.tmpl | 12 + mercurial/templates/paper/search.tmpl | 64 + mercurial/templates/paper/shortlog.tmpl | 89 + mercurial/templates/paper/shortlogentry.tmpl | 8 + mercurial/templates/paper/tags.tmpl | 53 + mercurial/templates/raw/__init__.py | 0 mercurial/templates/raw/changelog.tmpl | 5 + mercurial/templates/raw/changeset.tmpl | 9 + mercurial/templates/raw/error.tmpl | 2 + mercurial/templates/raw/fileannotate.tmpl | 5 + mercurial/templates/raw/filediff.tmpl | 5 + mercurial/templates/raw/graph.tmpl | 6 + mercurial/templates/raw/graphedge.tmpl | 1 + mercurial/templates/raw/graphnode.tmpl | 7 + mercurial/templates/raw/index.tmpl | 2 + mercurial/templates/raw/logentry.tmpl | 6 + mercurial/templates/raw/manifest.tmpl | 3 + mercurial/templates/raw/map | 41 + mercurial/templates/raw/notfound.tmpl | 2 + mercurial/templates/raw/search.tmpl | 7 + mercurial/templates/rss/__init__.py | 0 mercurial/templates/rss/bookmarkentry.tmpl | 6 + mercurial/templates/rss/bookmarks.tmpl | 6 + mercurial/templates/rss/branchentry.tmpl | 6 + mercurial/templates/rss/branches.tmpl | 6 + mercurial/templates/rss/changelog.tmpl | 6 + mercurial/templates/rss/changelogentry.tmpl | 41 + mercurial/templates/rss/error.tmpl | 10 + mercurial/templates/rss/filelog.tmpl | 6 + mercurial/templates/rss/filelogentry.tmpl | 7 + mercurial/templates/rss/header.tmpl | 5 + mercurial/templates/rss/map | 18 + mercurial/templates/rss/tagentry.tmpl | 6 + mercurial/templates/rss/tags.tmpl | 6 + mercurial/templates/spartan/__init__.py | 0 mercurial/templates/spartan/branches.tmpl | 27 + mercurial/templates/spartan/changelog.tmpl | 44 + .../templates/spartan/changelogentry.tmpl | 31 + mercurial/templates/spartan/changeset.tmpl | 58 + mercurial/templates/spartan/error.tmpl | 15 + mercurial/templates/spartan/fileannotate.tmpl | 51 + mercurial/templates/spartan/filediff.tmpl | 37 + mercurial/templates/spartan/filelog.tmpl | 29 + mercurial/templates/spartan/filelogentry.tmpl | 25 + mercurial/templates/spartan/filerevision.tmpl | 51 + mercurial/templates/spartan/footer.tmpl | 8 + mercurial/templates/spartan/graph.tmpl | 53 + mercurial/templates/spartan/graphentry.tmpl | 8 + mercurial/templates/spartan/header.tmpl | 7 + mercurial/templates/spartan/index.tmpl | 19 + mercurial/templates/spartan/manifest.tmpl | 24 + mercurial/templates/spartan/map | 227 + mercurial/templates/spartan/notfound.tmpl | 12 + mercurial/templates/spartan/search.tmpl | 37 + mercurial/templates/spartan/shortlog.tmpl | 44 + .../templates/spartan/shortlogentry.tmpl | 7 + mercurial/templates/spartan/tags.tmpl | 27 + mercurial/templates/static/__init__.py | 0 mercurial/templates/static/background.png | Bin 0 -> 603 bytes mercurial/templates/static/coal-file.png | Bin 0 -> 273 bytes mercurial/templates/static/coal-folder.png | Bin 0 -> 284 bytes .../templates/static/feed-icon-14x14.png | Bin 0 -> 689 bytes mercurial/templates/static/followlines.js | 286 + mercurial/templates/static/hgicon.png | Bin 0 -> 792 bytes mercurial/templates/static/hglogo.png | Bin 0 -> 4123 bytes mercurial/templates/static/mercurial.js | 580 + .../templates/static/style-extra-coal.css | 46 + mercurial/templates/static/style-gitweb.css | 389 + mercurial/templates/static/style-monoblue.css | 588 + mercurial/templates/static/style-paper.css | 548 + mercurial/templates/static/style.css | 117 + mercurial/templateutil.py | 1165 + mercurial/testing/__init__.py | 53 + mercurial/testing/revlog.py | 62 + mercurial/testing/storage.py | 1453 + mercurial/thirdparty/__init__.py | 0 mercurial/thirdparty/attr/LICENSE | 21 + mercurial/thirdparty/attr/__init__.py | 79 + mercurial/thirdparty/attr/__init__.pyi | 486 + mercurial/thirdparty/attr/_cmp.py | 155 + mercurial/thirdparty/attr/_cmp.pyi | 13 + mercurial/thirdparty/attr/_compat.py | 185 + mercurial/thirdparty/attr/_config.py | 31 + mercurial/thirdparty/attr/_funcs.py | 420 + mercurial/thirdparty/attr/_make.py | 3006 ++ mercurial/thirdparty/attr/_next_gen.py | 220 + mercurial/thirdparty/attr/_version_info.py | 86 + mercurial/thirdparty/attr/_version_info.pyi | 9 + mercurial/thirdparty/attr/converters.py | 144 + mercurial/thirdparty/attr/converters.pyi | 13 + mercurial/thirdparty/attr/exceptions.py | 92 + mercurial/thirdparty/attr/exceptions.pyi | 17 + mercurial/thirdparty/attr/filters.py | 51 + mercurial/thirdparty/attr/filters.pyi | 6 + mercurial/thirdparty/attr/py.typed | 0 mercurial/thirdparty/attr/setters.py | 73 + mercurial/thirdparty/attr/setters.pyi | 19 + mercurial/thirdparty/attr/validators.py | 594 + mercurial/thirdparty/attr/validators.pyi | 80 + mercurial/thirdparty/cbor/.travis.yml | 58 + mercurial/thirdparty/cbor/LICENSE.txt | 19 + mercurial/thirdparty/cbor/README.rst | 24 + mercurial/thirdparty/cbor/__init__.py | 10 + mercurial/thirdparty/cbor/cbor2/__init__.py | 3 + mercurial/thirdparty/cbor/cbor2/compat.py | 101 + mercurial/thirdparty/cbor/cbor2/decoder.py | 407 + mercurial/thirdparty/cbor/cbor2/encoder.py | 425 + mercurial/thirdparty/cbor/cbor2/types.py | 55 + mercurial/thirdparty/sha1dc/LICENSE.txt | 30 + mercurial/thirdparty/sha1dc/README.md | 145 + mercurial/thirdparty/sha1dc/cext.c | 212 + mercurial/thirdparty/sha1dc/lib/sha1.c | 1915 + mercurial/thirdparty/sha1dc/lib/sha1.h | 117 + mercurial/thirdparty/sha1dc/lib/ubc_check.c | 374 + mercurial/thirdparty/sha1dc/lib/ubc_check.h | 57 + mercurial/thirdparty/tomli/LICENSE | 21 + mercurial/thirdparty/tomli/README.md | 182 + mercurial/thirdparty/tomli/__init__.py | 9 + mercurial/thirdparty/tomli/_parser.py | 663 + mercurial/thirdparty/tomli/_re.py | 101 + mercurial/thirdparty/tomli/_types.py | 6 + mercurial/thirdparty/tomli/py.typed | 1 + mercurial/thirdparty/xdiff/xdiff.h | 91 + mercurial/thirdparty/xdiff/xdiffi.c | 1130 + mercurial/thirdparty/xdiff/xdiffi.h | 58 + mercurial/thirdparty/xdiff/xinclude.h | 40 + mercurial/thirdparty/xdiff/xmacros.h | 54 + mercurial/thirdparty/xdiff/xprepare.c | 552 + mercurial/thirdparty/xdiff/xprepare.h | 34 + mercurial/thirdparty/xdiff/xtypes.h | 105 + mercurial/thirdparty/xdiff/xutils.c | 150 + mercurial/thirdparty/xdiff/xutils.h | 39 + mercurial/thirdparty/zope/__init__.py | 0 .../thirdparty/zope/interface/LICENSE.txt | 44 + .../thirdparty/zope/interface/__init__.py | 93 + .../thirdparty/zope/interface/_compat.py | 60 + .../thirdparty/zope/interface/_flatten.py | 38 + .../_zope_interface_coptimizations.c | 1727 + .../thirdparty/zope/interface/adapter.py | 714 + mercurial/thirdparty/zope/interface/advice.py | 207 + .../zope/interface/common/__init__.py | 2 + .../zope/interface/common/idatetime.py | 577 + .../zope/interface/common/interfaces.py | 105 + .../zope/interface/common/mapping.py | 128 + .../zope/interface/common/sequence.py | 163 + .../thirdparty/zope/interface/declarations.py | 926 + .../thirdparty/zope/interface/document.py | 122 + .../thirdparty/zope/interface/exceptions.py | 69 + .../thirdparty/zope/interface/interface.py | 686 + .../thirdparty/zope/interface/interfaces.py | 1297 + .../thirdparty/zope/interface/registry.py | 657 + mercurial/thirdparty/zope/interface/ro.py | 67 + mercurial/thirdparty/zope/interface/verify.py | 122 + mercurial/transaction.py | 971 + mercurial/treediscovery.py | 206 + mercurial/txnutil.py | 32 + mercurial/typelib.py | 28 + mercurial/ui.py | 2347 + mercurial/unionrepo.py | 344 + mercurial/upgrade.py | 422 + mercurial/upgrade_utils/__init__.py | 0 mercurial/upgrade_utils/actions.py | 1133 + mercurial/upgrade_utils/auto_upgrade.py | 254 + mercurial/upgrade_utils/engine.py | 648 + mercurial/url.py | 663 + mercurial/urllibcompat.py | 152 + mercurial/util.py | 3312 ++ mercurial/utils/__init__.py | 0 mercurial/utils/cborutil.py | 1072 + mercurial/utils/compression.py | 807 + mercurial/utils/dateutil.py | 401 + mercurial/utils/hashutil.py | 8 + mercurial/utils/memorytop.py | 44 + mercurial/utils/procutil.py | 799 + mercurial/utils/repoviewutil.py | 23 + mercurial/utils/resourceutil.py | 120 + mercurial/utils/storageutil.py | 647 + mercurial/utils/stringutil.py | 1002 + mercurial/utils/urlutil.py | 968 + mercurial/verify.py | 629 + mercurial/vfs.py | 819 + mercurial/win32.py | 771 + mercurial/windows.py | 757 + mercurial/wireprotoframing.py | 2088 + mercurial/wireprotoserver.py | 550 + mercurial/wireprototypes.py | 446 + mercurial/wireprotov1peer.py | 660 + mercurial/wireprotov1server.py | 803 + mercurial/worker.py | 446 + pyproject.toml | 17 + relnotes/5.1 | 90 + relnotes/5.2 | 30 + relnotes/5.3 | 35 + relnotes/5.4 | 93 + relnotes/5.5 | 80 + relnotes/5.6 | 44 + relnotes/5.7 | 73 + relnotes/5.8 | 68 + relnotes/5.9 | 90 + relnotes/6.0 | 102 + relnotes/6.1 | 124 + relnotes/6.2 | 92 + relnotes/6.3 | 178 + relnotes/6.4 | 220 + relnotes/6.5 | 124 + relnotes/6.6 | 86 + relnotes/6.7 | 87 + relnotes/next | 18 + rust/.cargo/config | 7 + rust/Cargo.lock | 1601 + rust/Cargo.toml | 4 + rust/README.rst | 162 + rust/chg/Cargo.lock | 482 + rust/chg/Cargo.toml | 22 + rust/chg/build.rs | 7 + rust/chg/src/attachio.rs | 68 + rust/chg/src/clientext.rs | 133 + rust/chg/src/lib.rs | 15 + rust/chg/src/locator.rs | 455 + rust/chg/src/main.rs | 88 + rust/chg/src/message.rs | 331 + rust/chg/src/procutil.rs | 104 + rust/chg/src/runcommand.rs | 66 + rust/chg/src/sendfds.c | 51 + rust/chg/src/sighandlers.c | 175 + rust/chg/src/uihandler.rs | 94 + rust/clippy.toml | 1 + rust/hg-core/Cargo.toml | 54 + rust/hg-core/examples/nodemap/index.rs | 90 + rust/hg-core/examples/nodemap/main.rs | 148 + rust/hg-core/src/ancestors.rs | 835 + rust/hg-core/src/checkexec.rs | 121 + rust/hg-core/src/config/config_items.rs | 725 + rust/hg-core/src/config/layer.rs | 349 + rust/hg-core/src/config/mod.rs | 810 + rust/hg-core/src/config/plain_info.rs | 79 + rust/hg-core/src/config/values.rs | 267 + rust/hg-core/src/copy_tracing.rs | 677 + rust/hg-core/src/copy_tracing/tests.rs | 165 + .../hg-core/src/copy_tracing/tests_support.rs | 202 + rust/hg-core/src/dagops.rs | 313 + rust/hg-core/src/dirstate.rs | 50 + rust/hg-core/src/dirstate/dirs_multiset.rs | 416 + rust/hg-core/src/dirstate/entry.rs | 722 + rust/hg-core/src/dirstate/parsers.rs | 150 + rust/hg-core/src/dirstate/status.rs | 149 + rust/hg-core/src/dirstate_tree.rs | 5 + .../hg-core/src/dirstate_tree/dirstate_map.rs | 1937 + rust/hg-core/src/dirstate_tree/on_disk.rs | 869 + rust/hg-core/src/dirstate_tree/owning.rs | 91 + .../src/dirstate_tree/path_with_basename.rs | 187 + rust/hg-core/src/dirstate_tree/status.rs | 1055 + rust/hg-core/src/discovery.rs | 711 + rust/hg-core/src/errors.rs | 220 + rust/hg-core/src/exit_codes.rs | 26 + rust/hg-core/src/filepatterns.rs | 874 + rust/hg-core/src/lib.rs | 144 + rust/hg-core/src/lock.rs | 188 + rust/hg-core/src/logging.rs | 101 + rust/hg-core/src/matchers.rs | 2122 + rust/hg-core/src/narrow.rs | 115 + rust/hg-core/src/operations/cat.rs | 115 + rust/hg-core/src/operations/debugdata.rs | 38 + .../src/operations/list_tracked_files.rs | 45 + rust/hg-core/src/operations/mod.rs | 12 + rust/hg-core/src/operations/status_rev_rev.rs | 89 + rust/hg-core/src/repo.rs | 820 + rust/hg-core/src/requirements.rs | 183 + rust/hg-core/src/revlog/changelog.rs | 744 + rust/hg-core/src/revlog/filelog.rs | 245 + rust/hg-core/src/revlog/index.rs | 2077 + rust/hg-core/src/revlog/manifest.rs | 213 + rust/hg-core/src/revlog/mod.rs | 1033 + rust/hg-core/src/revlog/node.rs | 433 + rust/hg-core/src/revlog/nodemap.rs | 1108 + rust/hg-core/src/revlog/nodemap_docket.rs | 108 + rust/hg-core/src/revlog/patch.rs | 369 + rust/hg-core/src/revlog/path_encode.rs | 639 + rust/hg-core/src/revset.rs | 71 + rust/hg-core/src/sparse.rs | 341 + rust/hg-core/src/testing.rs | 77 + rust/hg-core/src/utils.rs | 572 + rust/hg-core/src/utils/debug.rs | 87 + rust/hg-core/src/utils/files.rs | 436 + rust/hg-core/src/utils/hg_path.rs | 816 + rust/hg-core/src/utils/path_auditor.rs | 223 + rust/hg-core/src/vfs.rs | 205 + rust/hg-core/tests/test_missing_ancestors.rs | 340 + rust/hg-cpython/Cargo.toml | 19 + rust/hg-cpython/src/ancestors.rs | 414 + rust/hg-cpython/src/cindex.rs | 217 + rust/hg-cpython/src/conversion.rs | 57 + rust/hg-cpython/src/copy_tracing.rs | 200 + rust/hg-cpython/src/dagops.rs | 84 + rust/hg-cpython/src/debug.rs | 24 + rust/hg-cpython/src/dirstate.rs | 70 + rust/hg-cpython/src/dirstate/copymap.rs | 122 + rust/hg-cpython/src/dirstate/dirs_multiset.rs | 109 + rust/hg-cpython/src/dirstate/dirstate_map.rs | 556 + rust/hg-cpython/src/dirstate/item.rs | 251 + rust/hg-cpython/src/dirstate/status.rs | 307 + rust/hg-cpython/src/discovery.rs | 277 + rust/hg-cpython/src/exceptions.rs | 63 + rust/hg-cpython/src/lib.rs | 112 + rust/hg-cpython/src/pybytes_deref.rs | 57 + rust/hg-cpython/src/ref_sharing.rs | 121 + rust/hg-cpython/src/revlog.rs | 1239 + rust/hg-cpython/src/utils.rs | 43 + rust/hgcli/.cargo/config | 13 + rust/hgcli/Cargo.lock | 509 + rust/hgcli/Cargo.toml | 28 + rust/hgcli/README.md | 48 + rust/hgcli/build.rs | 18 + rust/hgcli/pyoxidizer.bzl | 343 + rust/hgcli/src/main.rs | 39 + rust/rhg/Cargo.toml | 25 + rust/rhg/README.md | 51 + rust/rhg/src/blackbox.rs | 177 + rust/rhg/src/color.rs | 250 + rust/rhg/src/commands/cat.rs | 116 + rust/rhg/src/commands/config.rs | 37 + rust/rhg/src/commands/debugdata.rs | 71 + rust/rhg/src/commands/debugignorerhg.rs | 39 + rust/rhg/src/commands/debugrequirements.rs | 22 + rust/rhg/src/commands/debugrhgsparse.rs | 49 + rust/rhg/src/commands/files.rs | 149 + rust/rhg/src/commands/root.rs | 28 + rust/rhg/src/commands/status.rs | 819 + rust/rhg/src/error.rs | 308 + rust/rhg/src/main.rs | 849 + rust/rhg/src/ui.rs | 307 + rust/rhg/src/utils/path_utils.rs | 55 + rustfmt.toml | 4 + setup.cfg | 4 + setup.py | 1835 + tests/.balto.toml | 13 + tests/README | 7 + tests/artifacts/PURPOSE | 9 + tests/artifacts/cache/big-file-churn.hg.md5 | 1 + .../scripts/generate-churning-bundle.py | 142 + tests/autodiff.py | 65 + tests/basic_test_result.py | 56 + tests/binfile.bin | Bin 0 -> 593 bytes tests/blackbox-readonly-dispatch.py | 41 + tests/blacklists/README | 14 + tests/blacklists/fsmonitor | 38 + tests/blacklists/linux-vfat | 27 + tests/blacklists/nix | 8 + tests/bruterebase.py | 68 + tests/bundles/darcs1.hg | Bin 0 -> 1314 bytes tests/bundles/hgweb+obs.hg | Bin 0 -> 10686 bytes tests/bundles/issue4041.hg | Bin 0 -> 2216 bytes tests/bundles/issue4438-r1.hg | Bin 0 -> 4151 bytes tests/bundles/issue4438-r2.hg | Bin 0 -> 3864 bytes tests/bundles/issue6528.hg-v1 | Bin 0 -> 2223 bytes tests/bundles/issue6528.hg-v2 | Bin 0 -> 2406 bytes tests/bundles/issue6528.tar | Bin 0 -> 61440 bytes tests/bundles/legacy-encoding.hg | Bin 0 -> 548 bytes tests/bundles/rebase-revset.hg | Bin 0 -> 1844 bytes tests/bundles/rebase.hg | Bin 0 -> 1663 bytes tests/bundles/rebase.sh | 44 + tests/bundles/remote.hg | Bin 0 -> 1768 bytes tests/bundles/remote.sh | 32 + tests/bundles/rename.sh | 30 + tests/bundles/renames.hg | Bin 0 -> 1600 bytes tests/bundles/tampered.hg | Bin 0 -> 1171 bytes tests/bundles/test-invalid-branch-name.hg | Bin 0 -> 847 bytes tests/bundles/test-keyword.hg | Bin 0 -> 302 bytes tests/bundles/test-manifest.hg | Bin 0 -> 596 bytes tests/bundles/test-merge-symlinks.hg | Bin 0 -> 947 bytes tests/bundles/test-no-symlinks.hg | Bin 0 -> 558 bytes .../test-revlog-diff-relative-to-nullrev.sh | 41 + .../test-revlog-diff-relative-to-nullrev.tar | Bin 0 -> 30720 bytes tests/bzr-definitions | 16 + tests/cgienv | 29 + tests/check-gendoc | 11 + tests/check-perf-code.py | 92 + tests/common-pattern.py | 221 + tests/crashgetbundler.py | 10 + tests/drawdag.py | 448 + tests/dumbhttp.py | 112 + tests/dummysmtpd.py | 154 + tests/dummyssh | 34 + tests/f | 226 + tests/failfilemerge.py | 16 + tests/fakedirstatewritetime.py | 99 + tests/fakemergerecord.py | 31 + tests/fakepatchtime.py | 58 + tests/filterpyflakes.py | 35 + tests/filtertraceback.py | 44 + tests/flagprocessorext.py | 160 + tests/fsmonitor-run-tests.py | 157 + tests/generate-working-copy-states.py | 98 + tests/get-with-headers.py | 131 + tests/gpg/pubring.gpg | Bin 0 -> 597 bytes tests/gpg/secring.gpg | Bin 0 -> 1248 bytes tests/gpg/trustdb.gpg | Bin 0 -> 1280 bytes tests/helper-runtests.sh | 7 + tests/helpers-testrepo.sh | 60 + tests/heredoctest.py | 27 + tests/hghave | 77 + tests/hghave.py | 1165 + tests/hgterm.ti | 27 + tests/hgweberror.py | 23 + tests/histedit-helpers.sh | 7 + tests/httpserverauth.py | 125 + tests/hypothesishelpers.py | 79 + tests/killdaemons.py | 132 + tests/list-tree.py | 24 + tests/lockdelay.py | 22 + tests/logexceptions.py | 75 + tests/ls-l.py | 39 + tests/md5sum.py | 38 + tests/missing-comment.hg | Bin 0 -> 1077 bytes tests/mockblackbox.py | 15 + tests/mockmakedate.py | 22 + tests/mocktime.py | 18 + tests/narrow-library.sh | 6 + tests/notcapable | 25 + tests/pdiff | 69 + tests/phabricator/accept-4564.json | 141 + tests/phabricator/accept-7913.json | 141 + tests/phabricator/phab-conduit.json | 73 + tests/phabricator/phabimport-multi-drev.json | 277 + tests/phabricator/phabimport-stack.json | 277 + tests/phabricator/phabread-4480.json | 209 + tests/phabricator/phabread-conduit-error.json | 73 + tests/phabricator/phabread-empty-drev.json | 73 + tests/phabricator/phabread-multi-drev.json | 345 + tests/phabricator/phabread-str-time.json | 209 + .../phabsend-add-parent-setup.json | 617 + tests/phabricator/phabsend-add-parent.json | 1093 + .../phabricator/phabsend-binary-renames.json | 3411 ++ tests/phabricator/phabsend-binary.json | 1909 + .../phabricator/phabsend-comment-created.json | 617 + .../phabricator/phabsend-comment-updated.json | 549 + tests/phabricator/phabsend-create-alpha.json | 617 + tests/phabricator/phabsend-create-public.json | 957 + .../phabricator/phabsend-fold-extend-end.json | 889 + .../phabsend-fold-extend-front.json | 960 + tests/phabricator/phabsend-fold-fold-end.json | 957 + .../phabricator/phabsend-fold-immutable.json | 617 + tests/phabricator/phabsend-fold-initial.json | 753 + .../phabricator/phabsend-fold-no-changes.json | 685 + .../phabricator/phabsend-fold-split-end.json | 1028 + tests/phabricator/phabsend-fold-updated.json | 824 + tests/phabricator/phabsend-hash-fixes.json | 1096 + .../phabsend-no-restack-orphan.json | 1229 + tests/phabricator/phabsend-skipped.json | 141 + .../phabsend-update-alpha-create-beta.json | 1028 + tests/phabricator/phabupdate-change-6876.json | 141 + tests/phabricator/phabupdate-revs.json | 218 + tests/printenv.py | 79 + tests/printrevset.py | 49 + tests/pullext.py | 55 + tests/readlink.py | 16 + tests/remotefilelog-getflogheads.py | 34 + tests/remotefilelog-library.sh | 73 + tests/revlog-formatv0.py | 73 + tests/revnamesext.py | 20 + tests/run-tests.py | 4082 ++ tests/seq.py | 33 + tests/sha256line.py | 14 + tests/silenttestrunner.py | 25 + tests/simplestorerepo.py | 744 + tests/sitecustomize.py | 16 + tests/sshprotoext.py | 103 + tests/sslcerts/README | 45 + tests/sslcerts/client-cert.pem | 17 + tests/sslcerts/client-key-decrypted.pem | 27 + tests/sslcerts/client-key.pem | 30 + tests/sslcerts/priv.pem | 27 + tests/sslcerts/pub-expired.pem | 20 + tests/sslcerts/pub-not-yet.pem | 20 + tests/sslcerts/pub-other.pem | 20 + tests/sslcerts/pub.pem | 20 + tests/svn-safe-append.py | 31 + tests/svn/branches.svndump | 416 + tests/svn/empty.svndump | 129 + tests/svn/encoding.svndump | 280 + tests/svn/move.svndump | 569 + tests/svn/replace.svndump | 367 + tests/svn/startrev.svndump | 240 + tests/svn/svndump-branches.sh | 73 + tests/svn/svndump-empty.sh | 47 + tests/svn/svndump-encoding.sh | 57 + tests/svn/svndump-move.sh | 83 + tests/svn/svndump-replace.sh | 81 + tests/svn/svndump-startrev.sh | 45 + tests/svn/svndump-tags.sh | 57 + tests/svn/tags.svndump | 364 + tests/svnurlof.py | 19 + tests/svnxml.py | 58 + tests/test-abort-checkin.t | 37 + tests/test-absorb-edit-lines.t | 61 + tests/test-absorb-filefixupstate.py | 232 + tests/test-absorb-phase.t | 30 + tests/test-absorb-rename.t | 387 + tests/test-absorb-strip.t | 46 + tests/test-absorb-unfinished.t | 30 + tests/test-absorb.t | 676 + tests/test-acl.t | 2445 + tests/test-add.t | 332 + tests/test-addremove-similar.t | 174 + tests/test-addremove.t | 100 + tests/test-admin-commands.py | 399 + tests/test-admin-commands.t | 49 + tests/test-alias.t | 723 + tests/test-amend-subrepo.t | 199 + tests/test-amend.t | 634 + tests/test-ancestor.py | 465 + tests/test-ancestor.py.out | 41 + tests/test-annotate.py | 135 + tests/test-annotate.t | 1264 + tests/test-arbitraryfilectx.t | 100 + tests/test-archive-symlinks.t | 42 + tests/test-archive.t | 628 + tests/test-atomictempfile.py | 127 + tests/test-audit-path.t | 241 + tests/test-audit-subrepo.t | 732 + tests/test-automv.t | 338 + tests/test-backout.t | 824 + tests/test-backwards-remove.t | 19 + tests/test-bad-extension.t | 154 + tests/test-bad-pull.t | 15 + tests/test-basic.t | 260 + tests/test-batching.py | 253 + tests/test-batching.py.out | 22 + tests/test-bdiff.py | 187 + tests/test-bheads.t | 370 + tests/test-bisect.t | 795 + tests/test-bisect2.t | 807 + tests/test-bisect3.t | 249 + tests/test-blackbox.t | 520 + tests/test-bookflow.t | 292 + tests/test-bookmarks-corner-case.t | 236 + tests/test-bookmarks-current.t | 249 + tests/test-bookmarks-merge.t | 153 + tests/test-bookmarks-pushpull.t | 1453 + tests/test-bookmarks-rebase.t | 106 + tests/test-bookmarks-strip.t | 65 + tests/test-bookmarks.t | 1253 + tests/test-branch-change.t | 434 + tests/test-branch-option.t | 130 + tests/test-branch-tag-confict.t | 65 + tests/test-branches.t | 1366 + tests/test-bugzilla.t | 108 + tests/test-bundle-phase-internal.t | 286 + tests/test-bundle-phases.t | 431 + tests/test-bundle-r.t | 281 + tests/test-bundle-type.t | 622 + tests/test-bundle-vs-outgoing.t | 143 + tests/test-bundle.t | 1118 + tests/test-bundle2-exchange.t | 1136 + tests/test-bundle2-format.t | 1236 + tests/test-bundle2-multiple-changegroups.t | 557 + tests/test-bundle2-pushback.t | 109 + tests/test-bundle2-remote-changegroup.t | 598 + tests/test-byteify-strings.t | 253 + tests/test-cache-abuse.t | 103 + tests/test-cappedreader.py | 90 + tests/test-casecollision-merge.t | 346 + tests/test-casecollision.t | 69 + tests/test-casefolding.t | 257 + tests/test-cat.t | 128 + tests/test-cbor.py | 1303 + tests/test-censor.t | 665 + tests/test-censor2.t | 25 + tests/test-chainsaw-update.t | 250 + tests/test-changelog-exec.t | 57 + tests/test-check-cargo-lock.t | 11 + tests/test-check-clang-format.t | 10 + tests/test-check-code.t | 97 + tests/test-check-commit.t | 27 + tests/test-check-config.t | 47 + tests/test-check-encoding.t | 26 + tests/test-check-execute.t | 24 + tests/test-check-format.t | 11 + tests/test-check-help.t | 30 + tests/test-check-interfaces.py | 264 + tests/test-check-interfaces.py.out | 2 + tests/test-check-jshint.t | 11 + tests/test-check-module-imports.t | 45 + tests/test-check-py3-compat.t | 23 + tests/test-check-pyflakes.t | 32 + tests/test-check-pylint.t | 23 + tests/test-check-rust-format.t | 11 + tests/test-check-shbang.t | 27 + tests/test-chg.t | 575 + tests/test-children.t | 139 + tests/test-churn.t | 216 + tests/test-clone-cgi.t | 37 + tests/test-clone-pull-corruption.t | 48 + tests/test-clone-r.t | 199 + tests/test-clone-stream-format.t | 362 + tests/test-clone-stream-revlog-split.t | 186 + tests/test-clone-stream.t | 1036 + tests/test-clone-update-order.t | 113 + tests/test-clone.t | 1316 + tests/test-clonebundles-autogen.t | 516 + tests/test-clonebundles.t | 869 + tests/test-close-head.t | 78 + tests/test-commandserver.t | 1175 + tests/test-commit-amend.t | 1331 + tests/test-commit-interactive-curses.t | 489 + tests/test-commit-interactive.t | 2021 + tests/test-commit-multiple.t | 132 + tests/test-commit-unresolved.t | 157 + tests/test-commit.t | 876 + tests/test-committer.t | 110 + tests/test-completion.t | 463 + tests/test-config-env.py | 58 + tests/test-config-env.py.out | 6 + tests/test-config-parselist.py | 52 + tests/test-config.t | 546 + tests/test-conflict.t | 423 + tests/test-confused-revert.t | 83 + tests/test-context-metadata.t | 50 + tests/test-context.py | 253 + tests/test-context.py.out | 50 + tests/test-contrib-check-code.t | 423 + tests/test-contrib-check-commit.t | 133 + tests/test-contrib-dumprevlog.t | 91 + tests/test-contrib-emacs.t | 8 + tests/test-contrib-perf.t | 484 + tests/test-contrib-pull-logger.t | 78 + tests/test-contrib-relnotes.t | 317 + tests/test-contrib-testparseutil.t | 192 + tests/test-contrib.t | 175 + tests/test-convert-authormap.t | 58 + tests/test-convert-baz.t | 162 + tests/test-convert-bzr-114.t | 39 + tests/test-convert-bzr-directories.t | 197 + tests/test-convert-bzr-ghosts.t | 40 + tests/test-convert-bzr-merges.t | 225 + tests/test-convert-bzr-treeroot.t | 37 + tests/test-convert-bzr.t | 287 + tests/test-convert-clonebranches.t | 88 + tests/test-convert-cvs-branch.t | 196 + tests/test-convert-cvs-detectmerge.t | 234 + tests/test-convert-cvs-synthetic.t | 224 + tests/test-convert-cvs.t | 659 + tests/test-convert-cvsnt-mergepoints.rlog | 42 + tests/test-convert-cvsnt-mergepoints.t | 207 + tests/test-convert-darcs.t | 108 + tests/test-convert-datesort.t | 211 + tests/test-convert-filemap.t | 816 + tests/test-convert-git.t | 1170 + tests/test-convert-hg-sink.t | 624 + tests/test-convert-hg-source.t | 222 + tests/test-convert-hg-startrev.t | 245 + tests/test-convert-hg-svn.t | 118 + tests/test-convert-identity.t | 41 + tests/test-convert-mtn.t | 399 + tests/test-convert-p4-filetypes.t | 755 + tests/test-convert-p4.t | 163 + tests/test-convert-splicemap.t | 241 + tests/test-convert-svn-branches.t | 128 + tests/test-convert-svn-encoding.t | 217 + tests/test-convert-svn-move.t | 241 + tests/test-convert-svn-sink.t | 634 + tests/test-convert-svn-source.t | 320 + tests/test-convert-svn-startrev.t | 88 + tests/test-convert-svn-tags.t | 65 + tests/test-convert-tagsbranch-topology.t | 104 + tests/test-convert-tla.t | 134 + tests/test-convert.t | 652 + tests/test-copies-chain-merge.t | 3846 ++ tests/test-copies-in-changeset.t | 488 + tests/test-copies-unrelated.t | 456 + tests/test-copies.t | 748 + tests/test-copy-move-merge.t | 255 + tests/test-copy.t | 411 + tests/test-copytrace-heuristics.t | 726 + tests/test-custom-filters.t | 68 + tests/test-debian-packages.t | 30 + tests/test-debug-rebuild-dirstate.t | 39 + tests/test-debug-revlog-stats.t | 75 + tests/test-debugbackupbundle.t | 39 + tests/test-debugbuilddag.t | 330 + tests/test-debugbundle.t | 85 + tests/test-debugcommands.t | 831 + tests/test-debugextensions.t | 115 + tests/test-debugindexdot.t | 43 + tests/test-debugrename.t | 19 + tests/test-default-push.t | 186 + tests/test-demandimport.py | 196 + tests/test-devel-warnings.t | 470 + tests/test-diff-antipatience.t | 91 + tests/test-diff-binary-file.t | 144 + tests/test-diff-change.t | 298 + tests/test-diff-color.t | 416 + tests/test-diff-copy-depth.t | 51 + tests/test-diff-hashes.t | 47 + tests/test-diff-ignore-whitespace.t | 518 + tests/test-diff-indent-heuristic.t | 340 + tests/test-diff-issue2761.t | 24 + tests/test-diff-newlines.t | 20 + tests/test-diff-reverse.t | 66 + tests/test-diff-subdir.t | 67 + tests/test-diff-unified.t | 481 + tests/test-diff-upgrade.t | 290 + tests/test-diffdir.t | 77 + tests/test-diffstat.t | 294 + tests/test-directaccess.t | 214 + tests/test-dirs.py | 25 + tests/test-dirstate-backup.t | 21 + tests/test-dirstate-race.t | 250 + tests/test-dirstate-race2.t | 89 + tests/test-dirstate-read-race.t | 408 + tests/test-dirstate-status-write-race.t | 460 + tests/test-dirstate-version-fallback.t | 51 + tests/test-dirstate.t | 474 + tests/test-dispatch.py | 41 + tests/test-dispatch.py.out | 23 + tests/test-dispatch.t | 221 + tests/test-docker-packaging.t | 31 + tests/test-doctest.py | 171 + tests/test-double-merge.t | 66 + tests/test-drawdag.t | 273 + tests/test-duplicateoptions.py | 49 + tests/test-editor-filename.t | 65 + tests/test-empty-dir.t | 23 + tests/test-empty-file.t | 47 + tests/test-empty-group.t | 131 + tests/test-empty-manifest-index.t | 27 + tests/test-empty.t | 50 + tests/test-encode.t | 73 + tests/test-encoding-align.t | 154 + tests/test-encoding-func.py | 81 + tests/test-encoding-textwrap.t | 261 + tests/test-encoding.t | 287 + tests/test-eol-add.t | 125 + tests/test-eol-clone.t | 122 + tests/test-eol-hook.t | 211 + tests/test-eol-patch.t | 400 + tests/test-eol-tag.t | 39 + tests/test-eol-update.t | 278 + tests/test-eol.t | 564 + tests/test-eolfilename.t | 80 + tests/test-excessive-merge.t | 96 + tests/test-exchange-multi-source.t | 787 + tests/test-exchange-obsmarkers-case-A1.t | 301 + tests/test-exchange-obsmarkers-case-A2.t | 127 + tests/test-exchange-obsmarkers-case-A3.t | 254 + tests/test-exchange-obsmarkers-case-A4.t | 132 + tests/test-exchange-obsmarkers-case-A5.t | 142 + tests/test-exchange-obsmarkers-case-A6.t | 156 + tests/test-exchange-obsmarkers-case-A7.t | 94 + tests/test-exchange-obsmarkers-case-B1.t | 104 + tests/test-exchange-obsmarkers-case-B2.t | 137 + tests/test-exchange-obsmarkers-case-B3.t | 116 + tests/test-exchange-obsmarkers-case-B4.t | 163 + tests/test-exchange-obsmarkers-case-B5.t | 155 + tests/test-exchange-obsmarkers-case-B6.t | 119 + tests/test-exchange-obsmarkers-case-B7.t | 100 + tests/test-exchange-obsmarkers-case-C1.t | 159 + tests/test-exchange-obsmarkers-case-C2.t | 182 + tests/test-exchange-obsmarkers-case-C3.t | 181 + tests/test-exchange-obsmarkers-case-C4.t | 133 + tests/test-exchange-obsmarkers-case-D1.t | 183 + tests/test-exchange-obsmarkers-case-D2.t | 115 + tests/test-exchange-obsmarkers-case-D3.t | 112 + tests/test-exchange-obsmarkers-case-D4.t | 146 + tests/test-execute-bit.t | 29 + tests/test-export.t | 405 + tests/test-extdata.t | 120 + tests/test-extdiff.t | 555 + tests/test-extension-timing.t | 102 + tests/test-extension.t | 1978 + tests/test-extensions-afterloaded.t | 113 + tests/test-extensions-wrapfunction.py | 77 + tests/test-extensions-wrapfunction.py.out | 21 + tests/test-extra-filelog-entry.t | 22 + tests/test-fastannotate-corrupt.t | 83 + tests/test-fastannotate-diffopts.t | 33 + tests/test-fastannotate-hg.t | 818 + tests/test-fastannotate-perfhack.t | 180 + tests/test-fastannotate-protocol.t | 207 + tests/test-fastannotate-renames.t | 168 + tests/test-fastannotate-revmap.py | 221 + tests/test-fastannotate.t | 261 + tests/test-fastexport.t | 865 + tests/test-fetch.t | 442 + tests/test-filebranch.t | 140 + tests/test-filecache.py | 282 + tests/test-filecache.py.out | 63 + tests/test-filelog.py | 64 + tests/test-filelog.py.out | 2 + tests/test-fileset-generated.t | 199 + tests/test-fileset.t | 1037 + tests/test-fix-clang-format.t | 34 + tests/test-fix-metadata.t | 95 + tests/test-fix-pickle.t | 45 + tests/test-fix-topology.t | 555 + tests/test-fix.t | 1855 + tests/test-flagprocessor.t | 313 + tests/test-flags.t | 158 + tests/test-fncache.t | 538 + tests/test-fuzz-targets.t | 74 + tests/test-gendoc-da.t | 4 + tests/test-gendoc-de.t | 6 + tests/test-gendoc-el.t | 4 + tests/test-gendoc-fr.t | 4 + tests/test-gendoc-it.t | 4 + tests/test-gendoc-ja.t | 6 + tests/test-gendoc-pt_BR.t | 4 + tests/test-gendoc-ro.t | 9 + tests/test-gendoc-ru.t | 4 + tests/test-gendoc-sv.t | 4 + tests/test-gendoc-zh_CN.t | 4 + tests/test-gendoc-zh_TW.t | 4 + tests/test-gendoc.t | 32 + tests/test-generaldelta.t | 409 + tests/test-getbundle.t | 272 + tests/test-git-export.t | 616 + tests/test-git-interop.t | 438 + tests/test-githelp.t | 327 + tests/test-globalopts.t | 577 + tests/test-glog-beautifygraph.t | 3115 ++ tests/test-glog-topological.t | 154 + tests/test-glog.t | 3463 ++ tests/test-gpg.t | 74 + tests/test-graft-interrupted.t | 771 + tests/test-graft-rename.t | 724 + tests/test-graft.t | 923 + tests/test-grep.t | 1481 + tests/test-hardlinks.t | 469 + tests/test-hashutil.py | 79 + tests/test-help-hide.t | 269 + tests/test-help.t | 4118 ++ tests/test-hg-parseurl.py | 52 + tests/test-hghave.t | 47 + tests/test-hgignore.t | 546 + tests/test-hgk.t | 47 + tests/test-hgrc.t | 318 + tests/test-hgweb-annotate-whitespace.t | 788 + tests/test-hgweb-auth.py | 210 + tests/test-hgweb-auth.py.out | 217 + tests/test-hgweb-bundle.t | 37 + tests/test-hgweb-commands.t | 2440 + tests/test-hgweb-csp.t | 132 + tests/test-hgweb-descend-empties.t | 556 + tests/test-hgweb-diffs.t | 1205 + tests/test-hgweb-empty.t | 431 + tests/test-hgweb-filelog.t | 1847 + tests/test-hgweb-head.t | 102 + tests/test-hgweb-json.t | 2411 + tests/test-hgweb-no-path-info.t | 146 + tests/test-hgweb-no-request-uri.t | 176 + tests/test-hgweb-non-interactive.t | 95 + tests/test-hgweb-raw.t | 225 + tests/test-hgweb-removed.t | 247 + tests/test-hgweb-symrev.t | 1110 + tests/test-hgweb.t | 967 + tests/test-hgwebdir-gc.py | 47 + tests/test-hgwebdir-paths.py | 47 + tests/test-hgwebdir.t | 1792 + tests/test-hgwebdirsym.t | 80 + tests/test-highlight.t | 1042 + tests/test-histedit-arguments.t | 605 + tests/test-histedit-base.t | 258 + tests/test-histedit-bookmark-motion.t | 178 + tests/test-histedit-commute.t | 552 + tests/test-histedit-drop.t | 174 + tests/test-histedit-edit.t | 559 + tests/test-histedit-fold-non-commute.t | 342 + tests/test-histedit-fold.t | 706 + tests/test-histedit-merge-tools.t | 83 + tests/test-histedit-no-backup.t | 80 + tests/test-histedit-no-change.t | 218 + tests/test-histedit-non-commute-abort.t | 174 + tests/test-histedit-non-commute.t | 306 + tests/test-histedit-obsolete.t | 591 + tests/test-histedit-outgoing.t | 156 + tests/test-histedit-templates.t | 54 + tests/test-hook.t | 1467 + tests/test-hooklib-changeset_obsoleted.t | 114 + tests/test-hooklib-changeset_published.t | 84 + tests/test-hooklib-enforce_draft_commits.t | 45 + tests/test-hooklib-reject_merge_commits.t | 78 + tests/test-hooklib-reject_new_heads.t | 53 + tests/test-http-bad-server.t | 952 + tests/test-http-branchmap.t | 95 + tests/test-http-bundle1.t | 408 + tests/test-http-clone-r.t | 157 + tests/test-http-permissions.t | 1498 + tests/test-http-protocol.t | 663 + tests/test-http-proxy.t | 122 + tests/test-http.t | 611 + tests/test-https.t | 557 + tests/test-hybridencode.py | 1432 + tests/test-i18n.t | 74 + tests/test-identify.t | 175 + tests/test-impexp-branch.t | 82 + tests/test-import-bypass.t | 385 + tests/test-import-context.t | 128 + tests/test-import-eol.t | 173 + tests/test-import-git.t | 851 + tests/test-import-merge.t | 162 + tests/test-import-unknown.t | 69 + tests/test-import.t | 2092 + tests/test-imports-checker.t | 145 + tests/test-incoming-outgoing.t | 543 + tests/test-inherit-mode.t | 186 + tests/test-init.t | 323 + tests/test-install.t | 240 + tests/test-issue1089.t | 27 + tests/test-issue1102.t | 31 + tests/test-issue1175.t | 92 + tests/test-issue1306.t | 99 + tests/test-issue1438.t | 24 + tests/test-issue1502.t | 43 + tests/test-issue1802.t | 70 + tests/test-issue1877.t | 47 + tests/test-issue1993.t | 48 + tests/test-issue2137.t | 56 + tests/test-issue3084.t | 405 + tests/test-issue4074.t | 29 + tests/test-issue522.t | 53 + tests/test-issue586.t | 95 + tests/test-issue5979.t | 34 + tests/test-issue612.t | 35 + tests/test-issue619.t | 37 + tests/test-issue6528.t | 611 + tests/test-issue660.t | 166 + tests/test-issue6642.t | 35 + tests/test-issue672.t | 100 + tests/test-issue842.t | 40 + tests/test-journal-exists.t | 57 + tests/test-journal-share.t | 161 + tests/test-journal.t | 318 + tests/test-keyword.t | 1471 + tests/test-known.t | 37 + tests/test-largefiles-cache.t | 263 + tests/test-largefiles-misc.t | 1316 + tests/test-largefiles-small-disk.t | 74 + tests/test-largefiles-update.t | 842 + tests/test-largefiles-wireproto.t | 415 + tests/test-largefiles.t | 1879 + tests/test-legacy-exit-code.t | 50 + tests/test-lfconvert.t | 413 + tests/test-lfs-bundle.t | 126 + tests/test-lfs-largefiles.t | 351 + tests/test-lfs-pointer.py | 42 + tests/test-lfs-pointer.py.out | 12 + tests/test-lfs-serve-access.t | 518 + tests/test-lfs-serve.t | 721 + tests/test-lfs-test-server.t | 949 + tests/test-lfs.t | 1248 + tests/test-linelog.py | 238 + tests/test-linerange.py | 241 + tests/test-locale.t | 2 + tests/test-locate.t | 191 + tests/test-lock-badness.t | 178 + tests/test-lock.py | 208 + tests/test-log-bookmark.t | 198 + tests/test-log-exthook.t | 62 + tests/test-log-linerange.t | 1154 + tests/test-log.t | 2979 ++ tests/test-logexchange.t | 531 + tests/test-logtoprocess.t | 122 + tests/test-lrucachedict.py | 365 + tests/test-mac-packages.t | 71 + tests/test-mactext.t | 36 + tests/test-mailmap.t | 72 + tests/test-manifest-merging.t | 37 + tests/test-manifest.py | 458 + tests/test-manifest.t | 368 + tests/test-match.py | 1007 + tests/test-mdiff.py | 22 + tests/test-merge-changedelete.t | 1150 + tests/test-merge-closedheads.t | 87 + tests/test-merge-combination-exec-bytes.t | 63 + tests/test-merge-combination-file-content.t | 88 + tests/test-merge-combination-misc.t | 47 + tests/test-merge-commit.t | 183 + tests/test-merge-criss-cross.t | 936 + tests/test-merge-default.t | 191 + tests/test-merge-exec.t | 433 + tests/test-merge-force.t | 845 + tests/test-merge-halt.t | 215 + tests/test-merge-internal-tools-pattern.t | 162 + tests/test-merge-local.t | 152 + tests/test-merge-no-file-change.t | 379 + tests/test-merge-partial-tool.t | 316 + tests/test-merge-remove.t | 117 + tests/test-merge-revert.t | 75 + tests/test-merge-revert2.t | 94 + tests/test-merge-subrepos.t | 149 + tests/test-merge-symlinks.t | 64 + tests/test-merge-tools.t | 2124 + tests/test-merge-types.t | 472 + tests/test-merge1.t | 424 + tests/test-merge10.t | 55 + tests/test-merge2.t | 57 + tests/test-merge4.t | 60 + tests/test-merge5.t | 37 + tests/test-merge6.t | 73 + tests/test-merge7.t | 147 + tests/test-merge8.t | 30 + tests/test-merge9.t | 94 + tests/test-minifileset.py | 40 + tests/test-minirst.py | 272 + tests/test-minirst.py.out | 837 + tests/test-missing-capability.t | 42 + tests/test-mq-eol.t | 215 + tests/test-mq-git.t | 269 + tests/test-mq-guards.t | 594 + tests/test-mq-header-date.t | 901 + tests/test-mq-header-from.t | 974 + tests/test-mq-merge.t | 176 + tests/test-mq-missingfiles.t | 198 + tests/test-mq-pull-from-bundle.t | 139 + tests/test-mq-qclone-http.t | 160 + tests/test-mq-qdelete.t | 197 + tests/test-mq-qdiff.t | 179 + tests/test-mq-qfold.t | 264 + tests/test-mq-qgoto.t | 93 + tests/test-mq-qimport-fail-cleanup.t | 42 + tests/test-mq-qimport.t | 358 + tests/test-mq-qnew.t | 322 + tests/test-mq-qpush-exact.t | 289 + tests/test-mq-qpush-fail.t | 471 + tests/test-mq-qqueue.t | 188 + tests/test-mq-qrefresh-interactive.t | 375 + tests/test-mq-qrefresh-replace-log-message.t | 328 + tests/test-mq-qrefresh.t | 552 + tests/test-mq-qrename.t | 125 + tests/test-mq-qsave.t | 16 + tests/test-mq-safety.t | 216 + tests/test-mq-subrepo-svn.t | 52 + tests/test-mq-subrepo.t | 616 + tests/test-mq-symlinks.t | 113 + tests/test-mq.t | 1620 + tests/test-mv-cp-st-diff.t | 1694 + tests/test-narrow-acl-excludes.t | 75 + tests/test-narrow-acl.t | 79 + tests/test-narrow-archive.t | 32 + tests/test-narrow-clone-no-ellipsis.t | 166 + tests/test-narrow-clone-non-narrow-server.t | 67 + tests/test-narrow-clone-nonlinear.t | 148 + tests/test-narrow-clone-stream.t | 106 + tests/test-narrow-clone.t | 311 + tests/test-narrow-commit.t | 111 + tests/test-narrow-copies.t | 74 + tests/test-narrow-debugcommands.t | 44 + tests/test-narrow-debugrebuilddirstate.t | 31 + tests/test-narrow-exchange-merges.t | 207 + tests/test-narrow-exchange.t | 220 + tests/test-narrow-expanddirstate.t | 165 + tests/test-narrow-merge-outside.t | 111 + tests/test-narrow-merge.t | 159 + tests/test-narrow-patch.t | 84 + tests/test-narrow-patterns.t | 461 + tests/test-narrow-pull.t | 154 + tests/test-narrow-rebase.t | 99 + tests/test-narrow-shallow-merges.t | 347 + tests/test-narrow-shallow.t | 118 + tests/test-narrow-share.t | 192 + tests/test-narrow-sparse.t | 98 + tests/test-narrow-strip.t | 174 + tests/test-narrow-trackedcmd.t | 231 + tests/test-narrow-update.t | 76 + tests/test-narrow-widen-no-ellipsis.t | 414 + tests/test-narrow-widen.t | 441 + tests/test-narrow.t | 560 + tests/test-nested-repo.t | 44 + tests/test-newbranch.t | 534 + tests/test-newcgi.t | 60 + tests/test-newercgi.t | 54 + tests/test-no-symlinks.t | 60 + tests/test-nointerrupt.t | 103 + tests/test-notify-changegroup.t | 219 + tests/test-notify.t | 871 + tests/test-obshistory.t | 572 + tests/test-obsmarker-template.t | 3193 ++ tests/test-obsmarkers-effectflag.t | 167 + tests/test-obsolete-bounds-checking.t | 24 + tests/test-obsolete-bundle-strip.t | 1533 + tests/test-obsolete-changeset-exchange.t | 176 + tests/test-obsolete-check-push.t | 236 + tests/test-obsolete-checkheads.t | 322 + tests/test-obsolete-distributed.t | 628 + tests/test-obsolete-divergent.t | 798 + tests/test-obsolete-tag-cache.t | 125 + tests/test-obsolete.t | 1847 + tests/test-oldcgi.t | 74 + tests/test-origbackup-conflict.t | 137 + tests/test-pager-legacy.t | 263 + tests/test-pager.t | 437 + tests/test-parents.t | 154 + tests/test-parse-date.t | 294 + tests/test-parseindex.t | 225 + tests/test-parseindex2.py | 329 + tests/test-patch-offset.t | 82 + tests/test-patch.t | 104 + tests/test-patchbomb-bookmark.t | 168 + tests/test-patchbomb-tls.t | 164 + tests/test-patchbomb.t | 3199 ++ tests/test-pathconflicts-basic.t | 106 + tests/test-pathconflicts-merge.t | 173 + tests/test-pathconflicts-update.t | 160 + tests/test-pathencode.py | 278 + tests/test-paths.t | 527 + tests/test-pending.t | 139 + tests/test-permissions.t | 76 + tests/test-persistent-nodemap-stream-clone.t | 288 + tests/test-persistent-nodemap.t | 1013 + tests/test-phabricator.t | 1011 + tests/test-phase-archived.t | 198 + tests/test-phases-exchange.t | 1844 + tests/test-phases.t | 1163 + tests/test-profile.t | 180 + tests/test-progress.t | 408 + tests/test-propertycache.py | 254 + tests/test-propertycache.py.out | 84 + tests/test-pull-branch.t | 227 + tests/test-pull-bundle.t | 213 + tests/test-pull-http.t | 88 + tests/test-pull-network.t | 117 + tests/test-pull-permission.t | 28 + tests/test-pull-pull-corruption.t | 70 + tests/test-pull-r.t | 194 + tests/test-pull-update.t | 270 + tests/test-pullling-to-general-delta.t | 199 + tests/test-purge-ignored-directory.t | 12 + tests/test-purge.t | 358 + tests/test-push-cgi.t | 93 + tests/test-push-checkheads-multibranches-E1.t | 91 + tests/test-push-checkheads-multibranches-E2.t | 105 + tests/test-push-checkheads-multibranches-E3.t | 94 + tests/test-push-checkheads-partial-C1.t | 85 + tests/test-push-checkheads-partial-C2.t | 86 + tests/test-push-checkheads-partial-C3.t | 85 + tests/test-push-checkheads-partial-C4.t | 86 + tests/test-push-checkheads-pruned-B1.t | 75 + tests/test-push-checkheads-pruned-B2.t | 92 + tests/test-push-checkheads-pruned-B3.t | 93 + tests/test-push-checkheads-pruned-B4.t | 93 + tests/test-push-checkheads-pruned-B5.t | 101 + tests/test-push-checkheads-pruned-B6.t | 83 + tests/test-push-checkheads-pruned-B7.t | 82 + tests/test-push-checkheads-pruned-B8.t | 109 + tests/test-push-checkheads-superceed-A1.t | 72 + tests/test-push-checkheads-superceed-A2.t | 94 + tests/test-push-checkheads-superceed-A3.t | 97 + tests/test-push-checkheads-superceed-A4.t | 77 + tests/test-push-checkheads-superceed-A5.t | 78 + tests/test-push-checkheads-superceed-A6.t | 105 + tests/test-push-checkheads-superceed-A7.t | 105 + tests/test-push-checkheads-superceed-A8.t | 84 + tests/test-push-checkheads-unpushed-D1.t | 79 + tests/test-push-checkheads-unpushed-D2.t | 99 + tests/test-push-checkheads-unpushed-D3.t | 116 + tests/test-push-checkheads-unpushed-D4.t | 129 + tests/test-push-checkheads-unpushed-D5.t | 115 + tests/test-push-checkheads-unpushed-D6.t | 86 + tests/test-push-checkheads-unpushed-D7.t | 103 + tests/test-push-http.t | 553 + tests/test-push-race.t | 1904 + tests/test-push-warn.t | 847 + tests/test-push.t | 344 + tests/test-pushvars.t | 69 + tests/test-qrecord.t | 474 + tests/test-racy-mutations.t | 125 + tests/test-rank.t | 223 + tests/test-rebase-abort.t | 510 + tests/test-rebase-backup.t | 150 + tests/test-rebase-base-flag.t | 384 + tests/test-rebase-bookmarks.t | 245 + tests/test-rebase-brute-force.t | 56 + tests/test-rebase-cache.t | 483 + tests/test-rebase-check-restore.t | 223 + tests/test-rebase-collapse.t | 776 + tests/test-rebase-conflicts.t | 498 + tests/test-rebase-dest.t | 464 + tests/test-rebase-detach.t | 317 + tests/test-rebase-dry-run.t | 97 + tests/test-rebase-empty-successor.t | 44 + tests/test-rebase-emptycommit.t | 217 + tests/test-rebase-inmemory.t | 1048 + tests/test-rebase-interruptions.t | 540 + tests/test-rebase-issue-noparam-single-rev.t | 130 + tests/test-rebase-legacy.t | 93 + tests/test-rebase-mq-skip.t | 196 + tests/test-rebase-mq.t | 360 + tests/test-rebase-named-branches.t | 543 + tests/test-rebase-newancestor.t | 385 + tests/test-rebase-obsolete.t | 746 + tests/test-rebase-obsolete2.t | 344 + tests/test-rebase-obsolete3.t | 669 + tests/test-rebase-obsolete4.t | 501 + tests/test-rebase-parameters.t | 531 + tests/test-rebase-partial.t | 125 + tests/test-rebase-pull.t | 460 + tests/test-rebase-rename.t | 401 + tests/test-rebase-scenario-global.t | 983 + tests/test-rebase-templates.t | 123 + tests/test-rebase-transaction.t | 202 + tests/test-rebuildstate.t | 134 + tests/test-record.t | 91 + tests/test-releasenotes-formatting.t | 493 + tests/test-releasenotes-merging.t | 281 + tests/test-releasenotes-parsing.t | 202 + tests/test-relink.t | 110 + tests/test-remote-hidden.t | 406 + tests/test-remotefilelog-bad-configs.t | 40 + tests/test-remotefilelog-bgprefetch.t | 358 + tests/test-remotefilelog-blame.t | 40 + tests/test-remotefilelog-bundle2-legacy.t | 92 + tests/test-remotefilelog-bundle2.t | 78 + tests/test-remotefilelog-bundles.t | 76 + tests/test-remotefilelog-cacheprocess.t | 123 + tests/test-remotefilelog-clone-tree.t | 134 + tests/test-remotefilelog-clone.t | 131 + tests/test-remotefilelog-corrupt-cache.t | 72 + tests/test-remotefilelog-datapack.py | 415 + tests/test-remotefilelog-gc.t | 111 + tests/test-remotefilelog-gcrepack.t | 151 + tests/test-remotefilelog-hgweb.t | 38 + tests/test-remotefilelog-histpack.py | 312 + tests/test-remotefilelog-http.t | 95 + tests/test-remotefilelog-keepset.t | 39 + tests/test-remotefilelog-linknodes.t | 194 + tests/test-remotefilelog-local.t | 218 + tests/test-remotefilelog-log.t | 124 + tests/test-remotefilelog-partial-shallow.t | 79 + tests/test-remotefilelog-permissions.t | 50 + tests/test-remotefilelog-prefetch.t | 290 + tests/test-remotefilelog-pull-noshallow.t | 79 + tests/test-remotefilelog-push-pull.t | 229 + tests/test-remotefilelog-repack-fast.t | 374 + tests/test-remotefilelog-repack.t | 453 + tests/test-remotefilelog-share.t | 34 + tests/test-remotefilelog-sparse.t | 111 + tests/test-remotefilelog-strip.t | 68 + tests/test-remotefilelog-tags.t | 82 + tests/test-remotefilelog-wireproto.t | 50 + tests/test-remove.t | 544 + tests/test-removeemptydirs.t | 305 + tests/test-rename-after-merge.t | 133 + tests/test-rename-dir-merge.t | 338 + tests/test-rename-merge1.t | 237 + tests/test-rename-merge2.t | 967 + tests/test-rename-rev.t | 118 + tests/test-rename.t | 697 + tests/test-repair-strip.t | 150 + tests/test-repo-compengines.t | 224 + tests/test-repo-filters-tiptoe.t | 152 + tests/test-requires.t | 94 + tests/test-resolve.t | 758 + tests/test-revert-flags.t | 23 + tests/test-revert-interactive-curses.t | 72 + tests/test-revert-interactive.t | 552 + tests/test-revert-unknown.t | 31 + tests/test-revert.t | 1165 + tests/test-revisions.t | 45 + tests/test-revlog-ancestry.py | 94 + tests/test-revlog-ancestry.py.out | 19 + tests/test-revlog-delta-find.t | 355 + tests/test-revlog-group-emptyiter.t | 35 + tests/test-revlog-mmapindex.t | 57 + tests/test-revlog-packentry.t | 23 + tests/test-revlog-raw.py | 528 + tests/test-revlog-raw.py.out | 7 + tests/test-revlog-v2.t | 122 + tests/test-revlog.t | 89 + tests/test-revset-dirstate-parents.t | 66 + tests/test-revset-legacy-lookup.t | 289 + tests/test-revset-outgoing.t | 115 + tests/test-revset.t | 3143 ++ tests/test-revset2.t | 1877 + tests/test-rhg-no-generaldelta.t | 46 + tests/test-rhg-sparse-narrow.t | 121 + tests/test-rhg.t | 427 + tests/test-rollback.t | 457 + tests/test-run-tests.py | 118 + tests/test-run-tests.t | 2089 + tests/test-rust-ancestor.py | 167 + tests/test-rust-discovery.py | 120 + tests/test-rust-revlog.py | 90 + tests/test-schemes.t | 75 + tests/test-serve.t | 120 + tests/test-server-view.t | 120 + tests/test-setdiscovery.t | 1830 + tests/test-share-bookmarks.t | 288 + tests/test-share-safe.t | 655 + tests/test-share.t | 309 + tests/test-shelve.t | 1660 + tests/test-shelve2.t | 1004 + tests/test-show-stack.t | 220 + tests/test-show-work.t | 276 + tests/test-show.t | 173 + tests/test-sidedata-exchange.t | 473 + tests/test-sidedata.t | 82 + tests/test-simple-update.t | 128 + tests/test-simplekeyvaluefile.py | 98 + tests/test-simplemerge.py | 393 + ...single-head-obsolescence-named-branch-A1.t | 114 + ...single-head-obsolescence-named-branch-A2.t | 113 + ...single-head-obsolescence-named-branch-A3.t | 120 + ...single-head-obsolescence-named-branch-A4.t | 117 + ...single-head-obsolescence-named-branch-A5.t | 108 + tests/test-single-head.t | 391 + tests/test-sparse-clear.t | 80 + tests/test-sparse-clone.t | 75 + tests/test-sparse-fsmonitor.t | 44 + tests/test-sparse-import.t | 184 + tests/test-sparse-merges.t | 198 + tests/test-sparse-profiles.t | 303 + tests/test-sparse-requirement.t | 84 + tests/test-sparse-revlog.t | 431 + tests/test-sparse-verbose-json.t | 82 + tests/test-sparse-with-safe-share.t | 23 + tests/test-sparse.t | 463 + tests/test-split.t | 1146 + tests/test-sqlitestore.t | 135 + tests/test-ssh-batch.t | 15 + tests/test-ssh-bundle1.t | 585 + tests/test-ssh-clone-r.t | 145 + tests/test-ssh-proto-unbundle.t | 1170 + tests/test-ssh-proto.t | 1417 + tests/test-ssh-repoerror.t | 65 + tests/test-ssh.t | 701 + tests/test-sshserver.py | 62 + tests/test-stabletailgraph.t | 1146 + tests/test-stack.t | 253 + tests/test-state-extension.t | 136 + tests/test-static-http.t | 304 + tests/test-status-color.t | 407 + tests/test-status-committed-and-ignored.t | 33 + tests/test-status-eacces.t | 45 + tests/test-status-inprocess.py | 49 + tests/test-status-inprocess.py.out | 5 + tests/test-status-rev.t | 186 + tests/test-status-terse.t | 279 + tests/test-status-tracked-key.t | 240 + tests/test-status.t | 1031 + tests/test-stdio.py | 316 + tests/test-storage.py | 178 + tests/test-stream-bundle-v2.t | 345 + tests/test-strict.t | 27 + tests/test-strip-branch-cache.t | 56 + tests/test-strip-cross.t | 184 + tests/test-strip.t | 1458 + tests/test-subrepo-deep-nested-change.t | 1280 + tests/test-subrepo-git.t | 1275 + tests/test-subrepo-missing.t | 134 + tests/test-subrepo-paths.t | 61 + tests/test-subrepo-recursion.t | 761 + tests/test-subrepo-relative-path.t | 219 + tests/test-subrepo-svn.t | 699 + tests/test-subrepo.t | 2016 + tests/test-symlink-os-yes-fs-no.py | 65 + tests/test-symlink-os-yes-fs-no.py.out | 12 + tests/test-symlink-placeholder.t | 79 + tests/test-symlinks.t | 315 + tests/test-tag.t | 810 + tests/test-tags.t | 990 + tests/test-template-basic.t | 1089 + tests/test-template-functions.t | 1736 + tests/test-template-graph.t | 440 + tests/test-template-keywords.t | 1404 + tests/test-template-map.t | 2015 + tests/test-tools.t | 109 + ...est-transaction-rollback-on-revlog-split.t | 518 + tests/test-transaction-rollback-on-sigpipe.t | 80 + tests/test-transaction-safety.t | 287 + tests/test-transaction-wc-rollback-race.t | 263 + tests/test-transplant.t | 1107 + tests/test-treediscovery-legacy.t | 372 + tests/test-treediscovery.t | 576 + tests/test-treemanifest.t | 908 + tests/test-trusted.py | 319 + tests/test-trusted.py.out | 196 + tests/test-ui-color.py | 37 + tests/test-ui-color.py.out | 5 + tests/test-ui-config.py | 133 + tests/test-ui-config.py.out | 53 + tests/test-ui-verbosity.py | 64 + tests/test-ui-verbosity.py.out | 66 + tests/test-unamend.t | 456 + tests/test-unbundlehash.t | 43 + tests/test-uncommit.t | 596 + tests/test-unified-test.t | 143 + tests/test-unionrepo.t | 167 + tests/test-unrelated-pull.t | 46 + tests/test-up-local-change.t | 236 + tests/test-update-atomic.t | 145 + tests/test-update-branches.t | 726 + tests/test-update-dest.t | 49 + tests/test-update-issue1456.t | 45 + tests/test-update-names.t | 93 + tests/test-update-reverse.t | 86 + tests/test-upgrade-repo.t | 2110 + tests/test-url-download.t | 72 + tests/test-url-rev.t | 332 + tests/test-url.py | 462 + tests/test-username-newline.t | 28 + tests/test-util.py | 143 + tests/test-verify-repo-operations.py | 638 + tests/test-verify.t | 369 + tests/test-walk.t | 682 + tests/test-walkrepo.py | 76 + tests/test-websub.t | 38 + tests/test-win32text.t | 424 + tests/test-wireproto-clientreactor.py | 765 + tests/test-wireproto-framing.py | 305 + tests/test-wireproto-serverreactor.py | 845 + tests/test-wireproto.py | 122 + tests/test-wireproto.py.out | 2 + tests/test-wireproto.t | 157 + tests/test-worker.t | 162 + tests/test-wsgicgi.t | 18 + tests/test-wsgirequest.py | 511 + tests/test-xdg.t | 11 + tests/testlib/badserverext.py | 451 + tests/testlib/common.sh | 7 + tests/testlib/crash_transaction_late.py | 31 + tests/testlib/exchange-obsmarker-util.sh | 142 + tests/testlib/ext-phase-report.py | 29 + tests/testlib/ext-sidedata-2.py | 54 + tests/testlib/ext-sidedata-3.py | 93 + tests/testlib/ext-sidedata-4.py | 18 + tests/testlib/ext-sidedata-5.py | 85 + tests/testlib/ext-sidedata.py | 105 + tests/testlib/ext-stream-clone-steps.py | 44 + tests/testlib/merge-combination-util.sh | 73 + tests/testlib/obsmarker-common.sh | 16 + tests/testlib/persistent-nodemap-race-ext.py | 293 + tests/testlib/push-checkheads-util.sh | 50 + tests/testlib/sigpipe-remote.py | 146 + tests/testlib/sigpipe-worker.py | 18 + tests/testlib/stream_clone_setup.sh | 97 + tests/testlib/wait-on-file | 39 + tests/tinyproxy.py | 218 + tests/unwrap-message-id.py | 6 + tests/wireprotohelpers.sh | 34 + 2320 files changed, 1089281 insertions(+) create mode 100644 .arcconfig create mode 100644 .clang-format create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitlab/merge_request_templates/Default.md create mode 100644 .hgignore create mode 100644 .hgsigs create mode 100644 .hgtags create mode 100644 .jshintrc create mode 100644 CONTRIBUTING create mode 100644 CONTRIBUTORS create mode 100644 COPYING create mode 100644 MANIFEST.in create mode 100644 Makefile create mode 100644 PKG-INFO create mode 100644 README.rst create mode 100644 contrib/Makefile.python create mode 100644 contrib/all-revsets.txt create mode 100644 contrib/asv.conf.json create mode 100644 contrib/automation/README.rst create mode 100755 contrib/automation/automation.py create mode 100644 contrib/automation/hgautomation/__init__.py create mode 100644 contrib/automation/hgautomation/aws.py create mode 100644 contrib/automation/hgautomation/cli.py create mode 100644 contrib/automation/hgautomation/linux.py create mode 100644 contrib/automation/hgautomation/pypi.py create mode 100644 contrib/automation/hgautomation/ssh.py create mode 100644 contrib/automation/hgautomation/try_server.py create mode 100644 contrib/automation/hgautomation/windows.py create mode 100644 contrib/automation/hgautomation/winrm.py create mode 100644 contrib/automation/linux-requirements-py3.5.txt create mode 100644 contrib/automation/linux-requirements-py3.txt create mode 100644 contrib/automation/linux-requirements.txt.in create mode 100644 contrib/automation/requirements.txt create mode 100644 contrib/automation/requirements.txt.in create mode 100644 contrib/base-revsets.txt create mode 100644 contrib/bash_completion create mode 100644 contrib/bdiff-torture.py create mode 100644 contrib/benchmarks/__init__.py create mode 100644 contrib/benchmarks/perf.py create mode 100644 contrib/benchmarks/revset.py create mode 100755 contrib/byteify-strings.py create mode 100644 contrib/casesmash.py create mode 100755 contrib/catapipe.py create mode 100755 contrib/check-code.py create mode 100755 contrib/check-commit create mode 100755 contrib/check-config.py create mode 100755 contrib/check-py3-compat.py create mode 100755 contrib/check-pytype.sh create mode 100644 contrib/chg/Makefile create mode 100644 contrib/chg/README create mode 100644 contrib/chg/chg.1 create mode 100644 contrib/chg/chg.c create mode 100644 contrib/chg/hgclient.c create mode 100644 contrib/chg/hgclient.h create mode 100644 contrib/chg/procutil.c create mode 100644 contrib/chg/procutil.h create mode 100644 contrib/chg/util.c create mode 100644 contrib/chg/util.h create mode 100644 contrib/clang-format-ignorelist create mode 100755 contrib/debugcmdserver.py create mode 100644 contrib/debugshell.py create mode 100644 contrib/docker/apache-server/Dockerfile create mode 100644 contrib/docker/apache-server/README.rst create mode 100755 contrib/docker/apache-server/entrypoint.sh create mode 100644 contrib/docker/apache-server/hgwebconfig create mode 100644 contrib/docker/apache-server/vhost.conf create mode 100644 contrib/docker/pytype/Dockerfile create mode 100755 contrib/docker/pytype/entrypoint.sh create mode 100755 contrib/docker/pytype/recipe.sh create mode 100755 contrib/dumprevlog create mode 100755 contrib/editmerge create mode 100644 contrib/editmergeps.bat create mode 100644 contrib/editmergeps.ps1 create mode 100644 contrib/examples/fix.hgrc create mode 100644 contrib/fuzz/FuzzedDataProvider.h create mode 100644 contrib/fuzz/Makefile create mode 100644 contrib/fuzz/README.rst create mode 100644 contrib/fuzz/bdiff.cc create mode 100644 contrib/fuzz/dirs.cc create mode 100644 contrib/fuzz/dirs_corpus.py create mode 100644 contrib/fuzz/dirstate.cc create mode 100644 contrib/fuzz/dirstate_corpus.py create mode 100644 contrib/fuzz/fm1readmarkers.cc create mode 100644 contrib/fuzz/fm1readmarkers_corpus.py create mode 100644 contrib/fuzz/fncache.cc create mode 100644 contrib/fuzz/fuzzutil.h create mode 100644 contrib/fuzz/jsonescapeu8fast.cc create mode 100644 contrib/fuzz/manifest.cc create mode 100644 contrib/fuzz/manifest_corpus.py create mode 100644 contrib/fuzz/mpatch.cc create mode 100644 contrib/fuzz/mpatch_corpus.py create mode 100644 contrib/fuzz/pyutil.cc create mode 100644 contrib/fuzz/pyutil.h create mode 100644 contrib/fuzz/revlog.cc create mode 100644 contrib/fuzz/revlog_corpus.py create mode 100644 contrib/fuzz/standalone_fuzz_target_runner.cc create mode 100644 contrib/fuzz/xdiff.cc create mode 100755 contrib/genosxversion.py create mode 100644 contrib/heptapod-ci.yml create mode 100755 contrib/hg-ssh create mode 100644 contrib/hg-test-mode.el create mode 100644 contrib/hgclient.py create mode 100755 contrib/hgk create mode 100755 contrib/hgperf create mode 100644 contrib/hgsh/Makefile create mode 100644 contrib/hgsh/hgsh.c create mode 100755 contrib/hgweb.fcgi create mode 100644 contrib/hgweb.wsgi create mode 100755 contrib/import-checker.py create mode 100644 contrib/install-windows-dependencies.ps1 create mode 100644 contrib/logo-droplets.svg create mode 100644 contrib/memory.py create mode 100644 contrib/mercurial.el create mode 100644 contrib/merge-lists/Cargo.lock create mode 100644 contrib/merge-lists/Cargo.toml create mode 100644 contrib/merge-lists/src/main.rs create mode 100644 contrib/merge-lists/tests/test-merge-lists.rs create mode 100644 contrib/mq.el create mode 100644 contrib/nix/flake.lock create mode 100644 contrib/nix/flake.nix create mode 100755 contrib/openvms/build.com create mode 100755 contrib/openvms/vms/hgeditor.com create mode 100755 contrib/openvms/vms/hgmerge.com create mode 100755 contrib/openvms/vms/logicals.com create mode 100755 contrib/openvms/vms/setup.com create mode 100755 contrib/openvms/vms/startup.com create mode 100755 contrib/openvms/vms/stmlf.fdl create mode 100644 contrib/packaging/Makefile create mode 100755 contrib/packaging/build-linux-wheels.sh create mode 100755 contrib/packaging/builddeb create mode 100755 contrib/packaging/buildrpm create mode 100644 contrib/packaging/debian/cacerts.rc create mode 100644 contrib/packaging/debian/changelog create mode 100644 contrib/packaging/debian/compat create mode 100644 contrib/packaging/debian/control create mode 100644 contrib/packaging/debian/copyright create mode 100644 contrib/packaging/debian/default-tools.rc create mode 100644 contrib/packaging/debian/hgkpath.rc create mode 100755 contrib/packaging/debian/rules create mode 100644 contrib/packaging/docker/debian.template create mode 100644 contrib/packaging/docker/fedora.template create mode 100644 contrib/packaging/docker/rhel7 create mode 100644 contrib/packaging/docker/rhel8 create mode 100644 contrib/packaging/docker/rhel9 create mode 100644 contrib/packaging/docker/ubuntu.template create mode 100755 contrib/packaging/dockerdeb create mode 100755 contrib/packaging/dockerrpm create mode 100755 contrib/packaging/hg-docker create mode 100644 contrib/packaging/hgpackaging/__init__.py create mode 100644 contrib/packaging/hgpackaging/cli.py create mode 100644 contrib/packaging/hgpackaging/downloads.py create mode 100644 contrib/packaging/hgpackaging/inno.py create mode 100644 contrib/packaging/hgpackaging/pyoxidizer.py create mode 100644 contrib/packaging/hgpackaging/util.py create mode 100644 contrib/packaging/hgpackaging/wix.py create mode 100644 contrib/packaging/inno/mercurial.iss create mode 100644 contrib/packaging/inno/modpath.iss create mode 100644 contrib/packaging/inno/readme.rst create mode 100644 contrib/packaging/linux-wheel-centos5-blacklist create mode 100644 contrib/packaging/macosx/Readme.html create mode 100644 contrib/packaging/macosx/Welcome.html create mode 100644 contrib/packaging/macosx/distribution.xml create mode 100644 contrib/packaging/mercurial.spec create mode 100644 contrib/packaging/packagelib.sh create mode 100755 contrib/packaging/packaging.py create mode 100644 contrib/packaging/requirements-macos.txt create mode 100644 contrib/packaging/requirements-macos.txt.in create mode 100644 contrib/packaging/requirements-windows-py3.txt create mode 100644 contrib/packaging/requirements-windows.txt.in create mode 100644 contrib/packaging/requirements.txt create mode 100644 contrib/packaging/requirements.txt.in create mode 100644 contrib/packaging/wix/COPYING.rtf create mode 100644 contrib/packaging/wix/defines.wxi create mode 100644 contrib/packaging/wix/guids.wxi create mode 100644 contrib/packaging/wix/mercurial.wxs create mode 100644 contrib/packaging/wix/readme.rst create mode 100755 contrib/perf-utils/compare-discovery-case create mode 100755 contrib/perf-utils/discovery-helper.sh create mode 100755 contrib/perf-utils/perf-revlog-write-plot.py create mode 100755 contrib/perf-utils/search-discovery-case create mode 100644 contrib/perf-utils/subsetmaker.py create mode 100644 contrib/perf.py create mode 100755 contrib/phab-clean.py create mode 100755 contrib/phab-refresh-stack.sh create mode 100755 contrib/plan9/9diff create mode 100644 contrib/plan9/9mail create mode 100644 contrib/plan9/README create mode 100644 contrib/plan9/hgrc.d/9diff.rc create mode 100644 contrib/plan9/hgrc.d/9mail.rc create mode 100644 contrib/plan9/hgrc.d/factotum.rc create mode 100644 contrib/plan9/mkfile create mode 100644 contrib/plan9/proto create mode 100644 contrib/pull_logger.py create mode 100644 contrib/pylintrc create mode 100644 contrib/python-hook-examples.py create mode 100644 contrib/python-zstandard/LICENSE create mode 100644 contrib/python-zstandard/MANIFEST.in create mode 100644 contrib/python-zstandard/NEWS.rst create mode 100644 contrib/python-zstandard/README.rst create mode 100644 contrib/python-zstandard/c-ext/bufferutil.c create mode 100644 contrib/python-zstandard/c-ext/compressionchunker.c create mode 100644 contrib/python-zstandard/c-ext/compressiondict.c create mode 100644 contrib/python-zstandard/c-ext/compressionparams.c create mode 100644 contrib/python-zstandard/c-ext/compressionreader.c create mode 100644 contrib/python-zstandard/c-ext/compressionwriter.c create mode 100644 contrib/python-zstandard/c-ext/compressobj.c create mode 100644 contrib/python-zstandard/c-ext/compressor.c create mode 100644 contrib/python-zstandard/c-ext/compressoriterator.c create mode 100644 contrib/python-zstandard/c-ext/constants.c create mode 100644 contrib/python-zstandard/c-ext/decompressionreader.c create mode 100644 contrib/python-zstandard/c-ext/decompressionwriter.c create mode 100644 contrib/python-zstandard/c-ext/decompressobj.c create mode 100644 contrib/python-zstandard/c-ext/decompressor.c create mode 100644 contrib/python-zstandard/c-ext/decompressoriterator.c create mode 100644 contrib/python-zstandard/c-ext/frameparams.c create mode 100644 contrib/python-zstandard/c-ext/python-zstandard.h create mode 100644 contrib/python-zstandard/make_cffi.py create mode 100755 contrib/python-zstandard/setup.py create mode 100644 contrib/python-zstandard/setup_zstd.py create mode 100644 contrib/python-zstandard/tests/__init__.py create mode 100644 contrib/python-zstandard/tests/common.py create mode 100644 contrib/python-zstandard/tests/test_buffer_util.py create mode 100644 contrib/python-zstandard/tests/test_compressor.py create mode 100644 contrib/python-zstandard/tests/test_compressor_fuzzing.py create mode 100644 contrib/python-zstandard/tests/test_data_structures.py create mode 100644 contrib/python-zstandard/tests/test_data_structures_fuzzing.py create mode 100644 contrib/python-zstandard/tests/test_decompressor.py create mode 100644 contrib/python-zstandard/tests/test_decompressor_fuzzing.py create mode 100644 contrib/python-zstandard/tests/test_estimate_sizes.py create mode 100644 contrib/python-zstandard/tests/test_module_attributes.py create mode 100644 contrib/python-zstandard/tests/test_train_dictionary.py create mode 100644 contrib/python-zstandard/zstandard/__init__.py create mode 100644 contrib/python-zstandard/zstandard/cffi.py create mode 100644 contrib/python-zstandard/zstd.c create mode 100644 contrib/python-zstandard/zstd/COPYING create mode 100644 contrib/python-zstandard/zstd/LICENSE create mode 100644 contrib/python-zstandard/zstd/common/bitstream.h create mode 100644 contrib/python-zstandard/zstd/common/compiler.h create mode 100644 contrib/python-zstandard/zstd/common/cpu.h create mode 100644 contrib/python-zstandard/zstd/common/debug.c create mode 100644 contrib/python-zstandard/zstd/common/debug.h create mode 100644 contrib/python-zstandard/zstd/common/entropy_common.c create mode 100644 contrib/python-zstandard/zstd/common/error_private.c create mode 100644 contrib/python-zstandard/zstd/common/error_private.h create mode 100644 contrib/python-zstandard/zstd/common/fse.h create mode 100644 contrib/python-zstandard/zstd/common/fse_decompress.c create mode 100644 contrib/python-zstandard/zstd/common/huf.h create mode 100644 contrib/python-zstandard/zstd/common/mem.h create mode 100644 contrib/python-zstandard/zstd/common/pool.c create mode 100644 contrib/python-zstandard/zstd/common/pool.h create mode 100644 contrib/python-zstandard/zstd/common/pythoncapi_compat.h create mode 100644 contrib/python-zstandard/zstd/common/threading.c create mode 100644 contrib/python-zstandard/zstd/common/threading.h create mode 100644 contrib/python-zstandard/zstd/common/xxhash.c create mode 100644 contrib/python-zstandard/zstd/common/xxhash.h create mode 100644 contrib/python-zstandard/zstd/common/zstd_common.c create mode 100644 contrib/python-zstandard/zstd/common/zstd_errors.h create mode 100644 contrib/python-zstandard/zstd/common/zstd_internal.h create mode 100644 contrib/python-zstandard/zstd/compress/fse_compress.c create mode 100644 contrib/python-zstandard/zstd/compress/hist.c create mode 100644 contrib/python-zstandard/zstd/compress/hist.h create mode 100644 contrib/python-zstandard/zstd/compress/huf_compress.c create mode 100644 contrib/python-zstandard/zstd/compress/zstd_compress.c create mode 100644 contrib/python-zstandard/zstd/compress/zstd_compress_internal.h create mode 100644 contrib/python-zstandard/zstd/compress/zstd_compress_literals.c create mode 100644 contrib/python-zstandard/zstd/compress/zstd_compress_literals.h create mode 100644 contrib/python-zstandard/zstd/compress/zstd_compress_sequences.c create mode 100644 contrib/python-zstandard/zstd/compress/zstd_compress_sequences.h create mode 100644 contrib/python-zstandard/zstd/compress/zstd_cwksp.h create mode 100644 contrib/python-zstandard/zstd/compress/zstd_double_fast.c create mode 100644 contrib/python-zstandard/zstd/compress/zstd_double_fast.h create mode 100644 contrib/python-zstandard/zstd/compress/zstd_fast.c create mode 100644 contrib/python-zstandard/zstd/compress/zstd_fast.h create mode 100644 contrib/python-zstandard/zstd/compress/zstd_lazy.c create mode 100644 contrib/python-zstandard/zstd/compress/zstd_lazy.h create mode 100644 contrib/python-zstandard/zstd/compress/zstd_ldm.c create mode 100644 contrib/python-zstandard/zstd/compress/zstd_ldm.h create mode 100644 contrib/python-zstandard/zstd/compress/zstd_opt.c create mode 100644 contrib/python-zstandard/zstd/compress/zstd_opt.h create mode 100644 contrib/python-zstandard/zstd/compress/zstdmt_compress.c create mode 100644 contrib/python-zstandard/zstd/compress/zstdmt_compress.h create mode 100644 contrib/python-zstandard/zstd/decompress/huf_decompress.c create mode 100644 contrib/python-zstandard/zstd/decompress/zstd_ddict.c create mode 100644 contrib/python-zstandard/zstd/decompress/zstd_ddict.h create mode 100644 contrib/python-zstandard/zstd/decompress/zstd_decompress.c create mode 100644 contrib/python-zstandard/zstd/decompress/zstd_decompress_block.c create mode 100644 contrib/python-zstandard/zstd/decompress/zstd_decompress_block.h create mode 100644 contrib/python-zstandard/zstd/decompress/zstd_decompress_internal.h create mode 100644 contrib/python-zstandard/zstd/deprecated/zbuff.h create mode 100644 contrib/python-zstandard/zstd/deprecated/zbuff_common.c create mode 100644 contrib/python-zstandard/zstd/deprecated/zbuff_compress.c create mode 100644 contrib/python-zstandard/zstd/deprecated/zbuff_decompress.c create mode 100644 contrib/python-zstandard/zstd/dictBuilder/cover.c create mode 100644 contrib/python-zstandard/zstd/dictBuilder/cover.h create mode 100644 contrib/python-zstandard/zstd/dictBuilder/divsufsort.c create mode 100644 contrib/python-zstandard/zstd/dictBuilder/divsufsort.h create mode 100644 contrib/python-zstandard/zstd/dictBuilder/fastcover.c create mode 100644 contrib/python-zstandard/zstd/dictBuilder/zdict.c create mode 100644 contrib/python-zstandard/zstd/dictBuilder/zdict.h create mode 100644 contrib/python-zstandard/zstd/zstd.h create mode 100644 contrib/python3-ratchet.py create mode 100644 contrib/python3-whitelist create mode 100644 contrib/relnotes create mode 100755 contrib/revsetbenchmarks.py create mode 100755 contrib/setup-pytype.sh create mode 100644 contrib/showstack.py create mode 100644 contrib/simplemerge create mode 100644 contrib/synthrepo.py create mode 100644 contrib/tcsh_completion create mode 100755 contrib/tcsh_completion_build.sh create mode 100644 contrib/testparseutil.py create mode 100755 contrib/undumprevlog create mode 100644 contrib/vagrant/README.md create mode 100644 contrib/vagrant/Vagrantfile create mode 100644 contrib/vagrant/provision.sh create mode 100644 contrib/vagrant/run-tests.sh create mode 100644 contrib/vim/HGAnnotate.vim create mode 100644 contrib/vim/hg-menu.vim create mode 100644 contrib/vim/hgcommand.vim create mode 100644 contrib/vim/hgtest.vim create mode 100644 contrib/vim/patchreview.txt create mode 100644 contrib/vim/patchreview.vim create mode 100644 contrib/win32/ReadMe.html create mode 100644 contrib/win32/buildlocal.bat create mode 100644 contrib/win32/hg.bat create mode 100644 contrib/win32/hgwebdir_wsgi.py create mode 100644 contrib/win32/mercurial.ico create mode 100644 contrib/win32/mercurial.ini create mode 100644 contrib/win32/postinstall.txt create mode 100644 contrib/xml.rnc create mode 100644 contrib/zsh_completion create mode 100644 doc/Makefile create mode 100644 doc/README create mode 100755 doc/check-seclevel.py create mode 100755 doc/docchecker create mode 100755 doc/gendoc.py create mode 100644 doc/hg-ssh.8 create mode 100644 doc/hg-ssh.8.html create mode 100644 doc/hg.1 create mode 100644 doc/hg.1.html create mode 100644 doc/hgignore.5 create mode 100644 doc/hgignore.5.html create mode 100644 doc/hgmanpage.py create mode 100644 doc/hgrc.5 create mode 100644 doc/hgrc.5.html create mode 100755 doc/runrst create mode 100644 doc/style.css create mode 100755 hg create mode 100644 hgdemandimport/__init__.py create mode 100644 hgdemandimport/demandimportpy3.py create mode 100644 hgdemandimport/tracing.py create mode 100755 hgeditor create mode 100644 hgext/__init__.py create mode 100644 hgext/absorb.py create mode 100644 hgext/acl.py create mode 100644 hgext/amend.py create mode 100644 hgext/automv.py create mode 100644 hgext/beautifygraph.py create mode 100644 hgext/blackbox.py create mode 100644 hgext/bookflow.py create mode 100644 hgext/bugzilla.py create mode 100644 hgext/censor.py create mode 100644 hgext/children.py create mode 100644 hgext/churn.py create mode 100644 hgext/clonebundles.py create mode 100644 hgext/closehead.py create mode 100644 hgext/commitextras.py create mode 100644 hgext/convert/__init__.py create mode 100644 hgext/convert/bzr.py create mode 100644 hgext/convert/common.py create mode 100644 hgext/convert/convcmd.py create mode 100644 hgext/convert/cvs.py create mode 100644 hgext/convert/cvsps.py create mode 100644 hgext/convert/darcs.py create mode 100644 hgext/convert/filemap.py create mode 100644 hgext/convert/git.py create mode 100644 hgext/convert/gnuarch.py create mode 100644 hgext/convert/hg.py create mode 100644 hgext/convert/monotone.py create mode 100644 hgext/convert/p4.py create mode 100644 hgext/convert/subversion.py create mode 100644 hgext/convert/transport.py create mode 100644 hgext/eol.py create mode 100644 hgext/extdiff.py create mode 100644 hgext/factotum.py create mode 100644 hgext/fastannotate/__init__.py create mode 100644 hgext/fastannotate/commands.py create mode 100644 hgext/fastannotate/context.py create mode 100644 hgext/fastannotate/error.py create mode 100644 hgext/fastannotate/formatter.py create mode 100644 hgext/fastannotate/protocol.py create mode 100644 hgext/fastannotate/revmap.py create mode 100644 hgext/fastannotate/support.py create mode 100644 hgext/fastexport.py create mode 100644 hgext/fetch.py create mode 100644 hgext/fix.py create mode 100644 hgext/fsmonitor/__init__.py create mode 100644 hgext/fsmonitor/pywatchman/__init__.py create mode 100644 hgext/fsmonitor/pywatchman/bser.c create mode 100644 hgext/fsmonitor/pywatchman/capabilities.py create mode 100644 hgext/fsmonitor/pywatchman/compat.py create mode 100644 hgext/fsmonitor/pywatchman/encoding.py create mode 100644 hgext/fsmonitor/pywatchman/load.py create mode 100644 hgext/fsmonitor/pywatchman/pybser.py create mode 100644 hgext/fsmonitor/state.py create mode 100644 hgext/fsmonitor/watchmanclient.py create mode 100644 hgext/git/TODO.md create mode 100644 hgext/git/__init__.py create mode 100644 hgext/git/dirstate.py create mode 100644 hgext/git/gitlog.py create mode 100644 hgext/git/gitutil.py create mode 100644 hgext/git/index.py create mode 100644 hgext/git/manifest.py create mode 100644 hgext/githelp.py create mode 100644 hgext/gpg.py create mode 100644 hgext/graphlog.py create mode 100644 hgext/hgk.py create mode 100644 hgext/highlight/__init__.py create mode 100644 hgext/highlight/highlight.py create mode 100644 hgext/histedit.py create mode 100644 hgext/hooklib/__init__.py create mode 100644 hgext/hooklib/changeset_obsoleted.py create mode 100644 hgext/hooklib/changeset_published.py create mode 100644 hgext/hooklib/enforce_draft_commits.py create mode 100644 hgext/hooklib/reject_merge_commits.py create mode 100644 hgext/hooklib/reject_new_heads.py create mode 100644 hgext/journal.py create mode 100644 hgext/keyword.py create mode 100644 hgext/largefiles/CONTRIBUTORS create mode 100644 hgext/largefiles/__init__.py create mode 100644 hgext/largefiles/basestore.py create mode 100644 hgext/largefiles/lfcommands.py create mode 100644 hgext/largefiles/lfutil.py create mode 100644 hgext/largefiles/localstore.py create mode 100644 hgext/largefiles/overrides.py create mode 100644 hgext/largefiles/proto.py create mode 100644 hgext/largefiles/remotestore.py create mode 100644 hgext/largefiles/reposetup.py create mode 100644 hgext/largefiles/storefactory.py create mode 100644 hgext/largefiles/wirestore.py create mode 100644 hgext/lfs/TODO.rst create mode 100644 hgext/lfs/__init__.py create mode 100644 hgext/lfs/blobstore.py create mode 100644 hgext/lfs/pointer.py create mode 100644 hgext/lfs/wireprotolfsserver.py create mode 100644 hgext/lfs/wrapper.py create mode 100644 hgext/logtoprocess.py create mode 100644 hgext/mq.py create mode 100644 hgext/narrow/TODO.rst create mode 100644 hgext/narrow/__init__.py create mode 100644 hgext/narrow/narrowbundle2.py create mode 100644 hgext/narrow/narrowcommands.py create mode 100644 hgext/narrow/narrowdirstate.py create mode 100644 hgext/narrow/narrowrepo.py create mode 100644 hgext/narrow/narrowtemplates.py create mode 100644 hgext/narrow/narrowwirepeer.py create mode 100644 hgext/notify.py create mode 100644 hgext/pager.py create mode 100644 hgext/patchbomb.py create mode 100644 hgext/phabricator.py create mode 100644 hgext/purge.py create mode 100644 hgext/rebase.py create mode 100644 hgext/record.py create mode 100644 hgext/releasenotes.py create mode 100644 hgext/relink.py create mode 100644 hgext/remotefilelog/README.md create mode 100644 hgext/remotefilelog/__init__.py create mode 100644 hgext/remotefilelog/basepack.py create mode 100644 hgext/remotefilelog/basestore.py create mode 100644 hgext/remotefilelog/connectionpool.py create mode 100644 hgext/remotefilelog/constants.py create mode 100644 hgext/remotefilelog/contentstore.py create mode 100644 hgext/remotefilelog/datapack.py create mode 100644 hgext/remotefilelog/debugcommands.py create mode 100644 hgext/remotefilelog/fileserverclient.py create mode 100644 hgext/remotefilelog/historypack.py create mode 100644 hgext/remotefilelog/metadatastore.py create mode 100644 hgext/remotefilelog/remotefilectx.py create mode 100644 hgext/remotefilelog/remotefilelog.py create mode 100644 hgext/remotefilelog/remotefilelogserver.py create mode 100644 hgext/remotefilelog/repack.py create mode 100644 hgext/remotefilelog/shallowbundle.py create mode 100644 hgext/remotefilelog/shallowrepo.py create mode 100644 hgext/remotefilelog/shallowstore.py create mode 100644 hgext/remotefilelog/shallowutil.py create mode 100644 hgext/remotefilelog/shallowverifier.py create mode 100644 hgext/remotenames.py create mode 100644 hgext/schemes.py create mode 100644 hgext/share.py create mode 100644 hgext/show.py create mode 100644 hgext/sparse.py create mode 100644 hgext/split.py create mode 100644 hgext/sqlitestore.py create mode 100644 hgext/strip.py create mode 100644 hgext/transplant.py create mode 100644 hgext/uncommit.py create mode 100644 hgext/win32mbcs.py create mode 100644 hgext/win32text.py create mode 100644 hgext/zeroconf/Zeroconf.py create mode 100644 hgext/zeroconf/__init__.py create mode 100644 hgext3rd/__init__.py create mode 100755 hgweb.cgi create mode 100755 i18n/check-translation.py create mode 100644 i18n/da.po create mode 100644 i18n/de.po create mode 100644 i18n/el.po create mode 100644 i18n/fr.po create mode 100755 i18n/hggettext create mode 100644 i18n/it.po create mode 100644 i18n/ja.po create mode 100644 i18n/polib.LICENSE create mode 100644 i18n/polib.py create mode 100755 i18n/posplit create mode 100644 i18n/pt_BR.po create mode 100644 i18n/ro.po create mode 100644 i18n/ru.po create mode 100644 i18n/sv.po create mode 100644 i18n/zh_CN.po create mode 100644 i18n/zh_TW.po create mode 100644 mercurial.egg-info/PKG-INFO create mode 100644 mercurial.egg-info/SOURCES.txt create mode 100644 mercurial.egg-info/dependency_links.txt create mode 100644 mercurial.egg-info/top_level.txt create mode 100644 mercurial/__init__.py create mode 100644 mercurial/__main__.py create mode 100644 mercurial/__version__.py create mode 100644 mercurial/admin/__init__.py create mode 100644 mercurial/admin/chainsaw.py create mode 100644 mercurial/admin/verify.py create mode 100644 mercurial/admin_commands.py create mode 100644 mercurial/ancestor.py create mode 100644 mercurial/archival.py create mode 100644 mercurial/bdiff.c create mode 100644 mercurial/bdiff.h create mode 100644 mercurial/bitmanipulation.h create mode 100644 mercurial/bookmarks.py create mode 100644 mercurial/branchmap.py create mode 100644 mercurial/bundle2.py create mode 100644 mercurial/bundlecaches.py create mode 100644 mercurial/bundlerepo.py create mode 100644 mercurial/cacheutil.py create mode 100644 mercurial/cext/__init__.py create mode 100644 mercurial/cext/base85.c create mode 100644 mercurial/cext/base85.pyi create mode 100644 mercurial/cext/bdiff.c create mode 100644 mercurial/cext/bdiff.pyi create mode 100644 mercurial/cext/charencode.c create mode 100644 mercurial/cext/charencode.h create mode 100644 mercurial/cext/dirs.c create mode 100644 mercurial/cext/manifest.c create mode 100644 mercurial/cext/mpatch.c create mode 100644 mercurial/cext/mpatch.pyi create mode 100644 mercurial/cext/osutil.c create mode 100644 mercurial/cext/osutil.pyi create mode 100644 mercurial/cext/parsers.c create mode 100644 mercurial/cext/parsers.pyi create mode 100644 mercurial/cext/pathencode.c create mode 100644 mercurial/cext/py.typed create mode 100644 mercurial/cext/revlog.c create mode 100644 mercurial/cext/revlog.h create mode 100644 mercurial/cext/util.h create mode 100644 mercurial/cffi/__init__.py create mode 100644 mercurial/cffi/bdiff.py create mode 100644 mercurial/cffi/bdiffbuild.py create mode 100644 mercurial/cffi/mpatch.py create mode 100644 mercurial/cffi/mpatchbuild.py create mode 100644 mercurial/cffi/osutil.py create mode 100644 mercurial/cffi/osutilbuild.py create mode 100644 mercurial/changegroup.py create mode 100644 mercurial/changelog.py create mode 100644 mercurial/chgserver.py create mode 100644 mercurial/cmdutil.py create mode 100644 mercurial/color.py create mode 100644 mercurial/commands.py create mode 100644 mercurial/commandserver.py create mode 100644 mercurial/commit.py create mode 100644 mercurial/compat.h create mode 100644 mercurial/config.py create mode 100644 mercurial/configitems.py create mode 100644 mercurial/configitems.toml create mode 100644 mercurial/context.py create mode 100644 mercurial/copies.py create mode 100644 mercurial/crecord.py create mode 100644 mercurial/dagop.py create mode 100644 mercurial/dagparser.py create mode 100644 mercurial/debugcommands.py create mode 100644 mercurial/defaultrc/__init__.py create mode 100644 mercurial/defaultrc/mergetools.rc create mode 100644 mercurial/destutil.py create mode 100644 mercurial/diffhelper.py create mode 100644 mercurial/diffutil.py create mode 100644 mercurial/dirstate.py create mode 100644 mercurial/dirstatemap.py create mode 100644 mercurial/dirstateutils/__init__.py create mode 100644 mercurial/dirstateutils/docket.py create mode 100644 mercurial/dirstateutils/timestamp.py create mode 100644 mercurial/dirstateutils/v2.py create mode 100644 mercurial/discovery.py create mode 100644 mercurial/dispatch.py create mode 100644 mercurial/dummycert.pem create mode 100644 mercurial/encoding.py create mode 100644 mercurial/error.py create mode 100644 mercurial/exchange.py create mode 100644 mercurial/exewrapper.c create mode 100644 mercurial/extensions.py create mode 100644 mercurial/exthelper.py create mode 100644 mercurial/fancyopts.py create mode 100644 mercurial/filelog.py create mode 100644 mercurial/filemerge.py create mode 100644 mercurial/fileset.py create mode 100644 mercurial/filesetlang.py create mode 100644 mercurial/formatter.py create mode 100644 mercurial/graphmod.py create mode 100644 mercurial/grep.py create mode 100644 mercurial/hbisect.py create mode 100644 mercurial/help.py create mode 100644 mercurial/helptext/__init__.py create mode 100644 mercurial/helptext/bundlespec.txt create mode 100644 mercurial/helptext/color.txt create mode 100644 mercurial/helptext/common.txt create mode 100644 mercurial/helptext/config.txt create mode 100644 mercurial/helptext/dates.txt create mode 100644 mercurial/helptext/deprecated.txt create mode 100644 mercurial/helptext/diffs.txt create mode 100644 mercurial/helptext/environment.txt create mode 100644 mercurial/helptext/evolution.txt create mode 100644 mercurial/helptext/extensions.txt create mode 100644 mercurial/helptext/filesets.txt create mode 100644 mercurial/helptext/flags.txt create mode 100644 mercurial/helptext/glossary.txt create mode 100644 mercurial/helptext/hg-ssh.8.txt create mode 100644 mercurial/helptext/hg.1.txt create mode 100644 mercurial/helptext/hgignore.5.txt create mode 100644 mercurial/helptext/hgignore.txt create mode 100644 mercurial/helptext/hgrc.5.txt create mode 100644 mercurial/helptext/hgweb.txt create mode 100644 mercurial/helptext/internals/__init__.py create mode 100644 mercurial/helptext/internals/bid-merge.txt create mode 100644 mercurial/helptext/internals/bundle2.txt create mode 100644 mercurial/helptext/internals/bundles.txt create mode 100644 mercurial/helptext/internals/cbor.txt create mode 100644 mercurial/helptext/internals/censor.txt create mode 100644 mercurial/helptext/internals/changegroups.txt create mode 100644 mercurial/helptext/internals/config.txt create mode 100644 mercurial/helptext/internals/dirstate-v2.txt create mode 100644 mercurial/helptext/internals/extensions.txt create mode 100644 mercurial/helptext/internals/linelog.txt create mode 100644 mercurial/helptext/internals/mergestate.txt create mode 100644 mercurial/helptext/internals/requirements.txt create mode 100644 mercurial/helptext/internals/revlogs.txt create mode 100644 mercurial/helptext/internals/wireprotocol.txt create mode 100644 mercurial/helptext/internals/wireprotocolrpc.txt create mode 100644 mercurial/helptext/internals/wireprotocolv2.txt create mode 100644 mercurial/helptext/merge-tools.txt create mode 100644 mercurial/helptext/pager.txt create mode 100644 mercurial/helptext/patterns.txt create mode 100644 mercurial/helptext/phases.txt create mode 100644 mercurial/helptext/revisions.txt create mode 100644 mercurial/helptext/rust.txt create mode 100644 mercurial/helptext/scripting.txt create mode 100644 mercurial/helptext/subrepos.txt create mode 100644 mercurial/helptext/templates.txt create mode 100644 mercurial/helptext/urls.txt create mode 100644 mercurial/hg.py create mode 100644 mercurial/hgweb/__init__.py create mode 100644 mercurial/hgweb/common.py create mode 100644 mercurial/hgweb/hgweb_mod.py create mode 100644 mercurial/hgweb/hgwebdir_mod.py create mode 100644 mercurial/hgweb/request.py create mode 100644 mercurial/hgweb/server.py create mode 100644 mercurial/hgweb/webcommands.py create mode 100644 mercurial/hgweb/webutil.py create mode 100644 mercurial/hgweb/wsgicgi.py create mode 100644 mercurial/hgweb/wsgiheaders.py create mode 100644 mercurial/hook.py create mode 100644 mercurial/httpconnection.py create mode 100644 mercurial/httppeer.py create mode 100644 mercurial/i18n.py create mode 100644 mercurial/interfaces/__init__.py create mode 100644 mercurial/interfaces/dirstate.py create mode 100644 mercurial/interfaces/repository.py create mode 100644 mercurial/interfaces/util.py create mode 100644 mercurial/keepalive.py create mode 100644 mercurial/linelog.py create mode 100644 mercurial/localrepo.py create mode 100644 mercurial/lock.py create mode 100644 mercurial/logcmdutil.py create mode 100644 mercurial/logexchange.py create mode 100644 mercurial/loggingutil.py create mode 100644 mercurial/lsprof.py create mode 100644 mercurial/lsprofcalltree.py create mode 100644 mercurial/mail.py create mode 100644 mercurial/manifest.py create mode 100644 mercurial/match.py create mode 100644 mercurial/mdiff.py create mode 100644 mercurial/merge.py create mode 100644 mercurial/mergestate.py create mode 100644 mercurial/mergeutil.py create mode 100644 mercurial/metadata.py create mode 100644 mercurial/minifileset.py create mode 100644 mercurial/minirst.py create mode 100644 mercurial/mpatch.c create mode 100644 mercurial/mpatch.h create mode 100644 mercurial/namespaces.py create mode 100644 mercurial/narrowspec.py create mode 100644 mercurial/node.py create mode 100644 mercurial/obsolete.py create mode 100644 mercurial/obsutil.py create mode 100644 mercurial/parser.py create mode 100644 mercurial/patch.py create mode 100644 mercurial/pathutil.py create mode 100644 mercurial/phases.py create mode 100644 mercurial/policy.py create mode 100644 mercurial/posix.py create mode 100644 mercurial/profiling.py create mode 100644 mercurial/progress.py create mode 100644 mercurial/pure/__init__.py create mode 100644 mercurial/pure/base85.py create mode 100644 mercurial/pure/bdiff.py create mode 100644 mercurial/pure/charencode.py create mode 100644 mercurial/pure/mpatch.py create mode 100644 mercurial/pure/osutil.py create mode 100644 mercurial/pure/parsers.py create mode 100644 mercurial/pushkey.py create mode 100644 mercurial/pvec.py create mode 100644 mercurial/pycompat.py create mode 100644 mercurial/pythoncapi_compat.h create mode 100644 mercurial/rcutil.py create mode 100644 mercurial/registrar.py create mode 100644 mercurial/repair.py create mode 100644 mercurial/repocache.py create mode 100644 mercurial/repoview.py create mode 100644 mercurial/requirements.py create mode 100644 mercurial/revlog.py create mode 100644 mercurial/revlogutils/__init__.py create mode 100644 mercurial/revlogutils/concurrency_checker.py create mode 100644 mercurial/revlogutils/constants.py create mode 100644 mercurial/revlogutils/debug.py create mode 100644 mercurial/revlogutils/deltas.py create mode 100644 mercurial/revlogutils/docket.py create mode 100644 mercurial/revlogutils/flagutil.py create mode 100644 mercurial/revlogutils/nodemap.py create mode 100644 mercurial/revlogutils/randomaccessfile.py create mode 100644 mercurial/revlogutils/revlogv0.py create mode 100644 mercurial/revlogutils/rewrite.py create mode 100644 mercurial/revlogutils/sidedata.py create mode 100644 mercurial/revset.py create mode 100644 mercurial/revsetlang.py create mode 100644 mercurial/rewriteutil.py create mode 100644 mercurial/scmposix.py create mode 100644 mercurial/scmutil.py create mode 100644 mercurial/scmwindows.py create mode 100644 mercurial/server.py create mode 100644 mercurial/setdiscovery.py create mode 100644 mercurial/shelve.py create mode 100644 mercurial/similar.py create mode 100644 mercurial/simplemerge.py create mode 100644 mercurial/smartset.py create mode 100644 mercurial/sparse.py create mode 100644 mercurial/sshpeer.py create mode 100644 mercurial/sslutil.py create mode 100644 mercurial/stabletailgraph/__init__.py create mode 100644 mercurial/stabletailgraph/stabletailsort.py create mode 100644 mercurial/stack.py create mode 100644 mercurial/state.py create mode 100644 mercurial/statichttprepo.py create mode 100644 mercurial/statprof.py create mode 100644 mercurial/store.py create mode 100644 mercurial/streamclone.py create mode 100644 mercurial/strip.py create mode 100644 mercurial/subrepo.py create mode 100644 mercurial/subrepoutil.py create mode 100644 mercurial/tagmerge.py create mode 100644 mercurial/tags.py create mode 100644 mercurial/templatefilters.py create mode 100644 mercurial/templatefuncs.py create mode 100644 mercurial/templatekw.py create mode 100644 mercurial/templater.py create mode 100644 mercurial/templates/__init__.py create mode 100644 mercurial/templates/atom/__init__.py create mode 100644 mercurial/templates/atom/bookmarkentry.tmpl create mode 100644 mercurial/templates/atom/bookmarks.tmpl create mode 100644 mercurial/templates/atom/branchentry.tmpl create mode 100644 mercurial/templates/atom/branches.tmpl create mode 100644 mercurial/templates/atom/changelog.tmpl create mode 100644 mercurial/templates/atom/changelogentry.tmpl create mode 100644 mercurial/templates/atom/error.tmpl create mode 100644 mercurial/templates/atom/filelog.tmpl create mode 100644 mercurial/templates/atom/header.tmpl create mode 100644 mercurial/templates/atom/map create mode 100644 mercurial/templates/atom/tagentry.tmpl create mode 100644 mercurial/templates/atom/tags.tmpl create mode 100644 mercurial/templates/coal/__init__.py create mode 100644 mercurial/templates/coal/header.tmpl create mode 100644 mercurial/templates/coal/map create mode 100644 mercurial/templates/gitweb/__init__.py create mode 100644 mercurial/templates/gitweb/bookmarks.tmpl create mode 100644 mercurial/templates/gitweb/branches.tmpl create mode 100644 mercurial/templates/gitweb/changelog.tmpl create mode 100644 mercurial/templates/gitweb/changelogentry.tmpl create mode 100644 mercurial/templates/gitweb/changeset.tmpl create mode 100644 mercurial/templates/gitweb/error.tmpl create mode 100644 mercurial/templates/gitweb/fileannotate.tmpl create mode 100644 mercurial/templates/gitweb/filecomparison.tmpl create mode 100644 mercurial/templates/gitweb/filediff.tmpl create mode 100644 mercurial/templates/gitweb/filelog.tmpl create mode 100644 mercurial/templates/gitweb/filerevision.tmpl create mode 100644 mercurial/templates/gitweb/footer.tmpl create mode 100644 mercurial/templates/gitweb/graph.tmpl create mode 100644 mercurial/templates/gitweb/graphentry.tmpl create mode 100644 mercurial/templates/gitweb/header.tmpl create mode 100644 mercurial/templates/gitweb/help.tmpl create mode 100644 mercurial/templates/gitweb/helptopics.tmpl create mode 100644 mercurial/templates/gitweb/index.tmpl create mode 100644 mercurial/templates/gitweb/manifest.tmpl create mode 100644 mercurial/templates/gitweb/map create mode 100644 mercurial/templates/gitweb/notfound.tmpl create mode 100644 mercurial/templates/gitweb/search.tmpl create mode 100644 mercurial/templates/gitweb/shortlog.tmpl create mode 100644 mercurial/templates/gitweb/summary.tmpl create mode 100644 mercurial/templates/gitweb/tags.tmpl create mode 100644 mercurial/templates/json/__init__.py create mode 100644 mercurial/templates/json/changelist.tmpl create mode 100644 mercurial/templates/json/graph.tmpl create mode 100644 mercurial/templates/json/map create mode 100644 mercurial/templates/map-cmdline.bisect create mode 100644 mercurial/templates/map-cmdline.changelog create mode 100644 mercurial/templates/map-cmdline.compact create mode 100644 mercurial/templates/map-cmdline.default create mode 100644 mercurial/templates/map-cmdline.phases create mode 100644 mercurial/templates/map-cmdline.show create mode 100644 mercurial/templates/map-cmdline.status create mode 100644 mercurial/templates/map-cmdline.xml create mode 100644 mercurial/templates/monoblue/__init__.py create mode 100644 mercurial/templates/monoblue/bookmarks.tmpl create mode 100644 mercurial/templates/monoblue/branches.tmpl create mode 100644 mercurial/templates/monoblue/changelog.tmpl create mode 100644 mercurial/templates/monoblue/changelogentry.tmpl create mode 100644 mercurial/templates/monoblue/changeset.tmpl create mode 100644 mercurial/templates/monoblue/error.tmpl create mode 100644 mercurial/templates/monoblue/fileannotate.tmpl create mode 100644 mercurial/templates/monoblue/filecomparison.tmpl create mode 100644 mercurial/templates/monoblue/filediff.tmpl create mode 100644 mercurial/templates/monoblue/filelog.tmpl create mode 100644 mercurial/templates/monoblue/filerevision.tmpl create mode 100644 mercurial/templates/monoblue/footer.tmpl create mode 100644 mercurial/templates/monoblue/graph.tmpl create mode 100644 mercurial/templates/monoblue/graphentry.tmpl create mode 100644 mercurial/templates/monoblue/header.tmpl create mode 100644 mercurial/templates/monoblue/help.tmpl create mode 100644 mercurial/templates/monoblue/helptopics.tmpl create mode 100644 mercurial/templates/monoblue/index.tmpl create mode 100644 mercurial/templates/monoblue/manifest.tmpl create mode 100644 mercurial/templates/monoblue/map create mode 100644 mercurial/templates/monoblue/notfound.tmpl create mode 100644 mercurial/templates/monoblue/search.tmpl create mode 100644 mercurial/templates/monoblue/shortlog.tmpl create mode 100644 mercurial/templates/monoblue/summary.tmpl create mode 100644 mercurial/templates/monoblue/tags.tmpl create mode 100644 mercurial/templates/paper/__init__.py create mode 100644 mercurial/templates/paper/bookmarks.tmpl create mode 100644 mercurial/templates/paper/branches.tmpl create mode 100644 mercurial/templates/paper/changeset.tmpl create mode 100644 mercurial/templates/paper/diffstat.tmpl create mode 100644 mercurial/templates/paper/error.tmpl create mode 100644 mercurial/templates/paper/fileannotate.tmpl create mode 100644 mercurial/templates/paper/filecomparison.tmpl create mode 100644 mercurial/templates/paper/filediff.tmpl create mode 100644 mercurial/templates/paper/filelog.tmpl create mode 100644 mercurial/templates/paper/filelogentry.tmpl create mode 100644 mercurial/templates/paper/filerevision.tmpl create mode 100644 mercurial/templates/paper/footer.tmpl create mode 100644 mercurial/templates/paper/graph.tmpl create mode 100644 mercurial/templates/paper/graphentry.tmpl create mode 100644 mercurial/templates/paper/header.tmpl create mode 100644 mercurial/templates/paper/help.tmpl create mode 100644 mercurial/templates/paper/helptopics.tmpl create mode 100644 mercurial/templates/paper/index.tmpl create mode 100644 mercurial/templates/paper/manifest.tmpl create mode 100644 mercurial/templates/paper/map create mode 100644 mercurial/templates/paper/notfound.tmpl create mode 100644 mercurial/templates/paper/search.tmpl create mode 100644 mercurial/templates/paper/shortlog.tmpl create mode 100644 mercurial/templates/paper/shortlogentry.tmpl create mode 100644 mercurial/templates/paper/tags.tmpl create mode 100644 mercurial/templates/raw/__init__.py create mode 100644 mercurial/templates/raw/changelog.tmpl create mode 100644 mercurial/templates/raw/changeset.tmpl create mode 100644 mercurial/templates/raw/error.tmpl create mode 100644 mercurial/templates/raw/fileannotate.tmpl create mode 100644 mercurial/templates/raw/filediff.tmpl create mode 100644 mercurial/templates/raw/graph.tmpl create mode 100644 mercurial/templates/raw/graphedge.tmpl create mode 100644 mercurial/templates/raw/graphnode.tmpl create mode 100644 mercurial/templates/raw/index.tmpl create mode 100644 mercurial/templates/raw/logentry.tmpl create mode 100644 mercurial/templates/raw/manifest.tmpl create mode 100644 mercurial/templates/raw/map create mode 100644 mercurial/templates/raw/notfound.tmpl create mode 100644 mercurial/templates/raw/search.tmpl create mode 100644 mercurial/templates/rss/__init__.py create mode 100644 mercurial/templates/rss/bookmarkentry.tmpl create mode 100644 mercurial/templates/rss/bookmarks.tmpl create mode 100644 mercurial/templates/rss/branchentry.tmpl create mode 100644 mercurial/templates/rss/branches.tmpl create mode 100644 mercurial/templates/rss/changelog.tmpl create mode 100644 mercurial/templates/rss/changelogentry.tmpl create mode 100644 mercurial/templates/rss/error.tmpl create mode 100644 mercurial/templates/rss/filelog.tmpl create mode 100644 mercurial/templates/rss/filelogentry.tmpl create mode 100644 mercurial/templates/rss/header.tmpl create mode 100644 mercurial/templates/rss/map create mode 100644 mercurial/templates/rss/tagentry.tmpl create mode 100644 mercurial/templates/rss/tags.tmpl create mode 100644 mercurial/templates/spartan/__init__.py create mode 100644 mercurial/templates/spartan/branches.tmpl create mode 100644 mercurial/templates/spartan/changelog.tmpl create mode 100644 mercurial/templates/spartan/changelogentry.tmpl create mode 100644 mercurial/templates/spartan/changeset.tmpl create mode 100644 mercurial/templates/spartan/error.tmpl create mode 100644 mercurial/templates/spartan/fileannotate.tmpl create mode 100644 mercurial/templates/spartan/filediff.tmpl create mode 100644 mercurial/templates/spartan/filelog.tmpl create mode 100644 mercurial/templates/spartan/filelogentry.tmpl create mode 100644 mercurial/templates/spartan/filerevision.tmpl create mode 100644 mercurial/templates/spartan/footer.tmpl create mode 100644 mercurial/templates/spartan/graph.tmpl create mode 100644 mercurial/templates/spartan/graphentry.tmpl create mode 100644 mercurial/templates/spartan/header.tmpl create mode 100644 mercurial/templates/spartan/index.tmpl create mode 100644 mercurial/templates/spartan/manifest.tmpl create mode 100644 mercurial/templates/spartan/map create mode 100644 mercurial/templates/spartan/notfound.tmpl create mode 100644 mercurial/templates/spartan/search.tmpl create mode 100644 mercurial/templates/spartan/shortlog.tmpl create mode 100644 mercurial/templates/spartan/shortlogentry.tmpl create mode 100644 mercurial/templates/spartan/tags.tmpl create mode 100644 mercurial/templates/static/__init__.py create mode 100644 mercurial/templates/static/background.png create mode 100644 mercurial/templates/static/coal-file.png create mode 100644 mercurial/templates/static/coal-folder.png create mode 100644 mercurial/templates/static/feed-icon-14x14.png create mode 100644 mercurial/templates/static/followlines.js create mode 100644 mercurial/templates/static/hgicon.png create mode 100644 mercurial/templates/static/hglogo.png create mode 100644 mercurial/templates/static/mercurial.js create mode 100644 mercurial/templates/static/style-extra-coal.css create mode 100644 mercurial/templates/static/style-gitweb.css create mode 100644 mercurial/templates/static/style-monoblue.css create mode 100644 mercurial/templates/static/style-paper.css create mode 100644 mercurial/templates/static/style.css create mode 100644 mercurial/templateutil.py create mode 100644 mercurial/testing/__init__.py create mode 100644 mercurial/testing/revlog.py create mode 100644 mercurial/testing/storage.py create mode 100644 mercurial/thirdparty/__init__.py create mode 100644 mercurial/thirdparty/attr/LICENSE create mode 100644 mercurial/thirdparty/attr/__init__.py create mode 100644 mercurial/thirdparty/attr/__init__.pyi create mode 100644 mercurial/thirdparty/attr/_cmp.py create mode 100644 mercurial/thirdparty/attr/_cmp.pyi create mode 100644 mercurial/thirdparty/attr/_compat.py create mode 100644 mercurial/thirdparty/attr/_config.py create mode 100644 mercurial/thirdparty/attr/_funcs.py create mode 100644 mercurial/thirdparty/attr/_make.py create mode 100644 mercurial/thirdparty/attr/_next_gen.py create mode 100644 mercurial/thirdparty/attr/_version_info.py create mode 100644 mercurial/thirdparty/attr/_version_info.pyi create mode 100644 mercurial/thirdparty/attr/converters.py create mode 100644 mercurial/thirdparty/attr/converters.pyi create mode 100644 mercurial/thirdparty/attr/exceptions.py create mode 100644 mercurial/thirdparty/attr/exceptions.pyi create mode 100644 mercurial/thirdparty/attr/filters.py create mode 100644 mercurial/thirdparty/attr/filters.pyi create mode 100644 mercurial/thirdparty/attr/py.typed create mode 100644 mercurial/thirdparty/attr/setters.py create mode 100644 mercurial/thirdparty/attr/setters.pyi create mode 100644 mercurial/thirdparty/attr/validators.py create mode 100644 mercurial/thirdparty/attr/validators.pyi create mode 100644 mercurial/thirdparty/cbor/.travis.yml create mode 100644 mercurial/thirdparty/cbor/LICENSE.txt create mode 100644 mercurial/thirdparty/cbor/README.rst create mode 100644 mercurial/thirdparty/cbor/__init__.py create mode 100644 mercurial/thirdparty/cbor/cbor2/__init__.py create mode 100644 mercurial/thirdparty/cbor/cbor2/compat.py create mode 100644 mercurial/thirdparty/cbor/cbor2/decoder.py create mode 100644 mercurial/thirdparty/cbor/cbor2/encoder.py create mode 100644 mercurial/thirdparty/cbor/cbor2/types.py create mode 100644 mercurial/thirdparty/sha1dc/LICENSE.txt create mode 100644 mercurial/thirdparty/sha1dc/README.md create mode 100644 mercurial/thirdparty/sha1dc/cext.c create mode 100644 mercurial/thirdparty/sha1dc/lib/sha1.c create mode 100644 mercurial/thirdparty/sha1dc/lib/sha1.h create mode 100644 mercurial/thirdparty/sha1dc/lib/ubc_check.c create mode 100644 mercurial/thirdparty/sha1dc/lib/ubc_check.h create mode 100644 mercurial/thirdparty/tomli/LICENSE create mode 100644 mercurial/thirdparty/tomli/README.md create mode 100644 mercurial/thirdparty/tomli/__init__.py create mode 100644 mercurial/thirdparty/tomli/_parser.py create mode 100644 mercurial/thirdparty/tomli/_re.py create mode 100644 mercurial/thirdparty/tomli/_types.py create mode 100644 mercurial/thirdparty/tomli/py.typed create mode 100644 mercurial/thirdparty/xdiff/xdiff.h create mode 100644 mercurial/thirdparty/xdiff/xdiffi.c create mode 100644 mercurial/thirdparty/xdiff/xdiffi.h create mode 100644 mercurial/thirdparty/xdiff/xinclude.h create mode 100644 mercurial/thirdparty/xdiff/xmacros.h create mode 100644 mercurial/thirdparty/xdiff/xprepare.c create mode 100644 mercurial/thirdparty/xdiff/xprepare.h create mode 100644 mercurial/thirdparty/xdiff/xtypes.h create mode 100644 mercurial/thirdparty/xdiff/xutils.c create mode 100644 mercurial/thirdparty/xdiff/xutils.h create mode 100644 mercurial/thirdparty/zope/__init__.py create mode 100644 mercurial/thirdparty/zope/interface/LICENSE.txt create mode 100644 mercurial/thirdparty/zope/interface/__init__.py create mode 100644 mercurial/thirdparty/zope/interface/_compat.py create mode 100644 mercurial/thirdparty/zope/interface/_flatten.py create mode 100644 mercurial/thirdparty/zope/interface/_zope_interface_coptimizations.c create mode 100644 mercurial/thirdparty/zope/interface/adapter.py create mode 100644 mercurial/thirdparty/zope/interface/advice.py create mode 100644 mercurial/thirdparty/zope/interface/common/__init__.py create mode 100644 mercurial/thirdparty/zope/interface/common/idatetime.py create mode 100644 mercurial/thirdparty/zope/interface/common/interfaces.py create mode 100644 mercurial/thirdparty/zope/interface/common/mapping.py create mode 100644 mercurial/thirdparty/zope/interface/common/sequence.py create mode 100644 mercurial/thirdparty/zope/interface/declarations.py create mode 100644 mercurial/thirdparty/zope/interface/document.py create mode 100644 mercurial/thirdparty/zope/interface/exceptions.py create mode 100644 mercurial/thirdparty/zope/interface/interface.py create mode 100644 mercurial/thirdparty/zope/interface/interfaces.py create mode 100644 mercurial/thirdparty/zope/interface/registry.py create mode 100644 mercurial/thirdparty/zope/interface/ro.py create mode 100644 mercurial/thirdparty/zope/interface/verify.py create mode 100644 mercurial/transaction.py create mode 100644 mercurial/treediscovery.py create mode 100644 mercurial/txnutil.py create mode 100644 mercurial/typelib.py create mode 100644 mercurial/ui.py create mode 100644 mercurial/unionrepo.py create mode 100644 mercurial/upgrade.py create mode 100644 mercurial/upgrade_utils/__init__.py create mode 100644 mercurial/upgrade_utils/actions.py create mode 100644 mercurial/upgrade_utils/auto_upgrade.py create mode 100644 mercurial/upgrade_utils/engine.py create mode 100644 mercurial/url.py create mode 100644 mercurial/urllibcompat.py create mode 100644 mercurial/util.py create mode 100644 mercurial/utils/__init__.py create mode 100644 mercurial/utils/cborutil.py create mode 100644 mercurial/utils/compression.py create mode 100644 mercurial/utils/dateutil.py create mode 100644 mercurial/utils/hashutil.py create mode 100644 mercurial/utils/memorytop.py create mode 100644 mercurial/utils/procutil.py create mode 100644 mercurial/utils/repoviewutil.py create mode 100644 mercurial/utils/resourceutil.py create mode 100644 mercurial/utils/storageutil.py create mode 100644 mercurial/utils/stringutil.py create mode 100644 mercurial/utils/urlutil.py create mode 100644 mercurial/verify.py create mode 100644 mercurial/vfs.py create mode 100644 mercurial/win32.py create mode 100644 mercurial/windows.py create mode 100644 mercurial/wireprotoframing.py create mode 100644 mercurial/wireprotoserver.py create mode 100644 mercurial/wireprototypes.py create mode 100644 mercurial/wireprotov1peer.py create mode 100644 mercurial/wireprotov1server.py create mode 100644 mercurial/worker.py create mode 100644 pyproject.toml create mode 100644 relnotes/5.1 create mode 100644 relnotes/5.2 create mode 100644 relnotes/5.3 create mode 100644 relnotes/5.4 create mode 100644 relnotes/5.5 create mode 100644 relnotes/5.6 create mode 100644 relnotes/5.7 create mode 100644 relnotes/5.8 create mode 100644 relnotes/5.9 create mode 100644 relnotes/6.0 create mode 100644 relnotes/6.1 create mode 100644 relnotes/6.2 create mode 100644 relnotes/6.3 create mode 100644 relnotes/6.4 create mode 100644 relnotes/6.5 create mode 100644 relnotes/6.6 create mode 100644 relnotes/6.7 create mode 100644 relnotes/next create mode 100644 rust/.cargo/config create mode 100644 rust/Cargo.lock create mode 100644 rust/Cargo.toml create mode 100644 rust/README.rst create mode 100644 rust/chg/Cargo.lock create mode 100644 rust/chg/Cargo.toml create mode 100644 rust/chg/build.rs create mode 100644 rust/chg/src/attachio.rs create mode 100644 rust/chg/src/clientext.rs create mode 100644 rust/chg/src/lib.rs create mode 100644 rust/chg/src/locator.rs create mode 100644 rust/chg/src/main.rs create mode 100644 rust/chg/src/message.rs create mode 100644 rust/chg/src/procutil.rs create mode 100644 rust/chg/src/runcommand.rs create mode 100644 rust/chg/src/sendfds.c create mode 100644 rust/chg/src/sighandlers.c create mode 100644 rust/chg/src/uihandler.rs create mode 100644 rust/clippy.toml create mode 100644 rust/hg-core/Cargo.toml create mode 100644 rust/hg-core/examples/nodemap/index.rs create mode 100644 rust/hg-core/examples/nodemap/main.rs create mode 100644 rust/hg-core/src/ancestors.rs create mode 100644 rust/hg-core/src/checkexec.rs create mode 100644 rust/hg-core/src/config/config_items.rs create mode 100644 rust/hg-core/src/config/layer.rs create mode 100644 rust/hg-core/src/config/mod.rs create mode 100644 rust/hg-core/src/config/plain_info.rs create mode 100644 rust/hg-core/src/config/values.rs create mode 100644 rust/hg-core/src/copy_tracing.rs create mode 100644 rust/hg-core/src/copy_tracing/tests.rs create mode 100644 rust/hg-core/src/copy_tracing/tests_support.rs create mode 100644 rust/hg-core/src/dagops.rs create mode 100644 rust/hg-core/src/dirstate.rs create mode 100644 rust/hg-core/src/dirstate/dirs_multiset.rs create mode 100644 rust/hg-core/src/dirstate/entry.rs create mode 100644 rust/hg-core/src/dirstate/parsers.rs create mode 100644 rust/hg-core/src/dirstate/status.rs create mode 100644 rust/hg-core/src/dirstate_tree.rs create mode 100644 rust/hg-core/src/dirstate_tree/dirstate_map.rs create mode 100644 rust/hg-core/src/dirstate_tree/on_disk.rs create mode 100644 rust/hg-core/src/dirstate_tree/owning.rs create mode 100644 rust/hg-core/src/dirstate_tree/path_with_basename.rs create mode 100644 rust/hg-core/src/dirstate_tree/status.rs create mode 100644 rust/hg-core/src/discovery.rs create mode 100644 rust/hg-core/src/errors.rs create mode 100644 rust/hg-core/src/exit_codes.rs create mode 100644 rust/hg-core/src/filepatterns.rs create mode 100644 rust/hg-core/src/lib.rs create mode 100644 rust/hg-core/src/lock.rs create mode 100644 rust/hg-core/src/logging.rs create mode 100644 rust/hg-core/src/matchers.rs create mode 100644 rust/hg-core/src/narrow.rs create mode 100644 rust/hg-core/src/operations/cat.rs create mode 100644 rust/hg-core/src/operations/debugdata.rs create mode 100644 rust/hg-core/src/operations/list_tracked_files.rs create mode 100644 rust/hg-core/src/operations/mod.rs create mode 100644 rust/hg-core/src/operations/status_rev_rev.rs create mode 100644 rust/hg-core/src/repo.rs create mode 100644 rust/hg-core/src/requirements.rs create mode 100644 rust/hg-core/src/revlog/changelog.rs create mode 100644 rust/hg-core/src/revlog/filelog.rs create mode 100644 rust/hg-core/src/revlog/index.rs create mode 100644 rust/hg-core/src/revlog/manifest.rs create mode 100644 rust/hg-core/src/revlog/mod.rs create mode 100644 rust/hg-core/src/revlog/node.rs create mode 100644 rust/hg-core/src/revlog/nodemap.rs create mode 100644 rust/hg-core/src/revlog/nodemap_docket.rs create mode 100644 rust/hg-core/src/revlog/patch.rs create mode 100644 rust/hg-core/src/revlog/path_encode.rs create mode 100644 rust/hg-core/src/revset.rs create mode 100644 rust/hg-core/src/sparse.rs create mode 100644 rust/hg-core/src/testing.rs create mode 100644 rust/hg-core/src/utils.rs create mode 100644 rust/hg-core/src/utils/debug.rs create mode 100644 rust/hg-core/src/utils/files.rs create mode 100644 rust/hg-core/src/utils/hg_path.rs create mode 100644 rust/hg-core/src/utils/path_auditor.rs create mode 100644 rust/hg-core/src/vfs.rs create mode 100644 rust/hg-core/tests/test_missing_ancestors.rs create mode 100644 rust/hg-cpython/Cargo.toml create mode 100644 rust/hg-cpython/src/ancestors.rs create mode 100644 rust/hg-cpython/src/cindex.rs create mode 100644 rust/hg-cpython/src/conversion.rs create mode 100644 rust/hg-cpython/src/copy_tracing.rs create mode 100644 rust/hg-cpython/src/dagops.rs create mode 100644 rust/hg-cpython/src/debug.rs create mode 100644 rust/hg-cpython/src/dirstate.rs create mode 100644 rust/hg-cpython/src/dirstate/copymap.rs create mode 100644 rust/hg-cpython/src/dirstate/dirs_multiset.rs create mode 100644 rust/hg-cpython/src/dirstate/dirstate_map.rs create mode 100644 rust/hg-cpython/src/dirstate/item.rs create mode 100644 rust/hg-cpython/src/dirstate/status.rs create mode 100644 rust/hg-cpython/src/discovery.rs create mode 100644 rust/hg-cpython/src/exceptions.rs create mode 100644 rust/hg-cpython/src/lib.rs create mode 100644 rust/hg-cpython/src/pybytes_deref.rs create mode 100644 rust/hg-cpython/src/ref_sharing.rs create mode 100644 rust/hg-cpython/src/revlog.rs create mode 100644 rust/hg-cpython/src/utils.rs create mode 100644 rust/hgcli/.cargo/config create mode 100644 rust/hgcli/Cargo.lock create mode 100644 rust/hgcli/Cargo.toml create mode 100644 rust/hgcli/README.md create mode 100644 rust/hgcli/build.rs create mode 100644 rust/hgcli/pyoxidizer.bzl create mode 100644 rust/hgcli/src/main.rs create mode 100644 rust/rhg/Cargo.toml create mode 100644 rust/rhg/README.md create mode 100644 rust/rhg/src/blackbox.rs create mode 100644 rust/rhg/src/color.rs create mode 100644 rust/rhg/src/commands/cat.rs create mode 100644 rust/rhg/src/commands/config.rs create mode 100644 rust/rhg/src/commands/debugdata.rs create mode 100644 rust/rhg/src/commands/debugignorerhg.rs create mode 100644 rust/rhg/src/commands/debugrequirements.rs create mode 100644 rust/rhg/src/commands/debugrhgsparse.rs create mode 100644 rust/rhg/src/commands/files.rs create mode 100644 rust/rhg/src/commands/root.rs create mode 100644 rust/rhg/src/commands/status.rs create mode 100644 rust/rhg/src/error.rs create mode 100644 rust/rhg/src/main.rs create mode 100644 rust/rhg/src/ui.rs create mode 100644 rust/rhg/src/utils/path_utils.rs create mode 100644 rustfmt.toml create mode 100644 setup.cfg create mode 100644 setup.py create mode 100644 tests/.balto.toml create mode 100644 tests/README create mode 100644 tests/artifacts/PURPOSE create mode 100644 tests/artifacts/cache/big-file-churn.hg.md5 create mode 100755 tests/artifacts/scripts/generate-churning-bundle.py create mode 100644 tests/autodiff.py create mode 100644 tests/basic_test_result.py create mode 100644 tests/binfile.bin create mode 100644 tests/blackbox-readonly-dispatch.py create mode 100644 tests/blacklists/README create mode 100644 tests/blacklists/fsmonitor create mode 100644 tests/blacklists/linux-vfat create mode 100644 tests/blacklists/nix create mode 100644 tests/bruterebase.py create mode 100644 tests/bundles/darcs1.hg create mode 100644 tests/bundles/hgweb+obs.hg create mode 100644 tests/bundles/issue4041.hg create mode 100644 tests/bundles/issue4438-r1.hg create mode 100644 tests/bundles/issue4438-r2.hg create mode 100644 tests/bundles/issue6528.hg-v1 create mode 100644 tests/bundles/issue6528.hg-v2 create mode 100644 tests/bundles/issue6528.tar create mode 100644 tests/bundles/legacy-encoding.hg create mode 100644 tests/bundles/rebase-revset.hg create mode 100644 tests/bundles/rebase.hg create mode 100755 tests/bundles/rebase.sh create mode 100644 tests/bundles/remote.hg create mode 100755 tests/bundles/remote.sh create mode 100755 tests/bundles/rename.sh create mode 100644 tests/bundles/renames.hg create mode 100644 tests/bundles/tampered.hg create mode 100644 tests/bundles/test-invalid-branch-name.hg create mode 100644 tests/bundles/test-keyword.hg create mode 100644 tests/bundles/test-manifest.hg create mode 100644 tests/bundles/test-merge-symlinks.hg create mode 100644 tests/bundles/test-no-symlinks.hg create mode 100755 tests/bundles/test-revlog-diff-relative-to-nullrev.sh create mode 100644 tests/bundles/test-revlog-diff-relative-to-nullrev.tar create mode 100644 tests/bzr-definitions create mode 100644 tests/cgienv create mode 100755 tests/check-gendoc create mode 100755 tests/check-perf-code.py create mode 100644 tests/common-pattern.py create mode 100644 tests/crashgetbundler.py create mode 100644 tests/drawdag.py create mode 100755 tests/dumbhttp.py create mode 100755 tests/dummysmtpd.py create mode 100755 tests/dummyssh create mode 100755 tests/f create mode 100644 tests/failfilemerge.py create mode 100644 tests/fakedirstatewritetime.py create mode 100644 tests/fakemergerecord.py create mode 100644 tests/fakepatchtime.py create mode 100755 tests/filterpyflakes.py create mode 100755 tests/filtertraceback.py create mode 100644 tests/flagprocessorext.py create mode 100755 tests/fsmonitor-run-tests.py create mode 100644 tests/generate-working-copy-states.py create mode 100755 tests/get-with-headers.py create mode 100644 tests/gpg/pubring.gpg create mode 100644 tests/gpg/secring.gpg create mode 100644 tests/gpg/trustdb.gpg create mode 100644 tests/helper-runtests.sh create mode 100644 tests/helpers-testrepo.sh create mode 100644 tests/heredoctest.py create mode 100755 tests/hghave create mode 100644 tests/hghave.py create mode 100644 tests/hgterm.ti create mode 100644 tests/hgweberror.py create mode 100644 tests/histedit-helpers.sh create mode 100644 tests/httpserverauth.py create mode 100644 tests/hypothesishelpers.py create mode 100755 tests/killdaemons.py create mode 100644 tests/list-tree.py create mode 100644 tests/lockdelay.py create mode 100644 tests/logexceptions.py create mode 100755 tests/ls-l.py create mode 100755 tests/md5sum.py create mode 100644 tests/missing-comment.hg create mode 100644 tests/mockblackbox.py create mode 100644 tests/mockmakedate.py create mode 100644 tests/mocktime.py create mode 100644 tests/narrow-library.sh create mode 100644 tests/notcapable create mode 100755 tests/pdiff create mode 100644 tests/phabricator/accept-4564.json create mode 100644 tests/phabricator/accept-7913.json create mode 100644 tests/phabricator/phab-conduit.json create mode 100644 tests/phabricator/phabimport-multi-drev.json create mode 100644 tests/phabricator/phabimport-stack.json create mode 100644 tests/phabricator/phabread-4480.json create mode 100644 tests/phabricator/phabread-conduit-error.json create mode 100644 tests/phabricator/phabread-empty-drev.json create mode 100644 tests/phabricator/phabread-multi-drev.json create mode 100644 tests/phabricator/phabread-str-time.json create mode 100644 tests/phabricator/phabsend-add-parent-setup.json create mode 100644 tests/phabricator/phabsend-add-parent.json create mode 100644 tests/phabricator/phabsend-binary-renames.json create mode 100644 tests/phabricator/phabsend-binary.json create mode 100644 tests/phabricator/phabsend-comment-created.json create mode 100644 tests/phabricator/phabsend-comment-updated.json create mode 100644 tests/phabricator/phabsend-create-alpha.json create mode 100644 tests/phabricator/phabsend-create-public.json create mode 100644 tests/phabricator/phabsend-fold-extend-end.json create mode 100644 tests/phabricator/phabsend-fold-extend-front.json create mode 100644 tests/phabricator/phabsend-fold-fold-end.json create mode 100644 tests/phabricator/phabsend-fold-immutable.json create mode 100644 tests/phabricator/phabsend-fold-initial.json create mode 100644 tests/phabricator/phabsend-fold-no-changes.json create mode 100644 tests/phabricator/phabsend-fold-split-end.json create mode 100644 tests/phabricator/phabsend-fold-updated.json create mode 100644 tests/phabricator/phabsend-hash-fixes.json create mode 100644 tests/phabricator/phabsend-no-restack-orphan.json create mode 100644 tests/phabricator/phabsend-skipped.json create mode 100644 tests/phabricator/phabsend-update-alpha-create-beta.json create mode 100644 tests/phabricator/phabupdate-change-6876.json create mode 100644 tests/phabricator/phabupdate-revs.json create mode 100755 tests/printenv.py create mode 100644 tests/printrevset.py create mode 100644 tests/pullext.py create mode 100755 tests/readlink.py create mode 100644 tests/remotefilelog-getflogheads.py create mode 100644 tests/remotefilelog-library.sh create mode 100755 tests/revlog-formatv0.py create mode 100644 tests/revnamesext.py create mode 100755 tests/run-tests.py create mode 100755 tests/seq.py create mode 100755 tests/sha256line.py create mode 100644 tests/silenttestrunner.py create mode 100644 tests/simplestorerepo.py create mode 100644 tests/sitecustomize.py create mode 100644 tests/sshprotoext.py create mode 100644 tests/sslcerts/README create mode 100644 tests/sslcerts/client-cert.pem create mode 100644 tests/sslcerts/client-key-decrypted.pem create mode 100644 tests/sslcerts/client-key.pem create mode 100644 tests/sslcerts/priv.pem create mode 100644 tests/sslcerts/pub-expired.pem create mode 100644 tests/sslcerts/pub-not-yet.pem create mode 100644 tests/sslcerts/pub-other.pem create mode 100644 tests/sslcerts/pub.pem create mode 100755 tests/svn-safe-append.py create mode 100644 tests/svn/branches.svndump create mode 100644 tests/svn/empty.svndump create mode 100644 tests/svn/encoding.svndump create mode 100644 tests/svn/move.svndump create mode 100644 tests/svn/replace.svndump create mode 100644 tests/svn/startrev.svndump create mode 100755 tests/svn/svndump-branches.sh create mode 100755 tests/svn/svndump-empty.sh create mode 100755 tests/svn/svndump-encoding.sh create mode 100755 tests/svn/svndump-move.sh create mode 100755 tests/svn/svndump-replace.sh create mode 100755 tests/svn/svndump-startrev.sh create mode 100755 tests/svn/svndump-tags.sh create mode 100644 tests/svn/tags.svndump create mode 100644 tests/svnurlof.py create mode 100644 tests/svnxml.py create mode 100644 tests/test-abort-checkin.t create mode 100644 tests/test-absorb-edit-lines.t create mode 100644 tests/test-absorb-filefixupstate.py create mode 100644 tests/test-absorb-phase.t create mode 100644 tests/test-absorb-rename.t create mode 100644 tests/test-absorb-strip.t create mode 100644 tests/test-absorb-unfinished.t create mode 100644 tests/test-absorb.t create mode 100644 tests/test-acl.t create mode 100644 tests/test-add.t create mode 100644 tests/test-addremove-similar.t create mode 100644 tests/test-addremove.t create mode 100644 tests/test-admin-commands.py create mode 100644 tests/test-admin-commands.t create mode 100644 tests/test-alias.t create mode 100644 tests/test-amend-subrepo.t create mode 100644 tests/test-amend.t create mode 100644 tests/test-ancestor.py create mode 100644 tests/test-ancestor.py.out create mode 100644 tests/test-annotate.py create mode 100644 tests/test-annotate.t create mode 100644 tests/test-arbitraryfilectx.t create mode 100644 tests/test-archive-symlinks.t create mode 100644 tests/test-archive.t create mode 100644 tests/test-atomictempfile.py create mode 100644 tests/test-audit-path.t create mode 100644 tests/test-audit-subrepo.t create mode 100644 tests/test-automv.t create mode 100644 tests/test-backout.t create mode 100644 tests/test-backwards-remove.t create mode 100644 tests/test-bad-extension.t create mode 100644 tests/test-bad-pull.t create mode 100644 tests/test-basic.t create mode 100644 tests/test-batching.py create mode 100644 tests/test-batching.py.out create mode 100644 tests/test-bdiff.py create mode 100644 tests/test-bheads.t create mode 100644 tests/test-bisect.t create mode 100644 tests/test-bisect2.t create mode 100644 tests/test-bisect3.t create mode 100644 tests/test-blackbox.t create mode 100644 tests/test-bookflow.t create mode 100644 tests/test-bookmarks-corner-case.t create mode 100644 tests/test-bookmarks-current.t create mode 100644 tests/test-bookmarks-merge.t create mode 100644 tests/test-bookmarks-pushpull.t create mode 100644 tests/test-bookmarks-rebase.t create mode 100644 tests/test-bookmarks-strip.t create mode 100644 tests/test-bookmarks.t create mode 100644 tests/test-branch-change.t create mode 100644 tests/test-branch-option.t create mode 100644 tests/test-branch-tag-confict.t create mode 100644 tests/test-branches.t create mode 100644 tests/test-bugzilla.t create mode 100644 tests/test-bundle-phase-internal.t create mode 100644 tests/test-bundle-phases.t create mode 100644 tests/test-bundle-r.t create mode 100644 tests/test-bundle-type.t create mode 100644 tests/test-bundle-vs-outgoing.t create mode 100644 tests/test-bundle.t create mode 100644 tests/test-bundle2-exchange.t create mode 100644 tests/test-bundle2-format.t create mode 100644 tests/test-bundle2-multiple-changegroups.t create mode 100644 tests/test-bundle2-pushback.t create mode 100644 tests/test-bundle2-remote-changegroup.t create mode 100644 tests/test-byteify-strings.t create mode 100644 tests/test-cache-abuse.t create mode 100644 tests/test-cappedreader.py create mode 100644 tests/test-casecollision-merge.t create mode 100644 tests/test-casecollision.t create mode 100644 tests/test-casefolding.t create mode 100644 tests/test-cat.t create mode 100644 tests/test-cbor.py create mode 100644 tests/test-censor.t create mode 100644 tests/test-censor2.t create mode 100644 tests/test-chainsaw-update.t create mode 100644 tests/test-changelog-exec.t create mode 100644 tests/test-check-cargo-lock.t create mode 100644 tests/test-check-clang-format.t create mode 100644 tests/test-check-code.t create mode 100644 tests/test-check-commit.t create mode 100644 tests/test-check-config.t create mode 100644 tests/test-check-encoding.t create mode 100644 tests/test-check-execute.t create mode 100644 tests/test-check-format.t create mode 100644 tests/test-check-help.t create mode 100644 tests/test-check-interfaces.py create mode 100644 tests/test-check-interfaces.py.out create mode 100644 tests/test-check-jshint.t create mode 100644 tests/test-check-module-imports.t create mode 100644 tests/test-check-py3-compat.t create mode 100644 tests/test-check-pyflakes.t create mode 100644 tests/test-check-pylint.t create mode 100644 tests/test-check-rust-format.t create mode 100644 tests/test-check-shbang.t create mode 100644 tests/test-chg.t create mode 100644 tests/test-children.t create mode 100644 tests/test-churn.t create mode 100644 tests/test-clone-cgi.t create mode 100644 tests/test-clone-pull-corruption.t create mode 100644 tests/test-clone-r.t create mode 100644 tests/test-clone-stream-format.t create mode 100644 tests/test-clone-stream-revlog-split.t create mode 100644 tests/test-clone-stream.t create mode 100644 tests/test-clone-update-order.t create mode 100644 tests/test-clone.t create mode 100644 tests/test-clonebundles-autogen.t create mode 100644 tests/test-clonebundles.t create mode 100644 tests/test-close-head.t create mode 100644 tests/test-commandserver.t create mode 100644 tests/test-commit-amend.t create mode 100644 tests/test-commit-interactive-curses.t create mode 100644 tests/test-commit-interactive.t create mode 100644 tests/test-commit-multiple.t create mode 100644 tests/test-commit-unresolved.t create mode 100644 tests/test-commit.t create mode 100644 tests/test-committer.t create mode 100644 tests/test-completion.t create mode 100644 tests/test-config-env.py create mode 100644 tests/test-config-env.py.out create mode 100644 tests/test-config-parselist.py create mode 100644 tests/test-config.t create mode 100644 tests/test-conflict.t create mode 100644 tests/test-confused-revert.t create mode 100644 tests/test-context-metadata.t create mode 100644 tests/test-context.py create mode 100644 tests/test-context.py.out create mode 100644 tests/test-contrib-check-code.t create mode 100644 tests/test-contrib-check-commit.t create mode 100644 tests/test-contrib-dumprevlog.t create mode 100644 tests/test-contrib-emacs.t create mode 100644 tests/test-contrib-perf.t create mode 100644 tests/test-contrib-pull-logger.t create mode 100644 tests/test-contrib-relnotes.t create mode 100644 tests/test-contrib-testparseutil.t create mode 100644 tests/test-contrib.t create mode 100644 tests/test-convert-authormap.t create mode 100644 tests/test-convert-baz.t create mode 100644 tests/test-convert-bzr-114.t create mode 100644 tests/test-convert-bzr-directories.t create mode 100644 tests/test-convert-bzr-ghosts.t create mode 100644 tests/test-convert-bzr-merges.t create mode 100644 tests/test-convert-bzr-treeroot.t create mode 100644 tests/test-convert-bzr.t create mode 100644 tests/test-convert-clonebranches.t create mode 100644 tests/test-convert-cvs-branch.t create mode 100644 tests/test-convert-cvs-detectmerge.t create mode 100644 tests/test-convert-cvs-synthetic.t create mode 100644 tests/test-convert-cvs.t create mode 100644 tests/test-convert-cvsnt-mergepoints.rlog create mode 100644 tests/test-convert-cvsnt-mergepoints.t create mode 100644 tests/test-convert-darcs.t create mode 100644 tests/test-convert-datesort.t create mode 100644 tests/test-convert-filemap.t create mode 100644 tests/test-convert-git.t create mode 100644 tests/test-convert-hg-sink.t create mode 100644 tests/test-convert-hg-source.t create mode 100644 tests/test-convert-hg-startrev.t create mode 100644 tests/test-convert-hg-svn.t create mode 100644 tests/test-convert-identity.t create mode 100644 tests/test-convert-mtn.t create mode 100644 tests/test-convert-p4-filetypes.t create mode 100644 tests/test-convert-p4.t create mode 100644 tests/test-convert-splicemap.t create mode 100644 tests/test-convert-svn-branches.t create mode 100644 tests/test-convert-svn-encoding.t create mode 100644 tests/test-convert-svn-move.t create mode 100644 tests/test-convert-svn-sink.t create mode 100644 tests/test-convert-svn-source.t create mode 100644 tests/test-convert-svn-startrev.t create mode 100644 tests/test-convert-svn-tags.t create mode 100644 tests/test-convert-tagsbranch-topology.t create mode 100644 tests/test-convert-tla.t create mode 100644 tests/test-convert.t create mode 100644 tests/test-copies-chain-merge.t create mode 100644 tests/test-copies-in-changeset.t create mode 100644 tests/test-copies-unrelated.t create mode 100644 tests/test-copies.t create mode 100644 tests/test-copy-move-merge.t create mode 100644 tests/test-copy.t create mode 100644 tests/test-copytrace-heuristics.t create mode 100644 tests/test-custom-filters.t create mode 100644 tests/test-debian-packages.t create mode 100644 tests/test-debug-rebuild-dirstate.t create mode 100644 tests/test-debug-revlog-stats.t create mode 100644 tests/test-debugbackupbundle.t create mode 100644 tests/test-debugbuilddag.t create mode 100644 tests/test-debugbundle.t create mode 100644 tests/test-debugcommands.t create mode 100644 tests/test-debugextensions.t create mode 100644 tests/test-debugindexdot.t create mode 100644 tests/test-debugrename.t create mode 100644 tests/test-default-push.t create mode 100644 tests/test-demandimport.py create mode 100644 tests/test-devel-warnings.t create mode 100644 tests/test-diff-antipatience.t create mode 100644 tests/test-diff-binary-file.t create mode 100644 tests/test-diff-change.t create mode 100644 tests/test-diff-color.t create mode 100644 tests/test-diff-copy-depth.t create mode 100644 tests/test-diff-hashes.t create mode 100644 tests/test-diff-ignore-whitespace.t create mode 100644 tests/test-diff-indent-heuristic.t create mode 100644 tests/test-diff-issue2761.t create mode 100644 tests/test-diff-newlines.t create mode 100644 tests/test-diff-reverse.t create mode 100644 tests/test-diff-subdir.t create mode 100644 tests/test-diff-unified.t create mode 100644 tests/test-diff-upgrade.t create mode 100644 tests/test-diffdir.t create mode 100644 tests/test-diffstat.t create mode 100644 tests/test-directaccess.t create mode 100644 tests/test-dirs.py create mode 100644 tests/test-dirstate-backup.t create mode 100644 tests/test-dirstate-race.t create mode 100644 tests/test-dirstate-race2.t create mode 100644 tests/test-dirstate-read-race.t create mode 100644 tests/test-dirstate-status-write-race.t create mode 100644 tests/test-dirstate-version-fallback.t create mode 100644 tests/test-dirstate.t create mode 100644 tests/test-dispatch.py create mode 100644 tests/test-dispatch.py.out create mode 100644 tests/test-dispatch.t create mode 100644 tests/test-docker-packaging.t create mode 100644 tests/test-doctest.py create mode 100644 tests/test-double-merge.t create mode 100644 tests/test-drawdag.t create mode 100644 tests/test-duplicateoptions.py create mode 100644 tests/test-editor-filename.t create mode 100644 tests/test-empty-dir.t create mode 100644 tests/test-empty-file.t create mode 100644 tests/test-empty-group.t create mode 100644 tests/test-empty-manifest-index.t create mode 100644 tests/test-empty.t create mode 100644 tests/test-encode.t create mode 100644 tests/test-encoding-align.t create mode 100644 tests/test-encoding-func.py create mode 100644 tests/test-encoding-textwrap.t create mode 100644 tests/test-encoding.t create mode 100644 tests/test-eol-add.t create mode 100644 tests/test-eol-clone.t create mode 100644 tests/test-eol-hook.t create mode 100644 tests/test-eol-patch.t create mode 100644 tests/test-eol-tag.t create mode 100644 tests/test-eol-update.t create mode 100644 tests/test-eol.t create mode 100644 tests/test-eolfilename.t create mode 100644 tests/test-excessive-merge.t create mode 100644 tests/test-exchange-multi-source.t create mode 100644 tests/test-exchange-obsmarkers-case-A1.t create mode 100644 tests/test-exchange-obsmarkers-case-A2.t create mode 100644 tests/test-exchange-obsmarkers-case-A3.t create mode 100644 tests/test-exchange-obsmarkers-case-A4.t create mode 100644 tests/test-exchange-obsmarkers-case-A5.t create mode 100644 tests/test-exchange-obsmarkers-case-A6.t create mode 100644 tests/test-exchange-obsmarkers-case-A7.t create mode 100644 tests/test-exchange-obsmarkers-case-B1.t create mode 100644 tests/test-exchange-obsmarkers-case-B2.t create mode 100644 tests/test-exchange-obsmarkers-case-B3.t create mode 100644 tests/test-exchange-obsmarkers-case-B4.t create mode 100644 tests/test-exchange-obsmarkers-case-B5.t create mode 100644 tests/test-exchange-obsmarkers-case-B6.t create mode 100644 tests/test-exchange-obsmarkers-case-B7.t create mode 100644 tests/test-exchange-obsmarkers-case-C1.t create mode 100644 tests/test-exchange-obsmarkers-case-C2.t create mode 100644 tests/test-exchange-obsmarkers-case-C3.t create mode 100644 tests/test-exchange-obsmarkers-case-C4.t create mode 100644 tests/test-exchange-obsmarkers-case-D1.t create mode 100644 tests/test-exchange-obsmarkers-case-D2.t create mode 100644 tests/test-exchange-obsmarkers-case-D3.t create mode 100644 tests/test-exchange-obsmarkers-case-D4.t create mode 100644 tests/test-execute-bit.t create mode 100644 tests/test-export.t create mode 100644 tests/test-extdata.t create mode 100644 tests/test-extdiff.t create mode 100644 tests/test-extension-timing.t create mode 100644 tests/test-extension.t create mode 100644 tests/test-extensions-afterloaded.t create mode 100644 tests/test-extensions-wrapfunction.py create mode 100644 tests/test-extensions-wrapfunction.py.out create mode 100644 tests/test-extra-filelog-entry.t create mode 100644 tests/test-fastannotate-corrupt.t create mode 100644 tests/test-fastannotate-diffopts.t create mode 100644 tests/test-fastannotate-hg.t create mode 100644 tests/test-fastannotate-perfhack.t create mode 100644 tests/test-fastannotate-protocol.t create mode 100644 tests/test-fastannotate-renames.t create mode 100644 tests/test-fastannotate-revmap.py create mode 100644 tests/test-fastannotate.t create mode 100644 tests/test-fastexport.t create mode 100644 tests/test-fetch.t create mode 100644 tests/test-filebranch.t create mode 100644 tests/test-filecache.py create mode 100644 tests/test-filecache.py.out create mode 100755 tests/test-filelog.py create mode 100644 tests/test-filelog.py.out create mode 100644 tests/test-fileset-generated.t create mode 100644 tests/test-fileset.t create mode 100644 tests/test-fix-clang-format.t create mode 100644 tests/test-fix-metadata.t create mode 100644 tests/test-fix-pickle.t create mode 100644 tests/test-fix-topology.t create mode 100644 tests/test-fix.t create mode 100644 tests/test-flagprocessor.t create mode 100644 tests/test-flags.t create mode 100644 tests/test-fncache.t create mode 100644 tests/test-fuzz-targets.t create mode 100644 tests/test-gendoc-da.t create mode 100644 tests/test-gendoc-de.t create mode 100644 tests/test-gendoc-el.t create mode 100644 tests/test-gendoc-fr.t create mode 100644 tests/test-gendoc-it.t create mode 100644 tests/test-gendoc-ja.t create mode 100644 tests/test-gendoc-pt_BR.t create mode 100644 tests/test-gendoc-ro.t create mode 100644 tests/test-gendoc-ru.t create mode 100644 tests/test-gendoc-sv.t create mode 100644 tests/test-gendoc-zh_CN.t create mode 100644 tests/test-gendoc-zh_TW.t create mode 100644 tests/test-gendoc.t create mode 100644 tests/test-generaldelta.t create mode 100644 tests/test-getbundle.t create mode 100644 tests/test-git-export.t create mode 100644 tests/test-git-interop.t create mode 100644 tests/test-githelp.t create mode 100644 tests/test-globalopts.t create mode 100644 tests/test-glog-beautifygraph.t create mode 100644 tests/test-glog-topological.t create mode 100644 tests/test-glog.t create mode 100644 tests/test-gpg.t create mode 100644 tests/test-graft-interrupted.t create mode 100644 tests/test-graft-rename.t create mode 100644 tests/test-graft.t create mode 100644 tests/test-grep.t create mode 100644 tests/test-hardlinks.t create mode 100644 tests/test-hashutil.py create mode 100644 tests/test-help-hide.t create mode 100644 tests/test-help.t create mode 100644 tests/test-hg-parseurl.py create mode 100644 tests/test-hghave.t create mode 100644 tests/test-hgignore.t create mode 100644 tests/test-hgk.t create mode 100644 tests/test-hgrc.t create mode 100644 tests/test-hgweb-annotate-whitespace.t create mode 100644 tests/test-hgweb-auth.py create mode 100644 tests/test-hgweb-auth.py.out create mode 100644 tests/test-hgweb-bundle.t create mode 100644 tests/test-hgweb-commands.t create mode 100644 tests/test-hgweb-csp.t create mode 100644 tests/test-hgweb-descend-empties.t create mode 100644 tests/test-hgweb-diffs.t create mode 100644 tests/test-hgweb-empty.t create mode 100644 tests/test-hgweb-filelog.t create mode 100644 tests/test-hgweb-head.t create mode 100644 tests/test-hgweb-json.t create mode 100644 tests/test-hgweb-no-path-info.t create mode 100644 tests/test-hgweb-no-request-uri.t create mode 100644 tests/test-hgweb-non-interactive.t create mode 100644 tests/test-hgweb-raw.t create mode 100644 tests/test-hgweb-removed.t create mode 100644 tests/test-hgweb-symrev.t create mode 100644 tests/test-hgweb.t create mode 100644 tests/test-hgwebdir-gc.py create mode 100644 tests/test-hgwebdir-paths.py create mode 100644 tests/test-hgwebdir.t create mode 100644 tests/test-hgwebdirsym.t create mode 100644 tests/test-highlight.t create mode 100644 tests/test-histedit-arguments.t create mode 100644 tests/test-histedit-base.t create mode 100644 tests/test-histedit-bookmark-motion.t create mode 100644 tests/test-histedit-commute.t create mode 100644 tests/test-histedit-drop.t create mode 100644 tests/test-histedit-edit.t create mode 100644 tests/test-histedit-fold-non-commute.t create mode 100644 tests/test-histedit-fold.t create mode 100644 tests/test-histedit-merge-tools.t create mode 100644 tests/test-histedit-no-backup.t create mode 100644 tests/test-histedit-no-change.t create mode 100644 tests/test-histedit-non-commute-abort.t create mode 100644 tests/test-histedit-non-commute.t create mode 100644 tests/test-histedit-obsolete.t create mode 100644 tests/test-histedit-outgoing.t create mode 100644 tests/test-histedit-templates.t create mode 100644 tests/test-hook.t create mode 100644 tests/test-hooklib-changeset_obsoleted.t create mode 100644 tests/test-hooklib-changeset_published.t create mode 100644 tests/test-hooklib-enforce_draft_commits.t create mode 100644 tests/test-hooklib-reject_merge_commits.t create mode 100644 tests/test-hooklib-reject_new_heads.t create mode 100644 tests/test-http-bad-server.t create mode 100644 tests/test-http-branchmap.t create mode 100644 tests/test-http-bundle1.t create mode 100644 tests/test-http-clone-r.t create mode 100644 tests/test-http-permissions.t create mode 100644 tests/test-http-protocol.t create mode 100644 tests/test-http-proxy.t create mode 100644 tests/test-http.t create mode 100644 tests/test-https.t create mode 100644 tests/test-hybridencode.py create mode 100644 tests/test-i18n.t create mode 100644 tests/test-identify.t create mode 100644 tests/test-impexp-branch.t create mode 100644 tests/test-import-bypass.t create mode 100644 tests/test-import-context.t create mode 100644 tests/test-import-eol.t create mode 100644 tests/test-import-git.t create mode 100644 tests/test-import-merge.t create mode 100644 tests/test-import-unknown.t create mode 100644 tests/test-import.t create mode 100644 tests/test-imports-checker.t create mode 100644 tests/test-incoming-outgoing.t create mode 100644 tests/test-inherit-mode.t create mode 100644 tests/test-init.t create mode 100644 tests/test-install.t create mode 100644 tests/test-issue1089.t create mode 100644 tests/test-issue1102.t create mode 100644 tests/test-issue1175.t create mode 100644 tests/test-issue1306.t create mode 100644 tests/test-issue1438.t create mode 100644 tests/test-issue1502.t create mode 100644 tests/test-issue1802.t create mode 100644 tests/test-issue1877.t create mode 100644 tests/test-issue1993.t create mode 100644 tests/test-issue2137.t create mode 100644 tests/test-issue3084.t create mode 100644 tests/test-issue4074.t create mode 100644 tests/test-issue522.t create mode 100644 tests/test-issue586.t create mode 100644 tests/test-issue5979.t create mode 100644 tests/test-issue612.t create mode 100644 tests/test-issue619.t create mode 100644 tests/test-issue6528.t create mode 100644 tests/test-issue660.t create mode 100644 tests/test-issue6642.t create mode 100644 tests/test-issue672.t create mode 100644 tests/test-issue842.t create mode 100644 tests/test-journal-exists.t create mode 100644 tests/test-journal-share.t create mode 100644 tests/test-journal.t create mode 100644 tests/test-keyword.t create mode 100644 tests/test-known.t create mode 100644 tests/test-largefiles-cache.t create mode 100644 tests/test-largefiles-misc.t create mode 100644 tests/test-largefiles-small-disk.t create mode 100644 tests/test-largefiles-update.t create mode 100644 tests/test-largefiles-wireproto.t create mode 100644 tests/test-largefiles.t create mode 100644 tests/test-legacy-exit-code.t create mode 100644 tests/test-lfconvert.t create mode 100644 tests/test-lfs-bundle.t create mode 100644 tests/test-lfs-largefiles.t create mode 100644 tests/test-lfs-pointer.py create mode 100644 tests/test-lfs-pointer.py.out create mode 100644 tests/test-lfs-serve-access.t create mode 100644 tests/test-lfs-serve.t create mode 100644 tests/test-lfs-test-server.t create mode 100644 tests/test-lfs.t create mode 100644 tests/test-linelog.py create mode 100644 tests/test-linerange.py create mode 100644 tests/test-locale.t create mode 100644 tests/test-locate.t create mode 100644 tests/test-lock-badness.t create mode 100644 tests/test-lock.py create mode 100644 tests/test-log-bookmark.t create mode 100644 tests/test-log-exthook.t create mode 100644 tests/test-log-linerange.t create mode 100644 tests/test-log.t create mode 100644 tests/test-logexchange.t create mode 100644 tests/test-logtoprocess.t create mode 100644 tests/test-lrucachedict.py create mode 100644 tests/test-mac-packages.t create mode 100644 tests/test-mactext.t create mode 100644 tests/test-mailmap.t create mode 100644 tests/test-manifest-merging.t create mode 100644 tests/test-manifest.py create mode 100644 tests/test-manifest.t create mode 100644 tests/test-match.py create mode 100644 tests/test-mdiff.py create mode 100644 tests/test-merge-changedelete.t create mode 100644 tests/test-merge-closedheads.t create mode 100644 tests/test-merge-combination-exec-bytes.t create mode 100644 tests/test-merge-combination-file-content.t create mode 100644 tests/test-merge-combination-misc.t create mode 100644 tests/test-merge-commit.t create mode 100644 tests/test-merge-criss-cross.t create mode 100644 tests/test-merge-default.t create mode 100644 tests/test-merge-exec.t create mode 100644 tests/test-merge-force.t create mode 100644 tests/test-merge-halt.t create mode 100644 tests/test-merge-internal-tools-pattern.t create mode 100644 tests/test-merge-local.t create mode 100644 tests/test-merge-no-file-change.t create mode 100644 tests/test-merge-partial-tool.t create mode 100644 tests/test-merge-remove.t create mode 100644 tests/test-merge-revert.t create mode 100644 tests/test-merge-revert2.t create mode 100644 tests/test-merge-subrepos.t create mode 100644 tests/test-merge-symlinks.t create mode 100644 tests/test-merge-tools.t create mode 100644 tests/test-merge-types.t create mode 100644 tests/test-merge1.t create mode 100644 tests/test-merge10.t create mode 100644 tests/test-merge2.t create mode 100644 tests/test-merge4.t create mode 100644 tests/test-merge5.t create mode 100644 tests/test-merge6.t create mode 100644 tests/test-merge7.t create mode 100644 tests/test-merge8.t create mode 100644 tests/test-merge9.t create mode 100644 tests/test-minifileset.py create mode 100644 tests/test-minirst.py create mode 100644 tests/test-minirst.py.out create mode 100644 tests/test-missing-capability.t create mode 100644 tests/test-mq-eol.t create mode 100644 tests/test-mq-git.t create mode 100644 tests/test-mq-guards.t create mode 100644 tests/test-mq-header-date.t create mode 100644 tests/test-mq-header-from.t create mode 100644 tests/test-mq-merge.t create mode 100644 tests/test-mq-missingfiles.t create mode 100644 tests/test-mq-pull-from-bundle.t create mode 100644 tests/test-mq-qclone-http.t create mode 100644 tests/test-mq-qdelete.t create mode 100644 tests/test-mq-qdiff.t create mode 100644 tests/test-mq-qfold.t create mode 100644 tests/test-mq-qgoto.t create mode 100644 tests/test-mq-qimport-fail-cleanup.t create mode 100644 tests/test-mq-qimport.t create mode 100644 tests/test-mq-qnew.t create mode 100644 tests/test-mq-qpush-exact.t create mode 100644 tests/test-mq-qpush-fail.t create mode 100644 tests/test-mq-qqueue.t create mode 100644 tests/test-mq-qrefresh-interactive.t create mode 100644 tests/test-mq-qrefresh-replace-log-message.t create mode 100644 tests/test-mq-qrefresh.t create mode 100644 tests/test-mq-qrename.t create mode 100644 tests/test-mq-qsave.t create mode 100644 tests/test-mq-safety.t create mode 100644 tests/test-mq-subrepo-svn.t create mode 100644 tests/test-mq-subrepo.t create mode 100644 tests/test-mq-symlinks.t create mode 100644 tests/test-mq.t create mode 100644 tests/test-mv-cp-st-diff.t create mode 100644 tests/test-narrow-acl-excludes.t create mode 100644 tests/test-narrow-acl.t create mode 100644 tests/test-narrow-archive.t create mode 100644 tests/test-narrow-clone-no-ellipsis.t create mode 100644 tests/test-narrow-clone-non-narrow-server.t create mode 100644 tests/test-narrow-clone-nonlinear.t create mode 100644 tests/test-narrow-clone-stream.t create mode 100644 tests/test-narrow-clone.t create mode 100644 tests/test-narrow-commit.t create mode 100644 tests/test-narrow-copies.t create mode 100644 tests/test-narrow-debugcommands.t create mode 100644 tests/test-narrow-debugrebuilddirstate.t create mode 100644 tests/test-narrow-exchange-merges.t create mode 100644 tests/test-narrow-exchange.t create mode 100644 tests/test-narrow-expanddirstate.t create mode 100644 tests/test-narrow-merge-outside.t create mode 100644 tests/test-narrow-merge.t create mode 100644 tests/test-narrow-patch.t create mode 100644 tests/test-narrow-patterns.t create mode 100644 tests/test-narrow-pull.t create mode 100644 tests/test-narrow-rebase.t create mode 100644 tests/test-narrow-shallow-merges.t create mode 100644 tests/test-narrow-shallow.t create mode 100644 tests/test-narrow-share.t create mode 100644 tests/test-narrow-sparse.t create mode 100644 tests/test-narrow-strip.t create mode 100644 tests/test-narrow-trackedcmd.t create mode 100644 tests/test-narrow-update.t create mode 100644 tests/test-narrow-widen-no-ellipsis.t create mode 100644 tests/test-narrow-widen.t create mode 100644 tests/test-narrow.t create mode 100644 tests/test-nested-repo.t create mode 100644 tests/test-newbranch.t create mode 100644 tests/test-newcgi.t create mode 100644 tests/test-newercgi.t create mode 100644 tests/test-no-symlinks.t create mode 100644 tests/test-nointerrupt.t create mode 100644 tests/test-notify-changegroup.t create mode 100644 tests/test-notify.t create mode 100644 tests/test-obshistory.t create mode 100644 tests/test-obsmarker-template.t create mode 100644 tests/test-obsmarkers-effectflag.t create mode 100644 tests/test-obsolete-bounds-checking.t create mode 100644 tests/test-obsolete-bundle-strip.t create mode 100644 tests/test-obsolete-changeset-exchange.t create mode 100644 tests/test-obsolete-check-push.t create mode 100644 tests/test-obsolete-checkheads.t create mode 100644 tests/test-obsolete-distributed.t create mode 100644 tests/test-obsolete-divergent.t create mode 100644 tests/test-obsolete-tag-cache.t create mode 100644 tests/test-obsolete.t create mode 100644 tests/test-oldcgi.t create mode 100644 tests/test-origbackup-conflict.t create mode 100644 tests/test-pager-legacy.t create mode 100644 tests/test-pager.t create mode 100644 tests/test-parents.t create mode 100644 tests/test-parse-date.t create mode 100644 tests/test-parseindex.t create mode 100644 tests/test-parseindex2.py create mode 100644 tests/test-patch-offset.t create mode 100644 tests/test-patch.t create mode 100644 tests/test-patchbomb-bookmark.t create mode 100644 tests/test-patchbomb-tls.t create mode 100644 tests/test-patchbomb.t create mode 100644 tests/test-pathconflicts-basic.t create mode 100644 tests/test-pathconflicts-merge.t create mode 100644 tests/test-pathconflicts-update.t create mode 100644 tests/test-pathencode.py create mode 100644 tests/test-paths.t create mode 100644 tests/test-pending.t create mode 100644 tests/test-permissions.t create mode 100644 tests/test-persistent-nodemap-stream-clone.t create mode 100644 tests/test-persistent-nodemap.t create mode 100644 tests/test-phabricator.t create mode 100644 tests/test-phase-archived.t create mode 100644 tests/test-phases-exchange.t create mode 100644 tests/test-phases.t create mode 100644 tests/test-profile.t create mode 100644 tests/test-progress.t create mode 100644 tests/test-propertycache.py create mode 100644 tests/test-propertycache.py.out create mode 100644 tests/test-pull-branch.t create mode 100644 tests/test-pull-bundle.t create mode 100644 tests/test-pull-http.t create mode 100644 tests/test-pull-network.t create mode 100644 tests/test-pull-permission.t create mode 100644 tests/test-pull-pull-corruption.t create mode 100644 tests/test-pull-r.t create mode 100644 tests/test-pull-update.t create mode 100644 tests/test-pullling-to-general-delta.t create mode 100644 tests/test-purge-ignored-directory.t create mode 100644 tests/test-purge.t create mode 100644 tests/test-push-cgi.t create mode 100644 tests/test-push-checkheads-multibranches-E1.t create mode 100644 tests/test-push-checkheads-multibranches-E2.t create mode 100644 tests/test-push-checkheads-multibranches-E3.t create mode 100644 tests/test-push-checkheads-partial-C1.t create mode 100644 tests/test-push-checkheads-partial-C2.t create mode 100644 tests/test-push-checkheads-partial-C3.t create mode 100644 tests/test-push-checkheads-partial-C4.t create mode 100644 tests/test-push-checkheads-pruned-B1.t create mode 100644 tests/test-push-checkheads-pruned-B2.t create mode 100644 tests/test-push-checkheads-pruned-B3.t create mode 100644 tests/test-push-checkheads-pruned-B4.t create mode 100644 tests/test-push-checkheads-pruned-B5.t create mode 100644 tests/test-push-checkheads-pruned-B6.t create mode 100644 tests/test-push-checkheads-pruned-B7.t create mode 100644 tests/test-push-checkheads-pruned-B8.t create mode 100644 tests/test-push-checkheads-superceed-A1.t create mode 100644 tests/test-push-checkheads-superceed-A2.t create mode 100644 tests/test-push-checkheads-superceed-A3.t create mode 100644 tests/test-push-checkheads-superceed-A4.t create mode 100644 tests/test-push-checkheads-superceed-A5.t create mode 100644 tests/test-push-checkheads-superceed-A6.t create mode 100644 tests/test-push-checkheads-superceed-A7.t create mode 100644 tests/test-push-checkheads-superceed-A8.t create mode 100644 tests/test-push-checkheads-unpushed-D1.t create mode 100644 tests/test-push-checkheads-unpushed-D2.t create mode 100644 tests/test-push-checkheads-unpushed-D3.t create mode 100644 tests/test-push-checkheads-unpushed-D4.t create mode 100644 tests/test-push-checkheads-unpushed-D5.t create mode 100644 tests/test-push-checkheads-unpushed-D6.t create mode 100644 tests/test-push-checkheads-unpushed-D7.t create mode 100644 tests/test-push-http.t create mode 100644 tests/test-push-race.t create mode 100644 tests/test-push-warn.t create mode 100644 tests/test-push.t create mode 100644 tests/test-pushvars.t create mode 100644 tests/test-qrecord.t create mode 100644 tests/test-racy-mutations.t create mode 100644 tests/test-rank.t create mode 100644 tests/test-rebase-abort.t create mode 100644 tests/test-rebase-backup.t create mode 100644 tests/test-rebase-base-flag.t create mode 100644 tests/test-rebase-bookmarks.t create mode 100644 tests/test-rebase-brute-force.t create mode 100644 tests/test-rebase-cache.t create mode 100644 tests/test-rebase-check-restore.t create mode 100644 tests/test-rebase-collapse.t create mode 100644 tests/test-rebase-conflicts.t create mode 100644 tests/test-rebase-dest.t create mode 100644 tests/test-rebase-detach.t create mode 100644 tests/test-rebase-dry-run.t create mode 100644 tests/test-rebase-empty-successor.t create mode 100644 tests/test-rebase-emptycommit.t create mode 100644 tests/test-rebase-inmemory.t create mode 100644 tests/test-rebase-interruptions.t create mode 100644 tests/test-rebase-issue-noparam-single-rev.t create mode 100644 tests/test-rebase-legacy.t create mode 100644 tests/test-rebase-mq-skip.t create mode 100644 tests/test-rebase-mq.t create mode 100644 tests/test-rebase-named-branches.t create mode 100644 tests/test-rebase-newancestor.t create mode 100644 tests/test-rebase-obsolete.t create mode 100644 tests/test-rebase-obsolete2.t create mode 100644 tests/test-rebase-obsolete3.t create mode 100644 tests/test-rebase-obsolete4.t create mode 100644 tests/test-rebase-parameters.t create mode 100644 tests/test-rebase-partial.t create mode 100644 tests/test-rebase-pull.t create mode 100644 tests/test-rebase-rename.t create mode 100644 tests/test-rebase-scenario-global.t create mode 100644 tests/test-rebase-templates.t create mode 100644 tests/test-rebase-transaction.t create mode 100644 tests/test-rebuildstate.t create mode 100644 tests/test-record.t create mode 100644 tests/test-releasenotes-formatting.t create mode 100644 tests/test-releasenotes-merging.t create mode 100644 tests/test-releasenotes-parsing.t create mode 100644 tests/test-relink.t create mode 100644 tests/test-remote-hidden.t create mode 100644 tests/test-remotefilelog-bad-configs.t create mode 100644 tests/test-remotefilelog-bgprefetch.t create mode 100644 tests/test-remotefilelog-blame.t create mode 100644 tests/test-remotefilelog-bundle2-legacy.t create mode 100644 tests/test-remotefilelog-bundle2.t create mode 100644 tests/test-remotefilelog-bundles.t create mode 100644 tests/test-remotefilelog-cacheprocess.t create mode 100644 tests/test-remotefilelog-clone-tree.t create mode 100644 tests/test-remotefilelog-clone.t create mode 100644 tests/test-remotefilelog-corrupt-cache.t create mode 100755 tests/test-remotefilelog-datapack.py create mode 100644 tests/test-remotefilelog-gc.t create mode 100644 tests/test-remotefilelog-gcrepack.t create mode 100644 tests/test-remotefilelog-hgweb.t create mode 100755 tests/test-remotefilelog-histpack.py create mode 100644 tests/test-remotefilelog-http.t create mode 100644 tests/test-remotefilelog-keepset.t create mode 100644 tests/test-remotefilelog-linknodes.t create mode 100644 tests/test-remotefilelog-local.t create mode 100644 tests/test-remotefilelog-log.t create mode 100644 tests/test-remotefilelog-partial-shallow.t create mode 100644 tests/test-remotefilelog-permissions.t create mode 100644 tests/test-remotefilelog-prefetch.t create mode 100644 tests/test-remotefilelog-pull-noshallow.t create mode 100644 tests/test-remotefilelog-push-pull.t create mode 100644 tests/test-remotefilelog-repack-fast.t create mode 100644 tests/test-remotefilelog-repack.t create mode 100644 tests/test-remotefilelog-share.t create mode 100644 tests/test-remotefilelog-sparse.t create mode 100644 tests/test-remotefilelog-strip.t create mode 100644 tests/test-remotefilelog-tags.t create mode 100644 tests/test-remotefilelog-wireproto.t create mode 100644 tests/test-remove.t create mode 100644 tests/test-removeemptydirs.t create mode 100644 tests/test-rename-after-merge.t create mode 100644 tests/test-rename-dir-merge.t create mode 100644 tests/test-rename-merge1.t create mode 100644 tests/test-rename-merge2.t create mode 100644 tests/test-rename-rev.t create mode 100644 tests/test-rename.t create mode 100644 tests/test-repair-strip.t create mode 100644 tests/test-repo-compengines.t create mode 100644 tests/test-repo-filters-tiptoe.t create mode 100644 tests/test-requires.t create mode 100644 tests/test-resolve.t create mode 100644 tests/test-revert-flags.t create mode 100644 tests/test-revert-interactive-curses.t create mode 100644 tests/test-revert-interactive.t create mode 100644 tests/test-revert-unknown.t create mode 100644 tests/test-revert.t create mode 100644 tests/test-revisions.t create mode 100644 tests/test-revlog-ancestry.py create mode 100644 tests/test-revlog-ancestry.py.out create mode 100644 tests/test-revlog-delta-find.t create mode 100644 tests/test-revlog-group-emptyiter.t create mode 100644 tests/test-revlog-mmapindex.t create mode 100644 tests/test-revlog-packentry.t create mode 100644 tests/test-revlog-raw.py create mode 100644 tests/test-revlog-raw.py.out create mode 100644 tests/test-revlog-v2.t create mode 100644 tests/test-revlog.t create mode 100644 tests/test-revset-dirstate-parents.t create mode 100644 tests/test-revset-legacy-lookup.t create mode 100644 tests/test-revset-outgoing.t create mode 100644 tests/test-revset.t create mode 100644 tests/test-revset2.t create mode 100644 tests/test-rhg-no-generaldelta.t create mode 100644 tests/test-rhg-sparse-narrow.t create mode 100644 tests/test-rhg.t create mode 100644 tests/test-rollback.t create mode 100644 tests/test-run-tests.py create mode 100644 tests/test-run-tests.t create mode 100644 tests/test-rust-ancestor.py create mode 100644 tests/test-rust-discovery.py create mode 100644 tests/test-rust-revlog.py create mode 100644 tests/test-schemes.t create mode 100644 tests/test-serve.t create mode 100644 tests/test-server-view.t create mode 100644 tests/test-setdiscovery.t create mode 100644 tests/test-share-bookmarks.t create mode 100644 tests/test-share-safe.t create mode 100644 tests/test-share.t create mode 100644 tests/test-shelve.t create mode 100644 tests/test-shelve2.t create mode 100644 tests/test-show-stack.t create mode 100644 tests/test-show-work.t create mode 100644 tests/test-show.t create mode 100644 tests/test-sidedata-exchange.t create mode 100644 tests/test-sidedata.t create mode 100644 tests/test-simple-update.t create mode 100644 tests/test-simplekeyvaluefile.py create mode 100644 tests/test-simplemerge.py create mode 100644 tests/test-single-head-obsolescence-named-branch-A1.t create mode 100644 tests/test-single-head-obsolescence-named-branch-A2.t create mode 100644 tests/test-single-head-obsolescence-named-branch-A3.t create mode 100644 tests/test-single-head-obsolescence-named-branch-A4.t create mode 100644 tests/test-single-head-obsolescence-named-branch-A5.t create mode 100644 tests/test-single-head.t create mode 100644 tests/test-sparse-clear.t create mode 100644 tests/test-sparse-clone.t create mode 100644 tests/test-sparse-fsmonitor.t create mode 100644 tests/test-sparse-import.t create mode 100644 tests/test-sparse-merges.t create mode 100644 tests/test-sparse-profiles.t create mode 100644 tests/test-sparse-requirement.t create mode 100644 tests/test-sparse-revlog.t create mode 100644 tests/test-sparse-verbose-json.t create mode 100644 tests/test-sparse-with-safe-share.t create mode 100644 tests/test-sparse.t create mode 100644 tests/test-split.t create mode 100644 tests/test-sqlitestore.t create mode 100644 tests/test-ssh-batch.t create mode 100644 tests/test-ssh-bundle1.t create mode 100644 tests/test-ssh-clone-r.t create mode 100644 tests/test-ssh-proto-unbundle.t create mode 100644 tests/test-ssh-proto.t create mode 100644 tests/test-ssh-repoerror.t create mode 100644 tests/test-ssh.t create mode 100644 tests/test-sshserver.py create mode 100644 tests/test-stabletailgraph.t create mode 100644 tests/test-stack.t create mode 100644 tests/test-state-extension.t create mode 100644 tests/test-static-http.t create mode 100644 tests/test-status-color.t create mode 100644 tests/test-status-committed-and-ignored.t create mode 100644 tests/test-status-eacces.t create mode 100755 tests/test-status-inprocess.py create mode 100644 tests/test-status-inprocess.py.out create mode 100644 tests/test-status-rev.t create mode 100644 tests/test-status-terse.t create mode 100644 tests/test-status-tracked-key.t create mode 100644 tests/test-status.t create mode 100755 tests/test-stdio.py create mode 100644 tests/test-storage.py create mode 100644 tests/test-stream-bundle-v2.t create mode 100644 tests/test-strict.t create mode 100644 tests/test-strip-branch-cache.t create mode 100644 tests/test-strip-cross.t create mode 100644 tests/test-strip.t create mode 100644 tests/test-subrepo-deep-nested-change.t create mode 100644 tests/test-subrepo-git.t create mode 100644 tests/test-subrepo-missing.t create mode 100644 tests/test-subrepo-paths.t create mode 100644 tests/test-subrepo-recursion.t create mode 100644 tests/test-subrepo-relative-path.t create mode 100644 tests/test-subrepo-svn.t create mode 100644 tests/test-subrepo.t create mode 100644 tests/test-symlink-os-yes-fs-no.py create mode 100644 tests/test-symlink-os-yes-fs-no.py.out create mode 100644 tests/test-symlink-placeholder.t create mode 100644 tests/test-symlinks.t create mode 100644 tests/test-tag.t create mode 100644 tests/test-tags.t create mode 100644 tests/test-template-basic.t create mode 100644 tests/test-template-functions.t create mode 100644 tests/test-template-graph.t create mode 100644 tests/test-template-keywords.t create mode 100644 tests/test-template-map.t create mode 100644 tests/test-tools.t create mode 100644 tests/test-transaction-rollback-on-revlog-split.t create mode 100644 tests/test-transaction-rollback-on-sigpipe.t create mode 100644 tests/test-transaction-safety.t create mode 100644 tests/test-transaction-wc-rollback-race.t create mode 100644 tests/test-transplant.t create mode 100644 tests/test-treediscovery-legacy.t create mode 100644 tests/test-treediscovery.t create mode 100644 tests/test-treemanifest.t create mode 100644 tests/test-trusted.py create mode 100644 tests/test-trusted.py.out create mode 100644 tests/test-ui-color.py create mode 100644 tests/test-ui-color.py.out create mode 100644 tests/test-ui-config.py create mode 100644 tests/test-ui-config.py.out create mode 100644 tests/test-ui-verbosity.py create mode 100644 tests/test-ui-verbosity.py.out create mode 100644 tests/test-unamend.t create mode 100644 tests/test-unbundlehash.t create mode 100644 tests/test-uncommit.t create mode 100644 tests/test-unified-test.t create mode 100644 tests/test-unionrepo.t create mode 100644 tests/test-unrelated-pull.t create mode 100644 tests/test-up-local-change.t create mode 100644 tests/test-update-atomic.t create mode 100644 tests/test-update-branches.t create mode 100644 tests/test-update-dest.t create mode 100644 tests/test-update-issue1456.t create mode 100644 tests/test-update-names.t create mode 100644 tests/test-update-reverse.t create mode 100644 tests/test-upgrade-repo.t create mode 100644 tests/test-url-download.t create mode 100644 tests/test-url-rev.t create mode 100644 tests/test-url.py create mode 100644 tests/test-username-newline.t create mode 100644 tests/test-util.py create mode 100644 tests/test-verify-repo-operations.py create mode 100644 tests/test-verify.t create mode 100644 tests/test-walk.t create mode 100644 tests/test-walkrepo.py create mode 100644 tests/test-websub.t create mode 100644 tests/test-win32text.t create mode 100644 tests/test-wireproto-clientreactor.py create mode 100644 tests/test-wireproto-framing.py create mode 100644 tests/test-wireproto-serverreactor.py create mode 100644 tests/test-wireproto.py create mode 100644 tests/test-wireproto.py.out create mode 100644 tests/test-wireproto.t create mode 100644 tests/test-worker.t create mode 100644 tests/test-wsgicgi.t create mode 100644 tests/test-wsgirequest.py create mode 100644 tests/test-xdg.t create mode 100644 tests/testlib/badserverext.py create mode 100644 tests/testlib/common.sh create mode 100644 tests/testlib/crash_transaction_late.py create mode 100755 tests/testlib/exchange-obsmarker-util.sh create mode 100644 tests/testlib/ext-phase-report.py create mode 100644 tests/testlib/ext-sidedata-2.py create mode 100644 tests/testlib/ext-sidedata-3.py create mode 100644 tests/testlib/ext-sidedata-4.py create mode 100644 tests/testlib/ext-sidedata-5.py create mode 100644 tests/testlib/ext-sidedata.py create mode 100644 tests/testlib/ext-stream-clone-steps.py create mode 100644 tests/testlib/merge-combination-util.sh create mode 100644 tests/testlib/obsmarker-common.sh create mode 100644 tests/testlib/persistent-nodemap-race-ext.py create mode 100644 tests/testlib/push-checkheads-util.sh create mode 100755 tests/testlib/sigpipe-remote.py create mode 100755 tests/testlib/sigpipe-worker.py create mode 100644 tests/testlib/stream_clone_setup.sh create mode 100755 tests/testlib/wait-on-file create mode 100755 tests/tinyproxy.py create mode 100644 tests/unwrap-message-id.py create mode 100644 tests/wireprotohelpers.sh diff --git a/.arcconfig b/.arcconfig new file mode 100644 index 0000000..96991ec --- /dev/null +++ b/.arcconfig @@ -0,0 +1,7 @@ +{ + "conduit_uri": "https://phab.mercurial-scm.org/api", + "phabricator.uri": "https://phab.mercurial-scm.org/", + "repository.callsign": "HG", + "arc.land.onto.default": "@", + "base": "hg:.^" +} diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..ee2b1ee --- /dev/null +++ b/.clang-format @@ -0,0 +1,13 @@ +BasedOnStyle: LLVM +IndentWidth: 8 +UseTab: ForIndentation +BreakBeforeBraces: Linux +AllowShortIfStatementsOnASingleLine: false +IndentCaseLabels: false +AllowShortBlocksOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +IncludeCategories: + - Regex: '^<' + Priority: 1 + - Regex: '^"' + Priority: 2 diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..75b08a5 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +# See http://EditorConfig.org for the specification + +root = true + +[*.py] +indent_size = 4 +indent_style = space +trim_trailing_whitespace = true +end_of_line = lf + +[*.{c,h}] +indent_size = 8 +indent_style = tab +trim_trailing_whitespace = true +end_of_line = lf + +[*.t] +indent_size = 2 +indent_style = space +trim_trailing_whitespace = false +end_of_line = lf diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..39732d7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# So GitLab doesn't think we're using tons of Perl +*.t -linguist-detectable diff --git a/.gitlab/merge_request_templates/Default.md b/.gitlab/merge_request_templates/Default.md new file mode 100644 index 0000000..453b162 --- /dev/null +++ b/.gitlab/merge_request_templates/Default.md @@ -0,0 +1,18 @@ +/assign_reviewer @mercurial.review + + + diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..cb40d4d --- /dev/null +++ b/.hgignore @@ -0,0 +1,82 @@ +syntax: glob + +*.elc +*.tmp +*.orig +*.rej +*~ +*.mergebackup +*.o +*.so +*.dll +*.exe +*.pyd +*.pyc +*.pyo +*$py.class +*.swp +*.prof +*.zip +\#*\# +.\#* +result/ +tests/artifacts/cache/big-file-churn.hg +tests/.coverage* +tests/.testtimes* +# the file is written in the CWD when run-tests is run. +.testtimes +tests/.hypothesis +tests/hypothesis-generated +tests/annotated +tests/exceptions +tests/python3 +tests/*.err +tests/htmlcov +build +contrib/chg/chg +contrib/hgsh/hgsh +contrib/vagrant/.vagrant +contrib/merge-lists/target/ +dist +packages +doc/common.txt +doc/*.[0-9] +doc/*.[0-9].txt +doc/*.[0-9].gendoc.txt +doc/*.[0-9].{x,ht}ml +MANIFEST +MANIFEST.in +patches +mercurial/__modulepolicy__.py +mercurial/__version__.py +mercurial/hgpythonlib.h +mercurial.egg-info +.DS_Store +tags +cscope.* +.vscode/* +.idea/* +.asv/* +.pytype/* +.mypy_cache +i18n/hg.pot +locale/*/LC_MESSAGES/hg.mo +hgext/__index__.py + +rust/target/ +rust/*/target/ + +# Generated wheels +wheelhouse/ + +syntax: rootglob +# See Profiling in rust/README.rst +.cargo/config + +syntax: regexp +^\.pc/ +^\.(pydev)?project + +# hackable windows distribution additions +^hg-python +^hg.py$ diff --git a/.hgsigs b/.hgsigs new file mode 100644 index 0000000..c8411a4 --- /dev/null +++ b/.hgsigs @@ -0,0 +1,260 @@ +35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0 iD8DBQBEYmO2ywK+sNU5EO8RAnaYAKCO7x15xUn5mnhqWNXqk/ehlhRt2QCfRDfY0LrUq2q4oK/KypuJYPHgq1A= +2be3001847cb18a23c403439d9e7d0ace30804e9 0 iD8DBQBExUbjywK+sNU5EO8RAhzxAKCtyHAQUzcTSZTqlfJ0by6vhREwWQCghaQFHfkfN0l9/40EowNhuMOKnJk= +36a957364b1b89c150f2d0e60a99befe0ee08bd3 0 iD8DBQBFfL2QywK+sNU5EO8RAjYFAKCoGlaWRTeMsjdmxAjUYx6diZxOBwCfY6IpBYsKvPTwB3oktnPt5Rmrlys= +27230c29bfec36d5540fbe1c976810aefecfd1d2 0 iD8DBQBFheweywK+sNU5EO8RAt7VAKCrqJQWT2/uo2RWf0ZI4bLp6v82jACgjrMdsaTbxRsypcmEsdPhlG6/8F4= +fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0 iD8DBQBGgHicywK+sNU5EO8RAgNxAJ0VG8ixAaeudx4sZbhngI1syu49HQCeNUJQfWBgA8bkJ2pvsFpNxwYaX3I= +23889160905a1b09fffe1c07378e9fc1827606eb 0 iD8DBQBHGTzoywK+sNU5EO8RAr/UAJ0Y8s4jQtzgS+G9vM8z6CWBThZ8fwCcCT5XDj2XwxKkz/0s6UELwjsO3LU= +bae2e9c838e90a393bae3973a7850280413e091a 0 iD8DBQBH6DO5ywK+sNU5EO8RAsfrAJ0e4r9c9GF/MJsM7Xjd3NesLRC3+ACffj6+6HXdZf8cswAoFPO+DY00oD0= +d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 0 iD8DBQBINdwsywK+sNU5EO8RAjIUAKCPmlFJSpsPAAUKF+iNHAwVnwmzeQCdEXrL27CWclXuUKdbQC8De7LICtE= +d2375bbee6d47e62ba8e415c86e83a465dc4dce9 0 iD8DBQBIo1wpywK+sNU5EO8RAmRNAJ94x3OFt6blbqu/yBoypm/AJ44fuACfUaldXcV5z9tht97hSp22DVTEPGc= +2a67430f92f15ea5159c26b09ec4839a0c549a26 0 iEYEABECAAYFAkk1hykACgkQywK+sNU5EO85QACeNJNUanjc2tl4wUoPHNuv+lSj0ZMAoIm93wSTc/feyYnO2YCaQ1iyd9Nu +3773e510d433969e277b1863c317b674cbee2065 0 iEYEABECAAYFAklNbbAACgkQywK+sNU5EO8o+gCfeb2/lfIJZMvyDA1m+G1CsBAxfFsAoIa6iAMG8SBY7hW1Q85Yf/LXEvaE +11a4eb81fb4f4742451591489e2797dc47903277 0 iEYEABECAAYFAklcAnsACgkQywK+sNU5EO+uXwCbBVHNNsLy1g7BlAyQJwadYVyHOXoAoKvtAVO71+bv7EbVoukwTzT+P4Sx +11efa41037e280d08cfb07c09ad485df30fb0ea8 0 iEYEABECAAYFAkmvJRQACgkQywK+sNU5EO9XZwCeLMgDgPSMWMm6vgjL4lDs2pEc5+0AnRxfiFbpbBfuEFTqKz9nbzeyoBlx +02981000012e3adf40c4849bd7b3d5618f9ce82d 0 iEYEABECAAYFAknEH3wACgkQywK+sNU5EO+uXwCeI+LbLMmhjU1lKSfU3UWJHjjUC7oAoIZLvYDGOL/tNZFUuatc3RnZ2eje +196d40e7c885fa6e95f89134809b3ec7bdbca34b 0 iEYEABECAAYFAkpL2X4ACgkQywK+sNU5EO9FOwCfXJycjyKJXsvQqKkHrglwOQhEKS4An36GfKzptfN8b1qNc3+ya/5c2WOM +3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 0 iEYEABECAAYFAkpopLIACgkQywK+sNU5EO8QSgCfZ0ztsd071rOa2lhmp9Fyue/WoI0AoLTei80/xrhRlB8L/rZEf2KBl8dA +31ec469f9b556f11819937cf68ee53f2be927ebf 0 iEYEABECAAYFAksBuxAACgkQywK+sNU5EO+mBwCfagB+A0txzWZ6dRpug3LEoK7Z1QsAoKpbk8vsLjv6/oRDicSk/qBu33+m +439d7ea6fe3aa4ab9ec274a68846779153789de9 0 iEYEABECAAYFAksVw0kACgkQywK+sNU5EO/oZwCfdfBEkgp38xq6wN2F4nj+SzofrJIAnjmxt04vaJSeOOeHylHvk6lzuQsw +296a0b14a68621f6990c54fdba0083f6f20935bf 0 iEYEABECAAYFAks+jCoACgkQywK+sNU5EO9J8wCeMUGF9E/gS2UBsqIz56WS4HMPRPUAoI5J95mwEIK8Clrl7qFRidNI6APq +4aa619c4c2c09907034d9824ebb1dd0e878206eb 0 iEYEABECAAYFAktm9IsACgkQywK+sNU5EO9XGgCgk4HclRQhexEtooPE5GcUCdB6M8EAn2ptOhMVbIoO+JncA+tNACPFXh0O +ff2704a8ded37fbebd8b6eb5ec733731d725da8a 0 iEYEABECAAYFAkuRoSQACgkQywK+sNU5EO//3QCeJDc5r2uFyFCtAlpSA27DEE5rrxAAn2FSwTy9fhrB3QAdDQlwkEZcQzDh +2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 0 iEYEABECAAYFAku1IwIACgkQywK+sNU5EO9MjgCdHLVwkTZlNHxhcznZKBL1rjN+J7cAoLLWi9LTL6f/TgBaPSKOy1ublbaW +39f725929f0c48c5fb3b90c071fc3066012456ca 0 iEYEABECAAYFAkvclvsACgkQywK+sNU5EO9FSwCeL9i5x8ALW/LE5+lCX6MFEAe4MhwAn1ev5o6SX6GrNdDfKweiemfO2VBk +fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 0 iEYEABECAAYFAkvsKTkACgkQywK+sNU5EO9qEACgiSiRGvTG2vXGJ65tUSOIYihTuFAAnRzRIqEVSw8M8/RGeUXRps0IzaCO +24fe2629c6fd0c74c90bd066e77387c2b02e8437 0 iEYEABECAAYFAkwFLRsACgkQywK+sNU5EO+pJACgp13tPI+pbwKZV+LeMjcQ4H6tCZYAoJebzhd6a8yYx6qiwpJxA9BXZNXy +f786fc4b8764cd2a5526d259cf2f94d8a66924d9 0 iEYEABECAAYFAkwsyxcACgkQywK+sNU5EO+crACfUpNAF57PmClkSri9nJcBjb2goN4AniPCNaKvnki7TnUsi1u2oxltpKKL +bf1774d95bde614af3956d92b20e2a0c68c5fec7 0 iEYEABECAAYFAkxVwccACgkQywK+sNU5EO+oFQCeJzwZ+we1fIIyBGCddHceOUAN++cAnjvT6A8ZWW0zV21NXIFF1qQmjxJd +c00f03a4982e467fb6b6bd45908767db6df4771d 0 iEYEABECAAYFAkxXDqsACgkQywK+sNU5EO/GJACfT9Rz4hZOxPQEs91JwtmfjevO84gAmwSmtfo5mmWSm8gtTUebCcdTv0Kf +ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 0 iD8DBQBMdo+qywK+sNU5EO8RAqQpAJ975BL2CCAiWMz9SXthNQ9xG181IwCgp4O+KViHPkufZVFn2aTKMNvcr1A= +93d8bff78c96fe7e33237b257558ee97290048a4 0 iD8DBQBMpfvdywK+sNU5EO8RAsxVAJ0UaL1XB51C76JUBhafc9GBefuMxwCdEWkTOzwvE0SarJBe9i008jhbqW4= +333421b9e0f96c7bc788e5667c146a58a9440a55 0 iD8DBQBMz0HOywK+sNU5EO8RAlsEAJ0USh6yOG7OrWkADGunVt9QimBQnwCbBqeMnKgSbwEw8jZwE3Iz1mdrYlo= +4438875ec01bd0fc32be92b0872eb6daeed4d44f 0 iD8DBQBM4WYUywK+sNU5EO8RAhCVAJ0dJswachwFAHALmk1x0RJehxzqPQCbBNskP9n/X689jB+btNTZTyKU/fw= +6aff4f144ad356311318b0011df0bb21f2c97429 0 iD8DBQBM9uxXywK+sNU5EO8RAv+4AKCDj4qKP16GdPaq1tP6BUwpM/M1OACfRyzLPp/qiiN8xJTWoWYSe/XjJug= +e3bf16703e2601de99e563cdb3a5d50b64e6d320 0 iD8DBQBNH8WqywK+sNU5EO8RAiQTAJ9sBO+TeiGro4si77VVaQaA6jcRUgCfSA28dBbjj0oFoQwvPoZjANiZBH8= +a6c855c32ea081da3c3b8ff628f1847ff271482f 0 iD8DBQBNSJJ+ywK+sNU5EO8RAoJaAKCweDEF70fu+r1Zn7pYDXdlk5RuSgCeO9gK/eit8Lin/1n3pO7aYguFLok= +2b2155623ee2559caf288fd333f30475966c4525 0 iD8DBQBNSJeBywK+sNU5EO8RAm1KAJ4hW9Cm9nHaaGJguchBaPLlAr+O3wCgqgmMok8bdAS06N6PL60PSTM//Gg= +2616325766e3504c8ae7c84bd15ee610901fe91d 0 iD8DBQBNbWy9ywK+sNU5EO8RAlWCAJ4mW8HbzjJj9GpK98muX7k+7EvEHwCfaTLbC/DH3QEsZBhEP+M8tzL6RU4= +aa1f3be38ab127280761889d2dca906ca465b5f4 0 iD8DBQBNeQq7ywK+sNU5EO8RAlEOAJ4tlEDdetE9lKfjGgjbkcR8PrC3egCfXCfF3qNVvU/2YYjpgvRwevjvDy0= +b032bec2c0a651ca0ddecb65714bfe6770f67d70 0 iD8DBQBNlg5kywK+sNU5EO8RAnGEAJ9gmEx6MfaR4XcG2m/93vwtfyzs3gCgltzx8/YdHPwqDwRX/WbpYgi33is= +3cb1e95676ad089596bd81d0937cad37d6e3b7fb 0 iD8DBQBNvTy4ywK+sNU5EO8RAmp8AJ9QnxK4jTJ7G722MyeBxf0UXEdGwACgtlM7BKtNQfbEH/fOW5y+45W88VI= +733af5d9f6b22387913e1d11350fb8cb7c1487dd 0 iD8DBQBN5q/8ywK+sNU5EO8RArRGAKCNGT94GKIYtSuwZ57z1sQbcw6uLACfffpbMV4NAPMl8womAwg+7ZPKnIU= +de9eb6b1da4fc522b1cab16d86ca166204c24f25 0 iD8DBQBODhfhywK+sNU5EO8RAr2+AJ4ugbAj8ae8/K0bYZzx3sascIAg1QCeK3b+zbbVVqd3b7CDpwFnaX8kTd4= +4a43e23b8c55b4566b8200bf69fe2158485a2634 0 iD8DBQBONzIMywK+sNU5EO8RAj5SAJ0aPS3+JHnyI6bHB2Fl0LImbDmagwCdGbDLp1S7TFobxXudOH49bX45Iik= +d629f1e89021103f1753addcef6b310e4435b184 0 iD8DBQBOWAsBywK+sNU5EO8RAht4AJwJl9oNFopuGkj5m8aKuf7bqPkoAQCeNrEm7UhFsZKYT5iUOjnMV7s2LaM= +351a9292e430e35766c552066ed3e87c557b803b 0 iD8DBQBOh3zUywK+sNU5EO8RApFMAKCD3Y/u3avDFndznwqfG5UeTHMlvACfUivPIVQZyDZnhZMq0UhC6zhCEQg= +384082750f2c51dc917d85a7145748330fa6ef4d 0 iD8DBQBOmd+OywK+sNU5EO8RAgDgAJ9V/X+G7VLwhTpHrZNiOHabzSyzYQCdE2kKfIevJUYB9QLAWCWP6DPwrwI= +41453d55b481ddfcc1dacb445179649e24ca861d 0 iD8DBQBOsFhpywK+sNU5EO8RAqM6AKCyfxUae3/zLuiLdQz+JR78690eMACfQ6JTBQib4AbE+rUDdkeFYg9K/+4= +195dbd1cef0c2f9f8bcf4ea303238105f716bda3 0 iD8DBQBO1/fWywK+sNU5EO8RAmoPAKCR5lpv1D6JLURHD8KVLSV4GRVEBgCgnd0Sy78ligNfqAMafmACRDvj7vo= +6344043924497cd06d781d9014c66802285072e4 0 iD8DBQBPALgmywK+sNU5EO8RAlfhAJ9nYOdWnhfVDHYtDTJAyJtXBAQS9wCgnefoSQt7QABkbGxM+Q85UYEBuD0= +db33555eafeaf9df1e18950e29439eaa706d399b 0 iD8DBQBPGdzxywK+sNU5EO8RAppkAJ9jOXhUVE/97CPgiMA0pMGiIYnesQCfengAszcBiSiKGugiI8Okc9ghU+Y= +2aa5b51f310fb3befd26bed99c02267f5c12c734 0 iD8DBQBPKZ9bywK+sNU5EO8RAt1TAJ45r1eJ0YqSkInzrrayg4TVCh0SnQCgm0GA/Ua74jnnDwVQ60lAwROuz1Q= +53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 0 iD8DBQBPT/fvywK+sNU5EO8RAnfYAKCn7d0vwqIb100YfWm1F7nFD5B+FACeM02YHpQLSNsztrBCObtqcnfod7Q= +b9bd95e61b49c221c4cca24e6da7c946fc02f992 0 iD8DBQBPeLsIywK+sNU5EO8RAvpNAKCtKe2gitz8dYn52IRF0hFOPCR7AQCfRJL/RWCFweu2T1vH/mUOCf8SXXc= +d9e2f09d5488c395ae9ddbb320ceacd24757e055 0 iD8DBQBPju/dywK+sNU5EO8RArBYAJ9xtifdbk+hCOJO8OZa4JfHX8OYZQCeKPMBaBWiT8N/WHoOm1XU0q+iono= +00182b3d087909e3c3ae44761efecdde8f319ef3 0 iD8DBQBPoFhIywK+sNU5EO8RAhzhAKCBj1n2jxPTkZNJJ5pSp3soa+XHIgCgsZZpAQxOpXwCp0eCdNGe0+pmxmg= +5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 0 iD8DBQBPovNWywK+sNU5EO8RAhgiAJ980T91FdPTRMmVONDhpkMsZwVIMACgg3bKvoWSeuCW28llUhAJtUjrMv0= +85a358df5bbbe404ca25730c9c459b34263441dc 0 iD8DBQBPyZsWywK+sNU5EO8RAnpLAJ48qrGDJRT+pteS0mSQ11haqHstPwCdG4ccGbk+0JHb7aNy8/NRGAOqn9w= +b013baa3898e117959984fc64c29d8c784d2f28b 0 iD8DBQBP8QOPywK+sNU5EO8RAqimAKCFRSx0lvG6y8vne2IhNG062Hn0dACeMLI5/zhpWpHBIVeAAquYfx2XFeA= +7f5094bb3f423fc799e471aac2aee81a7ce57a0b 0 iD8DBQBQGiL8ywK+sNU5EO8RAq5oAJ4rMMCPx6O+OuzNXVOexogedWz/QgCeIiIxLd76I4pXO48tdXhr0hQcBuM= +072209ae4ddb654eb2d5fd35bff358c738414432 0 iD8DBQBQQkq0ywK+sNU5EO8RArDTAJ9nk5CySnNAjAXYvqvx4uWCw9ThZwCgqmFRehH/l+oTwj3f8nw8u8qTCdc= +b3f0f9a39c4e1d0250048cd803ab03542d6f140a 0 iD8DBQBQamltywK+sNU5EO8RAlsqAJ4qF/m6aFu4mJCOKTiAP5RvZFK02ACfawYShUZO6OXEFfveU0aAxDR0M1k= +d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 0 iD8DBQBQgPV5ywK+sNU5EO8RArylAJ0abcx5NlDjyv3ZDWpAfRIHyRsJtQCgn4TMuEayqgxzrvadQZHdTEU2g38= +195ad823b5d58c68903a6153a25e3fb4ed25239d 0 iD8DBQBQkuT9ywK+sNU5EO8RAhB4AKCeerItoK2Jipm2cVf4euGofAa/WACeJj3TVd4pFILpb+ogj7ebweFLJi0= +0c10cf8191469e7c3c8844922e17e71a176cb7cb 0 iD8DBQBQvQWoywK+sNU5EO8RAnq3AJoCn98u4geFx5YaQaeh99gFhCd7bQCgjoBwBSUyOvGd0yBy60E3Vv3VZhM= +a4765077b65e6ae29ba42bab7834717b5072d5ba 0 iD8DBQBQ486sywK+sNU5EO8RAhmJAJ90aLfLKZhmcZN7kqphigQJxiFOQACeJ5IUZxjGKH4xzi3MrgIcx9n+dB0= +f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 0 iD8DBQBQ+yuYywK+sNU5EO8RAm9JAJoD/UciWvpGeKBcpGtZJBFJVcL/HACghDXSgQ+xQDjB+6uGrdgAQsRR1Lg= +a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 0 iD8DBQBRDDROywK+sNU5EO8RAh75AJ9uJCGoCWnP0Lv/+XuYs4hvUl+sAgCcD36QgAnuw8IQXrvv684BAXAnHcA= +7511d4df752e61fe7ae4f3682e0a0008573b0402 0 iD8DBQBRFYaoywK+sNU5EO8RAuErAJoDyhXn+lptU3+AevVdwAIeNFyR2gCdHzPHyWd+JDeWCUR+pSOBi8O2ppM= +5b7175377babacce80a6c1e12366d8032a6d4340 0 iD8DBQBRMCYgywK+sNU5EO8RAq1/AKCWKlt9ysibyQgYwoxxIOZv5J8rpwCcDSHQaaf1fFZUTnQsOePwcM2Y/Sg= +50c922c1b5145dab8baefefb0437d363b6a6c21c 0 iD8DBQBRWnUnywK+sNU5EO8RAuQRAJwM42cJqJPeqJ0jVNdMqKMDqr4dSACeP0cRVGz1gitMuV0x8f3mrZrqc7I= +8a7bd2dccd44ed571afe7424cd7f95594f27c092 0 iD8DBQBRXfBvywK+sNU5EO8RAn+LAKCsMmflbuXjYRxlzFwId5ptm8TZcwCdGkyLbZcASBOkzQUm/WW1qfknJHU= +292cd385856d98bacb2c3086f8897bc660c2beea 0 iD8DBQBRcM0BywK+sNU5EO8RAjp4AKCJBykQbvXhKuvLSMxKx3a2TBiXcACfbr/kLg5GlZTF/XDPmY+PyHgI/GM= +23f785b38af38d2fca6b8f3db56b8007a84cd73a 0 iD8DBQBRgZwNywK+sNU5EO8RAmO4AJ4u2ILGuimRP6MJgE2t65LZ5dAdkACgiENEstIdrlFC80p+sWKD81kKIYI= +ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 0 iD8DBQBRkswvywK+sNU5EO8RAiYYAJsHTHyHbJeAgmGvBTmDrfcKu4doUgCeLm7eGBjx7yAPUvEtxef8rAkQmXI= +cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 0 iD8DBQBRqnFLywK+sNU5EO8RAsWNAJ9RR6t+y1DLFc2HeH0eN9VfZAKF9gCeJ8ezvhtKq/LMs0/nvcgKQc/d5jk= +009794acc6e37a650f0fae37872e733382ac1c0c 0 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 diff --git a/.hgtags b/.hgtags new file mode 100644 index 0000000..8d3153e --- /dev/null +++ b/.hgtags @@ -0,0 +1,276 @@ +d40cc5aacc31ed673d9b5b24f98bee78c283062c 0.4f +1c590d34bf61e2ea12c71738e5a746cd74586157 0.4e +7eca4cfa8aad5fce9a04f7d8acadcd0452e2f34e 0.4d +b4d0c3786ad3e47beacf8412157326a32b6d25a4 0.4c +f40273b0ad7b3a6d3012fd37736d0611f41ecf54 0.5 +0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 0.5b +12e0fdbc57a0be78f0e817fd1d170a3615cd35da 0.6 +4ccf3de52989b14c3d84e1097f59e39a992e00bd 0.6b +eac9c8efcd9bd8244e72fb6821f769f450457a32 0.6c +979c049974485125e1f9357f6bbe9c1b548a64c3 0.7 +3a56574f329a368d645853e0f9e09472aee62349 0.8 +6a03cff2b0f5d30281e6addefe96b993582f2eac 0.8.1 +35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0.9 +2be3001847cb18a23c403439d9e7d0ace30804e9 0.9.1 +36a957364b1b89c150f2d0e60a99befe0ee08bd3 0.9.2 +27230c29bfec36d5540fbe1c976810aefecfd1d2 0.9.3 +fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0.9.4 +23889160905a1b09fffe1c07378e9fc1827606eb 0.9.5 +bae2e9c838e90a393bae3973a7850280413e091a 1.0 +d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 1.0.1 +d2375bbee6d47e62ba8e415c86e83a465dc4dce9 1.0.2 +2a67430f92f15ea5159c26b09ec4839a0c549a26 1.1 +3773e510d433969e277b1863c317b674cbee2065 1.1.1 +11a4eb81fb4f4742451591489e2797dc47903277 1.1.2 +11efa41037e280d08cfb07c09ad485df30fb0ea8 1.2 +02981000012e3adf40c4849bd7b3d5618f9ce82d 1.2.1 +196d40e7c885fa6e95f89134809b3ec7bdbca34b 1.3 +3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 1.3.1 +31ec469f9b556f11819937cf68ee53f2be927ebf 1.4 +439d7ea6fe3aa4ab9ec274a68846779153789de9 1.4.1 +296a0b14a68621f6990c54fdba0083f6f20935bf 1.4.2 +4aa619c4c2c09907034d9824ebb1dd0e878206eb 1.4.3 +ff2704a8ded37fbebd8b6eb5ec733731d725da8a 1.5 +2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 1.5.1 +39f725929f0c48c5fb3b90c071fc3066012456ca 1.5.2 +fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 1.5.3 +24fe2629c6fd0c74c90bd066e77387c2b02e8437 1.5.4 +f786fc4b8764cd2a5526d259cf2f94d8a66924d9 1.6 +bf1774d95bde614af3956d92b20e2a0c68c5fec7 1.6.1 +c00f03a4982e467fb6b6bd45908767db6df4771d 1.6.2 +ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 1.6.3 +93d8bff78c96fe7e33237b257558ee97290048a4 1.6.4 +333421b9e0f96c7bc788e5667c146a58a9440a55 1.7 +4438875ec01bd0fc32be92b0872eb6daeed4d44f 1.7.1 +6aff4f144ad356311318b0011df0bb21f2c97429 1.7.2 +e3bf16703e2601de99e563cdb3a5d50b64e6d320 1.7.3 +a6c855c32ea081da3c3b8ff628f1847ff271482f 1.7.4 +2b2155623ee2559caf288fd333f30475966c4525 1.7.5 +2616325766e3504c8ae7c84bd15ee610901fe91d 1.8 +aa1f3be38ab127280761889d2dca906ca465b5f4 1.8.1 +b032bec2c0a651ca0ddecb65714bfe6770f67d70 1.8.2 +3cb1e95676ad089596bd81d0937cad37d6e3b7fb 1.8.3 +733af5d9f6b22387913e1d11350fb8cb7c1487dd 1.8.4 +de9eb6b1da4fc522b1cab16d86ca166204c24f25 1.9 +4a43e23b8c55b4566b8200bf69fe2158485a2634 1.9.1 +d629f1e89021103f1753addcef6b310e4435b184 1.9.2 +351a9292e430e35766c552066ed3e87c557b803b 1.9.3 +384082750f2c51dc917d85a7145748330fa6ef4d 2.0-rc +41453d55b481ddfcc1dacb445179649e24ca861d 2.0 +195dbd1cef0c2f9f8bcf4ea303238105f716bda3 2.0.1 +6344043924497cd06d781d9014c66802285072e4 2.0.2 +db33555eafeaf9df1e18950e29439eaa706d399b 2.1-rc +2aa5b51f310fb3befd26bed99c02267f5c12c734 2.1 +53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 2.1.1 +b9bd95e61b49c221c4cca24e6da7c946fc02f992 2.1.2 +d9e2f09d5488c395ae9ddbb320ceacd24757e055 2.2-rc +00182b3d087909e3c3ae44761efecdde8f319ef3 2.2 +5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 2.2.1 +85a358df5bbbe404ca25730c9c459b34263441dc 2.2.2 +b013baa3898e117959984fc64c29d8c784d2f28b 2.2.3 +a06e2681dd1786e2354d84a5fa9c1c88dd4fa3e0 2.3-rc +7f5094bb3f423fc799e471aac2aee81a7ce57a0b 2.3 +072209ae4ddb654eb2d5fd35bff358c738414432 2.3.1 +b3f0f9a39c4e1d0250048cd803ab03542d6f140a 2.3.2 +d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 2.4-rc +195ad823b5d58c68903a6153a25e3fb4ed25239d 2.4 +0c10cf8191469e7c3c8844922e17e71a176cb7cb 2.4.1 +a4765077b65e6ae29ba42bab7834717b5072d5ba 2.4.2 +f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 2.5-rc +a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 2.5 +7511d4df752e61fe7ae4f3682e0a0008573b0402 2.5.1 +5b7175377babacce80a6c1e12366d8032a6d4340 2.5.2 +50c922c1b5145dab8baefefb0437d363b6a6c21c 2.5.3 +8a7bd2dccd44ed571afe7424cd7f95594f27c092 2.5.4 +292cd385856d98bacb2c3086f8897bc660c2beea 2.6-rc +23f785b38af38d2fca6b8f3db56b8007a84cd73a 2.6 +ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 2.6.1 +cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 2.6.2 +009794acc6e37a650f0fae37872e733382ac1c0c 2.6.3 +f0d7721d7322dcfb5af33599c2543f27335334bb 2.7-rc +f37b5a17e6a0ee17afde2cdde5393dd74715fb58 2.7 +335a558f81dc73afeab4d7be63617392b130117f 2.7.1 +e7fa36d2ad3a7944a52dca126458d6f482db3524 2.7.2 +1596f2d8f2421314b1ddead8f7d0c91009358994 2.8-rc +d825e4025e39d1c39db943cdc89818abd0a87c27 2.8 +209e04a06467e2969c0cc6501335be0406d46ef0 2.8.1 +ca387377df7a3a67dbb90b6336b781cdadc3ef41 2.8.2 +8862469e16f9236208581b20de5f96bd13cc039d 2.9-rc +3cec5134e9c4bceab6a00c60f52a4f80677a78f2 2.9 +b96cb15ec9e04d8ac5ee08b34fcbbe4200588965 2.9.1 +3f83fc5cfe715d292069ee8417c83804f6c6c1e4 2.9.2 +564f55b251224f16508dd1311452db7780dafe2b 3.0-rc +2195ac506c6ababe86985b932f4948837c0891b5 3.0 +269c80ee5b3cb3684fa8edc61501b3506d02eb10 3.0.1 +2d8cd3d0e83c7336c0cb45a9f88638363f993848 3.0.2 +6c36dc6cd61a0e1b563f1d51e55bdf4dacf12162 3.1-rc +3178e49892020336491cdc6945885c4de26ffa8b 3.1 +5dc91146f35369949ea56b40172308158b59063a 3.1.1 +f768c888aaa68d12dd7f509dcc7f01c9584357d0 3.1.2 +7f8d16af8cae246fa5a48e723d48d58b015aed94 3.2-rc +ced632394371a36953ce4d394f86278ae51a2aae 3.2 +643c58303fb0ec020907af28b9e486be299ba043 3.2.1 +902554884335e5ca3661d63be9978eb4aec3f68a 3.2.2 +6dad422ecc5adb63d9fa649eeb8e05a5f9bc4900 3.2.3 +1265a3a71d75396f5d4cf6935ae7d9ba5407a547 3.2.4 +db8e3f7948b1fdeb9ad12d448fc3525759908b9f 3.3-rc +fbdd5195528fae4f41feebc1838215c110b25d6a 3.3 +5b4ed033390bf6e2879c8f5c28c84e1ee3b87231 3.3.1 +07a92bbd02e5e3a625e0820389b47786b02b2cea 3.3.2 +2e2e9a0750f91a6fe0ad88e4de34f8efefdcab08 3.3.3 +e89f909edffad558b56f4affa8239e4832f88de0 3.4-rc +8cc6036bca532e06681c5a8fa37efaa812de67b5 3.4 +ed18f4acf435a2824c6f49fba40f42b9df5da7ad 3.4.1 +540cd0ddac49c1125b2e013aa2ff18ecbd4dd954 3.4.2 +96a38d44ba093bd1d1ecfd34119e94056030278b 3.5-rc +21aa1c313b05b1a85f8ffa1120d51579ddf6bf24 3.5 +1a45e49a6bed023deb229102a8903234d18054d3 3.5.1 +9a466b9f9792e3ad7ae3fc6c43c3ff2e136b718d 3.5.2 +b66e3ca0b90c3095ea28dfd39aa24247bebf5c20 3.6-rc +47dd34f2e7272be9e3b2a5a83cd0d20be44293f4 3.6 +1aa5083cbebbe7575c88f3402ab377539b484897 3.6.1 +2d437a0f3355834a9485bbbeb30a52a052c98f19 3.6.2 +ea389970c08449440587712117f178d33bab3f1e 3.6.3 +158bdc8965720ca4061f8f8d806563cfc7cdb62e 3.7-rc +2408645de650d8a29a6ce9e7dce601d8dd0d1474 3.7 +b698abf971e7377d9b7ec7fc8c52df45255b0329 3.7.1 +d493d64757eb45ada99fcb3693e479a51b7782da 3.7.2 +ae279d4a19e9683214cbd1fe8298cf0b50571432 3.7.3 +740156eedf2c450aee58b1a90b0e826f47c5da64 3.8-rc +f85de28eae32e7d3064b1a1321309071bbaaa069 3.8 +a56296f55a5e1038ea5016dace2076b693c28a56 3.8.1 +aaabed77791a75968a12b8c43ad263631a23ee81 3.8.2 +a9764ab80e11bcf6a37255db7dd079011f767c6c 3.8.3 +26a5d605b8683a292bb89aea11f37a81b06ac016 3.8.4 +519bb4f9d3a47a6e83c2b414d58811ed38f503c2 3.9-rc +299546f84e68dbb9bd026f0f3a974ce4bdb93686 3.9 +ccd436f7db6d5d7b9af89715179b911d031d44f1 3.9.1 +149433e68974eb5c63ccb03f794d8b57339a80c4 3.9.2 +438173c415874f6ac653efc1099dec9c9150e90f 4.0-rc +eab27446995210c334c3d06f1a659e3b9b5da769 4.0 +b3b1ae98f6a0e14c1e1ba806a6c18e193b6dae5c 4.0.1 +e69874dc1f4e142746ff3df91e678a09c6fc208c 4.0.2 +a1dd2c0c479e0550040542e392e87bc91262517e 4.1-rc +e1526da1e6d84e03146151c9b6e6950fe9a83d7d 4.1 +25703b624d27e3917d978af56d6ad59331e0464a 4.1.1 +ed5b25874d998ababb181a939dd37a16ea644435 4.1.2 +77eaf9539499a1b8be259ffe7ada787d07857f80 4.1.3 +616e788321cc4ae9975b7f0c54c849f36d82182b 4.2-rc +bb96d4a497432722623ae60d9bc734a1e360179e 4.2 +c850f0ed54c1d42f9aa079ad528f8127e5775217 4.2.1 +26c49ed51a698ec016d2b4c6b44ca3c3f73cc788 4.2.2 +857876ebaed4e315f63157bd157d6ce553c7ab73 4.3-rc +5544af8622863796a0027566f6b646e10d522c4c 4.3 +943c91326b23954e6e1c6960d0239511f9530258 4.2.3 +3fee7f7d2da04226914c2258cc2884dc27384fd7 4.3.1 +920977f72c7b70acfdaf56ab35360584d7845827 4.3.2 +2f427b57bf9019c6dc3750baa539dc22c1be50f6 4.3.3 +1e2454b60e5936f5e77498cab2648db469504487 4.4-rc +0ccb43d4cf01d013ae05917ec4f305509f851b2d 4.4 +cabc840ffdee8a72f3689fb77dd74d04fdc2bc04 4.4.1 +a92b9f8e11ba330614cdfd6af0e03b15c1ff3797 4.4.2 +27b6df1b5adbdf647cf5c6675b40575e1b197c60 4.5-rc +d334afc585e29577f271c5eda03378736a16ca6b 4.5 +369aadf7a3264b03c8b09efce715bc41e6ab4a9b 4.5.1 +8bba684efde7f45add05f737952093bb2aa07155 4.5.2 +7de7bd407251af2bc98e5b809c8598ee95830daf 4.5.3 +ed5448edcbfa747b9154099e18630e49024fd47b 4.6rc0 +1ec874717d8a93b19e0d50628443e0ee5efab3a9 4.6rc1 +6614cac550aea66d19c601e45efd1b7bd08d7c40 4.6 +9c5ced5276d6e7d54f7c3dadf5247b7ee98ec79c 4.6.1 +0b63a6743010dfdbf8a8154186e119949bdaa1cc 4.6.2 +e90130af47ce8dd53a3109aed9d15876b3e7dee8 4.7rc0 +33ac6a72308a215e6086fbced347ec10aa963b0a 4.7 +ede3bf31fe63677fdf5bd8db687977d4e3d792ed 4.7.1 +5405cb1a79010ac50c58cd84e6f50c4556bf2a4c 4.7.2 +956ec6f1320df26f3133ec40f3de866ea0695fd7 4.8rc0 +a91a2837150bdcb27ae76b3646e6c93cd6a15904 4.8 +1c8c54cf97256f4468da2eb4dbee24f7f3888e71 4.8.1 +197f092b2cd9691e2a55d198f717b231af9be6f9 4.8.2 +593718ff5844cad7a27ee3eb5adad89ac8550949 4.9rc0 +83377b4b4ae0e9a6b8e579f7b0a693b8cf5c3b10 4.9 +4ea21df312ec7159c5b3633096b6ecf68750b0dd 4.9.1 +4a8d9ed864754837a185a642170cde24392f9abf 5.0rc0 +07e479ef7c9639be0029f00e6a722b96dcc05fee 5.0 +c3484ddbdb9621256d597ed86b90d229c59c2af9 5.0.1 +97ada9b8d51bef24c5cb4cdca4243f0db694ab6e 5.0.2 +e386b5f4f8360dbb43a576dd9b1368e386fefa5b 5.1rc0 +e91930d712e8507d1bc1b2dffd96c83edc4cbed3 5.1 +a4e32fd539ab41489a51b2aa88bda9a73b839562 5.1.1 +181e52f2b62f4768aa0d988936c929dc7c4a41a0 5.1.2 +59338f9561099de77c684c00f76507f11e46ebe8 5.2rc0 +ca3dca416f8d5863ca6f5a4a6a6bb835dcd5feeb 5.2 +a50fecefa691c9b72a99e49aa6fe9dd13943c2bf 5.2.1 +b4c82b70418022e67cc0e69b1aa3c3aa43aa1d29 5.2.2 +84a0102c05c7852c8215ef6cf21d809927586b69 5.3rc0 +e4344e463c0c888a2f437b78b5982ecdf3f6650a 5.3rc1 +7f5410dfc8a64bb587d19637deb95d378fd1eb5c 5.3 +6d121acbb82e65fe4dd3c2318a1b61981b958492 5.3.1 +8fca7e8449a847e3cf1054f2c07b51237699fad3 5.3.2 +26ce8e7515036d3431a03aaeb7bc72dd96cb1112 5.4rc0 +cf3e07d7648a4371ce584d15dd692e7a6845792f 5.4 +065704cbdbdbb05dcd6bb814eb9bbdd982211b28 5.4.1 +0ea9c86fac8974cd74dc12ea681c8986eb6da6c4 5.4.2 +28163c5de797e5416f9b588940f4608269b4d50a 5.5rc0 +7fc3c5fbc65f6fe85d70ea63923b8767dda4f2e0 5.5 +f62bb5d07848ca598aa860a517394130b61bf2ee 5.5.1 +07731064ac41dacdf0ec869ebd05c2e848c14fbf 5.5.2 +0e06a7ab9e0d5c65af4e511aee1e0342998799df 5.6rc0 +18c17d63fdabd009e70bf994e5efb7db422f4f7f 5.6 +1d5189a57405ceca5aa244052c9f948977f4699b 5.6.1 +9da65e3cf3706ff41e08b311381c588440c27baf 5.7rc0 +0e2e7300f4302b02412b0b734717697049494c4c 5.7 +d5d9177c0045d206db575bae6daa98e2cb2fe5bc 5.7.1 +f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 5.8rc0 +8d2b62d716b095507effaa8d56f87cd27ba659ab 5.8rc1 +067f2c53fb24506c9e9fb4639871b13b19a85f8a 5.8 +411dc27fd9fd076d6a031a08fcaace659afe2fe3 5.8.1 +d7515d29761d5ada7d9c765f517db67db75dea9a 5.9rc0 +2813d406b03607cdb8c06cb04c44efcc9a79d9a2 5.9rc1 +53221078e0de65d1a821ce5311dec45a7a978301 5.9 +86a60679cf619e14cee9442f865fcf31b142cb9f 5.9.1 +750920b18aaaddd654756be40dec59d90f2643be 5.9.2 +6ee0244fc1cf889ae543d2ce0ec45201ae0be6e1 5.9.3 +a44bb185f6bdbecc754996d8386722e2f0123b0a 6.0rc0 +5d08b289e2e526259d7d5ea32b70fe76d5b327d7 6.0 +799fdf4cca80cb9ae40537a90995e6bd163ebc0b 6.0.1 +75676122c2bf7594ac732b7388db4c74c648b365 6.0.2 +dcec16e799ddb6d33fcd11b04af530250a417a58 6.0.3 +c00d3ce4e94bb0ee8d809e25e1dcb2a5fab84e2c 6.1rc0 +d4486810a1795fba9521449b8885ced034f3a6dd 6.1 +5bd6bcd31dd1ebb63b8914b00064f96297267af7 6.1.1 +0ddd5e1f5f67438af85d12e4ce6c39021dde9916 6.1.2 +6b10151b962108f65bfa12b3918b1021ca334f73 6.1.3 +0cc5f74ff7f0f4ac2427096bddbe102dbc2453ae 6.1.4 +288de6f5d724bba7bf1669e2838f196962bb7528 6.2rc0 +094a5fa3cf52f936e0de3f1e507c818bee5ece6b 6.2 +f69bffd00abe3a1b94d1032eb2c92e611d16a192 6.2.1 +b5c8524827d20fe2e0ca8fb1234a0fe35a1a36c7 6.2.2 +dbdee8ac3e3fcdda1fa55b90c0a235125b7f8e6f 6.2.3 +a3356ab610fc50000cf0ba55c424a4d96da11db7 6.3rc0 +04f1dba53c961dfdb875c8469adc96fa999cfbed 6.3.0 +04f1dba53c961dfdb875c8469adc96fa999cfbed 6.3 +04f1dba53c961dfdb875c8469adc96fa999cfbed 6.3.0 +0000000000000000000000000000000000000000 6.3.0 +c890d8b8bc59b18e5febf60caada629df5356ee2 6.3.1 +59466b13a3ae0e29a5d4f485393e516cfbb057d0 6.3.2 +8830004967ad865ead89c28a410405a6e71e0796 6.3.3 +05de4896508e8ec387b33eb30d8aab78d1c8e9e4 6.4rc0 +f14864fffdcab725d9eac6d4f4c07be05a35f59a 6.4 +83ea6ce48b4fd09fb79c4e34cc5750c805699a53 6.4.1 +f952be90b0514a576dcc8bbe758ce3847faba9bb 6.4.2 +fc445f8abcf90b33db7c463816a1b3560681767f 6.4.3 +da372c745e0f053bb7a64e74cccd15810d96341d 6.4.4 +271a4ab29605ffa0bae5d3208eaa21a95427ff92 6.4.5 +bb42988c7e156931b0ff1e93732b98173ebbcb7f 6.5rc0 +3ffc7209bbae5804a53084c9dc2d41139e88c867 6.5 +787af4e0e8b787e1b77a8059926b123730a4cd01 6.5.1 +5a8b5420103937fca97c584c5162178eed828ada 6.5.2 +c083d9776cb2fb6056715b2988d1ea48055f3162 6.5.3 +27055614b68538576fb0439007009acf93fe0a49 6.6rc0 +26c57e7a0890b96e2c473b394de380d6753c9230 6.6 +71bd09bebbe36a09569cbfb388f371433360056b 6.6.1 +136902b3a95db38854ebaf5198a627641065c2ea 6.6.2 +3fd1efb3ad124e6686c0fb66e6943cd8aeea5681 6.6.3 +d1d48d18db37106b801ef6cb90955536458e7ffc 6.7rc0 +c9ceb4f6025690167bdb245e530de6bac8baae95 6.7 diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..4a03d3f --- /dev/null +++ b/.jshintrc @@ -0,0 +1,11 @@ +{ + // Enforcing + "eqeqeq" : true, // true: Require triple equals (===) for comparison + "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty() + "freeze" : true, // true: prohibits overwriting prototypes of native objects such as Array, Date etc. + "nonbsp" : true, // true: Prohibit "non-breaking whitespace" characters. + "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks) + + // Environments + "browser" : true // Web Browser (window, document, etc) +} diff --git a/CONTRIBUTING b/CONTRIBUTING new file mode 100644 index 0000000..8d593bc --- /dev/null +++ b/CONTRIBUTING @@ -0,0 +1,13 @@ +Our full contribution guidelines are in our wiki, please see: + +https://www.mercurial-scm.org/wiki/ContributingChanges + +If you just want a checklist to follow, you can go straight to + +https://www.mercurial-scm.org/wiki/ContributingChanges#Submission_checklist + +If you can't run the entire testsuite for some reason (it can be +difficult on Windows), please at least run `contrib/check-code.py` on +any files you've modified and run `python contrib/check-commit` on any +commits you've made (for example, `python contrib/check-commit +273ce12ad8f1` will report some style violations on a very old commit). diff --git a/CONTRIBUTORS b/CONTRIBUTORS new file mode 100644 index 0000000..81f8143 --- /dev/null +++ b/CONTRIBUTORS @@ -0,0 +1,41 @@ +[This file is here for historical purposes, all recent contributors +should appear in the changelog directly] + +Andrea Arcangeli +Thomas Arendsen Hein +Goffredo Baroncelli +Muli Ben-Yehuda +Mikael Berthe +Benoit Boissinot +Brendan Cully +Vincent Danjean +Jake Edge +Michael Fetterman +Edouard Gomez +Eric Hopper +Alecs King +Volker Kleinfeld +Vadim Lebedev +Christopher Li +Chris Mason +Colin McMillen +Wojciech Milkowski +Chad Netzer +Bryan O'Sullivan +Vicent Seguí Pascual +Sean Perry +Nguyen Anh Quynh +Ollivier Robert +Alexander Schremmer +Arun Sharma +Josef "Jeff" Sipek +Kevin Smith +TK Soh +Radoslaw Szkodzinski +Samuel Tardieu +K Thananchayan +Andrew Thompson +Michael S. Tsirkin +Rafael Villar Burke +Tristan Wibberley +Mark Williamson diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..276e789 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,2313 @@ +include .arcconfig +include .clang-format +include .editorconfig +include .gitattributes +include .gitlab/merge_request_templates/Default.md +include .hgignore +include .hgsigs +include .hgtags +include .jshintrc +include CONTRIBUTING +include CONTRIBUTORS +include COPYING +include Makefile +include README.rst +include contrib/Makefile.python +include contrib/all-revsets.txt +include contrib/asv.conf.json +include contrib/automation/README.rst +include contrib/automation/automation.py +include contrib/automation/hgautomation/__init__.py +include contrib/automation/hgautomation/aws.py +include contrib/automation/hgautomation/cli.py +include contrib/automation/hgautomation/linux.py +include contrib/automation/hgautomation/pypi.py +include contrib/automation/hgautomation/ssh.py +include contrib/automation/hgautomation/try_server.py +include contrib/automation/hgautomation/windows.py +include contrib/automation/hgautomation/winrm.py +include contrib/automation/linux-requirements-py3.5.txt +include contrib/automation/linux-requirements-py3.txt +include contrib/automation/linux-requirements.txt.in +include contrib/automation/requirements.txt +include contrib/automation/requirements.txt.in +include contrib/base-revsets.txt +include contrib/bash_completion +include contrib/bdiff-torture.py +include contrib/benchmarks/__init__.py +include contrib/benchmarks/perf.py +include contrib/benchmarks/revset.py +include contrib/byteify-strings.py +include contrib/casesmash.py +include contrib/catapipe.py +include contrib/check-code.py +include contrib/check-commit +include contrib/check-config.py +include contrib/check-py3-compat.py +include contrib/check-pytype.sh +include contrib/chg/Makefile +include contrib/chg/README +include contrib/chg/chg.1 +include contrib/chg/chg.c +include contrib/chg/hgclient.c +include contrib/chg/hgclient.h +include contrib/chg/procutil.c +include contrib/chg/procutil.h +include contrib/chg/util.c +include contrib/chg/util.h +include contrib/clang-format-ignorelist +include contrib/debugcmdserver.py +include contrib/debugshell.py +include contrib/docker/apache-server/Dockerfile +include contrib/docker/apache-server/README.rst +include contrib/docker/apache-server/entrypoint.sh +include contrib/docker/apache-server/hgwebconfig +include contrib/docker/apache-server/vhost.conf +include contrib/docker/pytype/Dockerfile +include contrib/docker/pytype/entrypoint.sh +include contrib/docker/pytype/recipe.sh +include contrib/dumprevlog +include contrib/editmerge +include contrib/editmergeps.bat +include contrib/editmergeps.ps1 +include contrib/examples/fix.hgrc +include contrib/fuzz/FuzzedDataProvider.h +include contrib/fuzz/Makefile +include contrib/fuzz/README.rst +include contrib/fuzz/bdiff.cc +include contrib/fuzz/dirs.cc +include contrib/fuzz/dirs_corpus.py +include contrib/fuzz/dirstate.cc +include contrib/fuzz/dirstate_corpus.py +include contrib/fuzz/fm1readmarkers.cc +include contrib/fuzz/fm1readmarkers_corpus.py +include contrib/fuzz/fncache.cc +include contrib/fuzz/fuzzutil.h +include contrib/fuzz/jsonescapeu8fast.cc +include contrib/fuzz/manifest.cc +include contrib/fuzz/manifest_corpus.py +include contrib/fuzz/mpatch.cc +include contrib/fuzz/mpatch_corpus.py +include contrib/fuzz/pyutil.cc +include contrib/fuzz/pyutil.h +include contrib/fuzz/revlog.cc +include contrib/fuzz/revlog_corpus.py +include contrib/fuzz/standalone_fuzz_target_runner.cc +include contrib/fuzz/xdiff.cc +include contrib/genosxversion.py +include contrib/heptapod-ci.yml +include contrib/hg-ssh +include contrib/hg-test-mode.el +include contrib/hgclient.py +include contrib/hgk +include contrib/hgperf +include contrib/hgsh/Makefile +include contrib/hgsh/hgsh.c +include contrib/hgweb.fcgi +include contrib/hgweb.wsgi +include contrib/import-checker.py +include contrib/install-windows-dependencies.ps1 +include contrib/logo-droplets.svg +include contrib/memory.py +include contrib/mercurial.el +include contrib/merge-lists/Cargo.lock +include contrib/merge-lists/Cargo.toml +include contrib/merge-lists/src/main.rs +include contrib/merge-lists/tests/test-merge-lists.rs +include contrib/mq.el +include contrib/nix/flake.lock +include contrib/nix/flake.nix +include contrib/openvms/build.com +include contrib/openvms/vms/hgeditor.com +include contrib/openvms/vms/hgmerge.com +include contrib/openvms/vms/logicals.com +include contrib/openvms/vms/setup.com +include contrib/openvms/vms/startup.com +include contrib/openvms/vms/stmlf.fdl +include contrib/packaging/Makefile +include contrib/packaging/build-linux-wheels.sh +include contrib/packaging/builddeb +include contrib/packaging/buildrpm +include contrib/packaging/debian/cacerts.rc +include contrib/packaging/debian/changelog +include contrib/packaging/debian/compat +include contrib/packaging/debian/control +include contrib/packaging/debian/copyright +include contrib/packaging/debian/default-tools.rc +include contrib/packaging/debian/hgkpath.rc +include contrib/packaging/debian/rules +include contrib/packaging/docker/debian.template +include contrib/packaging/docker/fedora.template +include contrib/packaging/docker/rhel7 +include contrib/packaging/docker/rhel8 +include contrib/packaging/docker/rhel9 +include contrib/packaging/docker/ubuntu.template +include contrib/packaging/dockerdeb +include contrib/packaging/dockerrpm +include contrib/packaging/hg-docker +include contrib/packaging/hgpackaging/__init__.py +include contrib/packaging/hgpackaging/cli.py +include contrib/packaging/hgpackaging/downloads.py +include contrib/packaging/hgpackaging/inno.py +include contrib/packaging/hgpackaging/pyoxidizer.py +include contrib/packaging/hgpackaging/util.py +include contrib/packaging/hgpackaging/wix.py +include contrib/packaging/inno/mercurial.iss +include contrib/packaging/inno/modpath.iss +include contrib/packaging/inno/readme.rst +include contrib/packaging/linux-wheel-centos5-blacklist +include contrib/packaging/macosx/Readme.html +include contrib/packaging/macosx/Welcome.html +include contrib/packaging/macosx/distribution.xml +include contrib/packaging/mercurial.spec +include contrib/packaging/packagelib.sh +include contrib/packaging/packaging.py +include contrib/packaging/requirements-macos.txt +include contrib/packaging/requirements-macos.txt.in +include contrib/packaging/requirements-windows-py3.txt +include contrib/packaging/requirements-windows.txt.in +include contrib/packaging/requirements.txt +include contrib/packaging/requirements.txt.in +include contrib/packaging/wix/COPYING.rtf +include contrib/packaging/wix/defines.wxi +include contrib/packaging/wix/guids.wxi +include contrib/packaging/wix/mercurial.wxs +include contrib/packaging/wix/readme.rst +include contrib/perf-utils/compare-discovery-case +include contrib/perf-utils/discovery-helper.sh +include contrib/perf-utils/perf-revlog-write-plot.py +include contrib/perf-utils/search-discovery-case +include contrib/perf-utils/subsetmaker.py +include contrib/perf.py +include contrib/phab-clean.py +include contrib/phab-refresh-stack.sh +include contrib/plan9/9diff +include contrib/plan9/9mail +include contrib/plan9/README +include contrib/plan9/hgrc.d/9diff.rc +include contrib/plan9/hgrc.d/9mail.rc +include contrib/plan9/hgrc.d/factotum.rc +include contrib/plan9/mkfile +include contrib/plan9/proto +include contrib/pull_logger.py +include contrib/pylintrc +include contrib/python-hook-examples.py +include contrib/python-zstandard/LICENSE +include contrib/python-zstandard/MANIFEST.in +include contrib/python-zstandard/NEWS.rst +include contrib/python-zstandard/README.rst +include contrib/python-zstandard/c-ext/bufferutil.c +include contrib/python-zstandard/c-ext/compressionchunker.c +include contrib/python-zstandard/c-ext/compressiondict.c +include contrib/python-zstandard/c-ext/compressionparams.c +include contrib/python-zstandard/c-ext/compressionreader.c +include contrib/python-zstandard/c-ext/compressionwriter.c +include contrib/python-zstandard/c-ext/compressobj.c +include contrib/python-zstandard/c-ext/compressor.c +include contrib/python-zstandard/c-ext/compressoriterator.c +include contrib/python-zstandard/c-ext/constants.c +include contrib/python-zstandard/c-ext/decompressionreader.c +include contrib/python-zstandard/c-ext/decompressionwriter.c +include contrib/python-zstandard/c-ext/decompressobj.c +include contrib/python-zstandard/c-ext/decompressor.c +include contrib/python-zstandard/c-ext/decompressoriterator.c +include contrib/python-zstandard/c-ext/frameparams.c +include contrib/python-zstandard/c-ext/python-zstandard.h +include contrib/python-zstandard/make_cffi.py +include contrib/python-zstandard/setup.py +include contrib/python-zstandard/setup_zstd.py +include contrib/python-zstandard/tests/__init__.py +include contrib/python-zstandard/tests/common.py +include contrib/python-zstandard/tests/test_buffer_util.py +include contrib/python-zstandard/tests/test_compressor.py +include contrib/python-zstandard/tests/test_compressor_fuzzing.py +include contrib/python-zstandard/tests/test_data_structures.py +include contrib/python-zstandard/tests/test_data_structures_fuzzing.py +include contrib/python-zstandard/tests/test_decompressor.py +include contrib/python-zstandard/tests/test_decompressor_fuzzing.py +include contrib/python-zstandard/tests/test_estimate_sizes.py +include contrib/python-zstandard/tests/test_module_attributes.py +include contrib/python-zstandard/tests/test_train_dictionary.py +include contrib/python-zstandard/zstandard/__init__.py +include contrib/python-zstandard/zstandard/cffi.py +include contrib/python-zstandard/zstd.c +include contrib/python-zstandard/zstd/COPYING +include contrib/python-zstandard/zstd/LICENSE +include contrib/python-zstandard/zstd/common/bitstream.h +include contrib/python-zstandard/zstd/common/compiler.h +include contrib/python-zstandard/zstd/common/cpu.h +include contrib/python-zstandard/zstd/common/debug.c +include contrib/python-zstandard/zstd/common/debug.h +include contrib/python-zstandard/zstd/common/entropy_common.c +include contrib/python-zstandard/zstd/common/error_private.c +include contrib/python-zstandard/zstd/common/error_private.h +include contrib/python-zstandard/zstd/common/fse.h +include contrib/python-zstandard/zstd/common/fse_decompress.c +include contrib/python-zstandard/zstd/common/huf.h +include contrib/python-zstandard/zstd/common/mem.h +include contrib/python-zstandard/zstd/common/pool.c +include contrib/python-zstandard/zstd/common/pool.h +include contrib/python-zstandard/zstd/common/pythoncapi_compat.h +include contrib/python-zstandard/zstd/common/threading.c +include contrib/python-zstandard/zstd/common/threading.h +include contrib/python-zstandard/zstd/common/xxhash.c +include contrib/python-zstandard/zstd/common/xxhash.h +include contrib/python-zstandard/zstd/common/zstd_common.c +include contrib/python-zstandard/zstd/common/zstd_errors.h +include contrib/python-zstandard/zstd/common/zstd_internal.h +include contrib/python-zstandard/zstd/compress/fse_compress.c +include contrib/python-zstandard/zstd/compress/hist.c +include contrib/python-zstandard/zstd/compress/hist.h +include contrib/python-zstandard/zstd/compress/huf_compress.c +include contrib/python-zstandard/zstd/compress/zstd_compress.c +include contrib/python-zstandard/zstd/compress/zstd_compress_internal.h +include contrib/python-zstandard/zstd/compress/zstd_compress_literals.c +include contrib/python-zstandard/zstd/compress/zstd_compress_literals.h +include contrib/python-zstandard/zstd/compress/zstd_compress_sequences.c +include contrib/python-zstandard/zstd/compress/zstd_compress_sequences.h +include contrib/python-zstandard/zstd/compress/zstd_cwksp.h +include contrib/python-zstandard/zstd/compress/zstd_double_fast.c +include contrib/python-zstandard/zstd/compress/zstd_double_fast.h +include contrib/python-zstandard/zstd/compress/zstd_fast.c +include contrib/python-zstandard/zstd/compress/zstd_fast.h +include contrib/python-zstandard/zstd/compress/zstd_lazy.c +include contrib/python-zstandard/zstd/compress/zstd_lazy.h +include contrib/python-zstandard/zstd/compress/zstd_ldm.c +include contrib/python-zstandard/zstd/compress/zstd_ldm.h +include contrib/python-zstandard/zstd/compress/zstd_opt.c +include contrib/python-zstandard/zstd/compress/zstd_opt.h +include contrib/python-zstandard/zstd/compress/zstdmt_compress.c +include contrib/python-zstandard/zstd/compress/zstdmt_compress.h +include contrib/python-zstandard/zstd/decompress/huf_decompress.c +include contrib/python-zstandard/zstd/decompress/zstd_ddict.c +include contrib/python-zstandard/zstd/decompress/zstd_ddict.h +include contrib/python-zstandard/zstd/decompress/zstd_decompress.c +include contrib/python-zstandard/zstd/decompress/zstd_decompress_block.c +include contrib/python-zstandard/zstd/decompress/zstd_decompress_block.h +include contrib/python-zstandard/zstd/decompress/zstd_decompress_internal.h +include contrib/python-zstandard/zstd/deprecated/zbuff.h +include contrib/python-zstandard/zstd/deprecated/zbuff_common.c +include contrib/python-zstandard/zstd/deprecated/zbuff_compress.c +include contrib/python-zstandard/zstd/deprecated/zbuff_decompress.c +include contrib/python-zstandard/zstd/dictBuilder/cover.c +include contrib/python-zstandard/zstd/dictBuilder/cover.h +include contrib/python-zstandard/zstd/dictBuilder/divsufsort.c +include contrib/python-zstandard/zstd/dictBuilder/divsufsort.h +include contrib/python-zstandard/zstd/dictBuilder/fastcover.c +include contrib/python-zstandard/zstd/dictBuilder/zdict.c +include contrib/python-zstandard/zstd/dictBuilder/zdict.h +include contrib/python-zstandard/zstd/zstd.h +include contrib/python3-ratchet.py +include contrib/python3-whitelist +include contrib/relnotes +include contrib/revsetbenchmarks.py +include contrib/setup-pytype.sh +include contrib/showstack.py +include contrib/simplemerge +include contrib/synthrepo.py +include contrib/tcsh_completion +include contrib/tcsh_completion_build.sh +include contrib/testparseutil.py +include contrib/undumprevlog +include contrib/vagrant/README.md +include contrib/vagrant/Vagrantfile +include contrib/vagrant/provision.sh +include contrib/vagrant/run-tests.sh +include contrib/vim/HGAnnotate.vim +include contrib/vim/hg-menu.vim +include contrib/vim/hgcommand.vim +include contrib/vim/hgtest.vim +include contrib/vim/patchreview.txt +include contrib/vim/patchreview.vim +include contrib/win32/ReadMe.html +include contrib/win32/buildlocal.bat +include contrib/win32/hg.bat +include contrib/win32/hgwebdir_wsgi.py +include contrib/win32/mercurial.ico +include contrib/win32/mercurial.ini +include contrib/win32/postinstall.txt +include contrib/xml.rnc +include contrib/zsh_completion +include doc/Makefile +include doc/README +include doc/check-seclevel.py +include doc/docchecker +include doc/gendoc.py +include doc/hgmanpage.py +include doc/runrst +include doc/style.css +include hg +include hgdemandimport/__init__.py +include hgdemandimport/demandimportpy3.py +include hgdemandimport/tracing.py +include hgeditor +include hgext/__init__.py +include hgext/absorb.py +include hgext/acl.py +include hgext/amend.py +include hgext/automv.py +include hgext/beautifygraph.py +include hgext/blackbox.py +include hgext/bookflow.py +include hgext/bugzilla.py +include hgext/censor.py +include hgext/children.py +include hgext/churn.py +include hgext/clonebundles.py +include hgext/closehead.py +include hgext/commitextras.py +include hgext/convert/__init__.py +include hgext/convert/bzr.py +include hgext/convert/common.py +include hgext/convert/convcmd.py +include hgext/convert/cvs.py +include hgext/convert/cvsps.py +include hgext/convert/darcs.py +include hgext/convert/filemap.py +include hgext/convert/git.py +include hgext/convert/gnuarch.py +include hgext/convert/hg.py +include hgext/convert/monotone.py +include hgext/convert/p4.py +include hgext/convert/subversion.py +include hgext/convert/transport.py +include hgext/eol.py +include hgext/extdiff.py +include hgext/factotum.py +include hgext/fastannotate/__init__.py +include hgext/fastannotate/commands.py +include hgext/fastannotate/context.py +include hgext/fastannotate/error.py +include hgext/fastannotate/formatter.py +include hgext/fastannotate/protocol.py +include hgext/fastannotate/revmap.py +include hgext/fastannotate/support.py +include hgext/fastexport.py +include hgext/fetch.py +include hgext/fix.py +include hgext/fsmonitor/__init__.py +include hgext/fsmonitor/pywatchman/__init__.py +include hgext/fsmonitor/pywatchman/bser.c +include hgext/fsmonitor/pywatchman/capabilities.py +include hgext/fsmonitor/pywatchman/compat.py +include hgext/fsmonitor/pywatchman/encoding.py +include hgext/fsmonitor/pywatchman/load.py +include hgext/fsmonitor/pywatchman/pybser.py +include hgext/fsmonitor/state.py +include hgext/fsmonitor/watchmanclient.py +include hgext/git/TODO.md +include hgext/git/__init__.py +include hgext/git/dirstate.py +include hgext/git/gitlog.py +include hgext/git/gitutil.py +include hgext/git/index.py +include hgext/git/manifest.py +include hgext/githelp.py +include hgext/gpg.py +include hgext/graphlog.py +include hgext/hgk.py +include hgext/highlight/__init__.py +include hgext/highlight/highlight.py +include hgext/histedit.py +include hgext/hooklib/__init__.py +include hgext/hooklib/changeset_obsoleted.py +include hgext/hooklib/changeset_published.py +include hgext/hooklib/enforce_draft_commits.py +include hgext/hooklib/reject_merge_commits.py +include hgext/hooklib/reject_new_heads.py +include hgext/journal.py +include hgext/keyword.py +include hgext/largefiles/CONTRIBUTORS +include hgext/largefiles/__init__.py +include hgext/largefiles/basestore.py +include hgext/largefiles/lfcommands.py +include hgext/largefiles/lfutil.py +include hgext/largefiles/localstore.py +include hgext/largefiles/overrides.py +include hgext/largefiles/proto.py +include hgext/largefiles/remotestore.py +include hgext/largefiles/reposetup.py +include hgext/largefiles/storefactory.py +include hgext/largefiles/wirestore.py +include hgext/lfs/TODO.rst +include hgext/lfs/__init__.py +include hgext/lfs/blobstore.py +include hgext/lfs/pointer.py +include hgext/lfs/wireprotolfsserver.py +include hgext/lfs/wrapper.py +include hgext/logtoprocess.py +include hgext/mq.py +include hgext/narrow/TODO.rst +include hgext/narrow/__init__.py +include hgext/narrow/narrowbundle2.py +include hgext/narrow/narrowcommands.py +include hgext/narrow/narrowdirstate.py +include hgext/narrow/narrowrepo.py +include hgext/narrow/narrowtemplates.py +include hgext/narrow/narrowwirepeer.py +include hgext/notify.py +include hgext/pager.py +include hgext/patchbomb.py +include hgext/phabricator.py +include hgext/purge.py +include hgext/rebase.py +include hgext/record.py +include hgext/releasenotes.py +include hgext/relink.py +include hgext/remotefilelog/README.md +include hgext/remotefilelog/__init__.py +include hgext/remotefilelog/basepack.py +include hgext/remotefilelog/basestore.py +include hgext/remotefilelog/connectionpool.py +include hgext/remotefilelog/constants.py +include hgext/remotefilelog/contentstore.py +include hgext/remotefilelog/datapack.py +include hgext/remotefilelog/debugcommands.py +include hgext/remotefilelog/fileserverclient.py +include hgext/remotefilelog/historypack.py +include hgext/remotefilelog/metadatastore.py +include hgext/remotefilelog/remotefilectx.py +include hgext/remotefilelog/remotefilelog.py +include hgext/remotefilelog/remotefilelogserver.py +include hgext/remotefilelog/repack.py +include hgext/remotefilelog/shallowbundle.py +include hgext/remotefilelog/shallowrepo.py +include hgext/remotefilelog/shallowstore.py +include hgext/remotefilelog/shallowutil.py +include hgext/remotefilelog/shallowverifier.py +include hgext/remotenames.py +include hgext/schemes.py +include hgext/share.py +include hgext/show.py +include hgext/sparse.py +include hgext/split.py +include hgext/sqlitestore.py +include hgext/strip.py +include hgext/transplant.py +include hgext/uncommit.py +include hgext/win32mbcs.py +include hgext/win32text.py +include hgext/zeroconf/Zeroconf.py +include hgext/zeroconf/__init__.py +include hgext3rd/__init__.py +include hgweb.cgi +include i18n/check-translation.py +include i18n/da.po +include i18n/de.po +include i18n/el.po +include i18n/fr.po +include i18n/hggettext +include i18n/it.po +include i18n/ja.po +include i18n/polib.LICENSE +include i18n/polib.py +include i18n/posplit +include i18n/pt_BR.po +include i18n/ro.po +include i18n/ru.po +include i18n/sv.po +include i18n/zh_CN.po +include i18n/zh_TW.po +include mercurial/__init__.py +include mercurial/__main__.py +include mercurial/admin/__init__.py +include mercurial/admin/chainsaw.py +include mercurial/admin/verify.py +include mercurial/admin_commands.py +include mercurial/ancestor.py +include mercurial/archival.py +include mercurial/bdiff.c +include mercurial/bdiff.h +include mercurial/bitmanipulation.h +include mercurial/bookmarks.py +include mercurial/branchmap.py +include mercurial/bundle2.py +include mercurial/bundlecaches.py +include mercurial/bundlerepo.py +include mercurial/cacheutil.py +include mercurial/cext/__init__.py +include mercurial/cext/base85.c +include mercurial/cext/base85.pyi +include mercurial/cext/bdiff.c +include mercurial/cext/bdiff.pyi +include mercurial/cext/charencode.c +include mercurial/cext/charencode.h +include mercurial/cext/dirs.c +include mercurial/cext/manifest.c +include mercurial/cext/mpatch.c +include mercurial/cext/mpatch.pyi +include mercurial/cext/osutil.c +include mercurial/cext/osutil.pyi +include mercurial/cext/parsers.c +include mercurial/cext/parsers.pyi +include mercurial/cext/pathencode.c +include mercurial/cext/py.typed +include mercurial/cext/revlog.c +include mercurial/cext/revlog.h +include mercurial/cext/util.h +include mercurial/cffi/__init__.py +include mercurial/cffi/bdiff.py +include mercurial/cffi/bdiffbuild.py +include mercurial/cffi/mpatch.py +include mercurial/cffi/mpatchbuild.py +include mercurial/cffi/osutil.py +include mercurial/cffi/osutilbuild.py +include mercurial/changegroup.py +include mercurial/changelog.py +include mercurial/chgserver.py +include mercurial/cmdutil.py +include mercurial/color.py +include mercurial/commands.py +include mercurial/commandserver.py +include mercurial/commit.py +include mercurial/compat.h +include mercurial/config.py +include mercurial/configitems.py +include mercurial/configitems.toml +include mercurial/context.py +include mercurial/copies.py +include mercurial/crecord.py +include mercurial/dagop.py +include mercurial/dagparser.py +include mercurial/debugcommands.py +include mercurial/defaultrc/__init__.py +include mercurial/defaultrc/mergetools.rc +include mercurial/destutil.py +include mercurial/diffhelper.py +include mercurial/diffutil.py +include mercurial/dirstate.py +include mercurial/dirstatemap.py +include mercurial/dirstateutils/__init__.py +include mercurial/dirstateutils/docket.py +include mercurial/dirstateutils/timestamp.py +include mercurial/dirstateutils/v2.py +include mercurial/discovery.py +include mercurial/dispatch.py +include mercurial/dummycert.pem +include mercurial/encoding.py +include mercurial/error.py +include mercurial/exchange.py +include mercurial/exewrapper.c +include mercurial/extensions.py +include mercurial/exthelper.py +include mercurial/fancyopts.py +include mercurial/filelog.py +include mercurial/filemerge.py +include mercurial/fileset.py +include mercurial/filesetlang.py +include mercurial/formatter.py +include mercurial/graphmod.py +include mercurial/grep.py +include mercurial/hbisect.py +include mercurial/help.py +include mercurial/helptext/__init__.py +include mercurial/helptext/bundlespec.txt +include mercurial/helptext/color.txt +include mercurial/helptext/common.txt +include mercurial/helptext/config.txt +include mercurial/helptext/dates.txt +include mercurial/helptext/deprecated.txt +include mercurial/helptext/diffs.txt +include mercurial/helptext/environment.txt +include mercurial/helptext/evolution.txt +include mercurial/helptext/extensions.txt +include mercurial/helptext/filesets.txt +include mercurial/helptext/flags.txt +include mercurial/helptext/glossary.txt +include mercurial/helptext/hg-ssh.8.txt +include mercurial/helptext/hg.1.txt +include mercurial/helptext/hgignore.5.txt +include mercurial/helptext/hgignore.txt +include mercurial/helptext/hgrc.5.txt +include mercurial/helptext/hgweb.txt +include mercurial/helptext/internals/__init__.py +include mercurial/helptext/internals/bid-merge.txt +include mercurial/helptext/internals/bundle2.txt +include mercurial/helptext/internals/bundles.txt +include mercurial/helptext/internals/cbor.txt +include mercurial/helptext/internals/censor.txt +include mercurial/helptext/internals/changegroups.txt +include mercurial/helptext/internals/config.txt +include mercurial/helptext/internals/dirstate-v2.txt +include mercurial/helptext/internals/extensions.txt +include mercurial/helptext/internals/linelog.txt +include mercurial/helptext/internals/mergestate.txt +include mercurial/helptext/internals/requirements.txt +include mercurial/helptext/internals/revlogs.txt +include mercurial/helptext/internals/wireprotocol.txt +include mercurial/helptext/internals/wireprotocolrpc.txt +include mercurial/helptext/internals/wireprotocolv2.txt +include mercurial/helptext/merge-tools.txt +include mercurial/helptext/pager.txt +include mercurial/helptext/patterns.txt +include mercurial/helptext/phases.txt +include mercurial/helptext/revisions.txt +include mercurial/helptext/rust.txt +include mercurial/helptext/scripting.txt +include mercurial/helptext/subrepos.txt +include mercurial/helptext/templates.txt +include mercurial/helptext/urls.txt +include mercurial/hg.py +include mercurial/hgweb/__init__.py +include mercurial/hgweb/common.py +include mercurial/hgweb/hgweb_mod.py +include mercurial/hgweb/hgwebdir_mod.py +include mercurial/hgweb/request.py +include mercurial/hgweb/server.py +include mercurial/hgweb/webcommands.py +include mercurial/hgweb/webutil.py +include mercurial/hgweb/wsgicgi.py +include mercurial/hgweb/wsgiheaders.py +include mercurial/hook.py +include mercurial/httpconnection.py +include mercurial/httppeer.py +include mercurial/i18n.py +include mercurial/interfaces/__init__.py +include mercurial/interfaces/dirstate.py +include mercurial/interfaces/repository.py +include mercurial/interfaces/util.py +include mercurial/keepalive.py +include mercurial/linelog.py +include mercurial/localrepo.py +include mercurial/lock.py +include mercurial/logcmdutil.py +include mercurial/logexchange.py +include mercurial/loggingutil.py +include mercurial/lsprof.py +include mercurial/lsprofcalltree.py +include mercurial/mail.py +include mercurial/manifest.py +include mercurial/match.py +include mercurial/mdiff.py +include mercurial/merge.py +include mercurial/mergestate.py +include mercurial/mergeutil.py +include mercurial/metadata.py +include mercurial/minifileset.py +include mercurial/minirst.py +include mercurial/mpatch.c +include mercurial/mpatch.h +include mercurial/namespaces.py +include mercurial/narrowspec.py +include mercurial/node.py +include mercurial/obsolete.py +include mercurial/obsutil.py +include mercurial/parser.py +include mercurial/patch.py +include mercurial/pathutil.py +include mercurial/phases.py +include mercurial/policy.py +include mercurial/posix.py +include mercurial/profiling.py +include mercurial/progress.py +include mercurial/pure/__init__.py +include mercurial/pure/base85.py +include mercurial/pure/bdiff.py +include mercurial/pure/charencode.py +include mercurial/pure/mpatch.py +include mercurial/pure/osutil.py +include mercurial/pure/parsers.py +include mercurial/pushkey.py +include mercurial/pvec.py +include mercurial/pycompat.py +include mercurial/pythoncapi_compat.h +include mercurial/rcutil.py +include mercurial/registrar.py +include mercurial/repair.py +include mercurial/repocache.py +include mercurial/repoview.py +include mercurial/requirements.py +include mercurial/revlog.py +include mercurial/revlogutils/__init__.py +include mercurial/revlogutils/concurrency_checker.py +include mercurial/revlogutils/constants.py +include mercurial/revlogutils/debug.py +include mercurial/revlogutils/deltas.py +include mercurial/revlogutils/docket.py +include mercurial/revlogutils/flagutil.py +include mercurial/revlogutils/nodemap.py +include mercurial/revlogutils/randomaccessfile.py +include mercurial/revlogutils/revlogv0.py +include mercurial/revlogutils/rewrite.py +include mercurial/revlogutils/sidedata.py +include mercurial/revset.py +include mercurial/revsetlang.py +include mercurial/rewriteutil.py +include mercurial/scmposix.py +include mercurial/scmutil.py +include mercurial/scmwindows.py +include mercurial/server.py +include mercurial/setdiscovery.py +include mercurial/shelve.py +include mercurial/similar.py +include mercurial/simplemerge.py +include mercurial/smartset.py +include mercurial/sparse.py +include mercurial/sshpeer.py +include mercurial/sslutil.py +include mercurial/stabletailgraph/__init__.py +include mercurial/stabletailgraph/stabletailsort.py +include mercurial/stack.py +include mercurial/state.py +include mercurial/statichttprepo.py +include mercurial/statprof.py +include mercurial/store.py +include mercurial/streamclone.py +include mercurial/strip.py +include mercurial/subrepo.py +include mercurial/subrepoutil.py +include mercurial/tagmerge.py +include mercurial/tags.py +include mercurial/templatefilters.py +include mercurial/templatefuncs.py +include mercurial/templatekw.py +include mercurial/templater.py +include mercurial/templates/__init__.py +include mercurial/templates/atom/__init__.py +include mercurial/templates/atom/bookmarkentry.tmpl +include mercurial/templates/atom/bookmarks.tmpl +include mercurial/templates/atom/branchentry.tmpl +include mercurial/templates/atom/branches.tmpl +include mercurial/templates/atom/changelog.tmpl +include mercurial/templates/atom/changelogentry.tmpl +include mercurial/templates/atom/error.tmpl +include mercurial/templates/atom/filelog.tmpl +include mercurial/templates/atom/header.tmpl +include mercurial/templates/atom/map +include mercurial/templates/atom/tagentry.tmpl +include mercurial/templates/atom/tags.tmpl +include mercurial/templates/coal/__init__.py +include mercurial/templates/coal/header.tmpl +include mercurial/templates/coal/map +include mercurial/templates/gitweb/__init__.py +include mercurial/templates/gitweb/bookmarks.tmpl +include mercurial/templates/gitweb/branches.tmpl +include mercurial/templates/gitweb/changelog.tmpl +include mercurial/templates/gitweb/changelogentry.tmpl +include mercurial/templates/gitweb/changeset.tmpl +include mercurial/templates/gitweb/error.tmpl +include mercurial/templates/gitweb/fileannotate.tmpl +include mercurial/templates/gitweb/filecomparison.tmpl +include mercurial/templates/gitweb/filediff.tmpl +include mercurial/templates/gitweb/filelog.tmpl +include mercurial/templates/gitweb/filerevision.tmpl +include mercurial/templates/gitweb/footer.tmpl +include mercurial/templates/gitweb/graph.tmpl +include mercurial/templates/gitweb/graphentry.tmpl +include mercurial/templates/gitweb/header.tmpl +include mercurial/templates/gitweb/help.tmpl +include mercurial/templates/gitweb/helptopics.tmpl +include mercurial/templates/gitweb/index.tmpl +include mercurial/templates/gitweb/manifest.tmpl +include mercurial/templates/gitweb/map +include mercurial/templates/gitweb/notfound.tmpl +include mercurial/templates/gitweb/search.tmpl +include mercurial/templates/gitweb/shortlog.tmpl +include mercurial/templates/gitweb/summary.tmpl +include mercurial/templates/gitweb/tags.tmpl +include mercurial/templates/json/__init__.py +include mercurial/templates/json/changelist.tmpl +include mercurial/templates/json/graph.tmpl +include mercurial/templates/json/map +include mercurial/templates/map-cmdline.bisect +include mercurial/templates/map-cmdline.changelog +include mercurial/templates/map-cmdline.compact +include mercurial/templates/map-cmdline.default +include mercurial/templates/map-cmdline.phases +include mercurial/templates/map-cmdline.show +include mercurial/templates/map-cmdline.status +include mercurial/templates/map-cmdline.xml +include mercurial/templates/monoblue/__init__.py +include mercurial/templates/monoblue/bookmarks.tmpl +include mercurial/templates/monoblue/branches.tmpl +include mercurial/templates/monoblue/changelog.tmpl +include mercurial/templates/monoblue/changelogentry.tmpl +include mercurial/templates/monoblue/changeset.tmpl +include mercurial/templates/monoblue/error.tmpl +include mercurial/templates/monoblue/fileannotate.tmpl +include mercurial/templates/monoblue/filecomparison.tmpl +include mercurial/templates/monoblue/filediff.tmpl +include mercurial/templates/monoblue/filelog.tmpl +include mercurial/templates/monoblue/filerevision.tmpl +include mercurial/templates/monoblue/footer.tmpl +include mercurial/templates/monoblue/graph.tmpl +include mercurial/templates/monoblue/graphentry.tmpl +include mercurial/templates/monoblue/header.tmpl +include mercurial/templates/monoblue/help.tmpl +include mercurial/templates/monoblue/helptopics.tmpl +include mercurial/templates/monoblue/index.tmpl +include mercurial/templates/monoblue/manifest.tmpl +include mercurial/templates/monoblue/map +include mercurial/templates/monoblue/notfound.tmpl +include mercurial/templates/monoblue/search.tmpl +include mercurial/templates/monoblue/shortlog.tmpl +include mercurial/templates/monoblue/summary.tmpl +include mercurial/templates/monoblue/tags.tmpl +include mercurial/templates/paper/__init__.py +include mercurial/templates/paper/bookmarks.tmpl +include mercurial/templates/paper/branches.tmpl +include mercurial/templates/paper/changeset.tmpl +include mercurial/templates/paper/diffstat.tmpl +include mercurial/templates/paper/error.tmpl +include mercurial/templates/paper/fileannotate.tmpl +include mercurial/templates/paper/filecomparison.tmpl +include mercurial/templates/paper/filediff.tmpl +include mercurial/templates/paper/filelog.tmpl +include mercurial/templates/paper/filelogentry.tmpl +include mercurial/templates/paper/filerevision.tmpl +include mercurial/templates/paper/footer.tmpl +include mercurial/templates/paper/graph.tmpl +include mercurial/templates/paper/graphentry.tmpl +include mercurial/templates/paper/header.tmpl +include mercurial/templates/paper/help.tmpl +include mercurial/templates/paper/helptopics.tmpl +include mercurial/templates/paper/index.tmpl +include mercurial/templates/paper/manifest.tmpl +include mercurial/templates/paper/map +include mercurial/templates/paper/notfound.tmpl +include mercurial/templates/paper/search.tmpl +include mercurial/templates/paper/shortlog.tmpl +include mercurial/templates/paper/shortlogentry.tmpl +include mercurial/templates/paper/tags.tmpl +include mercurial/templates/raw/__init__.py +include mercurial/templates/raw/changelog.tmpl +include mercurial/templates/raw/changeset.tmpl +include mercurial/templates/raw/error.tmpl +include mercurial/templates/raw/fileannotate.tmpl +include mercurial/templates/raw/filediff.tmpl +include mercurial/templates/raw/graph.tmpl +include mercurial/templates/raw/graphedge.tmpl +include mercurial/templates/raw/graphnode.tmpl +include mercurial/templates/raw/index.tmpl +include mercurial/templates/raw/logentry.tmpl +include mercurial/templates/raw/manifest.tmpl +include mercurial/templates/raw/map +include mercurial/templates/raw/notfound.tmpl +include mercurial/templates/raw/search.tmpl +include mercurial/templates/rss/__init__.py +include mercurial/templates/rss/bookmarkentry.tmpl +include mercurial/templates/rss/bookmarks.tmpl +include mercurial/templates/rss/branchentry.tmpl +include mercurial/templates/rss/branches.tmpl +include mercurial/templates/rss/changelog.tmpl +include mercurial/templates/rss/changelogentry.tmpl +include mercurial/templates/rss/error.tmpl +include mercurial/templates/rss/filelog.tmpl +include mercurial/templates/rss/filelogentry.tmpl +include mercurial/templates/rss/header.tmpl +include mercurial/templates/rss/map +include mercurial/templates/rss/tagentry.tmpl +include mercurial/templates/rss/tags.tmpl +include mercurial/templates/spartan/__init__.py +include mercurial/templates/spartan/branches.tmpl +include mercurial/templates/spartan/changelog.tmpl +include mercurial/templates/spartan/changelogentry.tmpl +include mercurial/templates/spartan/changeset.tmpl +include mercurial/templates/spartan/error.tmpl +include mercurial/templates/spartan/fileannotate.tmpl +include mercurial/templates/spartan/filediff.tmpl +include mercurial/templates/spartan/filelog.tmpl +include mercurial/templates/spartan/filelogentry.tmpl +include mercurial/templates/spartan/filerevision.tmpl +include mercurial/templates/spartan/footer.tmpl +include mercurial/templates/spartan/graph.tmpl +include mercurial/templates/spartan/graphentry.tmpl +include mercurial/templates/spartan/header.tmpl +include mercurial/templates/spartan/index.tmpl +include mercurial/templates/spartan/manifest.tmpl +include mercurial/templates/spartan/map +include mercurial/templates/spartan/notfound.tmpl +include mercurial/templates/spartan/search.tmpl +include mercurial/templates/spartan/shortlog.tmpl +include mercurial/templates/spartan/shortlogentry.tmpl +include mercurial/templates/spartan/tags.tmpl +include mercurial/templates/static/__init__.py +include mercurial/templates/static/background.png +include mercurial/templates/static/coal-file.png +include mercurial/templates/static/coal-folder.png +include mercurial/templates/static/feed-icon-14x14.png +include mercurial/templates/static/followlines.js +include mercurial/templates/static/hgicon.png +include mercurial/templates/static/hglogo.png +include mercurial/templates/static/mercurial.js +include mercurial/templates/static/style-extra-coal.css +include mercurial/templates/static/style-gitweb.css +include mercurial/templates/static/style-monoblue.css +include mercurial/templates/static/style-paper.css +include mercurial/templates/static/style.css +include mercurial/templateutil.py +include mercurial/testing/__init__.py +include mercurial/testing/revlog.py +include mercurial/testing/storage.py +include mercurial/thirdparty/__init__.py +include mercurial/thirdparty/attr/LICENSE +include mercurial/thirdparty/attr/__init__.py +include mercurial/thirdparty/attr/__init__.pyi +include mercurial/thirdparty/attr/_cmp.py +include mercurial/thirdparty/attr/_cmp.pyi +include mercurial/thirdparty/attr/_compat.py +include mercurial/thirdparty/attr/_config.py +include mercurial/thirdparty/attr/_funcs.py +include mercurial/thirdparty/attr/_make.py +include mercurial/thirdparty/attr/_next_gen.py +include mercurial/thirdparty/attr/_version_info.py +include mercurial/thirdparty/attr/_version_info.pyi +include mercurial/thirdparty/attr/converters.py +include mercurial/thirdparty/attr/converters.pyi +include mercurial/thirdparty/attr/exceptions.py +include mercurial/thirdparty/attr/exceptions.pyi +include mercurial/thirdparty/attr/filters.py +include mercurial/thirdparty/attr/filters.pyi +include mercurial/thirdparty/attr/py.typed +include mercurial/thirdparty/attr/setters.py +include mercurial/thirdparty/attr/setters.pyi +include mercurial/thirdparty/attr/validators.py +include mercurial/thirdparty/attr/validators.pyi +include mercurial/thirdparty/cbor/.travis.yml +include mercurial/thirdparty/cbor/LICENSE.txt +include mercurial/thirdparty/cbor/README.rst +include mercurial/thirdparty/cbor/__init__.py +include mercurial/thirdparty/cbor/cbor2/__init__.py +include mercurial/thirdparty/cbor/cbor2/compat.py +include mercurial/thirdparty/cbor/cbor2/decoder.py +include mercurial/thirdparty/cbor/cbor2/encoder.py +include mercurial/thirdparty/cbor/cbor2/types.py +include mercurial/thirdparty/sha1dc/LICENSE.txt +include mercurial/thirdparty/sha1dc/README.md +include mercurial/thirdparty/sha1dc/cext.c +include mercurial/thirdparty/sha1dc/lib/sha1.c +include mercurial/thirdparty/sha1dc/lib/sha1.h +include mercurial/thirdparty/sha1dc/lib/ubc_check.c +include mercurial/thirdparty/sha1dc/lib/ubc_check.h +include mercurial/thirdparty/tomli/LICENSE +include mercurial/thirdparty/tomli/README.md +include mercurial/thirdparty/tomli/__init__.py +include mercurial/thirdparty/tomli/_parser.py +include mercurial/thirdparty/tomli/_re.py +include mercurial/thirdparty/tomli/_types.py +include mercurial/thirdparty/tomli/py.typed +include mercurial/thirdparty/xdiff/xdiff.h +include mercurial/thirdparty/xdiff/xdiffi.c +include mercurial/thirdparty/xdiff/xdiffi.h +include mercurial/thirdparty/xdiff/xinclude.h +include mercurial/thirdparty/xdiff/xmacros.h +include mercurial/thirdparty/xdiff/xprepare.c +include mercurial/thirdparty/xdiff/xprepare.h +include mercurial/thirdparty/xdiff/xtypes.h +include mercurial/thirdparty/xdiff/xutils.c +include mercurial/thirdparty/xdiff/xutils.h +include mercurial/thirdparty/zope/__init__.py +include mercurial/thirdparty/zope/interface/LICENSE.txt +include mercurial/thirdparty/zope/interface/__init__.py +include mercurial/thirdparty/zope/interface/_compat.py +include mercurial/thirdparty/zope/interface/_flatten.py +include mercurial/thirdparty/zope/interface/_zope_interface_coptimizations.c +include mercurial/thirdparty/zope/interface/adapter.py +include mercurial/thirdparty/zope/interface/advice.py +include mercurial/thirdparty/zope/interface/common/__init__.py +include mercurial/thirdparty/zope/interface/common/idatetime.py +include mercurial/thirdparty/zope/interface/common/interfaces.py +include mercurial/thirdparty/zope/interface/common/mapping.py +include mercurial/thirdparty/zope/interface/common/sequence.py +include mercurial/thirdparty/zope/interface/declarations.py +include mercurial/thirdparty/zope/interface/document.py +include mercurial/thirdparty/zope/interface/exceptions.py +include mercurial/thirdparty/zope/interface/interface.py +include mercurial/thirdparty/zope/interface/interfaces.py +include mercurial/thirdparty/zope/interface/registry.py +include mercurial/thirdparty/zope/interface/ro.py +include mercurial/thirdparty/zope/interface/verify.py +include mercurial/transaction.py +include mercurial/treediscovery.py +include mercurial/txnutil.py +include mercurial/typelib.py +include mercurial/ui.py +include mercurial/unionrepo.py +include mercurial/upgrade.py +include mercurial/upgrade_utils/__init__.py +include mercurial/upgrade_utils/actions.py +include mercurial/upgrade_utils/auto_upgrade.py +include mercurial/upgrade_utils/engine.py +include mercurial/url.py +include mercurial/urllibcompat.py +include mercurial/util.py +include mercurial/utils/__init__.py +include mercurial/utils/cborutil.py +include mercurial/utils/compression.py +include mercurial/utils/dateutil.py +include mercurial/utils/hashutil.py +include mercurial/utils/memorytop.py +include mercurial/utils/procutil.py +include mercurial/utils/repoviewutil.py +include mercurial/utils/resourceutil.py +include mercurial/utils/storageutil.py +include mercurial/utils/stringutil.py +include mercurial/utils/urlutil.py +include mercurial/verify.py +include mercurial/vfs.py +include mercurial/win32.py +include mercurial/windows.py +include mercurial/wireprotoframing.py +include mercurial/wireprotoserver.py +include mercurial/wireprototypes.py +include mercurial/wireprotov1peer.py +include mercurial/wireprotov1server.py +include mercurial/worker.py +include pyproject.toml +include relnotes/5.1 +include relnotes/5.2 +include relnotes/5.3 +include relnotes/5.4 +include relnotes/5.5 +include relnotes/5.6 +include relnotes/5.7 +include relnotes/5.8 +include relnotes/5.9 +include relnotes/6.0 +include relnotes/6.1 +include relnotes/6.2 +include relnotes/6.3 +include relnotes/6.4 +include relnotes/6.5 +include relnotes/6.6 +include relnotes/6.7 +include relnotes/next +include rust/.cargo/config +include rust/Cargo.lock +include rust/Cargo.toml +include rust/README.rst +include rust/chg/Cargo.lock +include rust/chg/Cargo.toml +include rust/chg/build.rs +include rust/chg/src/attachio.rs +include rust/chg/src/clientext.rs +include rust/chg/src/lib.rs +include rust/chg/src/locator.rs +include rust/chg/src/main.rs +include rust/chg/src/message.rs +include rust/chg/src/procutil.rs +include rust/chg/src/runcommand.rs +include rust/chg/src/sendfds.c +include rust/chg/src/sighandlers.c +include rust/chg/src/uihandler.rs +include rust/clippy.toml +include rust/hg-core/Cargo.toml +include rust/hg-core/examples/nodemap/index.rs +include rust/hg-core/examples/nodemap/main.rs +include rust/hg-core/src/ancestors.rs +include rust/hg-core/src/checkexec.rs +include rust/hg-core/src/config/config_items.rs +include rust/hg-core/src/config/layer.rs +include rust/hg-core/src/config/mod.rs +include rust/hg-core/src/config/plain_info.rs +include rust/hg-core/src/config/values.rs +include rust/hg-core/src/copy_tracing.rs +include rust/hg-core/src/copy_tracing/tests.rs +include rust/hg-core/src/copy_tracing/tests_support.rs +include rust/hg-core/src/dagops.rs +include rust/hg-core/src/dirstate.rs +include rust/hg-core/src/dirstate/dirs_multiset.rs +include rust/hg-core/src/dirstate/entry.rs +include rust/hg-core/src/dirstate/parsers.rs +include rust/hg-core/src/dirstate/status.rs +include rust/hg-core/src/dirstate_tree.rs +include rust/hg-core/src/dirstate_tree/dirstate_map.rs +include rust/hg-core/src/dirstate_tree/on_disk.rs +include rust/hg-core/src/dirstate_tree/owning.rs +include rust/hg-core/src/dirstate_tree/path_with_basename.rs +include rust/hg-core/src/dirstate_tree/status.rs +include rust/hg-core/src/discovery.rs +include rust/hg-core/src/errors.rs +include rust/hg-core/src/exit_codes.rs +include rust/hg-core/src/filepatterns.rs +include rust/hg-core/src/lib.rs +include rust/hg-core/src/lock.rs +include rust/hg-core/src/logging.rs +include rust/hg-core/src/matchers.rs +include rust/hg-core/src/narrow.rs +include rust/hg-core/src/operations/cat.rs +include rust/hg-core/src/operations/debugdata.rs +include rust/hg-core/src/operations/list_tracked_files.rs +include rust/hg-core/src/operations/mod.rs +include rust/hg-core/src/operations/status_rev_rev.rs +include rust/hg-core/src/repo.rs +include rust/hg-core/src/requirements.rs +include rust/hg-core/src/revlog/changelog.rs +include rust/hg-core/src/revlog/filelog.rs +include rust/hg-core/src/revlog/index.rs +include rust/hg-core/src/revlog/manifest.rs +include rust/hg-core/src/revlog/mod.rs +include rust/hg-core/src/revlog/node.rs +include rust/hg-core/src/revlog/nodemap.rs +include rust/hg-core/src/revlog/nodemap_docket.rs +include rust/hg-core/src/revlog/patch.rs +include rust/hg-core/src/revlog/path_encode.rs +include rust/hg-core/src/revset.rs +include rust/hg-core/src/sparse.rs +include rust/hg-core/src/testing.rs +include rust/hg-core/src/utils.rs +include rust/hg-core/src/utils/debug.rs +include rust/hg-core/src/utils/files.rs +include rust/hg-core/src/utils/hg_path.rs +include rust/hg-core/src/utils/path_auditor.rs +include rust/hg-core/src/vfs.rs +include rust/hg-core/tests/test_missing_ancestors.rs +include rust/hg-cpython/Cargo.toml +include rust/hg-cpython/src/ancestors.rs +include rust/hg-cpython/src/cindex.rs +include rust/hg-cpython/src/conversion.rs +include rust/hg-cpython/src/copy_tracing.rs +include rust/hg-cpython/src/dagops.rs +include rust/hg-cpython/src/debug.rs +include rust/hg-cpython/src/dirstate.rs +include rust/hg-cpython/src/dirstate/copymap.rs +include rust/hg-cpython/src/dirstate/dirs_multiset.rs +include rust/hg-cpython/src/dirstate/dirstate_map.rs +include rust/hg-cpython/src/dirstate/item.rs +include rust/hg-cpython/src/dirstate/status.rs +include rust/hg-cpython/src/discovery.rs +include rust/hg-cpython/src/exceptions.rs +include rust/hg-cpython/src/lib.rs +include rust/hg-cpython/src/pybytes_deref.rs +include rust/hg-cpython/src/ref_sharing.rs +include rust/hg-cpython/src/revlog.rs +include rust/hg-cpython/src/utils.rs +include rust/hgcli/.cargo/config +include rust/hgcli/Cargo.lock +include rust/hgcli/Cargo.toml +include rust/hgcli/README.md +include rust/hgcli/build.rs +include rust/hgcli/pyoxidizer.bzl +include rust/hgcli/src/main.rs +include rust/rhg/Cargo.toml +include rust/rhg/README.md +include rust/rhg/src/blackbox.rs +include rust/rhg/src/color.rs +include rust/rhg/src/commands/cat.rs +include rust/rhg/src/commands/config.rs +include rust/rhg/src/commands/debugdata.rs +include rust/rhg/src/commands/debugignorerhg.rs +include rust/rhg/src/commands/debugrequirements.rs +include rust/rhg/src/commands/debugrhgsparse.rs +include rust/rhg/src/commands/files.rs +include rust/rhg/src/commands/root.rs +include rust/rhg/src/commands/status.rs +include rust/rhg/src/error.rs +include rust/rhg/src/main.rs +include rust/rhg/src/ui.rs +include rust/rhg/src/utils/path_utils.rs +include rustfmt.toml +include setup.py +include tests/.balto.toml +include tests/README +include tests/artifacts/PURPOSE +include tests/artifacts/cache/big-file-churn.hg.md5 +include tests/artifacts/scripts/generate-churning-bundle.py +include tests/autodiff.py +include tests/basic_test_result.py +include tests/binfile.bin +include tests/blackbox-readonly-dispatch.py +include tests/blacklists/README +include tests/blacklists/fsmonitor +include tests/blacklists/linux-vfat +include tests/blacklists/nix +include tests/bruterebase.py +include tests/bundles/darcs1.hg +include tests/bundles/hgweb+obs.hg +include tests/bundles/issue4041.hg +include tests/bundles/issue4438-r1.hg +include tests/bundles/issue4438-r2.hg +include tests/bundles/issue6528.hg-v1 +include tests/bundles/issue6528.hg-v2 +include tests/bundles/issue6528.tar +include tests/bundles/legacy-encoding.hg +include tests/bundles/rebase-revset.hg +include tests/bundles/rebase.hg +include tests/bundles/rebase.sh +include tests/bundles/remote.hg +include tests/bundles/remote.sh +include tests/bundles/rename.sh +include tests/bundles/renames.hg +include tests/bundles/tampered.hg +include tests/bundles/test-invalid-branch-name.hg +include tests/bundles/test-keyword.hg +include tests/bundles/test-manifest.hg +include tests/bundles/test-merge-symlinks.hg +include tests/bundles/test-no-symlinks.hg +include tests/bundles/test-revlog-diff-relative-to-nullrev.sh +include tests/bundles/test-revlog-diff-relative-to-nullrev.tar +include tests/bzr-definitions +include tests/cgienv +include tests/check-gendoc +include tests/check-perf-code.py +include tests/common-pattern.py +include tests/crashgetbundler.py +include tests/drawdag.py +include tests/dumbhttp.py +include tests/dummysmtpd.py +include tests/dummyssh +include tests/f +include tests/failfilemerge.py +include tests/fakedirstatewritetime.py +include tests/fakemergerecord.py +include tests/fakepatchtime.py +include tests/filterpyflakes.py +include tests/filtertraceback.py +include tests/flagprocessorext.py +include tests/fsmonitor-run-tests.py +include tests/generate-working-copy-states.py +include tests/get-with-headers.py +include tests/gpg/pubring.gpg +include tests/gpg/secring.gpg +include tests/gpg/trustdb.gpg +include tests/helper-runtests.sh +include tests/helpers-testrepo.sh +include tests/heredoctest.py +include tests/hghave +include tests/hghave.py +include tests/hgterm.ti +include tests/hgweberror.py +include tests/histedit-helpers.sh +include tests/httpserverauth.py +include tests/hypothesishelpers.py +include tests/killdaemons.py +include tests/list-tree.py +include tests/lockdelay.py +include tests/logexceptions.py +include tests/ls-l.py +include tests/md5sum.py +include tests/missing-comment.hg +include tests/mockblackbox.py +include tests/mockmakedate.py +include tests/mocktime.py +include tests/narrow-library.sh +include tests/notcapable +include tests/pdiff +include tests/phabricator/accept-4564.json +include tests/phabricator/accept-7913.json +include tests/phabricator/phab-conduit.json +include tests/phabricator/phabimport-multi-drev.json +include tests/phabricator/phabimport-stack.json +include tests/phabricator/phabread-4480.json +include tests/phabricator/phabread-conduit-error.json +include tests/phabricator/phabread-empty-drev.json +include tests/phabricator/phabread-multi-drev.json +include tests/phabricator/phabread-str-time.json +include tests/phabricator/phabsend-add-parent-setup.json +include tests/phabricator/phabsend-add-parent.json +include tests/phabricator/phabsend-binary-renames.json +include tests/phabricator/phabsend-binary.json +include tests/phabricator/phabsend-comment-created.json +include tests/phabricator/phabsend-comment-updated.json +include tests/phabricator/phabsend-create-alpha.json +include tests/phabricator/phabsend-create-public.json +include tests/phabricator/phabsend-fold-extend-end.json +include tests/phabricator/phabsend-fold-extend-front.json +include tests/phabricator/phabsend-fold-fold-end.json +include tests/phabricator/phabsend-fold-immutable.json +include tests/phabricator/phabsend-fold-initial.json +include tests/phabricator/phabsend-fold-no-changes.json +include tests/phabricator/phabsend-fold-split-end.json +include tests/phabricator/phabsend-fold-updated.json +include tests/phabricator/phabsend-hash-fixes.json +include tests/phabricator/phabsend-no-restack-orphan.json +include tests/phabricator/phabsend-skipped.json +include tests/phabricator/phabsend-update-alpha-create-beta.json +include tests/phabricator/phabupdate-change-6876.json +include tests/phabricator/phabupdate-revs.json +include tests/printenv.py +include tests/printrevset.py +include tests/pullext.py +include tests/readlink.py +include tests/remotefilelog-getflogheads.py +include tests/remotefilelog-library.sh +include tests/revlog-formatv0.py +include tests/revnamesext.py +include tests/run-tests.py +include tests/seq.py +include tests/sha256line.py +include tests/silenttestrunner.py +include tests/simplestorerepo.py +include tests/sitecustomize.py +include tests/sshprotoext.py +include tests/sslcerts/README +include tests/sslcerts/client-cert.pem +include tests/sslcerts/client-key-decrypted.pem +include tests/sslcerts/client-key.pem +include tests/sslcerts/priv.pem +include tests/sslcerts/pub-expired.pem +include tests/sslcerts/pub-not-yet.pem +include tests/sslcerts/pub-other.pem +include tests/sslcerts/pub.pem +include tests/svn-safe-append.py +include tests/svn/branches.svndump +include tests/svn/empty.svndump +include tests/svn/encoding.svndump +include tests/svn/move.svndump +include tests/svn/replace.svndump +include tests/svn/startrev.svndump +include tests/svn/svndump-branches.sh +include tests/svn/svndump-empty.sh +include tests/svn/svndump-encoding.sh +include tests/svn/svndump-move.sh +include tests/svn/svndump-replace.sh +include tests/svn/svndump-startrev.sh +include tests/svn/svndump-tags.sh +include tests/svn/tags.svndump +include tests/svnurlof.py +include tests/svnxml.py +include tests/test-abort-checkin.t +include tests/test-absorb-edit-lines.t +include tests/test-absorb-filefixupstate.py +include tests/test-absorb-phase.t +include tests/test-absorb-rename.t +include tests/test-absorb-strip.t +include tests/test-absorb-unfinished.t +include tests/test-absorb.t +include tests/test-acl.t +include tests/test-add.t +include tests/test-addremove-similar.t +include tests/test-addremove.t +include tests/test-admin-commands.py +include tests/test-admin-commands.t +include tests/test-alias.t +include tests/test-amend-subrepo.t +include tests/test-amend.t +include tests/test-ancestor.py +include tests/test-ancestor.py.out +include tests/test-annotate.py +include tests/test-annotate.t +include tests/test-arbitraryfilectx.t +include tests/test-archive-symlinks.t +include tests/test-archive.t +include tests/test-atomictempfile.py +include tests/test-audit-path.t +include tests/test-audit-subrepo.t +include tests/test-automv.t +include tests/test-backout.t +include tests/test-backwards-remove.t +include tests/test-bad-extension.t +include tests/test-bad-pull.t +include tests/test-basic.t +include tests/test-batching.py +include tests/test-batching.py.out +include tests/test-bdiff.py +include tests/test-bheads.t +include tests/test-bisect.t +include tests/test-bisect2.t +include tests/test-bisect3.t +include tests/test-blackbox.t +include tests/test-bookflow.t +include tests/test-bookmarks-corner-case.t +include tests/test-bookmarks-current.t +include tests/test-bookmarks-merge.t +include tests/test-bookmarks-pushpull.t +include tests/test-bookmarks-rebase.t +include tests/test-bookmarks-strip.t +include tests/test-bookmarks.t +include tests/test-branch-change.t +include tests/test-branch-option.t +include tests/test-branch-tag-confict.t +include tests/test-branches.t +include tests/test-bugzilla.t +include tests/test-bundle-phase-internal.t +include tests/test-bundle-phases.t +include tests/test-bundle-r.t +include tests/test-bundle-type.t +include tests/test-bundle-vs-outgoing.t +include tests/test-bundle.t +include tests/test-bundle2-exchange.t +include tests/test-bundle2-format.t +include tests/test-bundle2-multiple-changegroups.t +include tests/test-bundle2-pushback.t +include tests/test-bundle2-remote-changegroup.t +include tests/test-byteify-strings.t +include tests/test-cache-abuse.t +include tests/test-cappedreader.py +include tests/test-casecollision-merge.t +include tests/test-casecollision.t +include tests/test-casefolding.t +include tests/test-cat.t +include tests/test-cbor.py +include tests/test-censor.t +include tests/test-censor2.t +include tests/test-chainsaw-update.t +include tests/test-changelog-exec.t +include tests/test-check-cargo-lock.t +include tests/test-check-clang-format.t +include tests/test-check-code.t +include tests/test-check-commit.t +include tests/test-check-config.t +include tests/test-check-encoding.t +include tests/test-check-execute.t +include tests/test-check-format.t +include tests/test-check-help.t +include tests/test-check-interfaces.py +include tests/test-check-interfaces.py.out +include tests/test-check-jshint.t +include tests/test-check-module-imports.t +include tests/test-check-py3-compat.t +include tests/test-check-pyflakes.t +include tests/test-check-pylint.t +include tests/test-check-rust-format.t +include tests/test-check-shbang.t +include tests/test-chg.t +include tests/test-children.t +include tests/test-churn.t +include tests/test-clone-cgi.t +include tests/test-clone-pull-corruption.t +include tests/test-clone-r.t +include tests/test-clone-stream-format.t +include tests/test-clone-stream-revlog-split.t +include tests/test-clone-stream.t +include tests/test-clone-update-order.t +include tests/test-clone.t +include tests/test-clonebundles-autogen.t +include tests/test-clonebundles.t +include tests/test-close-head.t +include tests/test-commandserver.t +include tests/test-commit-amend.t +include tests/test-commit-interactive-curses.t +include tests/test-commit-interactive.t +include tests/test-commit-multiple.t +include tests/test-commit-unresolved.t +include tests/test-commit.t +include tests/test-committer.t +include tests/test-completion.t +include tests/test-config-env.py +include tests/test-config-env.py.out +include tests/test-config-parselist.py +include tests/test-config.t +include tests/test-conflict.t +include tests/test-confused-revert.t +include tests/test-context-metadata.t +include tests/test-context.py +include tests/test-context.py.out +include tests/test-contrib-check-code.t +include tests/test-contrib-check-commit.t +include tests/test-contrib-dumprevlog.t +include tests/test-contrib-emacs.t +include tests/test-contrib-perf.t +include tests/test-contrib-pull-logger.t +include tests/test-contrib-relnotes.t +include tests/test-contrib-testparseutil.t +include tests/test-contrib.t +include tests/test-convert-authormap.t +include tests/test-convert-baz.t +include tests/test-convert-bzr-114.t +include tests/test-convert-bzr-directories.t +include tests/test-convert-bzr-ghosts.t +include tests/test-convert-bzr-merges.t +include tests/test-convert-bzr-treeroot.t +include tests/test-convert-bzr.t +include tests/test-convert-clonebranches.t +include tests/test-convert-cvs-branch.t +include tests/test-convert-cvs-detectmerge.t +include tests/test-convert-cvs-synthetic.t +include tests/test-convert-cvs.t +include tests/test-convert-cvsnt-mergepoints.rlog +include tests/test-convert-cvsnt-mergepoints.t +include tests/test-convert-darcs.t +include tests/test-convert-datesort.t +include tests/test-convert-filemap.t +include tests/test-convert-git.t +include tests/test-convert-hg-sink.t +include tests/test-convert-hg-source.t +include tests/test-convert-hg-startrev.t +include tests/test-convert-hg-svn.t +include tests/test-convert-identity.t +include tests/test-convert-mtn.t +include tests/test-convert-p4-filetypes.t +include tests/test-convert-p4.t +include tests/test-convert-splicemap.t +include tests/test-convert-svn-branches.t +include tests/test-convert-svn-encoding.t +include tests/test-convert-svn-move.t +include tests/test-convert-svn-sink.t +include tests/test-convert-svn-source.t +include tests/test-convert-svn-startrev.t +include tests/test-convert-svn-tags.t +include tests/test-convert-tagsbranch-topology.t +include tests/test-convert-tla.t +include tests/test-convert.t +include tests/test-copies-chain-merge.t +include tests/test-copies-in-changeset.t +include tests/test-copies-unrelated.t +include tests/test-copies.t +include tests/test-copy-move-merge.t +include tests/test-copy.t +include tests/test-copytrace-heuristics.t +include tests/test-custom-filters.t +include tests/test-debian-packages.t +include tests/test-debug-rebuild-dirstate.t +include tests/test-debug-revlog-stats.t +include tests/test-debugbackupbundle.t +include tests/test-debugbuilddag.t +include tests/test-debugbundle.t +include tests/test-debugcommands.t +include tests/test-debugextensions.t +include tests/test-debugindexdot.t +include tests/test-debugrename.t +include tests/test-default-push.t +include tests/test-demandimport.py +include tests/test-devel-warnings.t +include tests/test-diff-antipatience.t +include tests/test-diff-binary-file.t +include tests/test-diff-change.t +include tests/test-diff-color.t +include tests/test-diff-copy-depth.t +include tests/test-diff-hashes.t +include tests/test-diff-ignore-whitespace.t +include tests/test-diff-indent-heuristic.t +include tests/test-diff-issue2761.t +include tests/test-diff-newlines.t +include tests/test-diff-reverse.t +include tests/test-diff-subdir.t +include tests/test-diff-unified.t +include tests/test-diff-upgrade.t +include tests/test-diffdir.t +include tests/test-diffstat.t +include tests/test-directaccess.t +include tests/test-dirs.py +include tests/test-dirstate-backup.t +include tests/test-dirstate-race.t +include tests/test-dirstate-race2.t +include tests/test-dirstate-read-race.t +include tests/test-dirstate-status-write-race.t +include tests/test-dirstate-version-fallback.t +include tests/test-dirstate.t +include tests/test-dispatch.py +include tests/test-dispatch.py.out +include tests/test-dispatch.t +include tests/test-docker-packaging.t +include tests/test-doctest.py +include tests/test-double-merge.t +include tests/test-drawdag.t +include tests/test-duplicateoptions.py +include tests/test-editor-filename.t +include tests/test-empty-dir.t +include tests/test-empty-file.t +include tests/test-empty-group.t +include tests/test-empty-manifest-index.t +include tests/test-empty.t +include tests/test-encode.t +include tests/test-encoding-align.t +include tests/test-encoding-func.py +include tests/test-encoding-textwrap.t +include tests/test-encoding.t +include tests/test-eol-add.t +include tests/test-eol-clone.t +include tests/test-eol-hook.t +include tests/test-eol-patch.t +include tests/test-eol-tag.t +include tests/test-eol-update.t +include tests/test-eol.t +include tests/test-eolfilename.t +include tests/test-excessive-merge.t +include tests/test-exchange-multi-source.t +include tests/test-exchange-obsmarkers-case-A1.t +include tests/test-exchange-obsmarkers-case-A2.t +include tests/test-exchange-obsmarkers-case-A3.t +include tests/test-exchange-obsmarkers-case-A4.t +include tests/test-exchange-obsmarkers-case-A5.t +include tests/test-exchange-obsmarkers-case-A6.t +include tests/test-exchange-obsmarkers-case-A7.t +include tests/test-exchange-obsmarkers-case-B1.t +include tests/test-exchange-obsmarkers-case-B2.t +include tests/test-exchange-obsmarkers-case-B3.t +include tests/test-exchange-obsmarkers-case-B4.t +include tests/test-exchange-obsmarkers-case-B5.t +include tests/test-exchange-obsmarkers-case-B6.t +include tests/test-exchange-obsmarkers-case-B7.t +include tests/test-exchange-obsmarkers-case-C1.t +include tests/test-exchange-obsmarkers-case-C2.t +include tests/test-exchange-obsmarkers-case-C3.t +include tests/test-exchange-obsmarkers-case-C4.t +include tests/test-exchange-obsmarkers-case-D1.t +include tests/test-exchange-obsmarkers-case-D2.t +include tests/test-exchange-obsmarkers-case-D3.t +include tests/test-exchange-obsmarkers-case-D4.t +include tests/test-execute-bit.t +include tests/test-export.t +include tests/test-extdata.t +include tests/test-extdiff.t +include tests/test-extension-timing.t +include tests/test-extension.t +include tests/test-extensions-afterloaded.t +include tests/test-extensions-wrapfunction.py +include tests/test-extensions-wrapfunction.py.out +include tests/test-extra-filelog-entry.t +include tests/test-fastannotate-corrupt.t +include tests/test-fastannotate-diffopts.t +include tests/test-fastannotate-hg.t +include tests/test-fastannotate-perfhack.t +include tests/test-fastannotate-protocol.t +include tests/test-fastannotate-renames.t +include tests/test-fastannotate-revmap.py +include tests/test-fastannotate.t +include tests/test-fastexport.t +include tests/test-fetch.t +include tests/test-filebranch.t +include tests/test-filecache.py +include tests/test-filecache.py.out +include tests/test-filelog.py +include tests/test-filelog.py.out +include tests/test-fileset-generated.t +include tests/test-fileset.t +include tests/test-fix-clang-format.t +include tests/test-fix-metadata.t +include tests/test-fix-pickle.t +include tests/test-fix-topology.t +include tests/test-fix.t +include tests/test-flagprocessor.t +include tests/test-flags.t +include tests/test-fncache.t +include tests/test-fuzz-targets.t +include tests/test-gendoc-da.t +include tests/test-gendoc-de.t +include tests/test-gendoc-el.t +include tests/test-gendoc-fr.t +include tests/test-gendoc-it.t +include tests/test-gendoc-ja.t +include tests/test-gendoc-pt_BR.t +include tests/test-gendoc-ro.t +include tests/test-gendoc-ru.t +include tests/test-gendoc-sv.t +include tests/test-gendoc-zh_CN.t +include tests/test-gendoc-zh_TW.t +include tests/test-gendoc.t +include tests/test-generaldelta.t +include tests/test-getbundle.t +include tests/test-git-export.t +include tests/test-git-interop.t +include tests/test-githelp.t +include tests/test-globalopts.t +include tests/test-glog-beautifygraph.t +include tests/test-glog-topological.t +include tests/test-glog.t +include tests/test-gpg.t +include tests/test-graft-interrupted.t +include tests/test-graft-rename.t +include tests/test-graft.t +include tests/test-grep.t +include tests/test-hardlinks.t +include tests/test-hashutil.py +include tests/test-help-hide.t +include tests/test-help.t +include tests/test-hg-parseurl.py +include tests/test-hghave.t +include tests/test-hgignore.t +include tests/test-hgk.t +include tests/test-hgrc.t +include tests/test-hgweb-annotate-whitespace.t +include tests/test-hgweb-auth.py +include tests/test-hgweb-auth.py.out +include tests/test-hgweb-bundle.t +include tests/test-hgweb-commands.t +include tests/test-hgweb-csp.t +include tests/test-hgweb-descend-empties.t +include tests/test-hgweb-diffs.t +include tests/test-hgweb-empty.t +include tests/test-hgweb-filelog.t +include tests/test-hgweb-head.t +include tests/test-hgweb-json.t +include tests/test-hgweb-no-path-info.t +include tests/test-hgweb-no-request-uri.t +include tests/test-hgweb-non-interactive.t +include tests/test-hgweb-raw.t +include tests/test-hgweb-removed.t +include tests/test-hgweb-symrev.t +include tests/test-hgweb.t +include tests/test-hgwebdir-gc.py +include tests/test-hgwebdir-paths.py +include tests/test-hgwebdir.t +include tests/test-hgwebdirsym.t +include tests/test-highlight.t +include tests/test-histedit-arguments.t +include tests/test-histedit-base.t +include tests/test-histedit-bookmark-motion.t +include tests/test-histedit-commute.t +include tests/test-histedit-drop.t +include tests/test-histedit-edit.t +include tests/test-histedit-fold-non-commute.t +include tests/test-histedit-fold.t +include tests/test-histedit-merge-tools.t +include tests/test-histedit-no-backup.t +include tests/test-histedit-no-change.t +include tests/test-histedit-non-commute-abort.t +include tests/test-histedit-non-commute.t +include tests/test-histedit-obsolete.t +include tests/test-histedit-outgoing.t +include tests/test-histedit-templates.t +include tests/test-hook.t +include tests/test-hooklib-changeset_obsoleted.t +include tests/test-hooklib-changeset_published.t +include tests/test-hooklib-enforce_draft_commits.t +include tests/test-hooklib-reject_merge_commits.t +include tests/test-hooklib-reject_new_heads.t +include tests/test-http-bad-server.t +include tests/test-http-branchmap.t +include tests/test-http-bundle1.t +include tests/test-http-clone-r.t +include tests/test-http-permissions.t +include tests/test-http-protocol.t +include tests/test-http-proxy.t +include tests/test-http.t +include tests/test-https.t +include tests/test-hybridencode.py +include tests/test-i18n.t +include tests/test-identify.t +include tests/test-impexp-branch.t +include tests/test-import-bypass.t +include tests/test-import-context.t +include tests/test-import-eol.t +include tests/test-import-git.t +include tests/test-import-merge.t +include tests/test-import-unknown.t +include tests/test-import.t +include tests/test-imports-checker.t +include tests/test-incoming-outgoing.t +include tests/test-inherit-mode.t +include tests/test-init.t +include tests/test-install.t +include tests/test-issue1089.t +include tests/test-issue1102.t +include tests/test-issue1175.t +include tests/test-issue1306.t +include tests/test-issue1438.t +include tests/test-issue1502.t +include tests/test-issue1802.t +include tests/test-issue1877.t +include tests/test-issue1993.t +include tests/test-issue2137.t +include tests/test-issue3084.t +include tests/test-issue4074.t +include tests/test-issue522.t +include tests/test-issue586.t +include tests/test-issue5979.t +include tests/test-issue612.t +include tests/test-issue619.t +include tests/test-issue6528.t +include tests/test-issue660.t +include tests/test-issue6642.t +include tests/test-issue672.t +include tests/test-issue842.t +include tests/test-journal-exists.t +include tests/test-journal-share.t +include tests/test-journal.t +include tests/test-keyword.t +include tests/test-known.t +include tests/test-largefiles-cache.t +include tests/test-largefiles-misc.t +include tests/test-largefiles-small-disk.t +include tests/test-largefiles-update.t +include tests/test-largefiles-wireproto.t +include tests/test-largefiles.t +include tests/test-legacy-exit-code.t +include tests/test-lfconvert.t +include tests/test-lfs-bundle.t +include tests/test-lfs-largefiles.t +include tests/test-lfs-pointer.py +include tests/test-lfs-pointer.py.out +include tests/test-lfs-serve-access.t +include tests/test-lfs-serve.t +include tests/test-lfs-test-server.t +include tests/test-lfs.t +include tests/test-linelog.py +include tests/test-linerange.py +include tests/test-locale.t +include tests/test-locate.t +include tests/test-lock-badness.t +include tests/test-lock.py +include tests/test-log-bookmark.t +include tests/test-log-exthook.t +include tests/test-log-linerange.t +include tests/test-log.t +include tests/test-logexchange.t +include tests/test-logtoprocess.t +include tests/test-lrucachedict.py +include tests/test-mac-packages.t +include tests/test-mactext.t +include tests/test-mailmap.t +include tests/test-manifest-merging.t +include tests/test-manifest.py +include tests/test-manifest.t +include tests/test-match.py +include tests/test-mdiff.py +include tests/test-merge-changedelete.t +include tests/test-merge-closedheads.t +include tests/test-merge-combination-exec-bytes.t +include tests/test-merge-combination-file-content.t +include tests/test-merge-combination-misc.t +include tests/test-merge-commit.t +include tests/test-merge-criss-cross.t +include tests/test-merge-default.t +include tests/test-merge-exec.t +include tests/test-merge-force.t +include tests/test-merge-halt.t +include tests/test-merge-internal-tools-pattern.t +include tests/test-merge-local.t +include tests/test-merge-no-file-change.t +include tests/test-merge-partial-tool.t +include tests/test-merge-remove.t +include tests/test-merge-revert.t +include tests/test-merge-revert2.t +include tests/test-merge-subrepos.t +include tests/test-merge-symlinks.t +include tests/test-merge-tools.t +include tests/test-merge-types.t +include tests/test-merge1.t +include tests/test-merge10.t +include tests/test-merge2.t +include tests/test-merge4.t +include tests/test-merge5.t +include tests/test-merge6.t +include tests/test-merge7.t +include tests/test-merge8.t +include tests/test-merge9.t +include tests/test-minifileset.py +include tests/test-minirst.py +include tests/test-minirst.py.out +include tests/test-missing-capability.t +include tests/test-mq-eol.t +include tests/test-mq-git.t +include tests/test-mq-guards.t +include tests/test-mq-header-date.t +include tests/test-mq-header-from.t +include tests/test-mq-merge.t +include tests/test-mq-missingfiles.t +include tests/test-mq-pull-from-bundle.t +include tests/test-mq-qclone-http.t +include tests/test-mq-qdelete.t +include tests/test-mq-qdiff.t +include tests/test-mq-qfold.t +include tests/test-mq-qgoto.t +include tests/test-mq-qimport-fail-cleanup.t +include tests/test-mq-qimport.t +include tests/test-mq-qnew.t +include tests/test-mq-qpush-exact.t +include tests/test-mq-qpush-fail.t +include tests/test-mq-qqueue.t +include tests/test-mq-qrefresh-interactive.t +include tests/test-mq-qrefresh-replace-log-message.t +include tests/test-mq-qrefresh.t +include tests/test-mq-qrename.t +include tests/test-mq-qsave.t +include tests/test-mq-safety.t +include tests/test-mq-subrepo-svn.t +include tests/test-mq-subrepo.t +include tests/test-mq-symlinks.t +include tests/test-mq.t +include tests/test-mv-cp-st-diff.t +include tests/test-narrow-acl-excludes.t +include tests/test-narrow-acl.t +include tests/test-narrow-archive.t +include tests/test-narrow-clone-no-ellipsis.t +include tests/test-narrow-clone-non-narrow-server.t +include tests/test-narrow-clone-nonlinear.t +include tests/test-narrow-clone-stream.t +include tests/test-narrow-clone.t +include tests/test-narrow-commit.t +include tests/test-narrow-copies.t +include tests/test-narrow-debugcommands.t +include tests/test-narrow-debugrebuilddirstate.t +include tests/test-narrow-exchange-merges.t +include tests/test-narrow-exchange.t +include tests/test-narrow-expanddirstate.t +include tests/test-narrow-merge-outside.t +include tests/test-narrow-merge.t +include tests/test-narrow-patch.t +include tests/test-narrow-patterns.t +include tests/test-narrow-pull.t +include tests/test-narrow-rebase.t +include tests/test-narrow-shallow-merges.t +include tests/test-narrow-shallow.t +include tests/test-narrow-share.t +include tests/test-narrow-sparse.t +include tests/test-narrow-strip.t +include tests/test-narrow-trackedcmd.t +include tests/test-narrow-update.t +include tests/test-narrow-widen-no-ellipsis.t +include tests/test-narrow-widen.t +include tests/test-narrow.t +include tests/test-nested-repo.t +include tests/test-newbranch.t +include tests/test-newcgi.t +include tests/test-newercgi.t +include tests/test-no-symlinks.t +include tests/test-nointerrupt.t +include tests/test-notify-changegroup.t +include tests/test-notify.t +include tests/test-obshistory.t +include tests/test-obsmarker-template.t +include tests/test-obsmarkers-effectflag.t +include tests/test-obsolete-bounds-checking.t +include tests/test-obsolete-bundle-strip.t +include tests/test-obsolete-changeset-exchange.t +include tests/test-obsolete-check-push.t +include tests/test-obsolete-checkheads.t +include tests/test-obsolete-distributed.t +include tests/test-obsolete-divergent.t +include tests/test-obsolete-tag-cache.t +include tests/test-obsolete.t +include tests/test-oldcgi.t +include tests/test-origbackup-conflict.t +include tests/test-pager-legacy.t +include tests/test-pager.t +include tests/test-parents.t +include tests/test-parse-date.t +include tests/test-parseindex.t +include tests/test-parseindex2.py +include tests/test-patch-offset.t +include tests/test-patch.t +include tests/test-patchbomb-bookmark.t +include tests/test-patchbomb-tls.t +include tests/test-patchbomb.t +include tests/test-pathconflicts-basic.t +include tests/test-pathconflicts-merge.t +include tests/test-pathconflicts-update.t +include tests/test-pathencode.py +include tests/test-paths.t +include tests/test-pending.t +include tests/test-permissions.t +include tests/test-persistent-nodemap-stream-clone.t +include tests/test-persistent-nodemap.t +include tests/test-phabricator.t +include tests/test-phase-archived.t +include tests/test-phases-exchange.t +include tests/test-phases.t +include tests/test-profile.t +include tests/test-progress.t +include tests/test-propertycache.py +include tests/test-propertycache.py.out +include tests/test-pull-branch.t +include tests/test-pull-bundle.t +include tests/test-pull-http.t +include tests/test-pull-network.t +include tests/test-pull-permission.t +include tests/test-pull-pull-corruption.t +include tests/test-pull-r.t +include tests/test-pull-update.t +include tests/test-pullling-to-general-delta.t +include tests/test-purge-ignored-directory.t +include tests/test-purge.t +include tests/test-push-cgi.t +include tests/test-push-checkheads-multibranches-E1.t +include tests/test-push-checkheads-multibranches-E2.t +include tests/test-push-checkheads-multibranches-E3.t +include tests/test-push-checkheads-partial-C1.t +include tests/test-push-checkheads-partial-C2.t +include tests/test-push-checkheads-partial-C3.t +include tests/test-push-checkheads-partial-C4.t +include tests/test-push-checkheads-pruned-B1.t +include tests/test-push-checkheads-pruned-B2.t +include tests/test-push-checkheads-pruned-B3.t +include tests/test-push-checkheads-pruned-B4.t +include tests/test-push-checkheads-pruned-B5.t +include tests/test-push-checkheads-pruned-B6.t +include tests/test-push-checkheads-pruned-B7.t +include tests/test-push-checkheads-pruned-B8.t +include tests/test-push-checkheads-superceed-A1.t +include tests/test-push-checkheads-superceed-A2.t +include tests/test-push-checkheads-superceed-A3.t +include tests/test-push-checkheads-superceed-A4.t +include tests/test-push-checkheads-superceed-A5.t +include tests/test-push-checkheads-superceed-A6.t +include tests/test-push-checkheads-superceed-A7.t +include tests/test-push-checkheads-superceed-A8.t +include tests/test-push-checkheads-unpushed-D1.t +include tests/test-push-checkheads-unpushed-D2.t +include tests/test-push-checkheads-unpushed-D3.t +include tests/test-push-checkheads-unpushed-D4.t +include tests/test-push-checkheads-unpushed-D5.t +include tests/test-push-checkheads-unpushed-D6.t +include tests/test-push-checkheads-unpushed-D7.t +include tests/test-push-http.t +include tests/test-push-race.t +include tests/test-push-warn.t +include tests/test-push.t +include tests/test-pushvars.t +include tests/test-qrecord.t +include tests/test-racy-mutations.t +include tests/test-rank.t +include tests/test-rebase-abort.t +include tests/test-rebase-backup.t +include tests/test-rebase-base-flag.t +include tests/test-rebase-bookmarks.t +include tests/test-rebase-brute-force.t +include tests/test-rebase-cache.t +include tests/test-rebase-check-restore.t +include tests/test-rebase-collapse.t +include tests/test-rebase-conflicts.t +include tests/test-rebase-dest.t +include tests/test-rebase-detach.t +include tests/test-rebase-dry-run.t +include tests/test-rebase-empty-successor.t +include tests/test-rebase-emptycommit.t +include tests/test-rebase-inmemory.t +include tests/test-rebase-interruptions.t +include tests/test-rebase-issue-noparam-single-rev.t +include tests/test-rebase-legacy.t +include tests/test-rebase-mq-skip.t +include tests/test-rebase-mq.t +include tests/test-rebase-named-branches.t +include tests/test-rebase-newancestor.t +include tests/test-rebase-obsolete.t +include tests/test-rebase-obsolete2.t +include tests/test-rebase-obsolete3.t +include tests/test-rebase-obsolete4.t +include tests/test-rebase-parameters.t +include tests/test-rebase-partial.t +include tests/test-rebase-pull.t +include tests/test-rebase-rename.t +include tests/test-rebase-scenario-global.t +include tests/test-rebase-templates.t +include tests/test-rebase-transaction.t +include tests/test-rebuildstate.t +include tests/test-record.t +include tests/test-releasenotes-formatting.t +include tests/test-releasenotes-merging.t +include tests/test-releasenotes-parsing.t +include tests/test-relink.t +include tests/test-remote-hidden.t +include tests/test-remotefilelog-bad-configs.t +include tests/test-remotefilelog-bgprefetch.t +include tests/test-remotefilelog-blame.t +include tests/test-remotefilelog-bundle2-legacy.t +include tests/test-remotefilelog-bundle2.t +include tests/test-remotefilelog-bundles.t +include tests/test-remotefilelog-cacheprocess.t +include tests/test-remotefilelog-clone-tree.t +include tests/test-remotefilelog-clone.t +include tests/test-remotefilelog-corrupt-cache.t +include tests/test-remotefilelog-datapack.py +include tests/test-remotefilelog-gc.t +include tests/test-remotefilelog-gcrepack.t +include tests/test-remotefilelog-hgweb.t +include tests/test-remotefilelog-histpack.py +include tests/test-remotefilelog-http.t +include tests/test-remotefilelog-keepset.t +include tests/test-remotefilelog-linknodes.t +include tests/test-remotefilelog-local.t +include tests/test-remotefilelog-log.t +include tests/test-remotefilelog-partial-shallow.t +include tests/test-remotefilelog-permissions.t +include tests/test-remotefilelog-prefetch.t +include tests/test-remotefilelog-pull-noshallow.t +include tests/test-remotefilelog-push-pull.t +include tests/test-remotefilelog-repack-fast.t +include tests/test-remotefilelog-repack.t +include tests/test-remotefilelog-share.t +include tests/test-remotefilelog-sparse.t +include tests/test-remotefilelog-strip.t +include tests/test-remotefilelog-tags.t +include tests/test-remotefilelog-wireproto.t +include tests/test-remove.t +include tests/test-removeemptydirs.t +include tests/test-rename-after-merge.t +include tests/test-rename-dir-merge.t +include tests/test-rename-merge1.t +include tests/test-rename-merge2.t +include tests/test-rename-rev.t +include tests/test-rename.t +include tests/test-repair-strip.t +include tests/test-repo-compengines.t +include tests/test-repo-filters-tiptoe.t +include tests/test-requires.t +include tests/test-resolve.t +include tests/test-revert-flags.t +include tests/test-revert-interactive-curses.t +include tests/test-revert-interactive.t +include tests/test-revert-unknown.t +include tests/test-revert.t +include tests/test-revisions.t +include tests/test-revlog-ancestry.py +include tests/test-revlog-ancestry.py.out +include tests/test-revlog-delta-find.t +include tests/test-revlog-group-emptyiter.t +include tests/test-revlog-mmapindex.t +include tests/test-revlog-packentry.t +include tests/test-revlog-raw.py +include tests/test-revlog-raw.py.out +include tests/test-revlog-v2.t +include tests/test-revlog.t +include tests/test-revset-dirstate-parents.t +include tests/test-revset-legacy-lookup.t +include tests/test-revset-outgoing.t +include tests/test-revset.t +include tests/test-revset2.t +include tests/test-rhg-no-generaldelta.t +include tests/test-rhg-sparse-narrow.t +include tests/test-rhg.t +include tests/test-rollback.t +include tests/test-run-tests.py +include tests/test-run-tests.t +include tests/test-rust-ancestor.py +include tests/test-rust-discovery.py +include tests/test-rust-revlog.py +include tests/test-schemes.t +include tests/test-serve.t +include tests/test-server-view.t +include tests/test-setdiscovery.t +include tests/test-share-bookmarks.t +include tests/test-share-safe.t +include tests/test-share.t +include tests/test-shelve.t +include tests/test-shelve2.t +include tests/test-show-stack.t +include tests/test-show-work.t +include tests/test-show.t +include tests/test-sidedata-exchange.t +include tests/test-sidedata.t +include tests/test-simple-update.t +include tests/test-simplekeyvaluefile.py +include tests/test-simplemerge.py +include tests/test-single-head-obsolescence-named-branch-A1.t +include tests/test-single-head-obsolescence-named-branch-A2.t +include tests/test-single-head-obsolescence-named-branch-A3.t +include tests/test-single-head-obsolescence-named-branch-A4.t +include tests/test-single-head-obsolescence-named-branch-A5.t +include tests/test-single-head.t +include tests/test-sparse-clear.t +include tests/test-sparse-clone.t +include tests/test-sparse-fsmonitor.t +include tests/test-sparse-import.t +include tests/test-sparse-merges.t +include tests/test-sparse-profiles.t +include tests/test-sparse-requirement.t +include tests/test-sparse-revlog.t +include tests/test-sparse-verbose-json.t +include tests/test-sparse-with-safe-share.t +include tests/test-sparse.t +include tests/test-split.t +include tests/test-sqlitestore.t +include tests/test-ssh-batch.t +include tests/test-ssh-bundle1.t +include tests/test-ssh-clone-r.t +include tests/test-ssh-proto-unbundle.t +include tests/test-ssh-proto.t +include tests/test-ssh-repoerror.t +include tests/test-ssh.t +include tests/test-sshserver.py +include tests/test-stabletailgraph.t +include tests/test-stack.t +include tests/test-state-extension.t +include tests/test-static-http.t +include tests/test-status-color.t +include tests/test-status-committed-and-ignored.t +include tests/test-status-eacces.t +include tests/test-status-inprocess.py +include tests/test-status-inprocess.py.out +include tests/test-status-rev.t +include tests/test-status-terse.t +include tests/test-status-tracked-key.t +include tests/test-status.t +include tests/test-stdio.py +include tests/test-storage.py +include tests/test-stream-bundle-v2.t +include tests/test-strict.t +include tests/test-strip-branch-cache.t +include tests/test-strip-cross.t +include tests/test-strip.t +include tests/test-subrepo-deep-nested-change.t +include tests/test-subrepo-git.t +include tests/test-subrepo-missing.t +include tests/test-subrepo-paths.t +include tests/test-subrepo-recursion.t +include tests/test-subrepo-relative-path.t +include tests/test-subrepo-svn.t +include tests/test-subrepo.t +include tests/test-symlink-os-yes-fs-no.py +include tests/test-symlink-os-yes-fs-no.py.out +include tests/test-symlink-placeholder.t +include tests/test-symlinks.t +include tests/test-tag.t +include tests/test-tags.t +include tests/test-template-basic.t +include tests/test-template-functions.t +include tests/test-template-graph.t +include tests/test-template-keywords.t +include tests/test-template-map.t +include tests/test-tools.t +include tests/test-transaction-rollback-on-revlog-split.t +include tests/test-transaction-rollback-on-sigpipe.t +include tests/test-transaction-safety.t +include tests/test-transaction-wc-rollback-race.t +include tests/test-transplant.t +include tests/test-treediscovery-legacy.t +include tests/test-treediscovery.t +include tests/test-treemanifest.t +include tests/test-trusted.py +include tests/test-trusted.py.out +include tests/test-ui-color.py +include tests/test-ui-color.py.out +include tests/test-ui-config.py +include tests/test-ui-config.py.out +include tests/test-ui-verbosity.py +include tests/test-ui-verbosity.py.out +include tests/test-unamend.t +include tests/test-unbundlehash.t +include tests/test-uncommit.t +include tests/test-unified-test.t +include tests/test-unionrepo.t +include tests/test-unrelated-pull.t +include tests/test-up-local-change.t +include tests/test-update-atomic.t +include tests/test-update-branches.t +include tests/test-update-dest.t +include tests/test-update-issue1456.t +include tests/test-update-names.t +include tests/test-update-reverse.t +include tests/test-upgrade-repo.t +include tests/test-url-download.t +include tests/test-url-rev.t +include tests/test-url.py +include tests/test-username-newline.t +include tests/test-util.py +include tests/test-verify-repo-operations.py +include tests/test-verify.t +include tests/test-walk.t +include tests/test-walkrepo.py +include tests/test-websub.t +include tests/test-win32text.t +include tests/test-wireproto-clientreactor.py +include tests/test-wireproto-framing.py +include tests/test-wireproto-serverreactor.py +include tests/test-wireproto.py +include tests/test-wireproto.py.out +include tests/test-wireproto.t +include tests/test-worker.t +include tests/test-wsgicgi.t +include tests/test-wsgirequest.py +include tests/test-xdg.t +include tests/testlib/badserverext.py +include tests/testlib/common.sh +include tests/testlib/crash_transaction_late.py +include tests/testlib/exchange-obsmarker-util.sh +include tests/testlib/ext-phase-report.py +include tests/testlib/ext-sidedata-2.py +include tests/testlib/ext-sidedata-3.py +include tests/testlib/ext-sidedata-4.py +include tests/testlib/ext-sidedata-5.py +include tests/testlib/ext-sidedata.py +include tests/testlib/ext-stream-clone-steps.py +include tests/testlib/merge-combination-util.sh +include tests/testlib/obsmarker-common.sh +include tests/testlib/persistent-nodemap-race-ext.py +include tests/testlib/push-checkheads-util.sh +include tests/testlib/sigpipe-remote.py +include tests/testlib/sigpipe-worker.py +include tests/testlib/stream_clone_setup.sh +include tests/testlib/wait-on-file +include tests/tinyproxy.py +include tests/unwrap-message-id.py +include tests/wireprotohelpers.sh +include mercurial/__version__.py +include doc/hg-ssh.8 +include doc/hg.1 +include doc/hgignore.5 +include doc/hgrc.5 +include doc/hg-ssh.8.html +include doc/hg.1.html +include doc/hgignore.5.html +include doc/hgrc.5.html diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2912984 --- /dev/null +++ b/Makefile @@ -0,0 +1,307 @@ +# If you want to change PREFIX, do not just edit it below. The changed +# value wont get passed on to recursive make calls. You should instead +# override the variable on the command like: +# +# % make PREFIX=/opt/ install + +export PREFIX=/usr/local + +# Default to Python 3. +# +# Windows ships Python 3 as `python.exe`, which may not be on PATH. py.exe is. +ifeq ($(OS),Windows_NT) +PYTHON?=py -3 +else +PYTHON?=python3 +endif + +PYOXIDIZER?=pyoxidizer + +$(eval HGROOT := $(shell pwd)) +HGPYTHONS ?= $(HGROOT)/build/pythons +PURE= +PYFILESCMD=find mercurial hgext doc -name '*.py' +PYFILES:=$(shell $(PYFILESCMD)) +DOCFILES=mercurial/helptext/*.txt +export LANGUAGE=C +export LC_ALL=C +TESTFLAGS ?= $(shell echo $$HGTESTFLAGS) +OSXVERSIONFLAGS ?= $(shell echo $$OSXVERSIONFLAGS) +CARGO = cargo + +# Set this to e.g. "mingw32" to use a non-default compiler. +COMPILER= + +COMPILERFLAG_tmp_ = +COMPILERFLAG_tmp_${COMPILER} ?= -c $(COMPILER) +COMPILERFLAG=${COMPILERFLAG_tmp_${COMPILER}} + +help: + @echo 'Commonly used make targets:' + @echo ' all - build program and documentation' + @echo ' install - install program and man pages to $$PREFIX ($(PREFIX))' + @echo ' install-home - install with setup.py install --home=$$HOME ($(HOME))' + @echo ' local - build for inplace usage' + @echo ' tests - run all tests in the automatic test suite' + @echo ' test-foo - run only specified tests (e.g. test-merge1.t)' + @echo ' dist - run all tests and create a source tarball in dist/' + @echo ' clean - remove files created by other targets' + @echo ' (except installed files or dist source tarball)' + @echo ' update-pot - update i18n/hg.pot' + @echo + @echo 'Example for a system-wide installation under /usr/local:' + @echo ' make all && su -c "make install" && hg version' + @echo + @echo 'Example for a local installation (usable in this directory):' + @echo ' make local && ./hg version' + +all: build doc + +local: + MERCURIAL_SETUP_MAKE_LOCAL=1 $(PYTHON) setup.py $(PURE) \ + build_py -c -d . \ + build_ext $(COMPILERFLAG) -i \ + build_hgexe $(COMPILERFLAG) -i \ + build_mo + env HGRCPATH= $(PYTHON) hg version + +build: + $(PYTHON) setup.py $(PURE) build $(COMPILERFLAG) + +build-chg: + make -C contrib/chg + +build-rhg: + (cd rust/rhg; cargo build --release) + +wheel: + FORCE_SETUPTOOLS=1 $(PYTHON) setup.py $(PURE) bdist_wheel $(COMPILERFLAG) + +doc: + $(MAKE) -C doc + +cleanbutpackages: + rm -f hg.exe + -$(PYTHON) setup.py clean --all # ignore errors from this command + find contrib doc hgext hgext3rd i18n mercurial tests hgdemandimport \ + \( -name '*.py[cdo]' -o -name '*.so' \) -exec rm -f '{}' ';' + rm -f MANIFEST MANIFEST.in hgext/__index__.py tests/*.err + rm -f mercurial/__modulepolicy__.py + if test -d .hg; then rm -f mercurial/__version__.py; fi + rm -rf build mercurial/locale + $(MAKE) -C doc clean + $(MAKE) -C contrib/chg distclean + rm -rf rust/target + rm -f mercurial/rustext.so + +clean: cleanbutpackages + rm -rf packages + +install: install-bin install-doc + +install-bin: build + $(PYTHON) setup.py $(PURE) install --root="$(DESTDIR)/" --prefix="$(PREFIX)" --force + +install-chg: build-chg + make -C contrib/chg install PREFIX="$(PREFIX)" + +install-doc: doc + cd doc && $(MAKE) $(MFLAGS) install + +install-home: install-home-bin install-home-doc + +install-home-bin: build + $(PYTHON) setup.py $(PURE) install --home="$(HOME)" --prefix="" --force + +install-home-doc: doc + cd doc && $(MAKE) $(MFLAGS) PREFIX="$(HOME)" install + +install-rhg: build-rhg + install -m 755 rust/target/release/rhg "$(PREFIX)"/bin/ + +MANIFEST-doc: + $(MAKE) -C doc MANIFEST + +MANIFEST.in: MANIFEST-doc + hg manifest | sed -e 's/^/include /' > MANIFEST.in + echo include mercurial/__version__.py >> MANIFEST.in + sed -e 's/^/include /' < doc/MANIFEST >> MANIFEST.in + +dist: tests dist-notests + +dist-notests: doc MANIFEST.in + TAR_OPTIONS="--owner=root --group=root --mode=u+w,go-w,a+rX-s" $(PYTHON) setup.py -q sdist + +check: tests + +tests: + # Run Rust tests if cargo is installed + if command -v $(CARGO) >/dev/null 2>&1; then \ + $(MAKE) rust-tests; \ + $(MAKE) cargo-clippy; \ + fi + cd tests && $(PYTHON) run-tests.py $(TESTFLAGS) + +test-%: + cd tests && $(PYTHON) run-tests.py $(TESTFLAGS) $@ + +testpy-%: + @echo Looking for Python $* in $(HGPYTHONS) + [ -e $(HGPYTHONS)/$*/bin/python ] || ( \ + cd $$(mktemp --directory --tmpdir) && \ + $(MAKE) -f $(HGROOT)/contrib/Makefile.python PYTHONVER=$* PREFIX=$(HGPYTHONS)/$* python ) + cd tests && $(HGPYTHONS)/$*/bin/python run-tests.py $(TESTFLAGS) + +rust-tests: + cd $(HGROOT)/rust \ + && $(CARGO) test --quiet --all --features "$(HG_RUST_FEATURES)" + +cargo-clippy: + cd $(HGROOT)/rust \ + && $(CARGO) clippy --all --features "$(HG_RUST_FEATURES)" -- -D warnings + +check-code: + hg manifest | xargs python contrib/check-code.py + +format-c: + clang-format --style file -i \ + `hg files 'set:(**.c or **.cc or **.h) and not "listfile:contrib/clang-format-ignorelist"'` + +update-pot: i18n/hg.pot + +i18n/hg.pot: $(PYFILES) $(DOCFILES) i18n/posplit i18n/hggettext + $(PYTHON) i18n/hggettext mercurial/commands.py \ + hgext/*.py hgext/*/__init__.py \ + mercurial/fileset.py mercurial/revset.py \ + mercurial/templatefilters.py \ + mercurial/templatefuncs.py \ + mercurial/templatekw.py \ + mercurial/filemerge.py \ + mercurial/hgweb/webcommands.py \ + mercurial/util.py \ + $(DOCFILES) > i18n/hg.pot.tmp + # All strings marked for translation in Mercurial contain + # ASCII characters only. But some files contain string + # literals like this '\037\213'. xgettext thinks it has to + # parse them even though they are not marked for translation. + # Extracting with an explicit encoding of ISO-8859-1 will make + # xgettext "parse" and ignore them. + $(PYFILESCMD) | xargs \ + xgettext --package-name "Mercurial" \ + --msgid-bugs-address "" \ + --copyright-holder "Olivia Mackall and others" \ + --from-code ISO-8859-1 --join --sort-by-file --add-comments=i18n: \ + -d hg -p i18n -o hg.pot.tmp + $(PYTHON) i18n/posplit i18n/hg.pot.tmp + # The target file is not created before the last step. So it never is in + # an intermediate state. + mv -f i18n/hg.pot.tmp i18n/hg.pot + +%.po: i18n/hg.pot + # work on a temporary copy for never having a half completed target + cp $@ $@.tmp + msgmerge --no-location --update $@.tmp $^ + mv -f $@.tmp $@ + +# Packaging targets + +packaging_targets := \ + rhel7 \ + rhel8 \ + rhel9 \ + deb \ + docker-rhel7 \ + docker-rhel8 \ + docker-rhel9 \ + docker-debian-bullseye \ + docker-debian-buster \ + docker-debian-stretch \ + docker-fedora \ + docker-ubuntu-xenial \ + docker-ubuntu-xenial-ppa \ + docker-ubuntu-bionic \ + docker-ubuntu-bionic-ppa \ + docker-ubuntu-focal \ + docker-ubuntu-focal-ppa \ + fedora \ + linux-wheels \ + linux-wheels-x86_64 \ + linux-wheels-i686 \ + ppa + +# Forward packaging targets for convenience. +$(packaging_targets): + $(MAKE) -C contrib/packaging $@ + +osx: + rm -rf build/mercurial + /usr/bin/python2.7 setup.py install --optimize=1 \ + --root=build/mercurial/ --prefix=/usr/local/ \ + --install-lib=/Library/Python/2.7/site-packages/ + make -C doc all install DESTDIR="$(PWD)/build/mercurial/" + # Place a bogon .DS_Store file in the target dir so we can be + # sure it doesn't get included in the final package. + touch build/mercurial/.DS_Store + make -C contrib/chg \ + HGPATH=/usr/local/bin/hg \ + PYTHON=/usr/bin/python2.7 \ + DESTDIR=../../build/mercurial \ + PREFIX=/usr/local \ + clean install + mkdir -p $${OUTPUTDIR:-dist} + HGVER=$$(python contrib/genosxversion.py $(OSXVERSIONFLAGS) build/mercurial/Library/Python/2.7/site-packages/mercurial/__version__.py) && \ + OSXVER=$$(sw_vers -productVersion | cut -d. -f1,2) && \ + pkgbuild --filter \\.DS_Store --root build/mercurial/ \ + --identifier org.mercurial-scm.mercurial \ + --version "$${HGVER}" \ + build/mercurial.pkg && \ + productbuild --distribution contrib/packaging/macosx/distribution.xml \ + --package-path build/ \ + --version "$${HGVER}" \ + --resources contrib/packaging/macosx/ \ + "$${OUTPUTDIR:-dist/}"/Mercurial-"$${HGVER}"-macosx"$${OSXVER}".pkg + +pyoxidizer: + $(PYOXIDIZER) build --path ./rust/hgcli --release + + +# a temporary target to setup all we need for run-tests.py --pyoxidizer +# (should go away as the run-tests implementation improves +pyoxidizer-windows-tests: PYOX_DIR=build/pyoxidizer/x86_64-pc-windows-msvc/release/app +pyoxidizer-windows-tests: pyoxidizer + rm -rf $(PYOX_DIR)/templates + cp -ar $(PYOX_DIR)/lib/mercurial/templates $(PYOX_DIR)/templates + rm -rf $(PYOX_DIR)/helptext + cp -ar $(PYOX_DIR)/lib/mercurial/helptext $(PYOX_DIR)/helptext + rm -rf $(PYOX_DIR)/defaultrc + cp -ar $(PYOX_DIR)/lib/mercurial/defaultrc $(PYOX_DIR)/defaultrc + rm -rf $(PYOX_DIR)/contrib + cp -ar contrib $(PYOX_DIR)/contrib + rm -rf $(PYOX_DIR)/doc + cp -ar doc $(PYOX_DIR)/doc + + +# a temporary target to setup all we need for run-tests.py --pyoxidizer +# (should go away as the run-tests implementation improves +pyoxidizer-macos-tests: PYOX_DIR=build/pyoxidizer/x86_64-apple-darwin/release/app +pyoxidizer-macos-tests: pyoxidizer + rm -rf $(PYOX_DIR)/templates + cp -a mercurial/templates $(PYOX_DIR)/templates + rm -rf $(PYOX_DIR)/helptext + cp -a mercurial/helptext $(PYOX_DIR)/helptext + rm -rf $(PYOX_DIR)/defaultrc + cp -a mercurial/defaultrc $(PYOX_DIR)/defaultrc + rm -rf $(PYOX_DIR)/contrib + cp -a contrib $(PYOX_DIR)/contrib + rm -rf $(PYOX_DIR)/doc + cp -a doc $(PYOX_DIR)/doc + +pytype-docker: + contrib/docker/pytype/recipe.sh + +.PHONY: help all local build doc cleanbutpackages clean install install-bin \ + install-doc install-home install-home-bin install-home-doc \ + dist dist-notests check tests rust-tests check-code format-c \ + update-pot pyoxidizer pyoxidizer-windows-tests pyoxidizer-macos-tests \ + $(packaging_targets) \ + osx pytype-docker diff --git a/PKG-INFO b/PKG-INFO new file mode 100644 index 0000000..de15223 --- /dev/null +++ b/PKG-INFO @@ -0,0 +1,29 @@ +Metadata-Version: 2.1 +Name: mercurial +Version: 6.7.1 +Summary: Fast scalable distributed SCM (revision control, version control) system +Home-page: https://mercurial-scm.org/ +Download-URL: https://mercurial-scm.org/release/ +Author: Olivia Mackall and many others +Author-email: mercurial@mercurial-scm.org +License: GNU GPLv2 or any later version +Classifier: Development Status :: 6 - Mature +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: GNU General Public License (GPL) +Classifier: Natural Language :: Danish +Classifier: Natural Language :: English +Classifier: Natural Language :: German +Classifier: Natural Language :: Italian +Classifier: Natural Language :: Japanese +Classifier: Natural Language :: Portuguese (Brazilian) +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: OS Independent +Classifier: Operating System :: POSIX +Classifier: Programming Language :: C +Classifier: Programming Language :: Python +Classifier: Topic :: Software Development :: Version Control +License-File: COPYING + +Mercurial is a distributed SCM tool written in Python. It is used by a number of large projects that require fast, reliable distributed revision control, such as Mozilla. diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..9ed8623 --- /dev/null +++ b/README.rst @@ -0,0 +1,30 @@ +Mercurial +========= + +Mercurial is a fast, easy to use, distributed revision control tool +for software developers. + +Basic install:: + + $ make # see install targets + $ make install # do a system-wide install + $ hg debuginstall # sanity-check setup + $ hg # see help + +Running without installing:: + + $ make local # build for inplace usage + $ ./hg --version # should show the latest version + +See https://mercurial-scm.org/ for detailed installation +instructions, platform-specific notes, and Mercurial user information. + +Notes for packagers +=================== + +Mercurial ships a copy of the python-zstandard sources. This is used to +provide support for zstd compression and decompression functionality. The +module is not intended to be replaced by the plain python-zstandard nor +is it intended to use a system zstd library. Patches can result in hard +to diagnose errors and are explicitly discouraged as unsupported +configuration. diff --git a/contrib/Makefile.python b/contrib/Makefile.python new file mode 100644 index 0000000..b8a6e50 --- /dev/null +++ b/contrib/Makefile.python @@ -0,0 +1,76 @@ +PYTHONVER=2.7.16 +PYTHONNAME=python- +PREFIX=$(HOME)/bin/prefix-$(PYTHONNAME)$(PYTHONVER) +SYMLINKDIR=$(HOME)/bin + +help: + @echo + @echo 'Make a custom installation of a Python version' + @echo + @echo 'Common make parameters:' + @echo ' PYTHONVER=... [$(PYTHONVER)]' + @echo ' PREFIX=... [$(PREFIX)]' + @echo ' SYMLINKDIR=... [$(SYMLINKDIR) creating $(PYTHONNAME)$(PYTHONVER)]' + @echo + @echo 'Common make targets:' + @echo ' python - install Python $$PYTHONVER in $$PREFIX' + @echo ' symlink - create a $$SYMLINKDIR/$(PYTHONNAME)$$PYTHONVER symlink' + @echo + @echo 'Example: create a temporary Python installation:' + @echo ' $$ make -f Makefile.python python PYTHONVER=${PYTHONVER} PREFIX=/tmp/p27' + @echo ' $$ /tmp/p27/bin/python -V' + @echo ' Python 2.7' + @echo + @echo 'Some external libraries are required for building Python: zlib bzip2 openssl.' + @echo 'Make sure their development packages are installed systemwide.' +# fedora: yum install zlib-devel bzip2-devel openssl-devel +# debian: apt-get install zlib1g-dev libbz2-dev libssl-dev + @echo + @echo 'To build a nice collection of interesting Python versions:' + @echo ' $$ for v in 2.{6{,.1,.2,.9},7{,.8,.10}}; do' + @echo ' make -f Makefile.python symlink PYTHONVER=$$v || break; done' + @echo 'To run a Mercurial test on all these Python versions:' + @echo ' $$ for py in `cd ~/bin && ls $(PYTHONNAME)2.*`; do' + @echo ' echo $$py; $$py run-tests.py test-http.t; echo; done' + @echo + +export LANGUAGE=C +export LC_ALL=C + +python: $(PREFIX)/bin/python docutils + printf 'import sys, zlib, bz2, docutils, ssl' | $(PREFIX)/bin/python + +PYTHON_SRCDIR=Python-$(PYTHONVER) +PYTHON_SRCFILE=$(PYTHON_SRCDIR).tgz + +$(PREFIX)/bin/python: + [ -f $(PYTHON_SRCFILE) ] || wget http://www.python.org/ftp/python/$(PYTHONVER)/$(PYTHON_SRCFILE) || curl -OL http://www.python.org/ftp/python/$(PYTHONVER)/$(PYTHON_SRCFILE) || [ -f $(PYTHON_SRCFILE) ] + rm -rf $(PYTHON_SRCDIR) + tar xf $(PYTHON_SRCFILE) + # Debian/Ubuntu disables SSLv2,3 the hard way, disable it on old Pythons too + -sed -i 's,self.*SSLv[23]_method(),0;//\0,g' $(PYTHON_SRCDIR)/Modules/_ssl.c + # Find multiarch system libraries on Ubuntu and disable fortify error when setting argv + LDFLAGS="-L/usr/lib/`dpkg-architecture -qDEB_HOST_MULTIARCH`"; \ + BASECFLAGS=-U_FORTIFY_SOURCE; \ + export LDFLAGS BASECFLAGS; \ + cd $(PYTHON_SRCDIR) && ./configure --prefix=$(PREFIX) && make all SVNVERSION=pwd && make install + printf 'import sys, zlib, bz2, ssl' | $(PREFIX)/bin/python + rm -rf $(PYTHON_SRCDIR) + +DOCUTILSVER=0.12 +DOCUTILS_SRCDIR=docutils-$(DOCUTILSVER) +DOCUTILS_SRCFILE=$(DOCUTILS_SRCDIR).tar.gz + +docutils: $(PREFIX)/bin/python + @$(PREFIX)/bin/python -c 'import docutils' || ( set -ex; \ + [ -f $(DOCUTILS_SRCFILE) ] || wget http://downloads.sourceforge.net/project/docutils/docutils/$(DOCUTILSVER)/$(DOCUTILS_SRCFILE) || [ -f $(DOCUTILS_SRCFILE) ]; \ + rm -rf $(DOCUTILS_SRCDIR); \ + tar xf $(DOCUTILS_SRCFILE); \ + cd $(DOCUTILS_SRCDIR) && $(PREFIX)/bin/python setup.py install --prefix=$(PREFIX); \ + $(PREFIX)/bin/python -c 'import docutils'; \ + rm -rf $(DOCUTILS_SRCDIR); ) + +symlink: python $(SYMLINKDIR) + ln -sf $(PREFIX)/bin/python $(SYMLINKDIR)/$(PYTHONNAME)$(PYTHONVER) + +.PHONY: help python docutils symlink diff --git a/contrib/all-revsets.txt b/contrib/all-revsets.txt new file mode 100644 index 0000000..3cd9096 --- /dev/null +++ b/contrib/all-revsets.txt @@ -0,0 +1,159 @@ +# All revsets ever used with revsetbenchmarks.py script +# +# The goal of this file is to gather all revsets ever used for benchmarking +# revset's performance. It should be used to gather revsets that test a +# specific usecase or a specific implementation of revset predicates. +# If you are working on the smartset implementation itself, check +# 'base-revsets.txt'. +# +# Please update this file with any revsets you use for benchmarking a change so +# that future contributors can easily find and retest it when doing further +# modification. Feel free to highlight interesting variants if needed. + + +## Revset from this section are all extracted from changelog when this file was +# created. Feel free to dig and improve documentation. + +# Used in revision da05fe01170b +(20000::) - (20000) +# Used in revision 95af98616aa7 +parents(20000) +# Used in revision 186fd06283b4 +(_intlist('20000\x0020001')) and merge() +# Used in revision 911f5a6579d1 +p1(20000) +p2(10000) +# Used in revision b6dc3b79bb25 +0:: +# Used in revision faf4f63533ff +bookmark() +# Used in revision 22ba2c0825da +tip~25 +# Used in revision 0cf46b8298fe +bisect(range) +# Used in revision 5b65429721d5 +divergent() +# Used in revision 6261b9c549a2 +file(COPYING) +# Used in revision 44f471102f3a +follow(COPYING) +# Used in revision 8040a44aab1c +origin(tip) +# Used in revision bbf4f3dfd700 +rev(25) +# Used in revision a428db9ab61d +p1() +# Used in revision c1546d7400ef +min(0::) +# Used in revision 546fa6576815 +author(lmoscovicz) or author(olivia) +author(olivia) or author(lmoscovicz) +# Used in revision 9bfe68357c01 +public() and id("d82e2223f132") +# Used in revision ba89f7b542c9 +rev(25) +# Used in revision eb763217152a +rev(210000) +# Used in revision 69524a05a7fa +10:100 +parents(10):parents(100) +# Used in revision 6f1b8b3f12fd +100~5 +parents(100)~5 +(100~5)~5 +# Used in revision 7a42e5d4c418 +children(tip~100) +# Used in revision 7e8737e6ab08 +100^1 +parents(100)^1 +(100^1)^1 +# Used in revision 30e0dcd7c5ff +matching(100) +matching(parents(100)) +# Used in revision aafeaba22826 +0|1|2|3|4|5|6|7|8|9 +# Used in revision 33c7a94d4dd0 +tip:0 +# Used in revision 7d369fae098e +(0:100000) +# Used in revision b333ca94403d +0 + 1 + 2 + ... + 200 +0 + 1 + 2 + ... + 1000 +sort(0 + 1 + 2 + ... + 200) +sort(0 + 1 + 2 + ... + 1000) +# Used in revision 7fbef7932af9 +first(0 + 1 + 2 + ... + 1000) +# Used in revision ceaf04bb14ff +0:1000 +# Used in revision 262e6ad93885 +not public() +(tip~1000::) - public() +not public() and branch("default") +# Used in revision 15412bba5a68 +0::tip + +## all the revsets from this section have been taken from the former central file +# for revset's benchmarking, they are undocumented for this reason. +all() +draft() +::tip +draft() and ::tip +::tip and draft() +author(lmoscovicz) +author(olivia) +::p1(p1(tip)):: +public() +:10000 and public() +:10000 and draft() +(not public() - obsolete()) + +# The one below is used by rebase +(children(ancestor(tip~5, tip)) and ::(tip~5)):: + +# those two `roots(...)` inputs are close to what phase movement use. +roots((tip~100::) - (tip~100::tip)) +roots((0::) - (0::tip)) + +# more roots testing +roots(tip~100:) +roots(:42) +roots(not public()) +roots((0:tip)::) +roots(0::tip) +42:68 and roots(42:tip) +# Used in revision f140d6207cca +roots(0:tip) +# test disjoint set with multiple roots +roots((:42) + (tip~42:)) + +# Testing the behavior of "head()" in various situations +head() +head() - public() +draft() and head() +head() and author("olivia") + +# testing the mutable phases set +draft() +secret() + +# test finding common ancestors +heads(commonancestors(last(head(), 2))) +heads(commonancestors(head())) + +# more heads testing +heads(all()) +heads(-10000:-1) +(-5000:-1000) and heads(-10000:-1) +heads(matching(tip, "author")) +heads(matching(tip, "author")) and -10000:-1 +(-10000:-1) and heads(matching(tip, "author")) +# more roots testing +roots(all()) +roots(-10000:-1) +(-5000:-1000) and roots(-10000:-1) +roots(matching(tip, "author")) +roots(matching(tip, "author")) and -10000:-1 +(-10000:-1) and roots(matching(tip, "author")) +only(max(head())) +only(max(head()), min(head())) +only(max(head()), limit(head(), 1, 1)) diff --git a/contrib/asv.conf.json b/contrib/asv.conf.json new file mode 100644 index 0000000..a5bce62 --- /dev/null +++ b/contrib/asv.conf.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "project": "mercurial", + "project_url": "https://mercurial-scm.org/", + "repo": "..", + "branches": ["default", "stable"], + "environment_type": "virtualenv", + "show_commit_url": "https://www.mercurial-scm.org/repo/hg/rev/", + "benchmark_dir": "benchmarks", + "env_dir": "../.asv/env", + "results_dir": "../.asv/results", + "html_dir": "../.asv/html" +} diff --git a/contrib/automation/README.rst b/contrib/automation/README.rst new file mode 100644 index 0000000..7fb7068 --- /dev/null +++ b/contrib/automation/README.rst @@ -0,0 +1,258 @@ +==================== +Mercurial Automation +==================== + +This directory contains code and utilities for building and testing Mercurial +on remote machines. + +The ``automation.py`` Script +============================ + +``automation.py`` is an executable Python script (requires Python 3.5+) +that serves as a driver to common automation tasks. + +When executed, the script will *bootstrap* a virtualenv in +``/build/venv-automation`` then re-execute itself using +that virtualenv. So there is no need for the caller to have a virtualenv +explicitly activated. This virtualenv will be populated with various +dependencies (as defined by the ``requirements.txt`` file). + +To see what you can do with this script, simply run it:: + + $ ./automation.py + +Local State +=========== + +By default, local state required to interact with remote servers is stored +in the ``~/.hgautomation`` directory. + +We attempt to limit persistent state to this directory. Even when +performing tasks that may have side-effects, we try to limit those +side-effects so they don't impact the local system. e.g. when we SSH +into a remote machine, we create a temporary directory for the SSH +config so the user's known hosts file isn't updated. + +Try Server +========== + +There exists a *Try Server* which allows automation to run against +an arbitrary Mercurial changeset and displays results via the web. + +.. note:: + + The *Try Server* is still experimental infrastructure. + +To use the *Try Server*:: + + $ ./automation.py try + +With a custom AWS profile:: + + $ AWS_PROFILE=hg contrib/automation/automation.py try + +By default, the ``.`` revision is submitted. **Any uncommitted changes +are not submitted.** + +To switch which revision is used:: + + $ ./automation.py try -r abcdef + +Access to the *Try Server* requires access to a special AWS account. +This account is currently run by Gregory Szorc. Here is the procedure +for accessing the *Try Server*: + +1. Email Gregory Szorc at gregory.szorc@gmail.com and request a + username. This username will be stored in the public domain. +2. Wait for an email reply containing your temporary AWS credentials. +3. Log in at https://gregoryszorc-hg.signin.aws.amazon.com/console + and set a new, secure password. +4. Go to https://console.aws.amazon.com/iam/home?region=us-west-2#/security_credentials +5. Under ``Access keys for CLI, SDK, & API access``, click the + ``Create access key`` button. +6. See the ``AWS Integration`` section for instructions on + configuring your local client to use the generated credentials. + +AWS Integration +=============== + +Various automation tasks integrate with AWS to provide access to +resources such as EC2 instances for generic compute. + +This obviously requires an AWS account and credentials to work. + +We use the ``boto3`` library for interacting with AWS APIs. We do not employ +any special functionality for telling ``boto3`` where to find AWS credentials. See +https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html +for how ``boto3`` works. Once you have configured your environment such +that ``boto3`` can find credentials, interaction with AWS should *just work*. + +To configure ``boto3``, you can use the ``aws configure`` command to +write out configuration files. (The ``aws`` command is typically provided +by an ``awscli`` package available in your package manager, including +``pip``.) Alternatively, you can write out files in ``~/.aws/`` directly. +e.g.:: + + # ~/.aws/config + [default] + region = us-west-2 + + # ~/.aws/credentials + [default] + aws_access_key_id = XXXX + aws_secret_access_key = YYYY + +If you have multiple AWS accounts, you can name the profile something +different from ``default``. e.g. ``hg``. You can influence which profile +is used by ``boto3`` by setting the ``AWS_PROFILE`` environment variable. +e.g. ``AWS_PROFILE=hg``. + +Resource Management +------------------- + +Depending on the task being performed, various AWS services will be accessed. +This of course requires AWS credentials with permissions to access these +services. + +The following AWS services can be accessed by automation tasks: + +* EC2 +* IAM +* Simple Systems Manager (SSM) + +Various resources will also be created as part of performing various tasks. +This also requires various permissions. + +The following AWS resources can be created by automation tasks: + +* EC2 key pairs +* EC2 security groups +* EC2 instances +* IAM roles and instance profiles +* SSM command invocations + +When possible, we prefix resource names with ``hg-`` so they can easily +be identified as belonging to Mercurial. + +.. important:: + + We currently assume that AWS accounts utilized by *us* are single + tenancy. Attempts to have discrete users of ``automation.py`` (including + sharing credentials across machines) using the same AWS account can result + in them interfering with each other and things breaking. + +Cost of Operation +----------------- + +``automation.py`` tries to be frugal with regards to utilization of remote +resources. Persistent remote resources are minimized in order to keep costs +in check. For example, EC2 instances are often ephemeral and only live as long +as the operation being performed. + +Under normal operation, recurring costs are limited to: + +* Storage costs for AMI / EBS snapshots. This should be just a few pennies + per month. + +When running EC2 instances, you'll be billed accordingly. Default instance +types vary by operation. We try to be respectful of your money when choosing +defaults. e.g. for Windows instances which are billed per hour, we use e.g. +``t3.medium`` instances, which cost ~$0.07 per hour. For operations that +scale well to many CPUs like running Linux tests, we may use a more powerful +instance like ``c5.9xlarge``. However, since Linux instances are billed +per second and the cost of running an e.g. ``c5.9xlarge`` for half the time +of a ``c5.4xlarge`` is roughly the same, the choice is justified. + +.. note:: + + When running Windows EC2 instances, AWS bills at the full hourly cost, even + if the instance doesn't run for a full hour (per-second billing doesn't + apply to Windows AMIs). + +Managing Remote Resources +------------------------- + +Occassionally, there may be an error purging a temporary resource. Or you +may wish to forcefully purge remote state. Commands can be invoked to manually +purge remote resources. + +To terminate all EC2 instances that we manage:: + + $ automation.py terminate-ec2-instances + +To purge all EC2 resources that we manage:: + + $ automation.py purge-ec2-resources + +Remote Machine Interfaces +========================= + +The code that connects to a remote machine and executes things is +theoretically machine agnostic as long as the remote machine conforms to +an *interface*. In other words, to perform actions like running tests +remotely or triggering packaging, it shouldn't matter if the remote machine +is an EC2 instance, a virtual machine, etc. This section attempts to document +the interface that remote machines need to provide in order to be valid +*targets* for remote execution. These interfaces are often not ideal nor +the most flexible. Instead, they have often evolved as the requirements of +our automation code have evolved. + +Linux +----- + +Remote Linux machines expose an SSH server on port 22. The SSH server +must allow the ``hg`` user to authenticate using the SSH key generated by +the automation code. The ``hg`` user should be part of the ``hg`` group +and it should have ``sudo`` access without password prompting. + +The SSH channel must support SFTP to facilitate transferring files from +client to server. + +``/bin/bash`` must be executable and point to a bash shell executable. + +The ``/hgdev`` directory must exist and all its content owned by ``hg::hg``. + +The ``/hgdev/pyenv`` directory should contain an installation of +``pyenv``. Various Python distributions should be installed. The exact +versions shouldn't matter. ``pyenv global`` should have been run so +``/hgdev/pyenv/shims/`` is populated with redirector scripts that point +to the appropriate Python executable. + +The ``/hgdev/venv-bootstrap`` directory must contain a virtualenv +with Mercurial installed. The ``/hgdev/venv-bootstrap/bin/hg`` executable +is referenced by various scripts and the client. + +The ``/hgdev/src`` directory MUST contain a clone of the Mercurial +source code. The state of the working directory is not important. + +In order to run tests, the ``/hgwork`` directory will be created. +This may require running various ``mkfs.*`` executables and ``mount`` +to provision a new filesystem. This will require elevated privileges +via ``sudo``. + +Various dependencies to run the Mercurial test harness are also required. +Documenting them is beyond the scope of this document. Various tests +also require other optional dependencies and missing dependencies will +be printed by the test runner when a test is skipped. + +Releasing Windows Artifacts +=========================== + +The `automation.py` script can be used to automate the release of Windows +artifacts:: + + $ ./automation.py build-all-windows-packages --revision 5.1.1 + $ ./automation.py publish-windows-artifacts 5.1.1 + +The first command will launch an EC2 instance to build all Windows packages +and copy them into the `dist` directory relative to the repository root. The +second command will then attempt to upload these files to PyPI (via `twine`) +and to `mercurial-scm.org` (via SSH). + +Uploading to PyPI requires a PyPI account with write access to the `Mercurial` +package. You can skip PyPI uploading by passing `--no-pypi`. + +Uploading to `mercurial-scm.org` requires an SSH account on that server +with `windows` group membership and for the SSH key for that account to be the +default SSH key (e.g. `~/.ssh/id_rsa`) or in a running SSH agent. You can +skip `mercurial-scm.org` uploading by passing `--no-mercurial-scm-org`. diff --git a/contrib/automation/automation.py b/contrib/automation/automation.py new file mode 100755 index 0000000..9b6571c --- /dev/null +++ b/contrib/automation/automation.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 +# +# automation.py - Perform tasks on remote machines +# +# Copyright 2019 Gregory Szorc +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +import os +import pathlib +import subprocess +import sys +import venv + + +HERE = pathlib.Path(os.path.abspath(__file__)).parent +REQUIREMENTS_TXT = HERE / 'requirements.txt' +SOURCE_DIR = HERE.parent.parent +VENV = SOURCE_DIR / 'build' / 'venv-automation' + + +def bootstrap(): + venv_created = not VENV.exists() + + VENV.parent.mkdir(exist_ok=True) + + venv.create(VENV, with_pip=True) + + if os.name == 'nt': + venv_bin = VENV / 'Scripts' + pip = venv_bin / 'pip.exe' + python = venv_bin / 'python.exe' + else: + venv_bin = VENV / 'bin' + pip = venv_bin / 'pip' + python = venv_bin / 'python' + + args = [ + str(pip), + 'install', + '-r', + str(REQUIREMENTS_TXT), + '--disable-pip-version-check', + ] + + if not venv_created: + args.append('-q') + + subprocess.run(args, check=True) + + os.environ['HGAUTOMATION_BOOTSTRAPPED'] = '1' + os.environ['PATH'] = '%s%s%s' % (venv_bin, os.pathsep, os.environ['PATH']) + + subprocess.run([str(python), __file__] + sys.argv[1:], check=True) + + +def run(): + import hgautomation.cli as cli + + # Need to strip off main Python executable. + cli.main() + + +if __name__ == '__main__': + try: + if 'HGAUTOMATION_BOOTSTRAPPED' not in os.environ: + bootstrap() + else: + run() + except subprocess.CalledProcessError as e: + sys.exit(e.returncode) + except KeyboardInterrupt: + sys.exit(1) diff --git a/contrib/automation/hgautomation/__init__.py b/contrib/automation/hgautomation/__init__.py new file mode 100644 index 0000000..a6d65cc --- /dev/null +++ b/contrib/automation/hgautomation/__init__.py @@ -0,0 +1,57 @@ +# __init__.py - High-level automation interfaces +# +# Copyright 2019 Gregory Szorc +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +# no-check-code because Python 3 native. + +import pathlib +import secrets + +from .aws import AWSConnection + + +class HGAutomation: + """High-level interface for Mercurial automation. + + Holds global state, provides access to other primitives, etc. + """ + + def __init__(self, state_path: pathlib.Path): + self.state_path = state_path + + state_path.mkdir(exist_ok=True) + + def default_password(self): + """Obtain the default password to use for remote machines. + + A new password will be generated if one is not stored. + """ + p = self.state_path / 'default-password' + + try: + with p.open('r', encoding='ascii') as fh: + data = fh.read().strip() + + if data: + return data + + except FileNotFoundError: + pass + + password = secrets.token_urlsafe(24) + + with p.open('w', encoding='ascii') as fh: + fh.write(password) + fh.write('\n') + + p.chmod(0o0600) + + return password + + def aws_connection(self, region: str, ensure_ec2_state: bool = True): + """Obtain an AWSConnection instance bound to a specific region.""" + + return AWSConnection(self, region, ensure_ec2_state=ensure_ec2_state) diff --git a/contrib/automation/hgautomation/aws.py b/contrib/automation/hgautomation/aws.py new file mode 100644 index 0000000..5d65ff8 --- /dev/null +++ b/contrib/automation/hgautomation/aws.py @@ -0,0 +1,1330 @@ +# aws.py - Automation code for Amazon Web Services +# +# Copyright 2019 Gregory Szorc +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +# no-check-code because Python 3 native. + +import contextlib +import copy +import hashlib +import json +import os +import pathlib +import subprocess +import time + +import boto3 +import botocore.exceptions + +from .linux import BOOTSTRAP_DEBIAN +from .ssh import ( + exec_command as ssh_exec_command, + wait_for_ssh, +) +from .winrm import ( + run_powershell, + wait_for_winrm, +) + + +SOURCE_ROOT = pathlib.Path( + os.path.abspath(__file__) +).parent.parent.parent.parent + +INSTALL_WINDOWS_DEPENDENCIES = ( + SOURCE_ROOT / 'contrib' / 'install-windows-dependencies.ps1' +) + + +INSTANCE_TYPES_WITH_STORAGE = { + 'c5d', + 'd2', + 'h1', + 'i3', + 'm5ad', + 'm5d', + 'r5d', + 'r5ad', + 'x1', + 'z1d', +} + + +AMAZON_ACCOUNT_ID = '801119661308' +DEBIAN_ACCOUNT_ID = '379101102735' +DEBIAN_ACCOUNT_ID_2 = '136693071363' +UBUNTU_ACCOUNT_ID = '099720109477' + + +WINDOWS_BASE_IMAGE_NAME = 'Windows_Server-2022-English-Full-Base-*' + + +KEY_PAIRS = { + 'automation', +} + + +SECURITY_GROUPS = { + 'linux-dev-1': { + 'description': 'Mercurial Linux instances that perform build/test automation', + 'ingress': [ + { + 'FromPort': 22, + 'ToPort': 22, + 'IpProtocol': 'tcp', + 'IpRanges': [ + { + 'CidrIp': '0.0.0.0/0', + 'Description': 'SSH from entire Internet', + }, + ], + }, + ], + }, + 'windows-dev-1': { + 'description': 'Mercurial Windows instances that perform build automation', + 'ingress': [ + { + 'FromPort': 22, + 'ToPort': 22, + 'IpProtocol': 'tcp', + 'IpRanges': [ + { + 'CidrIp': '0.0.0.0/0', + 'Description': 'SSH from entire Internet', + }, + ], + }, + { + 'FromPort': 3389, + 'ToPort': 3389, + 'IpProtocol': 'tcp', + 'IpRanges': [ + { + 'CidrIp': '0.0.0.0/0', + 'Description': 'RDP from entire Internet', + }, + ], + }, + { + 'FromPort': 5985, + 'ToPort': 5986, + 'IpProtocol': 'tcp', + 'IpRanges': [ + { + 'CidrIp': '0.0.0.0/0', + 'Description': 'PowerShell Remoting (Windows Remote Management)', + }, + ], + }, + ], + }, +} + + +IAM_ROLES = { + 'ephemeral-ec2-role-1': { + 'description': 'Mercurial temporary EC2 instances', + 'policy_arns': [ + 'arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM', + ], + }, +} + + +ASSUME_ROLE_POLICY_DOCUMENT = ''' +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + }, + "Action": "sts:AssumeRole" + } + ] +} +'''.strip() + + +IAM_INSTANCE_PROFILES = { + 'ephemeral-ec2-1': { + 'roles': [ + 'ephemeral-ec2-role-1', + ], + } +} + + +# User Data for Windows EC2 instance. Mainly used to set the password +# and configure WinRM. +# Inspired by the User Data script used by Packer +# (from https://www.packer.io/intro/getting-started/build-image.html). +WINDOWS_USER_DATA = r''' + + +# TODO enable this once we figure out what is failing. +#$ErrorActionPreference = "stop" + +# Set administrator password +net user Administrator "%s" +wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE + +# And set it via EC2Launch so it persists across reboots. +$config = & $env:ProgramFiles\Amazon\EC2Launch\EC2Launch.exe get-agent-config --format json | ConvertFrom-Json +$config | ConvertTo-Json -Depth 6 | Out-File -encoding UTF8 $env:ProgramData/Amazon/EC2Launch/config/agent-config.yml +$setAdminAccount = @" +{ + "task": "setAdminAccount", + "inputs": { + "password": { + "type": "static", + "data": "%s" + } + } +} +"@ +$config.config | %%{if($_.stage -eq 'preReady'){$_.tasks += (ConvertFrom-Json -InputObject $setAdminAccount)}} +$config | ConvertTo-Json -Depth 6 | Out-File -encoding UTF8 $env:ProgramData/Amazon/EC2Launch/config/agent-config.yml + +# First, make sure WinRM can't be connected to +netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=block + +# Delete any existing WinRM listeners +winrm delete winrm/config/listener?Address=*+Transport=HTTP 2>$Null +winrm delete winrm/config/listener?Address=*+Transport=HTTPS 2>$Null + +# Create a new WinRM listener and configure +winrm create winrm/config/listener?Address=*+Transport=HTTP +winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="0"}' +winrm set winrm/config '@{MaxTimeoutms="7200000"}' +winrm set winrm/config/service '@{AllowUnencrypted="true"}' +winrm set winrm/config/service '@{MaxConcurrentOperationsPerUser="12000"}' +winrm set winrm/config/service/auth '@{Basic="true"}' +winrm set winrm/config/client/auth '@{Basic="true"}' + +# Configure UAC to allow privilege elevation in remote shells +$Key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' +$Setting = 'LocalAccountTokenFilterPolicy' +Set-ItemProperty -Path $Key -Name $Setting -Value 1 -Force + +# Avoid long usernames in the temp directory path because the '~' causes extra quoting in ssh output +[System.Environment]::SetEnvironmentVariable('TMP', 'C:\Temp', [System.EnvironmentVariableTarget]::User) +[System.Environment]::SetEnvironmentVariable('TEMP', 'C:\Temp', [System.EnvironmentVariableTarget]::User) + +# Configure and restart the WinRM Service; Enable the required firewall exception +Stop-Service -Name WinRM +Set-Service -Name WinRM -StartupType Automatic +netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new action=allow localip=any remoteip=any +Start-Service -Name WinRM + +# Disable firewall on private network interfaces so prompts don't appear. +Set-NetFirewallProfile -Name private -Enabled false + +'''.lstrip() + + +WINDOWS_BOOTSTRAP_POWERSHELL = ''' +Write-Output "installing PowerShell dependencies" +Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force +Set-PSRepository -Name PSGallery -InstallationPolicy Trusted +Install-Module -Name OpenSSHUtils -RequiredVersion 0.0.2.0 + +Write-Output "installing OpenSSL server" +Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0 +# Various tools will attempt to use older versions of .NET. So we enable +# the feature that provides them so it doesn't have to be auto-enabled +# later. +Write-Output "enabling .NET Framework feature" +Install-WindowsFeature -Name Net-Framework-Core +''' + + +class AWSConnection: + """Manages the state of a connection with AWS.""" + + def __init__(self, automation, region: str, ensure_ec2_state: bool = True): + self.automation = automation + self.local_state_path = automation.state_path + + self.prefix = 'hg-' + + self.session = boto3.session.Session(region_name=region) + self.ec2client = self.session.client('ec2') + self.ec2resource = self.session.resource('ec2') + self.iamclient = self.session.client('iam') + self.iamresource = self.session.resource('iam') + self.security_groups = {} + + if ensure_ec2_state: + ensure_key_pairs(automation.state_path, self.ec2resource) + self.security_groups = ensure_security_groups(self.ec2resource) + ensure_iam_state(self.iamclient, self.iamresource) + + def key_pair_path_private(self, name): + """Path to a key pair private key file.""" + return self.local_state_path / 'keys' / ('keypair-%s' % name) + + def key_pair_path_public(self, name): + return self.local_state_path / 'keys' / ('keypair-%s.pub' % name) + + +def rsa_key_fingerprint(p: pathlib.Path): + """Compute the fingerprint of an RSA private key.""" + + # TODO use rsa package. + res = subprocess.run( + [ + 'openssl', + 'pkcs8', + '-in', + str(p), + '-nocrypt', + '-topk8', + '-outform', + 'DER', + ], + capture_output=True, + check=True, + ) + + sha1 = hashlib.sha1(res.stdout).hexdigest() + return ':'.join(a + b for a, b in zip(sha1[::2], sha1[1::2])) + + +def ensure_key_pairs(state_path: pathlib.Path, ec2resource, prefix='hg-'): + remote_existing = {} + + for kpi in ec2resource.key_pairs.all(): + if kpi.name.startswith(prefix): + remote_existing[kpi.name[len(prefix) :]] = kpi.key_fingerprint + + # Validate that we have these keys locally. + key_path = state_path / 'keys' + key_path.mkdir(exist_ok=True, mode=0o700) + + def remove_remote(name): + print('deleting key pair %s' % name) + key = ec2resource.KeyPair(name) + key.delete() + + def remove_local(name): + pub_full = key_path / ('keypair-%s.pub' % name) + priv_full = key_path / ('keypair-%s' % name) + + print('removing %s' % pub_full) + pub_full.unlink() + print('removing %s' % priv_full) + priv_full.unlink() + + local_existing = {} + + for f in sorted(os.listdir(key_path)): + if not f.startswith('keypair-') or not f.endswith('.pub'): + continue + + name = f[len('keypair-') : -len('.pub')] + + pub_full = key_path / f + priv_full = key_path / ('keypair-%s' % name) + + with open(pub_full, 'r', encoding='ascii') as fh: + data = fh.read() + + if not data.startswith('ssh-rsa '): + print( + 'unexpected format for key pair file: %s; removing' % pub_full + ) + pub_full.unlink() + priv_full.unlink() + continue + + local_existing[name] = rsa_key_fingerprint(priv_full) + + for name in sorted(set(remote_existing) | set(local_existing)): + if name not in local_existing: + actual = '%s%s' % (prefix, name) + print('remote key %s does not exist locally' % name) + remove_remote(actual) + del remote_existing[name] + + elif name not in remote_existing: + print('local key %s does not exist remotely' % name) + remove_local(name) + del local_existing[name] + + elif remote_existing[name] != local_existing[name]: + print( + 'key fingerprint mismatch for %s; ' + 'removing from local and remote' % name + ) + remove_local(name) + remove_remote('%s%s' % (prefix, name)) + del local_existing[name] + del remote_existing[name] + + missing = KEY_PAIRS - set(remote_existing) + + for name in sorted(missing): + actual = '%s%s' % (prefix, name) + print('creating key pair %s' % actual) + + priv_full = key_path / ('keypair-%s' % name) + pub_full = key_path / ('keypair-%s.pub' % name) + + kp = ec2resource.create_key_pair(KeyName=actual) + + with priv_full.open('w', encoding='ascii') as fh: + fh.write(kp.key_material) + fh.write('\n') + + priv_full.chmod(0o0600) + + # SSH public key can be extracted via `ssh-keygen`. + with pub_full.open('w', encoding='ascii') as fh: + subprocess.run( + ['ssh-keygen', '-y', '-f', str(priv_full)], + stdout=fh, + check=True, + ) + + pub_full.chmod(0o0600) + + +def delete_instance_profile(profile): + for role in profile.roles: + print( + 'removing role %s from instance profile %s' + % (role.name, profile.name) + ) + profile.remove_role(RoleName=role.name) + + print('deleting instance profile %s' % profile.name) + profile.delete() + + +def ensure_iam_state(iamclient, iamresource, prefix='hg-'): + """Ensure IAM state is in sync with our canonical definition.""" + + remote_profiles = {} + + for profile in iamresource.instance_profiles.all(): + if profile.name.startswith(prefix): + remote_profiles[profile.name[len(prefix) :]] = profile + + for name in sorted(set(remote_profiles) - set(IAM_INSTANCE_PROFILES)): + delete_instance_profile(remote_profiles[name]) + del remote_profiles[name] + + remote_roles = {} + + for role in iamresource.roles.all(): + if role.name.startswith(prefix): + remote_roles[role.name[len(prefix) :]] = role + + for name in sorted(set(remote_roles) - set(IAM_ROLES)): + role = remote_roles[name] + + print('removing role %s' % role.name) + role.delete() + del remote_roles[name] + + # We've purged remote state that doesn't belong. Create missing + # instance profiles and roles. + for name in sorted(set(IAM_INSTANCE_PROFILES) - set(remote_profiles)): + actual = '%s%s' % (prefix, name) + print('creating IAM instance profile %s' % actual) + + profile = iamresource.create_instance_profile( + InstanceProfileName=actual + ) + remote_profiles[name] = profile + + waiter = iamclient.get_waiter('instance_profile_exists') + waiter.wait(InstanceProfileName=actual) + print('IAM instance profile %s is available' % actual) + + for name in sorted(set(IAM_ROLES) - set(remote_roles)): + entry = IAM_ROLES[name] + + actual = '%s%s' % (prefix, name) + print('creating IAM role %s' % actual) + + role = iamresource.create_role( + RoleName=actual, + Description=entry['description'], + AssumeRolePolicyDocument=ASSUME_ROLE_POLICY_DOCUMENT, + ) + + waiter = iamclient.get_waiter('role_exists') + waiter.wait(RoleName=actual) + print('IAM role %s is available' % actual) + + remote_roles[name] = role + + for arn in entry['policy_arns']: + print('attaching policy %s to %s' % (arn, role.name)) + role.attach_policy(PolicyArn=arn) + + # Now reconcile state of profiles. + for name, meta in sorted(IAM_INSTANCE_PROFILES.items()): + profile = remote_profiles[name] + wanted = {'%s%s' % (prefix, role) for role in meta['roles']} + have = {role.name for role in profile.roles} + + for role in sorted(have - wanted): + print('removing role %s from %s' % (role, profile.name)) + profile.remove_role(RoleName=role) + + for role in sorted(wanted - have): + print('adding role %s to %s' % (role, profile.name)) + profile.add_role(RoleName=role) + + +def find_image(ec2resource, owner_id, name, reverse_sort_field=None): + """Find an AMI by its owner ID and name.""" + + images = ec2resource.images.filter( + Filters=[ + { + 'Name': 'owner-id', + 'Values': [owner_id], + }, + { + 'Name': 'state', + 'Values': ['available'], + }, + { + 'Name': 'image-type', + 'Values': ['machine'], + }, + { + 'Name': 'name', + 'Values': [name], + }, + ] + ) + + if reverse_sort_field: + images = sorted( + images, + key=lambda image: getattr(image, reverse_sort_field), + reverse=True, + ) + + for image in images: + return image + + raise Exception('unable to find image for %s' % name) + + +def ensure_security_groups(ec2resource, prefix='hg-'): + """Ensure all necessary Mercurial security groups are present. + + All security groups are prefixed with ``hg-`` by default. Any security + groups having this prefix but aren't in our list are deleted. + """ + existing = {} + + for group in ec2resource.security_groups.all(): + if group.group_name.startswith(prefix): + existing[group.group_name[len(prefix) :]] = group + + purge = set(existing) - set(SECURITY_GROUPS) + + for name in sorted(purge): + group = existing[name] + print('removing legacy security group: %s' % group.group_name) + group.delete() + + security_groups = {} + + for name, group in sorted(SECURITY_GROUPS.items()): + if name in existing: + security_groups[name] = existing[name] + continue + + actual = '%s%s' % (prefix, name) + print('adding security group %s' % actual) + + group_res = ec2resource.create_security_group( + Description=group['description'], + GroupName=actual, + ) + + group_res.authorize_ingress( + IpPermissions=group['ingress'], + ) + + security_groups[name] = group_res + + return security_groups + + +def terminate_ec2_instances(ec2resource, prefix='hg-'): + """Terminate all EC2 instances managed by us.""" + waiting = [] + + for instance in ec2resource.instances.all(): + if instance.state['Name'] == 'terminated': + continue + + for tag in instance.tags or []: + if tag['Key'] == 'Name' and tag['Value'].startswith(prefix): + print('terminating %s' % instance.id) + instance.terminate() + waiting.append(instance) + + for instance in waiting: + instance.wait_until_terminated() + + +def remove_resources(c, prefix='hg-'): + """Purge all of our resources in this EC2 region.""" + ec2resource = c.ec2resource + iamresource = c.iamresource + + terminate_ec2_instances(ec2resource, prefix=prefix) + + for image in ec2resource.images.filter(Owners=['self']): + if image.name.startswith(prefix): + remove_ami(ec2resource, image) + + for group in ec2resource.security_groups.all(): + if group.group_name.startswith(prefix): + print('removing security group %s' % group.group_name) + group.delete() + + for profile in iamresource.instance_profiles.all(): + if profile.name.startswith(prefix): + delete_instance_profile(profile) + + for role in iamresource.roles.all(): + if role.name.startswith(prefix): + for p in role.attached_policies.all(): + print('detaching policy %s from %s' % (p.arn, role.name)) + role.detach_policy(PolicyArn=p.arn) + + print('removing role %s' % role.name) + role.delete() + + +def wait_for_ip_addresses(instances): + """Wait for the public IP addresses of an iterable of instances.""" + for instance in instances: + while True: + if not instance.public_ip_address: + time.sleep(2) + instance.reload() + continue + + print( + 'public IP address for %s: %s' + % (instance.id, instance.public_ip_address) + ) + break + + +def remove_ami(ec2resource, image): + """Remove an AMI and its underlying snapshots.""" + snapshots = [] + + for device in image.block_device_mappings: + if 'Ebs' in device: + snapshots.append(ec2resource.Snapshot(device['Ebs']['SnapshotId'])) + + print('deregistering %s' % image.id) + image.deregister() + + for snapshot in snapshots: + print('deleting snapshot %s' % snapshot.id) + snapshot.delete() + + +def wait_for_ssm(ssmclient, instances): + """Wait for SSM to come online for an iterable of instance IDs.""" + while True: + res = ssmclient.describe_instance_information( + Filters=[ + { + 'Key': 'InstanceIds', + 'Values': [i.id for i in instances], + }, + ], + ) + + available = len(res['InstanceInformationList']) + wanted = len(instances) + + print('%d/%d instances available in SSM' % (available, wanted)) + + if available == wanted: + return + + time.sleep(2) + + +def run_ssm_command(ssmclient, instances, document_name, parameters): + """Run a PowerShell script on an EC2 instance.""" + + res = ssmclient.send_command( + InstanceIds=[i.id for i in instances], + DocumentName=document_name, + Parameters=parameters, + CloudWatchOutputConfig={ + 'CloudWatchOutputEnabled': True, + }, + ) + + command_id = res['Command']['CommandId'] + + for instance in instances: + while True: + try: + res = ssmclient.get_command_invocation( + CommandId=command_id, + InstanceId=instance.id, + ) + except botocore.exceptions.ClientError as e: + if e.response['Error']['Code'] == 'InvocationDoesNotExist': + print('could not find SSM command invocation; waiting') + time.sleep(1) + continue + else: + raise + + if res['Status'] == 'Success': + break + elif res['Status'] in ('Pending', 'InProgress', 'Delayed'): + time.sleep(2) + else: + raise Exception( + 'command failed on %s: %s' % (instance.id, res['Status']) + ) + + +@contextlib.contextmanager +def temporary_ec2_instances(ec2resource, config): + """Create temporary EC2 instances. + + This is a proxy to ``ec2client.run_instances(**config)`` that takes care of + managing the lifecycle of the instances. + + When the context manager exits, the instances are terminated. + + The context manager evaluates to the list of data structures + describing each created instance. The instances may not be available + for work immediately: it is up to the caller to wait for the instance + to start responding. + """ + + ids = None + + try: + res = ec2resource.create_instances(**config) + + ids = [i.id for i in res] + print('started instances: %s' % ' '.join(ids)) + + yield res + finally: + if ids: + print('terminating instances: %s' % ' '.join(ids)) + for instance in res: + instance.terminate() + print('terminated %d instances' % len(ids)) + + +@contextlib.contextmanager +def create_temp_windows_ec2_instances( + c: AWSConnection, config, bootstrap: bool = False +): + """Create temporary Windows EC2 instances. + + This is a higher-level wrapper around ``create_temp_ec2_instances()`` that + configures the Windows instance for Windows Remote Management. The emitted + instances will have a ``winrm_client`` attribute containing a + ``pypsrp.client.Client`` instance bound to the instance. + """ + if 'IamInstanceProfile' in config: + raise ValueError('IamInstanceProfile cannot be provided in config') + if 'UserData' in config: + raise ValueError('UserData cannot be provided in config') + + password = c.automation.default_password() + + config = copy.deepcopy(config) + config['IamInstanceProfile'] = { + 'Name': 'hg-ephemeral-ec2-1', + } + config.setdefault('TagSpecifications', []).append( + { + 'ResourceType': 'instance', + 'Tags': [{'Key': 'Name', 'Value': 'hg-temp-windows'}], + } + ) + + if bootstrap: + config['UserData'] = WINDOWS_USER_DATA % (password, password) + + with temporary_ec2_instances(c.ec2resource, config) as instances: + wait_for_ip_addresses(instances) + + print('waiting for Windows Remote Management service...') + + for instance in instances: + client = wait_for_winrm( + instance.public_ip_address, 'Administrator', password + ) + print('established WinRM connection to %s' % instance.id) + instance.winrm_client = client + + yield instances + + +def resolve_fingerprint(fingerprint): + fingerprint = json.dumps(fingerprint, sort_keys=True) + return hashlib.sha256(fingerprint.encode('utf-8')).hexdigest() + + +def find_and_reconcile_image(ec2resource, name, fingerprint): + """Attempt to find an existing EC2 AMI with a name and fingerprint. + + If an image with the specified fingerprint is found, it is returned. + Otherwise None is returned. + + Existing images for the specified name that don't have the specified + fingerprint or are missing required metadata or deleted. + """ + # Find existing AMIs with this name and delete the ones that are invalid. + # Store a reference to a good image so it can be returned one the + # image state is reconciled. + images = ec2resource.images.filter( + Filters=[{'Name': 'name', 'Values': [name]}] + ) + + existing_image = None + + for image in images: + if image.tags is None: + print( + 'image %s for %s lacks required tags; removing' + % (image.id, image.name) + ) + remove_ami(ec2resource, image) + else: + tags = {t['Key']: t['Value'] for t in image.tags} + + if tags.get('HGIMAGEFINGERPRINT') == fingerprint: + existing_image = image + else: + print( + 'image %s for %s has wrong fingerprint; removing' + % (image.id, image.name) + ) + remove_ami(ec2resource, image) + + return existing_image + + +def create_ami_from_instance( + ec2client, instance, name, description, fingerprint +): + """Create an AMI from a running instance. + + Returns the ``ec2resource.Image`` representing the created AMI. + """ + instance.stop() + + ec2client.get_waiter('instance_stopped').wait( + InstanceIds=[instance.id], + WaiterConfig={ + 'Delay': 5, + }, + ) + print('%s is stopped' % instance.id) + + image = instance.create_image( + Name=name, + Description=description, + ) + + image.create_tags( + Tags=[ + { + 'Key': 'HGIMAGEFINGERPRINT', + 'Value': fingerprint, + }, + ] + ) + + print('waiting for image %s' % image.id) + + ec2client.get_waiter('image_available').wait( + ImageIds=[image.id], + ) + + print('image %s available as %s' % (image.id, image.name)) + + return image + + +def ensure_linux_dev_ami(c: AWSConnection, distro='debian10', prefix='hg-'): + """Ensures a Linux development AMI is available and up-to-date. + + Returns an ``ec2.Image`` of either an existing AMI or a newly-built one. + """ + ec2client = c.ec2client + ec2resource = c.ec2resource + + name = '%s%s-%s' % (prefix, 'linux-dev', distro) + + if distro == 'debian9': + image = find_image( + ec2resource, + DEBIAN_ACCOUNT_ID, + 'debian-stretch-hvm-x86_64-gp2-2019-09-08-17994', + ) + ssh_username = 'admin' + elif distro == 'debian10': + image = find_image( + ec2resource, + DEBIAN_ACCOUNT_ID_2, + 'debian-10-amd64-20190909-10', + ) + ssh_username = 'admin' + elif distro == 'ubuntu18.04': + image = find_image( + ec2resource, + UBUNTU_ACCOUNT_ID, + 'ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20190918', + ) + ssh_username = 'ubuntu' + elif distro == 'ubuntu19.04': + image = find_image( + ec2resource, + UBUNTU_ACCOUNT_ID, + 'ubuntu/images/hvm-ssd/ubuntu-disco-19.04-amd64-server-20190918', + ) + ssh_username = 'ubuntu' + else: + raise ValueError('unsupported Linux distro: %s' % distro) + + config = { + 'BlockDeviceMappings': [ + { + 'DeviceName': image.block_device_mappings[0]['DeviceName'], + 'Ebs': { + 'DeleteOnTermination': True, + 'VolumeSize': 10, + 'VolumeType': 'gp3', + }, + }, + ], + 'EbsOptimized': True, + 'ImageId': image.id, + 'InstanceInitiatedShutdownBehavior': 'stop', + # 8 VCPUs for compiling Python. + 'InstanceType': 't3.2xlarge', + 'KeyName': '%sautomation' % prefix, + 'MaxCount': 1, + 'MinCount': 1, + 'SecurityGroupIds': [c.security_groups['linux-dev-1'].id], + } + + requirements3_path = ( + pathlib.Path(__file__).parent.parent / 'linux-requirements-py3.txt' + ) + requirements35_path = ( + pathlib.Path(__file__).parent.parent / 'linux-requirements-py3.5.txt' + ) + with requirements3_path.open('r', encoding='utf-8') as fh: + requirements3 = fh.read() + with requirements35_path.open('r', encoding='utf-8') as fh: + requirements35 = fh.read() + + # Compute a deterministic fingerprint to determine whether image needs to + # be regenerated. + fingerprint = resolve_fingerprint( + { + 'instance_config': config, + 'bootstrap_script': BOOTSTRAP_DEBIAN, + 'requirements_py3': requirements3, + 'requirements_py35': requirements35, + } + ) + + existing_image = find_and_reconcile_image(ec2resource, name, fingerprint) + + if existing_image: + return existing_image + + print('no suitable %s image found; creating one...' % name) + + with temporary_ec2_instances(ec2resource, config) as instances: + wait_for_ip_addresses(instances) + + instance = instances[0] + + client = wait_for_ssh( + instance.public_ip_address, + 22, + username=ssh_username, + key_filename=str(c.key_pair_path_private('automation')), + ) + + home = '/home/%s' % ssh_username + + with client: + print('connecting to SSH server') + sftp = client.open_sftp() + + print('uploading bootstrap files') + with sftp.open('%s/bootstrap' % home, 'wb') as fh: + fh.write(BOOTSTRAP_DEBIAN) + fh.chmod(0o0700) + + with sftp.open('%s/requirements-py3.txt' % home, 'wb') as fh: + fh.write(requirements3) + fh.chmod(0o0700) + + with sftp.open('%s/requirements-py3.5.txt' % home, 'wb') as fh: + fh.write(requirements35) + fh.chmod(0o0700) + + print('executing bootstrap') + chan, stdin, stdout = ssh_exec_command( + client, '%s/bootstrap' % home + ) + stdin.close() + + for line in stdout: + print(line, end='') + + res = chan.recv_exit_status() + if res: + raise Exception('non-0 exit from bootstrap: %d' % res) + + print( + 'bootstrap completed; stopping %s to create %s' + % (instance.id, name) + ) + + return create_ami_from_instance( + ec2client, + instance, + name, + 'Mercurial Linux development environment', + fingerprint, + ) + + +@contextlib.contextmanager +def temporary_linux_dev_instances( + c: AWSConnection, + image, + instance_type, + prefix='hg-', + ensure_extra_volume=False, +): + """Create temporary Linux development EC2 instances. + + Context manager resolves to a list of ``ec2.Instance`` that were created + and are running. + + ``ensure_extra_volume`` can be set to ``True`` to require that instances + have a 2nd storage volume available other than the primary AMI volume. + For instance types with instance storage, this does nothing special. + But for instance types without instance storage, an additional EBS volume + will be added to the instance. + + Instances have an ``ssh_client`` attribute containing a paramiko SSHClient + instance bound to the instance. + + Instances have an ``ssh_private_key_path`` attributing containing the + str path to the SSH private key to connect to the instance. + """ + + block_device_mappings = [ + { + 'DeviceName': image.block_device_mappings[0]['DeviceName'], + 'Ebs': { + 'DeleteOnTermination': True, + 'VolumeSize': 12, + 'VolumeType': 'gp3', + }, + } + ] + + # This is not an exhaustive list of instance types having instance storage. + # But + if ensure_extra_volume and not instance_type.startswith( + tuple(INSTANCE_TYPES_WITH_STORAGE) + ): + main_device = block_device_mappings[0]['DeviceName'] + + if main_device == 'xvda': + second_device = 'xvdb' + elif main_device == '/dev/sda1': + second_device = '/dev/sdb' + else: + raise ValueError( + 'unhandled primary EBS device name: %s' % main_device + ) + + block_device_mappings.append( + { + 'DeviceName': second_device, + 'Ebs': { + 'DeleteOnTermination': True, + 'VolumeSize': 8, + 'VolumeType': 'gp3', + }, + } + ) + + config = { + 'BlockDeviceMappings': block_device_mappings, + 'EbsOptimized': True, + 'ImageId': image.id, + 'InstanceInitiatedShutdownBehavior': 'terminate', + 'InstanceType': instance_type, + 'KeyName': '%sautomation' % prefix, + 'MaxCount': 1, + 'MinCount': 1, + 'SecurityGroupIds': [c.security_groups['linux-dev-1'].id], + } + + with temporary_ec2_instances(c.ec2resource, config) as instances: + wait_for_ip_addresses(instances) + + ssh_private_key_path = str(c.key_pair_path_private('automation')) + + for instance in instances: + client = wait_for_ssh( + instance.public_ip_address, + 22, + username='hg', + key_filename=ssh_private_key_path, + ) + + instance.ssh_client = client + instance.ssh_private_key_path = ssh_private_key_path + + try: + yield instances + finally: + for instance in instances: + instance.ssh_client.close() + + +def ensure_windows_dev_ami( + c: AWSConnection, + prefix='hg-', + base_image_name=WINDOWS_BASE_IMAGE_NAME, +): + """Ensure Windows Development AMI is available and up-to-date. + + If necessary, a modern AMI will be built by starting a temporary EC2 + instance and bootstrapping it. + + Obsolete AMIs will be deleted so there is only a single AMI having the + desired name. + + Returns an ``ec2.Image`` of either an existing AMI or a newly-built + one. + """ + ec2client = c.ec2client + ec2resource = c.ec2resource + ssmclient = c.session.client('ssm') + + name = '%s%s' % (prefix, 'windows-dev') + + image = find_image( + ec2resource, + AMAZON_ACCOUNT_ID, + base_image_name, + reverse_sort_field="name", + ) + + config = { + 'BlockDeviceMappings': [ + { + 'DeviceName': '/dev/sda1', + 'Ebs': { + 'DeleteOnTermination': True, + 'VolumeSize': 32, + 'VolumeType': 'gp3', + }, + } + ], + 'ImageId': image.id, + 'InstanceInitiatedShutdownBehavior': 'stop', + 'InstanceType': 'm6i.large', + 'KeyName': '%sautomation' % prefix, + 'MaxCount': 1, + 'MinCount': 1, + 'SecurityGroupIds': [c.security_groups['windows-dev-1'].id], + } + + commands = [ + # Need to start the service so sshd_config is generated. + 'Start-Service sshd', + 'Write-Output "modifying sshd_config"', + r'$content = Get-Content C:\ProgramData\ssh\sshd_config', + '$content = $content -replace "Match Group administrators","" -replace "AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys",""', + r'$content | Set-Content C:\ProgramData\ssh\sshd_config', + 'Import-Module OpenSSHUtils', + r'Repair-SshdConfigPermission C:\ProgramData\ssh\sshd_config -Confirm:$false', + 'Restart-Service sshd', + 'Write-Output "installing OpenSSL client"', + 'Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0', + 'Set-Service -Name sshd -StartupType "Automatic"', + 'Write-Output "OpenSSH server running"', + ] + + with INSTALL_WINDOWS_DEPENDENCIES.open('r', encoding='utf-8') as fh: + commands.extend(l.rstrip() for l in fh) + + # Disable Windows Defender when bootstrapping because it just slows + # things down. + commands.insert(0, 'Set-MpPreference -DisableRealtimeMonitoring $true') + commands.append('Set-MpPreference -DisableRealtimeMonitoring $false') + + # Trigger shutdown to prepare for imaging. + commands.append( + 'Stop-Computer -ComputerName localhost', + ) + + # Compute a deterministic fingerprint to determine whether image needs + # to be regenerated. + fingerprint = resolve_fingerprint( + { + 'instance_config': config, + 'user_data': WINDOWS_USER_DATA, + 'initial_bootstrap': WINDOWS_BOOTSTRAP_POWERSHELL, + 'bootstrap_commands': commands, + 'base_image_name': base_image_name, + } + ) + + existing_image = find_and_reconcile_image(ec2resource, name, fingerprint) + + if existing_image: + return existing_image + + print('no suitable Windows development image found; creating one...') + + with create_temp_windows_ec2_instances( + c, config, bootstrap=True + ) as instances: + assert len(instances) == 1 + instance = instances[0] + + wait_for_ssm(ssmclient, [instance]) + + # On first boot, install various Windows updates. + # We would ideally use PowerShell Remoting for this. However, there are + # trust issues that make it difficult to invoke Windows Update + # remotely. So we use SSM, which has a mechanism for running Windows + # Update. + print('installing Windows features...') + run_ssm_command( + ssmclient, + [instance], + 'AWS-RunPowerShellScript', + { + 'commands': WINDOWS_BOOTSTRAP_POWERSHELL.split('\n'), + }, + ) + + # Reboot so all updates are fully applied. + # + # We don't use instance.reboot() here because it is asynchronous and + # we don't know when exactly the instance has rebooted. It could take + # a while to stop and we may start trying to interact with the instance + # before it has rebooted. + print('rebooting instance %s' % instance.id) + instance.stop() + ec2client.get_waiter('instance_stopped').wait( + InstanceIds=[instance.id], + WaiterConfig={ + 'Delay': 5, + }, + ) + + instance.start() + wait_for_ip_addresses([instance]) + + # There is a race condition here between the User Data PS script running + # and us connecting to WinRM. This can manifest as + # "AuthorizationManager check failed" failures during run_powershell(). + # TODO figure out a workaround. + + print('waiting for Windows Remote Management to come back...') + client = wait_for_winrm( + instance.public_ip_address, + 'Administrator', + c.automation.default_password(), + ) + print('established WinRM connection to %s' % instance.id) + instance.winrm_client = client + + print('bootstrapping instance...') + run_powershell(instance.winrm_client, '\n'.join(commands)) + + print('bootstrap completed; stopping %s to create image' % instance.id) + return create_ami_from_instance( + ec2client, + instance, + name, + 'Mercurial Windows development environment', + fingerprint, + ) + + +@contextlib.contextmanager +def temporary_windows_dev_instances( + c: AWSConnection, + image, + instance_type, + prefix='hg-', + disable_antivirus=False, +): + """Create a temporary Windows development EC2 instance. + + Context manager resolves to the list of ``EC2.Instance`` that were created. + """ + config = { + 'BlockDeviceMappings': [ + { + 'DeviceName': '/dev/sda1', + 'Ebs': { + 'DeleteOnTermination': True, + 'VolumeSize': 32, + 'VolumeType': 'gp3', + }, + } + ], + 'ImageId': image.id, + 'InstanceInitiatedShutdownBehavior': 'stop', + 'InstanceType': instance_type, + 'KeyName': '%sautomation' % prefix, + 'MaxCount': 1, + 'MinCount': 1, + 'SecurityGroupIds': [c.security_groups['windows-dev-1'].id], + } + + with create_temp_windows_ec2_instances(c, config) as instances: + if disable_antivirus: + for instance in instances: + run_powershell( + instance.winrm_client, + 'Set-MpPreference -DisableRealtimeMonitoring $true', + ) + + yield instances diff --git a/contrib/automation/hgautomation/cli.py b/contrib/automation/hgautomation/cli.py new file mode 100644 index 0000000..947daab --- /dev/null +++ b/contrib/automation/hgautomation/cli.py @@ -0,0 +1,551 @@ +# cli.py - Command line interface for automation +# +# Copyright 2019 Gregory Szorc +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +# no-check-code because Python 3 native. + +import argparse +import concurrent.futures as futures +import os +import pathlib +import time + +from . import ( + aws, + HGAutomation, + linux, + try_server, + windows, +) + + +SOURCE_ROOT = pathlib.Path( + os.path.abspath(__file__) +).parent.parent.parent.parent +DIST_PATH = SOURCE_ROOT / 'dist' + + +def bootstrap_linux_dev( + hga: HGAutomation, aws_region, distros=None, parallel=False +): + c = hga.aws_connection(aws_region) + + if distros: + distros = distros.split(',') + else: + distros = sorted(linux.DISTROS) + + # TODO There is a wonky interaction involving KeyboardInterrupt whereby + # the context manager that is supposed to terminate the temporary EC2 + # instance doesn't run. Until we fix this, make parallel building opt-in + # so we don't orphan instances. + if parallel: + fs = [] + + with futures.ThreadPoolExecutor(len(distros)) as e: + for distro in distros: + fs.append(e.submit(aws.ensure_linux_dev_ami, c, distro=distro)) + + for f in fs: + f.result() + else: + for distro in distros: + aws.ensure_linux_dev_ami(c, distro=distro) + + +def bootstrap_windows_dev(hga: HGAutomation, aws_region, base_image_name): + c = hga.aws_connection(aws_region) + image = aws.ensure_windows_dev_ami(c, base_image_name=base_image_name) + print('Windows development AMI available as %s' % image.id) + + +def build_inno( + hga: HGAutomation, + aws_region, + arch, + revision, + version, + base_image_name, +): + c = hga.aws_connection(aws_region) + image = aws.ensure_windows_dev_ami(c, base_image_name=base_image_name) + DIST_PATH.mkdir(exist_ok=True) + + with aws.temporary_windows_dev_instances(c, image, 't3.medium') as insts: + instance = insts[0] + + windows.synchronize_hg(SOURCE_ROOT, revision, instance) + + for a in arch: + windows.build_inno_installer( + instance.winrm_client, + a, + DIST_PATH, + version=version, + ) + + +def build_wix( + hga: HGAutomation, + aws_region, + arch, + revision, + version, + base_image_name, +): + c = hga.aws_connection(aws_region) + image = aws.ensure_windows_dev_ami(c, base_image_name=base_image_name) + DIST_PATH.mkdir(exist_ok=True) + + with aws.temporary_windows_dev_instances(c, image, 't3.medium') as insts: + instance = insts[0] + + windows.synchronize_hg(SOURCE_ROOT, revision, instance) + + for a in arch: + windows.build_wix_installer( + instance.winrm_client, + a, + DIST_PATH, + version=version, + ) + + +def build_windows_wheel( + hga: HGAutomation, + aws_region, + python_version, + arch, + revision, + base_image_name, +): + c = hga.aws_connection(aws_region) + image = aws.ensure_windows_dev_ami(c, base_image_name=base_image_name) + DIST_PATH.mkdir(exist_ok=True) + + with aws.temporary_windows_dev_instances(c, image, 't3.medium') as insts: + instance = insts[0] + + windows.synchronize_hg(SOURCE_ROOT, revision, instance) + + for py_version in python_version: + for a in arch: + windows.build_wheel( + instance.winrm_client, py_version, a, DIST_PATH + ) + + +def build_all_windows_packages( + hga: HGAutomation, aws_region, revision, version, base_image_name +): + c = hga.aws_connection(aws_region) + image = aws.ensure_windows_dev_ami(c, base_image_name=base_image_name) + DIST_PATH.mkdir(exist_ok=True) + + with aws.temporary_windows_dev_instances(c, image, 'm6i.large') as insts: + instance = insts[0] + + winrm_client = instance.winrm_client + + windows.synchronize_hg(SOURCE_ROOT, revision, instance) + + for py_version in ("3.7", "3.8", "3.9", "3.10"): + for arch in ("x86", "x64"): + windows.purge_hg(winrm_client) + windows.build_wheel( + winrm_client, + python_version=py_version, + arch=arch, + dest_path=DIST_PATH, + ) + + for arch in ('x86', 'x64'): + windows.purge_hg(winrm_client) + windows.build_inno_installer( + winrm_client, arch, DIST_PATH, version=version + ) + windows.build_wix_installer( + winrm_client, arch, DIST_PATH, version=version + ) + + +def terminate_ec2_instances(hga: HGAutomation, aws_region): + c = hga.aws_connection(aws_region, ensure_ec2_state=False) + aws.terminate_ec2_instances(c.ec2resource) + + +def purge_ec2_resources(hga: HGAutomation, aws_region): + c = hga.aws_connection(aws_region, ensure_ec2_state=False) + aws.remove_resources(c) + + +def run_tests_linux( + hga: HGAutomation, + aws_region, + instance_type, + python_version, + test_flags, + distro, + filesystem, +): + c = hga.aws_connection(aws_region) + image = aws.ensure_linux_dev_ami(c, distro=distro) + + t_start = time.time() + + ensure_extra_volume = filesystem not in ('default', 'tmpfs') + + with aws.temporary_linux_dev_instances( + c, image, instance_type, ensure_extra_volume=ensure_extra_volume + ) as insts: + + instance = insts[0] + + linux.prepare_exec_environment( + instance.ssh_client, filesystem=filesystem + ) + linux.synchronize_hg(SOURCE_ROOT, instance, '.') + t_prepared = time.time() + linux.run_tests(instance.ssh_client, python_version, test_flags) + t_done = time.time() + + t_setup = t_prepared - t_start + t_all = t_done - t_start + + print( + 'total time: %.1fs; setup: %.1fs; tests: %.1fs; setup overhead: %.1f%%' + % (t_all, t_setup, t_done - t_prepared, t_setup / t_all * 100.0) + ) + + +def run_tests_windows( + hga: HGAutomation, + aws_region, + instance_type, + python_version, + arch, + test_flags, + base_image_name, +): + c = hga.aws_connection(aws_region) + image = aws.ensure_windows_dev_ami(c, base_image_name=base_image_name) + + with aws.temporary_windows_dev_instances( + c, image, instance_type, disable_antivirus=True + ) as insts: + instance = insts[0] + + windows.synchronize_hg(SOURCE_ROOT, '.', instance) + windows.run_tests( + instance.winrm_client, python_version, arch, test_flags + ) + + +def publish_windows_artifacts( + hg: HGAutomation, + aws_region, + version: str, + pypi: bool, + mercurial_scm_org: bool, + ssh_username: str, +): + windows.publish_artifacts( + DIST_PATH, + version, + pypi=pypi, + mercurial_scm_org=mercurial_scm_org, + ssh_username=ssh_username, + ) + + +def run_try(hga: HGAutomation, aws_region: str, rev: str): + c = hga.aws_connection(aws_region, ensure_ec2_state=False) + try_server.trigger_try(c, rev=rev) + + +def get_parser(): + parser = argparse.ArgumentParser() + + parser.add_argument( + '--state-path', + default='~/.hgautomation', + help='Path for local state files', + ) + parser.add_argument( + '--aws-region', + help='AWS region to use', + default='us-west-2', + ) + + subparsers = parser.add_subparsers() + + sp = subparsers.add_parser( + 'bootstrap-linux-dev', + help='Bootstrap Linux development environments', + ) + sp.add_argument( + '--distros', + help='Comma delimited list of distros to bootstrap', + ) + sp.add_argument( + '--parallel', + action='store_true', + help='Generate AMIs in parallel (not CTRL-c safe)', + ) + sp.set_defaults(func=bootstrap_linux_dev) + + sp = subparsers.add_parser( + 'bootstrap-windows-dev', + help='Bootstrap the Windows development environment', + ) + sp.add_argument( + '--base-image-name', + help='AMI name of base image', + default=aws.WINDOWS_BASE_IMAGE_NAME, + ) + sp.set_defaults(func=bootstrap_windows_dev) + + sp = subparsers.add_parser( + 'build-all-windows-packages', + help='Build all Windows packages', + ) + sp.add_argument( + '--revision', + help='Mercurial revision to build', + default='.', + ) + sp.add_argument( + '--version', + help='Mercurial version string to use', + ) + sp.add_argument( + '--base-image-name', + help='AMI name of base image', + default=aws.WINDOWS_BASE_IMAGE_NAME, + ) + sp.set_defaults(func=build_all_windows_packages) + + sp = subparsers.add_parser( + 'build-inno', + help='Build Inno Setup installer(s)', + ) + sp.add_argument( + '--arch', + help='Architecture to build for', + choices={'x86', 'x64'}, + nargs='*', + default=['x64'], + ) + sp.add_argument( + '--revision', + help='Mercurial revision to build', + default='.', + ) + sp.add_argument( + '--version', + help='Mercurial version string to use in installer', + ) + sp.add_argument( + '--base-image-name', + help='AMI name of base image', + default=aws.WINDOWS_BASE_IMAGE_NAME, + ) + sp.set_defaults(func=build_inno) + + sp = subparsers.add_parser( + 'build-windows-wheel', + help='Build Windows wheel(s)', + ) + sp.add_argument( + '--python-version', + help='Python version to build for', + choices={'3.7', '3.8', '3.9', '3.10'}, + nargs='*', + default=['3.8'], + ) + sp.add_argument( + '--arch', + help='Architecture to build for', + choices={'x86', 'x64'}, + nargs='*', + default=['x64'], + ) + sp.add_argument( + '--revision', + help='Mercurial revision to build', + default='.', + ) + sp.add_argument( + '--base-image-name', + help='AMI name of base image', + default=aws.WINDOWS_BASE_IMAGE_NAME, + ) + sp.set_defaults(func=build_windows_wheel) + + sp = subparsers.add_parser('build-wix', help='Build WiX installer(s)') + sp.add_argument( + '--arch', + help='Architecture to build for', + choices={'x86', 'x64'}, + nargs='*', + default=['x64'], + ) + sp.add_argument( + '--revision', + help='Mercurial revision to build', + default='.', + ) + sp.add_argument( + '--version', + help='Mercurial version string to use in installer', + ) + sp.add_argument( + '--base-image-name', + help='AMI name of base image', + default=aws.WINDOWS_BASE_IMAGE_NAME, + ) + sp.set_defaults(func=build_wix) + + sp = subparsers.add_parser( + 'terminate-ec2-instances', + help='Terminate all active EC2 instances managed by us', + ) + sp.set_defaults(func=terminate_ec2_instances) + + sp = subparsers.add_parser( + 'purge-ec2-resources', + help='Purge all EC2 resources managed by us', + ) + sp.set_defaults(func=purge_ec2_resources) + + sp = subparsers.add_parser( + 'run-tests-linux', + help='Run tests on Linux', + ) + sp.add_argument( + '--distro', + help='Linux distribution to run tests on', + choices=linux.DISTROS, + default='debian10', + ) + sp.add_argument( + '--filesystem', + help='Filesystem type to use', + choices={'btrfs', 'default', 'ext3', 'ext4', 'jfs', 'tmpfs', 'xfs'}, + default='default', + ) + sp.add_argument( + '--instance-type', + help='EC2 instance type to use', + default='c5.9xlarge', + ) + sp.add_argument( + '--python-version', + help='Python version to use', + choices={ + 'system3', + '3.5', + '3.6', + '3.7', + '3.8', + 'pypy', + 'pypy3.5', + 'pypy3.6', + }, + default='system3', + ) + sp.add_argument( + 'test_flags', + help='Extra command line flags to pass to run-tests.py', + nargs='*', + ) + sp.set_defaults(func=run_tests_linux) + + sp = subparsers.add_parser( + 'run-tests-windows', + help='Run tests on Windows', + ) + sp.add_argument( + '--instance-type', + help='EC2 instance type to use', + default='m6i.large', + ) + sp.add_argument( + '--python-version', + help='Python version to use', + choices={'3.5', '3.6', '3.7', '3.8', '3.9', '3.10'}, + default='3.9', + ) + sp.add_argument( + '--arch', + help='Architecture to test', + choices={'x86', 'x64'}, + default='x64', + ) + sp.add_argument( + '--test-flags', + help='Extra command line flags to pass to run-tests.py', + ) + sp.add_argument( + '--base-image-name', + help='AMI name of base image', + default=aws.WINDOWS_BASE_IMAGE_NAME, + ) + sp.set_defaults(func=run_tests_windows) + + sp = subparsers.add_parser( + 'publish-windows-artifacts', + help='Publish built Windows artifacts (wheels, installers, etc)', + ) + sp.add_argument( + '--no-pypi', + dest='pypi', + action='store_false', + default=True, + help='Skip uploading to PyPI', + ) + sp.add_argument( + '--no-mercurial-scm-org', + dest='mercurial_scm_org', + action='store_false', + default=True, + help='Skip uploading to www.mercurial-scm.org', + ) + sp.add_argument( + '--ssh-username', + help='SSH username for mercurial-scm.org', + ) + sp.add_argument( + 'version', + help='Mercurial version string to locate local packages', + ) + sp.set_defaults(func=publish_windows_artifacts) + + sp = subparsers.add_parser( + 'try', help='Run CI automation against a custom changeset' + ) + sp.add_argument('-r', '--rev', default='.', help='Revision to run CI on') + sp.set_defaults(func=run_try) + + return parser + + +def main(): + parser = get_parser() + args = parser.parse_args() + + local_state_path = pathlib.Path(os.path.expanduser(args.state_path)) + automation = HGAutomation(local_state_path) + + if not hasattr(args, 'func'): + parser.print_help() + return + + kwargs = dict(vars(args)) + del kwargs['func'] + del kwargs['state_path'] + + args.func(automation, **kwargs) diff --git a/contrib/automation/hgautomation/linux.py b/contrib/automation/hgautomation/linux.py new file mode 100644 index 0000000..4ad2a0d --- /dev/null +++ b/contrib/automation/hgautomation/linux.py @@ -0,0 +1,602 @@ +# linux.py - Linux specific automation functionality +# +# Copyright 2019 Gregory Szorc +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +# no-check-code because Python 3 native. + +import os +import pathlib +import shlex +import subprocess +import tempfile + +from .ssh import exec_command + + +# Linux distributions that are supported. +DISTROS = { + 'debian9', + 'debian10', + 'ubuntu18.04', + 'ubuntu19.04', +} + +INSTALL_PYTHONS = r''' +PYENV3_VERSIONS="3.5.10 3.6.13 3.7.10 3.8.10 3.9.5 pypy3.5-7.0.0 pypy3.6-7.3.3 pypy3.7-7.3.3" + +git clone https://github.com/pyenv/pyenv.git /hgdev/pyenv +pushd /hgdev/pyenv +git checkout 328fd42c3a2fbf14ae46dae2021a087fe27ba7e2 +popd + +export PYENV_ROOT="/hgdev/pyenv" +export PATH="$PYENV_ROOT/bin:$PATH" + +# pip 19.2.3. +PIP_SHA256=57e3643ff19f018f8a00dfaa6b7e4620e3c1a7a2171fd218425366ec006b3bfe +wget -O get-pip.py --progress dot:mega https://github.com/pypa/get-pip/raw/309a56c5fd94bd1134053a541cb4657a4e47e09d/get-pip.py +echo "${PIP_SHA256} get-pip.py" | sha256sum --check - + +VIRTUALENV_SHA256=f78d81b62d3147396ac33fc9d77579ddc42cc2a98dd9ea38886f616b33bc7fb2 +VIRTUALENV_TARBALL=virtualenv-16.7.5.tar.gz +wget -O ${VIRTUALENV_TARBALL} --progress dot:mega https://files.pythonhosted.org/packages/66/f0/6867af06d2e2f511e4e1d7094ff663acdebc4f15d4a0cb0fed1007395124/${VIRTUALENV_TARBALL} +echo "${VIRTUALENV_SHA256} ${VIRTUALENV_TARBALL}" | sha256sum --check - + +for v in ${PYENV3_VERSIONS}; do + pyenv install -v ${v} + ${PYENV_ROOT}/versions/${v}/bin/python get-pip.py + + case ${v} in + 3.5.*) + REQUIREMENTS=requirements-py3.5.txt + ;; + pypy3.5*) + REQUIREMENTS=requirements-py3.5.txt + ;; + *) + REQUIREMENTS=requirements-py3.txt + ;; + esac + + ${PYENV_ROOT}/versions/${v}/bin/pip install -r /hgdev/${REQUIREMENTS} +done + +pyenv global ${PYENV3_VERSIONS} system +'''.lstrip().replace( + '\r\n', '\n' +) + +INSTALL_PYOXIDIZER = r''' +PYOXIDIZER_VERSION=0.16.0 +PYOXIDIZER_SHA256=8875471c270312fbb934007fd30f65f1904cc0f5da6188d61c90ed2129b9f9c1 +PYOXIDIZER_URL=https://github.com/indygreg/PyOxidizer/releases/download/pyoxidizer%2F${PYOXIDIZER_VERSION}/pyoxidizer-${PYOXIDIZER_VERSION}-linux_x86_64.zip + +wget -O pyoxidizer.zip --progress dot:mega ${PYOXIDIZER_URL} +echo "${PYOXIDIZER_SHA256} pyoxidizer.zip" | sha256sum --check - + +unzip pyoxidizer.zip +chmod +x pyoxidizer +sudo mv pyoxidizer /usr/local/bin/pyoxidizer +''' + +INSTALL_RUST = r''' +RUSTUP_INIT_SHA256=a46fe67199b7bcbbde2dcbc23ae08db6f29883e260e23899a88b9073effc9076 +wget -O rustup-init --progress dot:mega https://static.rust-lang.org/rustup/archive/1.18.3/x86_64-unknown-linux-gnu/rustup-init +echo "${RUSTUP_INIT_SHA256} rustup-init" | sha256sum --check - + +chmod +x rustup-init +sudo -H -u hg -g hg ./rustup-init -y +sudo -H -u hg -g hg /home/hg/.cargo/bin/rustup install 1.41.1 1.52.0 +sudo -H -u hg -g hg /home/hg/.cargo/bin/rustup component add clippy +''' + + +BOOTSTRAP_VIRTUALENV = r''' +/usr/bin/virtualenv /hgdev/venv-bootstrap + +HG_SHA256=35fc8ba5e0379c1b3affa2757e83fb0509e8ac314cbd9f1fd133cf265d16e49f +HG_TARBALL=mercurial-5.1.1.tar.gz + +wget -O ${HG_TARBALL} --progress dot:mega https://www.mercurial-scm.org/release/${HG_TARBALL} +echo "${HG_SHA256} ${HG_TARBALL}" | sha256sum --check - + +/hgdev/venv-bootstrap/bin/pip install ${HG_TARBALL} +'''.lstrip().replace( + '\r\n', '\n' +) + + +BOOTSTRAP_DEBIAN = ( + r''' +#!/bin/bash + +set -ex + +DISTRO=`grep DISTRIB_ID /etc/lsb-release | awk -F= '{{print $2}}'` +DEBIAN_VERSION=`cat /etc/debian_version` +LSB_RELEASE=`lsb_release -cs` + +sudo /usr/sbin/groupadd hg +sudo /usr/sbin/groupadd docker +sudo /usr/sbin/useradd -g hg -G sudo,docker -d /home/hg -m -s /bin/bash hg +sudo mkdir /home/hg/.ssh +sudo cp ~/.ssh/authorized_keys /home/hg/.ssh/authorized_keys +sudo chown -R hg:hg /home/hg/.ssh +sudo chmod 700 /home/hg/.ssh +sudo chmod 600 /home/hg/.ssh/authorized_keys + +cat << EOF | sudo tee /etc/sudoers.d/90-hg +hg ALL=(ALL) NOPASSWD:ALL +EOF + +sudo apt-get update +sudo DEBIAN_FRONTEND=noninteractive apt-get -yq dist-upgrade + +# Install packages necessary to set up Docker Apt repo. +sudo DEBIAN_FRONTEND=noninteractive apt-get -yq install --no-install-recommends \ + apt-transport-https \ + gnupg + +cat > docker-apt-key << EOF +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +YT90qFF93M3v01BbxP+EIY2/9tiIPbrd +=0YYh +-----END PGP PUBLIC KEY BLOCK----- +EOF + +sudo apt-key add docker-apt-key + +if [ "$LSB_RELEASE" = "stretch" ]; then +cat << EOF | sudo tee -a /etc/apt/sources.list +# Need backports for clang-format-6.0 +deb http://deb.debian.org/debian stretch-backports main +EOF +fi + +if [ "$LSB_RELEASE" = "stretch" -o "$LSB_RELEASE" = "buster" ]; then +cat << EOF | sudo tee -a /etc/apt/sources.list +# Sources are useful if we want to compile things locally. +deb-src http://deb.debian.org/debian $LSB_RELEASE main +deb-src http://security.debian.org/debian-security $LSB_RELEASE/updates main +deb-src http://deb.debian.org/debian $LSB_RELEASE-updates main +deb-src http://deb.debian.org/debian $LSB_RELEASE-backports main + +deb [arch=amd64] https://download.docker.com/linux/debian $LSB_RELEASE stable +EOF + +elif [ "$DISTRO" = "Ubuntu" ]; then +cat << EOF | sudo tee -a /etc/apt/sources.list +deb [arch=amd64] https://download.docker.com/linux/ubuntu $LSB_RELEASE stable +EOF + +fi + +sudo apt-get update + +PACKAGES="\ + awscli \ + btrfs-progs \ + build-essential \ + bzr \ + clang-format-6.0 \ + cvs \ + darcs \ + debhelper \ + devscripts \ + docker-ce \ + dpkg-dev \ + dstat \ + emacs \ + gettext \ + git \ + htop \ + iotop \ + jfsutils \ + libbz2-dev \ + libexpat1-dev \ + libffi-dev \ + libgdbm-dev \ + liblzma-dev \ + libncurses5-dev \ + libnss3-dev \ + libreadline-dev \ + libsqlite3-dev \ + libssl-dev \ + netbase \ + ntfs-3g \ + nvme-cli \ + pyflakes3 \ + pylint3 \ + python3-boto3 \ + python3-dev \ + python3-docutils \ + python3-fuzzywuzzy \ + python3-pygments \ + python3-vcr \ + python3-venv \ + rsync \ + sqlite3 \ + subversion \ + tcl-dev \ + tk-dev \ + tla \ + unzip \ + uuid-dev \ + vim \ + virtualenv \ + wget \ + xfsprogs \ + zip \ + zlib1g-dev" + +if [ "LSB_RELEASE" = "stretch" ]; then + PACKAGES="$PACKAGES linux-perf" +elif [ "$DISTRO" = "Ubuntu" ]; then + PACKAGES="$PACKAGES linux-tools-common" +fi + +# Monotone only available in older releases. +if [ "$LSB_RELEASE" = "stretch" -o "$LSB_RELEASE" = "xenial" ]; then + PACKAGES="$PACKAGES monotone" +fi + +sudo DEBIAN_FRONTEND=noninteractive apt-get -yq install --no-install-recommends $PACKAGES + +# Create clang-format symlink so test harness finds it. +sudo update-alternatives --install /usr/bin/clang-format clang-format \ + /usr/bin/clang-format-6.0 1000 + +sudo mkdir /hgdev +# Will be normalized to hg:hg later. +sudo chown `whoami` /hgdev + +{install_rust} +{install_pyoxidizer} + +cp requirements-*.txt /hgdev/ + +# Disable the pip version check because it uses the network and can +# be annoying. +cat << EOF | sudo tee -a /etc/pip.conf +[global] +disable-pip-version-check = True +EOF + +{install_pythons} +{bootstrap_virtualenv} + +/hgdev/venv-bootstrap/bin/hg clone https://www.mercurial-scm.org/repo/hg /hgdev/src + +# Mark the repo as non-publishing. +cat >> /hgdev/src/.hg/hgrc << EOF +[phases] +publish = false +EOF + +sudo chown -R hg:hg /hgdev +'''.lstrip() + .format( + install_rust=INSTALL_RUST, + install_pyoxidizer=INSTALL_PYOXIDIZER, + install_pythons=INSTALL_PYTHONS, + bootstrap_virtualenv=BOOTSTRAP_VIRTUALENV, + ) + .replace('\r\n', '\n') +) + + +# Prepares /hgdev for operations. +PREPARE_HGDEV = ''' +#!/bin/bash + +set -e + +FS=$1 + +ensure_device() { + if [ -z "${DEVICE}" ]; then + echo "could not find block device to format" + exit 1 + fi +} + +# Determine device to partition for extra filesystem. +# If only 1 volume is present, it will be the root volume and +# should be /dev/nvme0. If multiple volumes are present, the +# root volume could be nvme0 or nvme1. Use whichever one doesn't have +# a partition. +if [ -e /dev/nvme1n1 ]; then + if [ -e /dev/nvme0n1p1 ]; then + DEVICE=/dev/nvme1n1 + else + DEVICE=/dev/nvme0n1 + fi +else + DEVICE= +fi + +sudo mkdir /hgwork + +if [ "${FS}" != "default" -a "${FS}" != "tmpfs" ]; then + ensure_device + echo "creating ${FS} filesystem on ${DEVICE}" +fi + +if [ "${FS}" = "default" ]; then + : + +elif [ "${FS}" = "btrfs" ]; then + sudo mkfs.btrfs ${DEVICE} + sudo mount ${DEVICE} /hgwork + +elif [ "${FS}" = "ext3" ]; then + # lazy_journal_init speeds up filesystem creation at the expense of + # integrity if things crash. We are an ephemeral instance, so we don't + # care about integrity. + sudo mkfs.ext3 -E lazy_journal_init=1 ${DEVICE} + sudo mount ${DEVICE} /hgwork + +elif [ "${FS}" = "ext4" ]; then + sudo mkfs.ext4 -E lazy_journal_init=1 ${DEVICE} + sudo mount ${DEVICE} /hgwork + +elif [ "${FS}" = "jfs" ]; then + sudo mkfs.jfs ${DEVICE} + sudo mount ${DEVICE} /hgwork + +elif [ "${FS}" = "tmpfs" ]; then + echo "creating tmpfs volume in /hgwork" + sudo mount -t tmpfs -o size=1024M tmpfs /hgwork + +elif [ "${FS}" = "xfs" ]; then + sudo mkfs.xfs ${DEVICE} + sudo mount ${DEVICE} /hgwork + +else + echo "unsupported filesystem: ${FS}" + exit 1 +fi + +echo "/hgwork ready" + +sudo chown hg:hg /hgwork +mkdir /hgwork/tmp +chown hg:hg /hgwork/tmp + +rsync -a /hgdev/src /hgwork/ +'''.lstrip().replace( + '\r\n', '\n' +) + + +HG_UPDATE_CLEAN = ''' +set -ex + +HG=/hgdev/venv-bootstrap/bin/hg + +cd /hgwork/src +${HG} --config extensions.purge= purge --all +${HG} update -C $1 +${HG} log -r . +'''.lstrip().replace( + '\r\n', '\n' +) + + +def prepare_exec_environment(ssh_client, filesystem='default'): + """Prepare an EC2 instance to execute things. + + The AMI has an ``/hgdev`` bootstrapped with various Python installs + and a clone of the Mercurial repo. + + In EC2, EBS volumes launched from snapshots have wonky performance behavior. + Notably, blocks have to be copied on first access, which makes volume + I/O extremely slow on fresh volumes. + + Furthermore, we may want to run operations, tests, etc on alternative + filesystems so we examine behavior on different filesystems. + + This function is used to facilitate executing operations on alternate + volumes. + """ + sftp = ssh_client.open_sftp() + + with sftp.open('/hgdev/prepare-hgdev', 'wb') as fh: + fh.write(PREPARE_HGDEV) + fh.chmod(0o0777) + + command = 'sudo /hgdev/prepare-hgdev %s' % filesystem + chan, stdin, stdout = exec_command(ssh_client, command) + stdin.close() + + for line in stdout: + print(line, end='') + + res = chan.recv_exit_status() + + if res: + raise Exception('non-0 exit code updating working directory; %d' % res) + + +def synchronize_hg( + source_path: pathlib.Path, ec2_instance, revision: str = None +): + """Synchronize a local Mercurial source path to remote EC2 instance.""" + + with tempfile.TemporaryDirectory() as temp_dir: + temp_dir = pathlib.Path(temp_dir) + + ssh_dir = temp_dir / '.ssh' + ssh_dir.mkdir() + ssh_dir.chmod(0o0700) + + public_ip = ec2_instance.public_ip_address + + ssh_config = ssh_dir / 'config' + + with ssh_config.open('w', encoding='utf-8') as fh: + fh.write('Host %s\n' % public_ip) + fh.write(' User hg\n') + fh.write(' StrictHostKeyChecking no\n') + fh.write(' UserKnownHostsFile %s\n' % (ssh_dir / 'known_hosts')) + fh.write(' IdentityFile %s\n' % ec2_instance.ssh_private_key_path) + + if not (source_path / '.hg').is_dir(): + raise Exception( + '%s is not a Mercurial repository; synchronization ' + 'not yet supported' % source_path + ) + + env = dict(os.environ) + env['HGPLAIN'] = '1' + env['HGENCODING'] = 'utf-8' + + hg_bin = source_path / 'hg' + + res = subprocess.run( + ['python3', str(hg_bin), 'log', '-r', revision, '-T', '{node}'], + cwd=str(source_path), + env=env, + check=True, + capture_output=True, + ) + + full_revision = res.stdout.decode('ascii') + + args = [ + 'python3', + str(hg_bin), + '--config', + 'ui.ssh=ssh -F %s' % ssh_config, + '--config', + 'ui.remotecmd=/hgdev/venv-bootstrap/bin/hg', + # Also ensure .hgtags changes are present so auto version + # calculation works. + 'push', + '-f', + '-r', + full_revision, + '-r', + 'file(.hgtags)', + 'ssh://%s//hgwork/src' % public_ip, + ] + + res = subprocess.run(args, cwd=str(source_path), env=env) + + # Allow 1 (no-op) to not trigger error. + if res.returncode not in (0, 1): + res.check_returncode() + + # TODO support synchronizing dirty working directory. + + sftp = ec2_instance.ssh_client.open_sftp() + + with sftp.open('/hgdev/hgup', 'wb') as fh: + fh.write(HG_UPDATE_CLEAN) + fh.chmod(0o0700) + + chan, stdin, stdout = exec_command( + ec2_instance.ssh_client, '/hgdev/hgup %s' % full_revision + ) + stdin.close() + + for line in stdout: + print(line, end='') + + res = chan.recv_exit_status() + + if res: + raise Exception( + 'non-0 exit code updating working directory; %d' % res + ) + + +def run_tests(ssh_client, python_version, test_flags=None): + """Run tests on a remote Linux machine via an SSH client.""" + test_flags = test_flags or [] + + print('running tests') + + if python_version == 'system3': + python = '/usr/bin/python3' + elif python_version.startswith('pypy'): + python = '/hgdev/pyenv/shims/%s' % python_version + else: + python = '/hgdev/pyenv/shims/python%s' % python_version + + test_flags = ' '.join(shlex.quote(a) for a in test_flags) + + command = ( + '/bin/sh -c "export TMPDIR=/hgwork/tmp; ' + 'cd /hgwork/src/tests && %s run-tests.py %s"' % (python, test_flags) + ) + + chan, stdin, stdout = exec_command(ssh_client, command) + + stdin.close() + + for line in stdout: + print(line, end='') + + return chan.recv_exit_status() diff --git a/contrib/automation/hgautomation/pypi.py b/contrib/automation/hgautomation/pypi.py new file mode 100644 index 0000000..d94f5dd --- /dev/null +++ b/contrib/automation/hgautomation/pypi.py @@ -0,0 +1,21 @@ +# pypi.py - Automation around PyPI +# +# Copyright 2019 Gregory Szorc +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +# no-check-code because Python 3 native. + +from twine.commands.upload import upload as twine_upload +from twine.settings import Settings + + +def upload(paths): + """Upload files to PyPI. + + `paths` is an iterable of `pathlib.Path`. + """ + settings = Settings() + + twine_upload(settings, [str(p) for p in paths]) diff --git a/contrib/automation/hgautomation/ssh.py b/contrib/automation/hgautomation/ssh.py new file mode 100644 index 0000000..2059852 --- /dev/null +++ b/contrib/automation/hgautomation/ssh.py @@ -0,0 +1,72 @@ +# ssh.py - Interact with remote SSH servers +# +# Copyright 2019 Gregory Szorc +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +# no-check-code because Python 3 native. + +import socket +import time +import warnings + +from cryptography.utils import CryptographyDeprecationWarning +import paramiko + + +def wait_for_ssh(hostname, port, timeout=60, username=None, key_filename=None): + """Wait for an SSH server to start on the specified host and port.""" + + class IgnoreHostKeyPolicy(paramiko.MissingHostKeyPolicy): + def missing_host_key(self, client, hostname, key): + return + + end_time = time.time() + timeout + + # paramiko triggers a CryptographyDeprecationWarning in the cryptography + # package. Let's suppress + with warnings.catch_warnings(): + warnings.filterwarnings( + 'ignore', category=CryptographyDeprecationWarning + ) + + while True: + client = paramiko.SSHClient() + client.set_missing_host_key_policy(IgnoreHostKeyPolicy()) + try: + client.connect( + hostname, + port=port, + username=username, + key_filename=key_filename, + timeout=5.0, + allow_agent=False, + look_for_keys=False, + ) + + return client + except socket.error: + pass + except paramiko.AuthenticationException: + raise + except paramiko.SSHException: + pass + + if time.time() >= end_time: + raise Exception('Timeout reached waiting for SSH') + + time.sleep(1.0) + + +def exec_command(client, command): + """exec_command wrapper that combines stderr/stdout and returns channel""" + chan = client.get_transport().open_session() + + chan.exec_command(command) + chan.set_combine_stderr(True) + + stdin = chan.makefile('wb', -1) + stdout = chan.makefile('r', -1) + + return chan, stdin, stdout diff --git a/contrib/automation/hgautomation/try_server.py b/contrib/automation/hgautomation/try_server.py new file mode 100644 index 0000000..f40db04 --- /dev/null +++ b/contrib/automation/hgautomation/try_server.py @@ -0,0 +1,99 @@ +# try_server.py - Interact with Try server +# +# Copyright 2019 Gregory Szorc +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +# no-check-code because Python 3 native. + +import base64 +import json +import os +import subprocess +import tempfile + +from .aws import AWSConnection + +LAMBDA_FUNCTION = "ci-try-server-upload" + + +def trigger_try(c: AWSConnection, rev="."): + """Trigger a new Try run.""" + lambda_client = c.session.client("lambda") + + cset, bundle = generate_bundle(rev=rev) + + payload = { + "bundle": base64.b64encode(bundle).decode("utf-8"), + "node": cset["node"], + "branch": cset["branch"], + "user": cset["user"], + "message": cset["desc"], + } + + print("resolved revision:") + print("node: %s" % cset["node"]) + print("branch: %s" % cset["branch"]) + print("user: %s" % cset["user"]) + print("desc: %s" % cset["desc"].splitlines()[0]) + print() + + print("sending to Try...") + res = lambda_client.invoke( + FunctionName=LAMBDA_FUNCTION, + InvocationType="RequestResponse", + Payload=json.dumps(payload).encode("utf-8"), + ) + + body = json.load(res["Payload"]) + for message in body: + print("remote: %s" % message) + + +def generate_bundle(rev="."): + """Generate a bundle suitable for use by the Try service. + + Returns a tuple of revision metadata and raw Mercurial bundle data. + """ + # `hg bundle` doesn't support streaming to stdout. So we use a temporary + # file. + path = None + try: + fd, path = tempfile.mkstemp(prefix="hg-bundle-", suffix=".hg") + os.close(fd) + + args = [ + "hg", + "bundle", + "--type", + "gzip-v2", + "--base", + "public()", + "--rev", + rev, + path, + ] + + print("generating bundle...") + subprocess.run(args, check=True) + + with open(path, "rb") as fh: + bundle_data = fh.read() + + finally: + if path: + os.unlink(path) + + args = [ + "hg", + "log", + "-r", + rev, + # We have to upload as JSON, so it won't matter if we emit binary + # since we need to normalize to UTF-8. + "-T", + "json", + ] + res = subprocess.run(args, check=True, capture_output=True) + return json.loads(res.stdout)[0], bundle_data diff --git a/contrib/automation/hgautomation/windows.py b/contrib/automation/hgautomation/windows.py new file mode 100644 index 0000000..b7632ce --- /dev/null +++ b/contrib/automation/hgautomation/windows.py @@ -0,0 +1,542 @@ +# windows.py - Automation specific to Windows +# +# Copyright 2019 Gregory Szorc +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +# no-check-code because Python 3 native. + +import datetime +import os +import paramiko +import pathlib +import re +import subprocess +import tempfile + +from .pypi import upload as pypi_upload +from .winrm import run_powershell + + +HG_PURGE = r''' +$Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH" +Set-Location C:\hgdev\src +hg.exe --config extensions.purge= purge --all +if ($LASTEXITCODE -ne 0) { + throw "process exited non-0: $LASTEXITCODE" +} +Write-Output "purged Mercurial repo" +''' + +HG_UPDATE_CLEAN = r''' +$Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH" +Set-Location C:\hgdev\src +hg.exe --config extensions.purge= purge --all +if ($LASTEXITCODE -ne 0) {{ + throw "process exited non-0: $LASTEXITCODE" +}} +hg.exe update -C {revision} +if ($LASTEXITCODE -ne 0) {{ + throw "process exited non-0: $LASTEXITCODE" +}} +hg.exe log -r . +Write-Output "updated Mercurial working directory to {revision}" +'''.lstrip() + +BUILD_INNO_PYTHON3 = r''' +$Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH" +$Env:RUSTUP_HOME = "C:\hgdev\rustup" +$Env:CARGO_HOME = "C:\hgdev\cargo" +Set-Location C:\hgdev\src +C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py inno --pyoxidizer-target {pyoxidizer_target} --version {version} +if ($LASTEXITCODE -ne 0) {{ + throw "process exited non-0: $LASTEXITCODE" +}} +''' + + +BUILD_WHEEL = r''' +$Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH" +Set-Location C:\hgdev\src +C:\hgdev\python{python_version}-{arch}\python.exe -m pip wheel --wheel-dir dist . +if ($LASTEXITCODE -ne 0) {{ + throw "process exited non-0: $LASTEXITCODE" +}} +''' + +BUILD_WIX_PYTHON3 = r''' +$Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH" +$Env:RUSTUP_HOME = "C:\hgdev\rustup" +$Env:CARGO_HOME = "C:\hgdev\cargo" +Set-Location C:\hgdev\src +C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py wix --pyoxidizer-target {pyoxidizer_target} --version {version} +if ($LASTEXITCODE -ne 0) {{ + throw "process exited non-0: $LASTEXITCODE" +}} +''' + + +RUN_TESTS = r''' +C:\hgdev\MinGW\msys\1.0\bin\sh.exe --login -c "cd /c/hgdev/src/tests && /c/hgdev/{python_path}/python.exe run-tests.py {test_flags}" +if ($LASTEXITCODE -ne 0) {{ + throw "process exited non-0: $LASTEXITCODE" +}} +''' + + +WHEEL_FILENAME_PYTHON37_X86 = 'mercurial-{version}-cp37-cp37m-win32.whl' +WHEEL_FILENAME_PYTHON37_X64 = 'mercurial-{version}-cp37-cp37m-win_amd64.whl' +WHEEL_FILENAME_PYTHON38_X86 = 'mercurial-{version}-cp38-cp38-win32.whl' +WHEEL_FILENAME_PYTHON38_X64 = 'mercurial-{version}-cp38-cp38-win_amd64.whl' +WHEEL_FILENAME_PYTHON39_X86 = 'mercurial-{version}-cp39-cp39-win32.whl' +WHEEL_FILENAME_PYTHON39_X64 = 'mercurial-{version}-cp39-cp39-win_amd64.whl' +WHEEL_FILENAME_PYTHON310_X86 = 'mercurial-{version}-cp310-cp310-win32.whl' +WHEEL_FILENAME_PYTHON310_X64 = 'mercurial-{version}-cp310-cp310-win_amd64.whl' + +EXE_FILENAME_PYTHON3_X86 = 'Mercurial-{version}-x86.exe' +EXE_FILENAME_PYTHON3_X64 = 'Mercurial-{version}-x64.exe' + +MSI_FILENAME_PYTHON3_X86 = 'mercurial-{version}-x86.msi' +MSI_FILENAME_PYTHON3_X64 = 'mercurial-{version}-x64.msi' + +MERCURIAL_SCM_BASE_URL = 'https://mercurial-scm.org/release/windows' + +X86_USER_AGENT_PATTERN = '.*Windows.*' +X64_USER_AGENT_PATTERN = '.*Windows.*(WOW|x)64.*' + +# TODO remove Python version once Python 2 is dropped. +EXE_PYTHON3_X86_DESCRIPTION = ( + 'Mercurial {version} Inno Setup installer - x86 Windows (Python 3) ' + '- does not require admin rights' +) +EXE_PYTHON3_X64_DESCRIPTION = ( + 'Mercurial {version} Inno Setup installer - x64 Windows (Python 3) ' + '- does not require admin rights' +) +MSI_PYTHON3_X86_DESCRIPTION = ( + 'Mercurial {version} MSI installer - x86 Windows (Python 3) ' + '- requires admin rights' +) +MSI_PYTHON3_X64_DESCRIPTION = ( + 'Mercurial {version} MSI installer - x64 Windows (Python 3) ' + '- requires admin rights' +) + + +def fix_authorized_keys_permissions(winrm_client, path): + commands = [ + '$ErrorActionPreference = "Stop"', + 'Repair-AuthorizedKeyPermission -FilePath %s -Confirm:$false' % path, + r'icacls %s /remove:g "NT Service\sshd"' % path, + ] + + run_powershell(winrm_client, '\n'.join(commands)) + + +def synchronize_hg(hg_repo: pathlib.Path, revision: str, ec2_instance): + """Synchronize local Mercurial repo to remote EC2 instance.""" + + winrm_client = ec2_instance.winrm_client + + with tempfile.TemporaryDirectory() as temp_dir: + temp_dir = pathlib.Path(temp_dir) + + ssh_dir = temp_dir / '.ssh' + ssh_dir.mkdir() + ssh_dir.chmod(0o0700) + + # Generate SSH key to use for communication. + subprocess.run( + [ + 'ssh-keygen', + '-t', + 'rsa', + '-b', + '4096', + '-N', + '', + '-f', + str(ssh_dir / 'id_rsa'), + ], + check=True, + capture_output=True, + ) + + # Add it to ~/.ssh/authorized_keys on remote. + # This assumes the file doesn't already exist. + authorized_keys = r'c:\Users\Administrator\.ssh\authorized_keys' + winrm_client.execute_cmd(r'mkdir c:\Users\Administrator\.ssh') + winrm_client.copy(str(ssh_dir / 'id_rsa.pub'), authorized_keys) + fix_authorized_keys_permissions(winrm_client, authorized_keys) + + public_ip = ec2_instance.public_ip_address + + ssh_config = temp_dir / '.ssh' / 'config' + + with open(ssh_config, 'w', encoding='utf-8') as fh: + fh.write('Host %s\n' % public_ip) + fh.write(' User Administrator\n') + fh.write(' StrictHostKeyChecking no\n') + fh.write(' UserKnownHostsFile %s\n' % (ssh_dir / 'known_hosts')) + fh.write(' IdentityFile %s\n' % (ssh_dir / 'id_rsa')) + + if not (hg_repo / '.hg').is_dir(): + raise Exception( + '%s is not a Mercurial repository; ' + 'synchronization not yet supported' % hg_repo + ) + + env = dict(os.environ) + env['HGPLAIN'] = '1' + env['HGENCODING'] = 'utf-8' + + hg_bin = hg_repo / 'hg' + + res = subprocess.run( + ['python3', str(hg_bin), 'log', '-r', revision, '-T', '{node}'], + cwd=str(hg_repo), + env=env, + check=True, + capture_output=True, + ) + + full_revision = res.stdout.decode('ascii') + + args = [ + 'python3', + hg_bin, + '--config', + 'ui.ssh=ssh -F %s' % ssh_config, + '--config', + 'ui.remotecmd=c:/hgdev/venv-bootstrap/Scripts/hg.exe', + # Also ensure .hgtags changes are present so auto version + # calculation works. + 'push', + '-f', + '-r', + full_revision, + '-r', + 'file(.hgtags)', + 'ssh://%s/c:/hgdev/src' % public_ip, + ] + + res = subprocess.run(args, cwd=str(hg_repo), env=env) + + # Allow 1 (no-op) to not trigger error. + if res.returncode not in (0, 1): + res.check_returncode() + + run_powershell( + winrm_client, HG_UPDATE_CLEAN.format(revision=full_revision) + ) + + # TODO detect dirty local working directory and synchronize accordingly. + + +def purge_hg(winrm_client): + """Purge the Mercurial source repository on an EC2 instance.""" + run_powershell(winrm_client, HG_PURGE) + + +def find_latest_dist(winrm_client, pattern): + """Find path to newest file in dist/ directory matching a pattern.""" + + res = winrm_client.execute_ps( + r'$v = Get-ChildItem -Path C:\hgdev\src\dist -Filter "%s" ' + '| Sort-Object LastWriteTime -Descending ' + '| Select-Object -First 1\n' + '$v.name' % pattern + ) + return res[0] + + +def copy_latest_dist(winrm_client, pattern, dest_path): + """Copy latest file matching pattern in dist/ directory. + + Given a WinRM client and a file pattern, find the latest file on the remote + matching that pattern and copy it to the ``dest_path`` directory on the + local machine. + """ + latest = find_latest_dist(winrm_client, pattern) + source = r'C:\hgdev\src\dist\%s' % latest + dest = dest_path / latest + print('copying %s to %s' % (source, dest)) + winrm_client.fetch(source, str(dest)) + + +def build_inno_installer( + winrm_client, + arch: str, + dest_path: pathlib.Path, + version=None, +): + """Build the Inno Setup installer on a remote machine. + + Using a WinRM client, remote commands are executed to build + a Mercurial Inno Setup installer. + """ + print('building Inno Setup installer for %s' % arch) + + # TODO fix this limitation in packaging code + if not version: + raise Exception("version string is required when building for Python 3") + + if arch == "x86": + target_triple = "i686-pc-windows-msvc" + elif arch == "x64": + target_triple = "x86_64-pc-windows-msvc" + else: + raise Exception("unhandled arch: %s" % arch) + + ps = BUILD_INNO_PYTHON3.format( + pyoxidizer_target=target_triple, + version=version, + ) + + run_powershell(winrm_client, ps) + copy_latest_dist(winrm_client, '*.exe', dest_path) + + +def build_wheel( + winrm_client, python_version: str, arch: str, dest_path: pathlib.Path +): + """Build Python wheels on a remote machine. + + Using a WinRM client, remote commands are executed to build a Python wheel + for Mercurial. + """ + print('Building Windows wheel for Python %s %s' % (python_version, arch)) + + ps = BUILD_WHEEL.format( + python_version=python_version.replace(".", ""), arch=arch + ) + + run_powershell(winrm_client, ps) + copy_latest_dist(winrm_client, '*.whl', dest_path) + + +def build_wix_installer( + winrm_client, + arch: str, + dest_path: pathlib.Path, + version=None, +): + """Build the WiX installer on a remote machine. + + Using a WinRM client, remote commands are executed to build a WiX installer. + """ + print('Building WiX installer for %s' % arch) + + # TODO fix this limitation in packaging code + if not version: + raise Exception("version string is required when building for Python 3") + + if arch == "x86": + target_triple = "i686-pc-windows-msvc" + elif arch == "x64": + target_triple = "x86_64-pc-windows-msvc" + else: + raise Exception("unhandled arch: %s" % arch) + + ps = BUILD_WIX_PYTHON3.format( + pyoxidizer_target=target_triple, + version=version, + ) + + run_powershell(winrm_client, ps) + copy_latest_dist(winrm_client, '*.msi', dest_path) + + +def run_tests(winrm_client, python_version, arch, test_flags=''): + """Run tests on a remote Windows machine. + + ``python_version`` is a ``X.Y`` string like ``2.7`` or ``3.7``. + ``arch`` is ``x86`` or ``x64``. + ``test_flags`` is a str representing extra arguments to pass to + ``run-tests.py``. + """ + if not re.match(r'\d\.\d', python_version): + raise ValueError( + r'python_version must be \d.\d; got %s' % python_version + ) + + if arch not in ('x86', 'x64'): + raise ValueError('arch must be x86 or x64; got %s' % arch) + + python_path = 'python%s-%s' % (python_version.replace('.', ''), arch) + + ps = RUN_TESTS.format( + python_path=python_path, + test_flags=test_flags or '', + ) + + run_powershell(winrm_client, ps) + + +def resolve_wheel_artifacts(dist_path: pathlib.Path, version: str): + return ( + dist_path / WHEEL_FILENAME_PYTHON37_X86.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON37_X64.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON38_X86.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON38_X64.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON39_X86.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON39_X64.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON310_X86.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON310_X64.format(version=version), + ) + + +def resolve_all_artifacts(dist_path: pathlib.Path, version: str): + return ( + dist_path / WHEEL_FILENAME_PYTHON37_X86.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON37_X64.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON38_X86.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON38_X64.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON39_X86.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON39_X64.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON310_X86.format(version=version), + dist_path / WHEEL_FILENAME_PYTHON310_X64.format(version=version), + dist_path / EXE_FILENAME_PYTHON3_X86.format(version=version), + dist_path / EXE_FILENAME_PYTHON3_X64.format(version=version), + dist_path / MSI_FILENAME_PYTHON3_X86.format(version=version), + dist_path / MSI_FILENAME_PYTHON3_X64.format(version=version), + ) + + +def generate_latest_dat(version: str): + python3_x86_exe_filename = EXE_FILENAME_PYTHON3_X86.format(version=version) + python3_x64_exe_filename = EXE_FILENAME_PYTHON3_X64.format(version=version) + python3_x86_msi_filename = MSI_FILENAME_PYTHON3_X86.format(version=version) + python3_x64_msi_filename = MSI_FILENAME_PYTHON3_X64.format(version=version) + + entries = ( + ( + '10', + version, + X86_USER_AGENT_PATTERN, + '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x86_exe_filename), + EXE_PYTHON3_X86_DESCRIPTION.format(version=version), + ), + ( + '10', + version, + X64_USER_AGENT_PATTERN, + '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x64_exe_filename), + EXE_PYTHON3_X64_DESCRIPTION.format(version=version), + ), + ( + '10', + version, + X86_USER_AGENT_PATTERN, + '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x86_msi_filename), + MSI_PYTHON3_X86_DESCRIPTION.format(version=version), + ), + ( + '10', + version, + X64_USER_AGENT_PATTERN, + '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x64_msi_filename), + MSI_PYTHON3_X64_DESCRIPTION.format(version=version), + ), + ) + + lines = ['\t'.join(e) for e in entries] + + return '\n'.join(lines) + '\n' + + +def publish_artifacts_pypi(dist_path: pathlib.Path, version: str): + """Publish Windows release artifacts to PyPI.""" + + wheel_paths = resolve_wheel_artifacts(dist_path, version) + + for p in wheel_paths: + if not p.exists(): + raise Exception('%s not found' % p) + + print('uploading wheels to PyPI (you may be prompted for credentials)') + pypi_upload(wheel_paths) + + +def publish_artifacts_mercurial_scm_org( + dist_path: pathlib.Path, version: str, ssh_username=None +): + """Publish Windows release artifacts to mercurial-scm.org.""" + all_paths = resolve_all_artifacts(dist_path, version) + + for p in all_paths: + if not p.exists(): + raise Exception('%s not found' % p) + + client = paramiko.SSHClient() + client.load_system_host_keys() + # We assume the system SSH configuration knows how to connect. + print('connecting to mercurial-scm.org via ssh...') + try: + client.connect('mercurial-scm.org', username=ssh_username) + except paramiko.AuthenticationException: + print('error authenticating; is an SSH key available in an SSH agent?') + raise + + print('SSH connection established') + + print('opening SFTP client...') + sftp = client.open_sftp() + print('SFTP client obtained') + + for p in all_paths: + dest_path = '/var/www/release/windows/%s' % p.name + print('uploading %s to %s' % (p, dest_path)) + + with p.open('rb') as fh: + data = fh.read() + + with sftp.open(dest_path, 'wb') as fh: + fh.write(data) + fh.chmod(0o0664) + + latest_dat_path = '/var/www/release/windows/latest.dat' + + now = datetime.datetime.utcnow() + backup_path = dist_path / ( + 'latest-windows-%s.dat' % now.strftime('%Y%m%dT%H%M%S') + ) + print('backing up %s to %s' % (latest_dat_path, backup_path)) + + with sftp.open(latest_dat_path, 'rb') as fh: + latest_dat_old = fh.read() + + with backup_path.open('wb') as fh: + fh.write(latest_dat_old) + + print('writing %s with content:' % latest_dat_path) + latest_dat_content = generate_latest_dat(version) + print(latest_dat_content) + + with sftp.open(latest_dat_path, 'wb') as fh: + fh.write(latest_dat_content.encode('ascii')) + + +def publish_artifacts( + dist_path: pathlib.Path, + version: str, + pypi=True, + mercurial_scm_org=True, + ssh_username=None, +): + """Publish Windows release artifacts. + + Files are found in `dist_path`. We will look for files with version string + `version`. + + `pypi` controls whether we upload to PyPI. + `mercurial_scm_org` controls whether we upload to mercurial-scm.org. + """ + if pypi: + publish_artifacts_pypi(dist_path, version) + + if mercurial_scm_org: + publish_artifacts_mercurial_scm_org( + dist_path, version, ssh_username=ssh_username + ) diff --git a/contrib/automation/hgautomation/winrm.py b/contrib/automation/hgautomation/winrm.py new file mode 100644 index 0000000..ed65178 --- /dev/null +++ b/contrib/automation/hgautomation/winrm.py @@ -0,0 +1,87 @@ +# winrm.py - Interact with Windows Remote Management (WinRM) +# +# Copyright 2019 Gregory Szorc +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +# no-check-code because Python 3 native. + +import logging +import pprint +import time + +from pypsrp.client import Client +from pypsrp.powershell import ( + PowerShell, + PSInvocationState, + RunspacePool, +) +import requests.exceptions + + +logger = logging.getLogger(__name__) + + +def wait_for_winrm(host, username, password, timeout=180, ssl=False): + """Wait for the Windows Remoting (WinRM) service to become available. + + Returns a ``psrpclient.Client`` instance. + """ + + end_time = time.time() + timeout + + while True: + try: + client = Client( + host, + username=username, + password=password, + ssl=ssl, + connection_timeout=5, + ) + client.execute_ps("Write-Host 'Hello, World!'") + return client + except requests.exceptions.ConnectionError: + if time.time() >= end_time: + raise + + time.sleep(1) + + +def format_object(o): + if isinstance(o, str): + return o + + try: + o = str(o) + except (AttributeError, TypeError): + o = pprint.pformat(o.extended_properties) + + return o + + +def run_powershell(client, script): + with RunspacePool(client.wsman) as pool: + ps = PowerShell(pool) + ps.add_script(script) + + ps.begin_invoke() + + while ps.state == PSInvocationState.RUNNING: + ps.poll_invoke() + for o in ps.output: + print(format_object(o)) + + ps.output[:] = [] + + ps.end_invoke() + + for o in ps.output: + print(format_object(o)) + + if ps.state == PSInvocationState.FAILED: + raise Exception( + 'PowerShell execution failed: %s' + % ' '.join(map(format_object, ps.streams.error)) + ) diff --git a/contrib/automation/linux-requirements-py3.5.txt b/contrib/automation/linux-requirements-py3.5.txt new file mode 100644 index 0000000..c5b4437 --- /dev/null +++ b/contrib/automation/linux-requirements-py3.5.txt @@ -0,0 +1,194 @@ +# +# This file is autogenerated by pip-compile +# To update, run: +# +# pip-compile --generate-hashes --output-file=contrib/automation/linux-requirements-py3.5.txt contrib/automation/linux-requirements.txt.in +# +astroid==2.4.2 \ + --hash=sha256:2f4078c2a41bf377eea06d71c9d2ba4eb8f6b1af2135bec27bbbb7d8f12bb703 \ + --hash=sha256:bc58d83eb610252fd8de6363e39d4f1d0619c894b0ed24603b881c02e64c7386 + # via pylint +docutils==0.17.1 \ + --hash=sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125 \ + --hash=sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61 + # via -r contrib/automation/linux-requirements.txt.in +fuzzywuzzy==0.18.0 \ + --hash=sha256:45016e92264780e58972dca1b3d939ac864b78437422beecebb3095f8efd00e8 \ + --hash=sha256:928244b28db720d1e0ee7587acf660ea49d7e4c632569cad4f1cd7e68a5f0993 + # via -r contrib/automation/linux-requirements.txt.in +idna==3.1 \ + --hash=sha256:5205d03e7bcbb919cc9c19885f9920d622ca52448306f2377daede5cf3faac16 \ + --hash=sha256:c5b02147e01ea9920e6b0a3f1f7bb833612d507592c837a6c49552768f4054e1 + # via yarl +isort==4.3.21 \ + --hash=sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1 \ + --hash=sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd + # via + # -r contrib/automation/linux-requirements.txt.in + # pylint +lazy-object-proxy==1.4.3 \ + --hash=sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d \ + --hash=sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449 \ + --hash=sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08 \ + --hash=sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a \ + --hash=sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50 \ + --hash=sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd \ + --hash=sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239 \ + --hash=sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb \ + --hash=sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea \ + --hash=sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e \ + --hash=sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156 \ + --hash=sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142 \ + --hash=sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442 \ + --hash=sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62 \ + --hash=sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db \ + --hash=sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531 \ + --hash=sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383 \ + --hash=sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a \ + --hash=sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357 \ + --hash=sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4 \ + --hash=sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0 + # via astroid +mccabe==0.6.1 \ + --hash=sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42 \ + --hash=sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f + # via pylint +multidict==5.0.2 \ + --hash=sha256:060d68ae3e674c913ec41a464916f12c4d7ff17a3a9ebbf37ba7f2c681c2b33e \ + --hash=sha256:06f39f0ddc308dab4e5fa282d145f90cd38d7ed75390fc83335636909a9ec191 \ + --hash=sha256:17847fede1aafdb7e74e01bb34ab47a1a1ea726e8184c623c45d7e428d2d5d34 \ + --hash=sha256:1cd102057b09223b919f9447c669cf2efabeefb42a42ae6233f25ffd7ee31a79 \ + --hash=sha256:20cc9b2dd31761990abff7d0e63cd14dbfca4ebb52a77afc917b603473951a38 \ + --hash=sha256:2576e30bbec004e863d87216bc34abe24962cc2e964613241a1c01c7681092ab \ + --hash=sha256:2ab9cad4c5ef5c41e1123ed1f89f555aabefb9391d4e01fd6182de970b7267ed \ + --hash=sha256:359ea00e1b53ceef282232308da9d9a3f60d645868a97f64df19485c7f9ef628 \ + --hash=sha256:3e61cc244fd30bd9fdfae13bdd0c5ec65da51a86575ff1191255cae677045ffe \ + --hash=sha256:43c7a87d8c31913311a1ab24b138254a0ee89142983b327a2c2eab7a7d10fea9 \ + --hash=sha256:4a3f19da871befa53b48dd81ee48542f519beffa13090dc135fffc18d8fe36db \ + --hash=sha256:4df708ef412fd9b59b7e6c77857e64c1f6b4c0116b751cb399384ec9a28baa66 \ + --hash=sha256:59182e975b8c197d0146a003d0f0d5dc5487ce4899502061d8df585b0f51fba2 \ + --hash=sha256:6128d2c0956fd60e39ec7d1c8f79426f0c915d36458df59ddd1f0cff0340305f \ + --hash=sha256:6168839491a533fa75f3f5d48acbb829475e6c7d9fa5c6e245153b5f79b986a3 \ + --hash=sha256:62abab8088704121297d39c8f47156cb8fab1da731f513e59ba73946b22cf3d0 \ + --hash=sha256:653b2bbb0bbf282c37279dd04f429947ac92713049e1efc615f68d4e64b1dbc2 \ + --hash=sha256:6566749cd78cb37cbf8e8171b5cd2cbfc03c99f0891de12255cf17a11c07b1a3 \ + --hash=sha256:76cbdb22f48de64811f9ce1dd4dee09665f84f32d6a26de249a50c1e90e244e0 \ + --hash=sha256:8efcf070d60fd497db771429b1c769a3783e3a0dd96c78c027e676990176adc5 \ + --hash=sha256:8fa4549f341a057feec4c3139056ba73e17ed03a506469f447797a51f85081b5 \ + --hash=sha256:9380b3f2b00b23a4106ba9dd022df3e6e2e84e1788acdbdd27603b621b3288df \ + --hash=sha256:9ed9b280f7778ad6f71826b38a73c2fdca4077817c64bc1102fdada58e75c03c \ + --hash=sha256:a7b8b5bd16376c8ac2977748bd978a200326af5145d8d0e7f799e2b355d425b6 \ + --hash=sha256:af271c2540d1cd2a137bef8d95a8052230aa1cda26dd3b2c73d858d89993d518 \ + --hash=sha256:b561e76c9e21402d9a446cdae13398f9942388b9bff529f32dfa46220af54d00 \ + --hash=sha256:b82400ef848bbac6b9035a105ac6acaa1fb3eea0d164e35bbb21619b88e49fed \ + --hash=sha256:b98af08d7bb37d3456a22f689819ea793e8d6961b9629322d7728c4039071641 \ + --hash=sha256:c58e53e1c73109fdf4b759db9f2939325f510a8a5215135330fe6755921e4886 \ + --hash=sha256:cbabfc12b401d074298bfda099c58dfa5348415ae2e4ec841290627cb7cb6b2e \ + --hash=sha256:d4a6fb98e9e9be3f7d70fd3e852369c00a027bd5ed0f3e8ade3821bcad257408 \ + --hash=sha256:d99da85d6890267292065e654a329e1d2f483a5d2485e347383800e616a8c0b1 \ + --hash=sha256:e58db0e0d60029915f7fc95a8683fa815e204f2e1990f1fb46a7778d57ca8c35 \ + --hash=sha256:e5bf89fe57f702a046c7ec718fe330ed50efd4bcf74722940db2eb0919cddb1c \ + --hash=sha256:f612e8ef8408391a4a3366e3508bab8ef97b063b4918a317cb6e6de4415f01af \ + --hash=sha256:f65a2442c113afde52fb09f9a6276bbc31da71add99dc76c3adf6083234e07c6 \ + --hash=sha256:fa0503947a99a1be94f799fac89d67a5e20c333e78ddae16e8534b151cdc588a + # via yarl +pyflakes==2.3.1 \ + --hash=sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3 \ + --hash=sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db + # via -r contrib/automation/linux-requirements.txt.in +pygments==2.9.0 \ + --hash=sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f \ + --hash=sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e + # via -r contrib/automation/linux-requirements.txt.in +pylint==2.6.2 \ + --hash=sha256:718b74786ea7ed07aa0c58bf572154d4679f960d26e9641cc1de204a30b87fc9 \ + --hash=sha256:e71c2e9614a4f06e36498f310027942b0f4f2fde20aebb01655b31edc63b9eaf + # via -r contrib/automation/linux-requirements.txt.in +python-levenshtein==0.12.2 \ + --hash=sha256:dc2395fbd148a1ab31090dd113c366695934b9e85fe5a4b2a032745efd0346f6 + # via -r contrib/automation/linux-requirements.txt.in +pyyaml==5.3.1 \ + --hash=sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97 \ + --hash=sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76 \ + --hash=sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2 \ + --hash=sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e \ + --hash=sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648 \ + --hash=sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf \ + --hash=sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f \ + --hash=sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2 \ + --hash=sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee \ + --hash=sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a \ + --hash=sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d \ + --hash=sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c \ + --hash=sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a + # via vcrpy +six==1.16.0 \ + --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ + --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 + # via + # astroid + # vcrpy +toml==0.10.2 \ + --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ + --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f + # via pylint +typed-ast==1.4.3 ; python_version >= "3.0" and platform_python_implementation != "PyPy" \ + --hash=sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace \ + --hash=sha256:067a74454df670dcaa4e59349a2e5c81e567d8d65458d480a5b3dfecec08c5ff \ + --hash=sha256:0fb71b8c643187d7492c1f8352f2c15b4c4af3f6338f21681d3681b3dc31a266 \ + --hash=sha256:1b3ead4a96c9101bef08f9f7d1217c096f31667617b58de957f690c92378b528 \ + --hash=sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6 \ + --hash=sha256:209596a4ec71d990d71d5e0d312ac935d86930e6eecff6ccc7007fe54d703808 \ + --hash=sha256:2c726c276d09fc5c414693a2de063f521052d9ea7c240ce553316f70656c84d4 \ + --hash=sha256:398e44cd480f4d2b7ee8d98385ca104e35c81525dd98c519acff1b79bdaac363 \ + --hash=sha256:52b1eb8c83f178ab787f3a4283f68258525f8d70f778a2f6dd54d3b5e5fb4341 \ + --hash=sha256:5feca99c17af94057417d744607b82dd0a664fd5e4ca98061480fd8b14b18d04 \ + --hash=sha256:7538e495704e2ccda9b234b82423a4038f324f3a10c43bc088a1636180f11a41 \ + --hash=sha256:760ad187b1041a154f0e4d0f6aae3e40fdb51d6de16e5c99aedadd9246450e9e \ + --hash=sha256:777a26c84bea6cd934422ac2e3b78863a37017618b6e5c08f92ef69853e765d3 \ + --hash=sha256:95431a26309a21874005845c21118c83991c63ea800dd44843e42a916aec5899 \ + --hash=sha256:9ad2c92ec681e02baf81fdfa056fe0d818645efa9af1f1cd5fd6f1bd2bdfd805 \ + --hash=sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c \ + --hash=sha256:aee0c1256be6c07bd3e1263ff920c325b59849dc95392a05f258bb9b259cf39c \ + --hash=sha256:af3d4a73793725138d6b334d9d247ce7e5f084d96284ed23f22ee626a7b88e39 \ + --hash=sha256:b36b4f3920103a25e1d5d024d155c504080959582b928e91cb608a65c3a49e1a \ + --hash=sha256:b9574c6f03f685070d859e75c7f9eeca02d6933273b5e69572e5ff9d5e3931c3 \ + --hash=sha256:bff6ad71c81b3bba8fa35f0f1921fb24ff4476235a6e94a26ada2e54370e6da7 \ + --hash=sha256:c190f0899e9f9f8b6b7863debfb739abcb21a5c054f911ca3596d12b8a4c4c7f \ + --hash=sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075 \ + --hash=sha256:cae53c389825d3b46fb37538441f75d6aecc4174f615d048321b716df2757fb0 \ + --hash=sha256:dd4a21253f42b8d2b48410cb31fe501d32f8b9fbeb1f55063ad102fe9c425e40 \ + --hash=sha256:dde816ca9dac1d9c01dd504ea5967821606f02e510438120091b84e852367428 \ + --hash=sha256:f2362f3cb0f3172c42938946dbc5b7843c2a28aec307c49100c8b38764eb6927 \ + --hash=sha256:f328adcfebed9f11301eaedfa48e15bdece9b519fb27e6a8c01aa52a17ec31b3 \ + --hash=sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f \ + --hash=sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65 + # via + # -r contrib/automation/linux-requirements.txt.in + # astroid +vcrpy==4.1.1 \ + --hash=sha256:12c3fcdae7b88ecf11fc0d3e6d77586549d4575a2ceee18e82eee75c1f626162 \ + --hash=sha256:57095bf22fc0a2d99ee9674cdafebed0f3ba763018582450706f7d3a74fff599 + # via -r contrib/automation/linux-requirements.txt.in +wrapt==1.12.1 \ + --hash=sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7 + # via + # astroid + # vcrpy +yarl==1.3.0 \ + --hash=sha256:024ecdc12bc02b321bc66b41327f930d1c2c543fa9a561b39861da9388ba7aa9 \ + --hash=sha256:2f3010703295fbe1aec51023740871e64bb9664c789cba5a6bdf404e93f7568f \ + --hash=sha256:3890ab952d508523ef4881457c4099056546593fa05e93da84c7250516e632eb \ + --hash=sha256:3e2724eb9af5dc41648e5bb304fcf4891adc33258c6e14e2a7414ea32541e320 \ + --hash=sha256:5badb97dd0abf26623a9982cd448ff12cb39b8e4c94032ccdedf22ce01a64842 \ + --hash=sha256:73f447d11b530d860ca1e6b582f947688286ad16ca42256413083d13f260b7a0 \ + --hash=sha256:7ab825726f2940c16d92aaec7d204cfc34ac26c0040da727cf8ba87255a33829 \ + --hash=sha256:b25de84a8c20540531526dfbb0e2d2b648c13fd5dd126728c496d7c3fea33310 \ + --hash=sha256:c6e341f5a6562af74ba55205dbd56d248daf1b5748ec48a0200ba227bb9e33f4 \ + --hash=sha256:c9bb7c249c4432cd47e75af3864bc02d26c9594f49c82e2a28624417f0ae63b8 \ + --hash=sha256:e060906c0c585565c718d1c3841747b61c5439af2211e185f6739a9412dfbde1 + # via vcrpy + +# WARNING: The following packages were not pinned, but pip requires them to be +# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag. +# setuptools diff --git a/contrib/automation/linux-requirements-py3.txt b/contrib/automation/linux-requirements-py3.txt new file mode 100644 index 0000000..fdb545c --- /dev/null +++ b/contrib/automation/linux-requirements-py3.txt @@ -0,0 +1,306 @@ +# +# This file is autogenerated by pip-compile +# To update, run: +# +# pip-compile --generate-hashes --output-file=contrib/automation/linux-requirements-py3.txt contrib/automation/linux-requirements.txt.in +# +appdirs==1.4.4 \ + --hash=sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41 \ + --hash=sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128 + # via black +astroid==2.5.6 \ + --hash=sha256:4db03ab5fc3340cf619dbc25e42c2cc3755154ce6009469766d7143d1fc2ee4e \ + --hash=sha256:8a398dfce302c13f14bab13e2b14fe385d32b73f4e4853b9bdfb64598baa1975 + # via pylint +attrs==21.1.0 \ + --hash=sha256:3901be1cb7c2a780f14668691474d9252c070a756be0a9ead98cfeabfa11aeb8 \ + --hash=sha256:8ee1e5f5a1afc5b19bdfae4fdf0c35ed324074bdce3500c939842c8f818645d9 + # via black +black==19.10b0 ; python_version >= "3.6" and platform_python_implementation != "PyPy" \ + --hash=sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b \ + --hash=sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539 + # via -r contrib/automation/linux-requirements.txt.in +click==7.1.2 \ + --hash=sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a \ + --hash=sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc + # via black +docutils==0.17.1 \ + --hash=sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125 \ + --hash=sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61 + # via -r contrib/automation/linux-requirements.txt.in +fuzzywuzzy==0.18.0 \ + --hash=sha256:45016e92264780e58972dca1b3d939ac864b78437422beecebb3095f8efd00e8 \ + --hash=sha256:928244b28db720d1e0ee7587acf660ea49d7e4c632569cad4f1cd7e68a5f0993 + # via -r contrib/automation/linux-requirements.txt.in +idna==3.1 \ + --hash=sha256:5205d03e7bcbb919cc9c19885f9920d622ca52448306f2377daede5cf3faac16 \ + --hash=sha256:c5b02147e01ea9920e6b0a3f1f7bb833612d507592c837a6c49552768f4054e1 + # via yarl +isort==4.3.21 \ + --hash=sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1 \ + --hash=sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd + # via + # -r contrib/automation/linux-requirements.txt.in + # pylint +lazy-object-proxy==1.6.0 \ + --hash=sha256:17e0967ba374fc24141738c69736da90e94419338fd4c7c7bef01ee26b339653 \ + --hash=sha256:1fee665d2638491f4d6e55bd483e15ef21f6c8c2095f235fef72601021e64f61 \ + --hash=sha256:22ddd618cefe54305df49e4c069fa65715be4ad0e78e8d252a33debf00f6ede2 \ + --hash=sha256:24a5045889cc2729033b3e604d496c2b6f588c754f7a62027ad4437a7ecc4837 \ + --hash=sha256:410283732af311b51b837894fa2f24f2c0039aa7f220135192b38fcc42bd43d3 \ + --hash=sha256:4732c765372bd78a2d6b2150a6e99d00a78ec963375f236979c0626b97ed8e43 \ + --hash=sha256:489000d368377571c6f982fba6497f2aa13c6d1facc40660963da62f5c379726 \ + --hash=sha256:4f60460e9f1eb632584c9685bccea152f4ac2130e299784dbaf9fae9f49891b3 \ + --hash=sha256:5743a5ab42ae40caa8421b320ebf3a998f89c85cdc8376d6b2e00bd12bd1b587 \ + --hash=sha256:85fb7608121fd5621cc4377a8961d0b32ccf84a7285b4f1d21988b2eae2868e8 \ + --hash=sha256:9698110e36e2df951c7c36b6729e96429c9c32b3331989ef19976592c5f3c77a \ + --hash=sha256:9d397bf41caad3f489e10774667310d73cb9c4258e9aed94b9ec734b34b495fd \ + --hash=sha256:b579f8acbf2bdd9ea200b1d5dea36abd93cabf56cf626ab9c744a432e15c815f \ + --hash=sha256:b865b01a2e7f96db0c5d12cfea590f98d8c5ba64ad222300d93ce6ff9138bcad \ + --hash=sha256:bf34e368e8dd976423396555078def5cfc3039ebc6fc06d1ae2c5a65eebbcde4 \ + --hash=sha256:c6938967f8528b3668622a9ed3b31d145fab161a32f5891ea7b84f6b790be05b \ + --hash=sha256:d1c2676e3d840852a2de7c7d5d76407c772927addff8d742b9808fe0afccebdf \ + --hash=sha256:d7124f52f3bd259f510651450e18e0fd081ed82f3c08541dffc7b94b883aa981 \ + --hash=sha256:d900d949b707778696fdf01036f58c9876a0d8bfe116e8d220cfd4b15f14e741 \ + --hash=sha256:ebfd274dcd5133e0afae738e6d9da4323c3eb021b3e13052d8cbd0e457b1256e \ + --hash=sha256:ed361bb83436f117f9917d282a456f9e5009ea12fd6de8742d1a4752c3017e93 \ + --hash=sha256:f5144c75445ae3ca2057faac03fda5a902eff196702b0a24daf1d6ce0650514b + # via astroid +mccabe==0.6.1 \ + --hash=sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42 \ + --hash=sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f + # via pylint +multidict==5.1.0 \ + --hash=sha256:018132dbd8688c7a69ad89c4a3f39ea2f9f33302ebe567a879da8f4ca73f0d0a \ + --hash=sha256:051012ccee979b2b06be928a6150d237aec75dd6bf2d1eeeb190baf2b05abc93 \ + --hash=sha256:05c20b68e512166fddba59a918773ba002fdd77800cad9f55b59790030bab632 \ + --hash=sha256:07b42215124aedecc6083f1ce6b7e5ec5b50047afa701f3442054373a6deb656 \ + --hash=sha256:0e3c84e6c67eba89c2dbcee08504ba8644ab4284863452450520dad8f1e89b79 \ + --hash=sha256:0e929169f9c090dae0646a011c8b058e5e5fb391466016b39d21745b48817fd7 \ + --hash=sha256:1ab820665e67373de5802acae069a6a05567ae234ddb129f31d290fc3d1aa56d \ + --hash=sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5 \ + --hash=sha256:2e68965192c4ea61fff1b81c14ff712fc7dc15d2bd120602e4a3494ea6584224 \ + --hash=sha256:2f1a132f1c88724674271d636e6b7351477c27722f2ed789f719f9e3545a3d26 \ + --hash=sha256:37e5438e1c78931df5d3c0c78ae049092877e5e9c02dd1ff5abb9cf27a5914ea \ + --hash=sha256:3a041b76d13706b7fff23b9fc83117c7b8fe8d5fe9e6be45eee72b9baa75f348 \ + --hash=sha256:3a4f32116f8f72ecf2a29dabfb27b23ab7cdc0ba807e8459e59a93a9be9506f6 \ + --hash=sha256:46c73e09ad374a6d876c599f2328161bcd95e280f84d2060cf57991dec5cfe76 \ + --hash=sha256:46dd362c2f045095c920162e9307de5ffd0a1bfbba0a6e990b344366f55a30c1 \ + --hash=sha256:4b186eb7d6ae7c06eb4392411189469e6a820da81447f46c0072a41c748ab73f \ + --hash=sha256:54fd1e83a184e19c598d5e70ba508196fd0bbdd676ce159feb412a4a6664f952 \ + --hash=sha256:585fd452dd7782130d112f7ddf3473ffdd521414674c33876187e101b588738a \ + --hash=sha256:5cf3443199b83ed9e955f511b5b241fd3ae004e3cb81c58ec10f4fe47c7dce37 \ + --hash=sha256:6a4d5ce640e37b0efcc8441caeea8f43a06addace2335bd11151bc02d2ee31f9 \ + --hash=sha256:7df80d07818b385f3129180369079bd6934cf70469f99daaebfac89dca288359 \ + --hash=sha256:806068d4f86cb06af37cd65821554f98240a19ce646d3cd24e1c33587f313eb8 \ + --hash=sha256:830f57206cc96ed0ccf68304141fec9481a096c4d2e2831f311bde1c404401da \ + --hash=sha256:929006d3c2d923788ba153ad0de8ed2e5ed39fdbe8e7be21e2f22ed06c6783d3 \ + --hash=sha256:9436dc58c123f07b230383083855593550c4d301d2532045a17ccf6eca505f6d \ + --hash=sha256:9dd6e9b1a913d096ac95d0399bd737e00f2af1e1594a787e00f7975778c8b2bf \ + --hash=sha256:ace010325c787c378afd7f7c1ac66b26313b3344628652eacd149bdd23c68841 \ + --hash=sha256:b47a43177a5e65b771b80db71e7be76c0ba23cc8aa73eeeb089ed5219cdbe27d \ + --hash=sha256:b797515be8743b771aa868f83563f789bbd4b236659ba52243b735d80b29ed93 \ + --hash=sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f \ + --hash=sha256:d5c65bdf4484872c4af3150aeebe101ba560dcfb34488d9a8ff8dbcd21079647 \ + --hash=sha256:d81eddcb12d608cc08081fa88d046c78afb1bf8107e6feab5d43503fea74a635 \ + --hash=sha256:dc862056f76443a0db4509116c5cd480fe1b6a2d45512a653f9a855cc0517456 \ + --hash=sha256:ecc771ab628ea281517e24fd2c52e8f31c41e66652d07599ad8818abaad38cda \ + --hash=sha256:f200755768dc19c6f4e2b672421e0ebb3dd54c38d5a4f262b872d8cfcc9e93b5 \ + --hash=sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281 \ + --hash=sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80 + # via yarl +pathspec==0.8.1 \ + --hash=sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd \ + --hash=sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d + # via black +pyflakes==2.3.1 \ + --hash=sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3 \ + --hash=sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db + # via -r contrib/automation/linux-requirements.txt.in +pygments==2.9.0 \ + --hash=sha256:a18f47b506a429f6f4b9df81bb02beab9ca21d0a5fee38ed15aef65f0545519f \ + --hash=sha256:d66e804411278594d764fc69ec36ec13d9ae9147193a1740cd34d272ca383b8e + # via -r contrib/automation/linux-requirements.txt.in +pylint==2.8.2 \ + --hash=sha256:586d8fa9b1891f4b725f587ef267abe2a1bad89d6b184520c7f07a253dd6e217 \ + --hash=sha256:f7e2072654a6b6afdf5e2fb38147d3e2d2d43c89f648637baab63e026481279b + # via -r contrib/automation/linux-requirements.txt.in +python-levenshtein==0.12.2 \ + --hash=sha256:dc2395fbd148a1ab31090dd113c366695934b9e85fe5a4b2a032745efd0346f6 + # via -r contrib/automation/linux-requirements.txt.in +pyyaml==5.4.1 \ + --hash=sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf \ + --hash=sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696 \ + --hash=sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393 \ + --hash=sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77 \ + --hash=sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922 \ + --hash=sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5 \ + --hash=sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8 \ + --hash=sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10 \ + --hash=sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc \ + --hash=sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018 \ + --hash=sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e \ + --hash=sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253 \ + --hash=sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347 \ + --hash=sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183 \ + --hash=sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541 \ + --hash=sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb \ + --hash=sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185 \ + --hash=sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc \ + --hash=sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db \ + --hash=sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa \ + --hash=sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46 \ + --hash=sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122 \ + --hash=sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b \ + --hash=sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63 \ + --hash=sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df \ + --hash=sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc \ + --hash=sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247 \ + --hash=sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6 \ + --hash=sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0 + # via vcrpy +regex==2021.4.4 \ + --hash=sha256:01afaf2ec48e196ba91b37451aa353cb7eda77efe518e481707e0515025f0cd5 \ + --hash=sha256:11d773d75fa650cd36f68d7ca936e3c7afaae41b863b8c387a22aaa78d3c5c79 \ + --hash=sha256:18c071c3eb09c30a264879f0d310d37fe5d3a3111662438889ae2eb6fc570c31 \ + --hash=sha256:1e1c20e29358165242928c2de1482fb2cf4ea54a6a6dea2bd7a0e0d8ee321500 \ + --hash=sha256:281d2fd05555079448537fe108d79eb031b403dac622621c78944c235f3fcf11 \ + --hash=sha256:314d66636c494ed9c148a42731b3834496cc9a2c4251b1661e40936814542b14 \ + --hash=sha256:32e65442138b7b76dd8173ffa2cf67356b7bc1768851dded39a7a13bf9223da3 \ + --hash=sha256:339456e7d8c06dd36a22e451d58ef72cef293112b559010db3d054d5560ef439 \ + --hash=sha256:3916d08be28a1149fb97f7728fca1f7c15d309a9f9682d89d79db75d5e52091c \ + --hash=sha256:3a9cd17e6e5c7eb328517969e0cb0c3d31fd329298dd0c04af99ebf42e904f82 \ + --hash=sha256:47bf5bf60cf04d72bf6055ae5927a0bd9016096bf3d742fa50d9bf9f45aa0711 \ + --hash=sha256:4c46e22a0933dd783467cf32b3516299fb98cfebd895817d685130cc50cd1093 \ + --hash=sha256:4c557a7b470908b1712fe27fb1ef20772b78079808c87d20a90d051660b1d69a \ + --hash=sha256:52ba3d3f9b942c49d7e4bc105bb28551c44065f139a65062ab7912bef10c9afb \ + --hash=sha256:563085e55b0d4fb8f746f6a335893bda5c2cef43b2f0258fe1020ab1dd874df8 \ + --hash=sha256:598585c9f0af8374c28edd609eb291b5726d7cbce16be6a8b95aa074d252ee17 \ + --hash=sha256:619d71c59a78b84d7f18891fe914446d07edd48dc8328c8e149cbe0929b4e000 \ + --hash=sha256:67bdb9702427ceddc6ef3dc382455e90f785af4c13d495f9626861763ee13f9d \ + --hash=sha256:6d1b01031dedf2503631d0903cb563743f397ccaf6607a5e3b19a3d76fc10480 \ + --hash=sha256:741a9647fcf2e45f3a1cf0e24f5e17febf3efe8d4ba1281dcc3aa0459ef424dc \ + --hash=sha256:7c2a1af393fcc09e898beba5dd59196edaa3116191cc7257f9224beaed3e1aa0 \ + --hash=sha256:7d9884d86dd4dd489e981d94a65cd30d6f07203d90e98f6f657f05170f6324c9 \ + --hash=sha256:90f11ff637fe8798933fb29f5ae1148c978cccb0452005bf4c69e13db951e765 \ + --hash=sha256:919859aa909429fb5aa9cf8807f6045592c85ef56fdd30a9a3747e513db2536e \ + --hash=sha256:96fcd1888ab4d03adfc9303a7b3c0bd78c5412b2bfbe76db5b56d9eae004907a \ + --hash=sha256:97f29f57d5b84e73fbaf99ab3e26134e6687348e95ef6b48cfd2c06807005a07 \ + --hash=sha256:980d7be47c84979d9136328d882f67ec5e50008681d94ecc8afa8a65ed1f4a6f \ + --hash=sha256:a91aa8619b23b79bcbeb37abe286f2f408d2f2d6f29a17237afda55bb54e7aac \ + --hash=sha256:ade17eb5d643b7fead300a1641e9f45401c98eee23763e9ed66a43f92f20b4a7 \ + --hash=sha256:b9c3db21af35e3b3c05764461b262d6f05bbca08a71a7849fd79d47ba7bc33ed \ + --hash=sha256:bd28bc2e3a772acbb07787c6308e00d9626ff89e3bfcdebe87fa5afbfdedf968 \ + --hash=sha256:bf5824bfac591ddb2c1f0a5f4ab72da28994548c708d2191e3b87dd207eb3ad7 \ + --hash=sha256:c0502c0fadef0d23b128605d69b58edb2c681c25d44574fc673b0e52dce71ee2 \ + --hash=sha256:c38c71df845e2aabb7fb0b920d11a1b5ac8526005e533a8920aea97efb8ec6a4 \ + --hash=sha256:ce15b6d103daff8e9fee13cf7f0add05245a05d866e73926c358e871221eae87 \ + --hash=sha256:d3029c340cfbb3ac0a71798100ccc13b97dddf373a4ae56b6a72cf70dfd53bc8 \ + --hash=sha256:e512d8ef5ad7b898cdb2d8ee1cb09a8339e4f8be706d27eaa180c2f177248a10 \ + --hash=sha256:e8e5b509d5c2ff12f8418006d5a90e9436766133b564db0abaec92fd27fcee29 \ + --hash=sha256:ee54ff27bf0afaf4c3b3a62bcd016c12c3fdb4ec4f413391a90bd38bc3624605 \ + --hash=sha256:fa4537fb4a98fe8fde99626e4681cc644bdcf2a795038533f9f711513a862ae6 \ + --hash=sha256:fd45ff9293d9274c5008a2054ecef86a9bfe819a67c7be1afb65e69b405b3042 + # via black +six==1.16.0 \ + --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ + --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 + # via vcrpy +toml==0.10.2 \ + --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ + --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f + # via + # black + # pylint +typed-ast==1.4.3 ; python_version >= "3.0" and platform_python_implementation != "PyPy" \ + --hash=sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace \ + --hash=sha256:067a74454df670dcaa4e59349a2e5c81e567d8d65458d480a5b3dfecec08c5ff \ + --hash=sha256:0fb71b8c643187d7492c1f8352f2c15b4c4af3f6338f21681d3681b3dc31a266 \ + --hash=sha256:1b3ead4a96c9101bef08f9f7d1217c096f31667617b58de957f690c92378b528 \ + --hash=sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6 \ + --hash=sha256:209596a4ec71d990d71d5e0d312ac935d86930e6eecff6ccc7007fe54d703808 \ + --hash=sha256:2c726c276d09fc5c414693a2de063f521052d9ea7c240ce553316f70656c84d4 \ + --hash=sha256:398e44cd480f4d2b7ee8d98385ca104e35c81525dd98c519acff1b79bdaac363 \ + --hash=sha256:52b1eb8c83f178ab787f3a4283f68258525f8d70f778a2f6dd54d3b5e5fb4341 \ + --hash=sha256:5feca99c17af94057417d744607b82dd0a664fd5e4ca98061480fd8b14b18d04 \ + --hash=sha256:7538e495704e2ccda9b234b82423a4038f324f3a10c43bc088a1636180f11a41 \ + --hash=sha256:760ad187b1041a154f0e4d0f6aae3e40fdb51d6de16e5c99aedadd9246450e9e \ + --hash=sha256:777a26c84bea6cd934422ac2e3b78863a37017618b6e5c08f92ef69853e765d3 \ + --hash=sha256:95431a26309a21874005845c21118c83991c63ea800dd44843e42a916aec5899 \ + --hash=sha256:9ad2c92ec681e02baf81fdfa056fe0d818645efa9af1f1cd5fd6f1bd2bdfd805 \ + --hash=sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c \ + --hash=sha256:aee0c1256be6c07bd3e1263ff920c325b59849dc95392a05f258bb9b259cf39c \ + --hash=sha256:af3d4a73793725138d6b334d9d247ce7e5f084d96284ed23f22ee626a7b88e39 \ + --hash=sha256:b36b4f3920103a25e1d5d024d155c504080959582b928e91cb608a65c3a49e1a \ + --hash=sha256:b9574c6f03f685070d859e75c7f9eeca02d6933273b5e69572e5ff9d5e3931c3 \ + --hash=sha256:bff6ad71c81b3bba8fa35f0f1921fb24ff4476235a6e94a26ada2e54370e6da7 \ + --hash=sha256:c190f0899e9f9f8b6b7863debfb739abcb21a5c054f911ca3596d12b8a4c4c7f \ + --hash=sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075 \ + --hash=sha256:cae53c389825d3b46fb37538441f75d6aecc4174f615d048321b716df2757fb0 \ + --hash=sha256:dd4a21253f42b8d2b48410cb31fe501d32f8b9fbeb1f55063ad102fe9c425e40 \ + --hash=sha256:dde816ca9dac1d9c01dd504ea5967821606f02e510438120091b84e852367428 \ + --hash=sha256:f2362f3cb0f3172c42938946dbc5b7843c2a28aec307c49100c8b38764eb6927 \ + --hash=sha256:f328adcfebed9f11301eaedfa48e15bdece9b519fb27e6a8c01aa52a17ec31b3 \ + --hash=sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f \ + --hash=sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65 + # via + # -r contrib/automation/linux-requirements.txt.in + # astroid + # black +typing-extensions==3.10.0.0 \ + --hash=sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497 \ + --hash=sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342 \ + --hash=sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84 + # via yarl +vcrpy==4.1.1 \ + --hash=sha256:12c3fcdae7b88ecf11fc0d3e6d77586549d4575a2ceee18e82eee75c1f626162 \ + --hash=sha256:57095bf22fc0a2d99ee9674cdafebed0f3ba763018582450706f7d3a74fff599 + # via -r contrib/automation/linux-requirements.txt.in +wrapt==1.12.1 \ + --hash=sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7 + # via + # astroid + # vcrpy +yarl==1.6.3 \ + --hash=sha256:00d7ad91b6583602eb9c1d085a2cf281ada267e9a197e8b7cae487dadbfa293e \ + --hash=sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434 \ + --hash=sha256:15263c3b0b47968c1d90daa89f21fcc889bb4b1aac5555580d74565de6836366 \ + --hash=sha256:2ce4c621d21326a4a5500c25031e102af589edb50c09b321049e388b3934eec3 \ + --hash=sha256:31ede6e8c4329fb81c86706ba8f6bf661a924b53ba191b27aa5fcee5714d18ec \ + --hash=sha256:324ba3d3c6fee56e2e0b0d09bf5c73824b9f08234339d2b788af65e60040c959 \ + --hash=sha256:329412812ecfc94a57cd37c9d547579510a9e83c516bc069470db5f75684629e \ + --hash=sha256:4736eaee5626db8d9cda9eb5282028cc834e2aeb194e0d8b50217d707e98bb5c \ + --hash=sha256:4953fb0b4fdb7e08b2f3b3be80a00d28c5c8a2056bb066169de00e6501b986b6 \ + --hash=sha256:4c5bcfc3ed226bf6419f7a33982fb4b8ec2e45785a0561eb99274ebbf09fdd6a \ + --hash=sha256:547f7665ad50fa8563150ed079f8e805e63dd85def6674c97efd78eed6c224a6 \ + --hash=sha256:5b883e458058f8d6099e4420f0cc2567989032b5f34b271c0827de9f1079a424 \ + --hash=sha256:63f90b20ca654b3ecc7a8d62c03ffa46999595f0167d6450fa8383bab252987e \ + --hash=sha256:68dc568889b1c13f1e4745c96b931cc94fdd0defe92a72c2b8ce01091b22e35f \ + --hash=sha256:69ee97c71fee1f63d04c945f56d5d726483c4762845400a6795a3b75d56b6c50 \ + --hash=sha256:6d6283d8e0631b617edf0fd726353cb76630b83a089a40933043894e7f6721e2 \ + --hash=sha256:72a660bdd24497e3e84f5519e57a9ee9220b6f3ac4d45056961bf22838ce20cc \ + --hash=sha256:73494d5b71099ae8cb8754f1df131c11d433b387efab7b51849e7e1e851f07a4 \ + --hash=sha256:7356644cbed76119d0b6bd32ffba704d30d747e0c217109d7979a7bc36c4d970 \ + --hash=sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10 \ + --hash=sha256:8aa3decd5e0e852dc68335abf5478a518b41bf2ab2f330fe44916399efedfae0 \ + --hash=sha256:97b5bdc450d63c3ba30a127d018b866ea94e65655efaf889ebeabc20f7d12406 \ + --hash=sha256:9ede61b0854e267fd565e7527e2f2eb3ef8858b301319be0604177690e1a3896 \ + --hash=sha256:b2e9a456c121e26d13c29251f8267541bd75e6a1ccf9e859179701c36a078643 \ + --hash=sha256:b5dfc9a40c198334f4f3f55880ecf910adebdcb2a0b9a9c23c9345faa9185721 \ + --hash=sha256:bafb450deef6861815ed579c7a6113a879a6ef58aed4c3a4be54400ae8871478 \ + --hash=sha256:c49ff66d479d38ab863c50f7bb27dee97c6627c5fe60697de15529da9c3de724 \ + --hash=sha256:ce3beb46a72d9f2190f9e1027886bfc513702d748047b548b05dab7dfb584d2e \ + --hash=sha256:d26608cf178efb8faa5ff0f2d2e77c208f471c5a3709e577a7b3fd0445703ac8 \ + --hash=sha256:d597767fcd2c3dc49d6eea360c458b65643d1e4dbed91361cf5e36e53c1f8c96 \ + --hash=sha256:d5c32c82990e4ac4d8150fd7652b972216b204de4e83a122546dce571c1bdf25 \ + --hash=sha256:d8d07d102f17b68966e2de0e07bfd6e139c7c02ef06d3a0f8d2f0f055e13bb76 \ + --hash=sha256:e46fba844f4895b36f4c398c5af062a9808d1f26b2999c58909517384d5deda2 \ + --hash=sha256:e6b5460dc5ad42ad2b36cca524491dfcaffbfd9c8df50508bddc354e787b8dc2 \ + --hash=sha256:f040bcc6725c821a4c0665f3aa96a4d0805a7aaf2caf266d256b8ed71b9f041c \ + --hash=sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a \ + --hash=sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71 + # via vcrpy + +# WARNING: The following packages were not pinned, but pip requires them to be +# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag. +# setuptools diff --git a/contrib/automation/linux-requirements.txt.in b/contrib/automation/linux-requirements.txt.in new file mode 100644 index 0000000..77833df --- /dev/null +++ b/contrib/automation/linux-requirements.txt.in @@ -0,0 +1,17 @@ +# black pulls in typed-ast, which doesn't install on PyPy. +black==19.10b0 ; python_version >= '3.6' and platform_python_implementation != 'PyPy' +# Bazaar doesn't work with Python 3 nor PyPy. +bzr ; python_version <= '2.7' and platform_python_implementation == 'CPython' +docutils +fuzzywuzzy +# isort 5.0 drops support for Python 3.5. We can remove this line when we +# drop support for 3.5. +isort < 5.0 +pyflakes +pygments +pylint +# Needed to avoid warnings from fuzzywuzzy. +python-Levenshtein +# typed-ast dependency doesn't install on PyPy. +typed-ast ; python_version >= '3.0' and platform_python_implementation != 'PyPy' +vcrpy diff --git a/contrib/automation/requirements.txt b/contrib/automation/requirements.txt new file mode 100644 index 0000000..b7036eb --- /dev/null +++ b/contrib/automation/requirements.txt @@ -0,0 +1,267 @@ +# +# This file is autogenerated by pip-compile with python 3.10 +# To update, run: +# +# pip-compile --generate-hashes --output-file=contrib/automation/requirements.txt contrib/automation/requirements.txt.in +# +bcrypt==3.2.2 \ + --hash=sha256:2b02d6bfc6336d1094276f3f588aa1225a598e27f8e3388f4db9948cb707b521 \ + --hash=sha256:433c410c2177057705da2a9f2cd01dd157493b2a7ac14c8593a16b3dab6b6bfb \ + --hash=sha256:4e029cef560967fb0cf4a802bcf4d562d3d6b4b1bf81de5ec1abbe0f1adb027e \ + --hash=sha256:61bae49580dce88095d669226d5076d0b9d927754cedbdf76c6c9f5099ad6f26 \ + --hash=sha256:6d2cb9d969bfca5bc08e45864137276e4c3d3d7de2b162171def3d188bf9d34a \ + --hash=sha256:7180d98a96f00b1050e93f5b0f556e658605dd9f524d0b0e68ae7944673f525e \ + --hash=sha256:7d9ba2e41e330d2af4af6b1b6ec9e6128e91343d0b4afb9282e54e5508f31baa \ + --hash=sha256:7ff2069240c6bbe49109fe84ca80508773a904f5a8cb960e02a977f7f519b129 \ + --hash=sha256:88273d806ab3a50d06bc6a2fc7c87d737dd669b76ad955f449c43095389bc8fb \ + --hash=sha256:a2c46100e315c3a5b90fdc53e429c006c5f962529bc27e1dfd656292c20ccc40 \ + --hash=sha256:cd43303d6b8a165c29ec6756afd169faba9396a9472cdff753fe9f19b96ce2fa + # via paramiko +bleach==5.0.0 \ + --hash=sha256:08a1fe86d253b5c88c92cc3d810fd8048a16d15762e1e5b74d502256e5926aa1 \ + --hash=sha256:c6d6cc054bdc9c83b48b8083e236e5f00f238428666d2ce2e083eaa5fd568565 + # via readme-renderer +boto3==1.22.7 \ + --hash=sha256:4dc0df36c3465ff0d586017da68b0152123695f38f30ad98fed7185e59298d2c \ + --hash=sha256:de4fa49ca1cbc93313144e93e6d0997cbb61c8cca91f3418b4e3646dc215f441 + # via -r contrib/automation/requirements.txt.in +botocore==1.25.7 \ + --hash=sha256:190361776d96323ff401b976175f76172acf7ebbe3efbb19c4c6f9800a9ad6b6 \ + --hash=sha256:83da857c12fff5cf4c1a64afaa72a28ff5bef929a2834ec4ed5b0b674f88fd0e + # via + # boto3 + # s3transfer +certifi==2021.10.8 \ + --hash=sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872 \ + --hash=sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569 + # via requests +cffi==1.15.0 \ + --hash=sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3 \ + --hash=sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2 \ + --hash=sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636 \ + --hash=sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20 \ + --hash=sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728 \ + --hash=sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27 \ + --hash=sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66 \ + --hash=sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443 \ + --hash=sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0 \ + --hash=sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7 \ + --hash=sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39 \ + --hash=sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605 \ + --hash=sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a \ + --hash=sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37 \ + --hash=sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029 \ + --hash=sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139 \ + --hash=sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc \ + --hash=sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df \ + --hash=sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14 \ + --hash=sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880 \ + --hash=sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2 \ + --hash=sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a \ + --hash=sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e \ + --hash=sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474 \ + --hash=sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024 \ + --hash=sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8 \ + --hash=sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0 \ + --hash=sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e \ + --hash=sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a \ + --hash=sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e \ + --hash=sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032 \ + --hash=sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6 \ + --hash=sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e \ + --hash=sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b \ + --hash=sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e \ + --hash=sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954 \ + --hash=sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962 \ + --hash=sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c \ + --hash=sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4 \ + --hash=sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55 \ + --hash=sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962 \ + --hash=sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023 \ + --hash=sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c \ + --hash=sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6 \ + --hash=sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8 \ + --hash=sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382 \ + --hash=sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7 \ + --hash=sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc \ + --hash=sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997 \ + --hash=sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796 + # via + # bcrypt + # cryptography + # pynacl +charset-normalizer==2.0.12 \ + --hash=sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597 \ + --hash=sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df + # via requests +commonmark==0.9.1 \ + --hash=sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60 \ + --hash=sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9 + # via rich +cryptography==37.0.2 \ + --hash=sha256:093cb351031656d3ee2f4fa1be579a8c69c754cf874206be1d4cf3b542042804 \ + --hash=sha256:0cc20f655157d4cfc7bada909dc5cc228211b075ba8407c46467f63597c78178 \ + --hash=sha256:1b9362d34363f2c71b7853f6251219298124aa4cc2075ae2932e64c91a3e2717 \ + --hash=sha256:1f3bfbd611db5cb58ca82f3deb35e83af34bb8cf06043fa61500157d50a70982 \ + --hash=sha256:2bd1096476aaac820426239ab534b636c77d71af66c547b9ddcd76eb9c79e004 \ + --hash=sha256:31fe38d14d2e5f787e0aecef831457da6cec68e0bb09a35835b0b44ae8b988fe \ + --hash=sha256:3b8398b3d0efc420e777c40c16764d6870bcef2eb383df9c6dbb9ffe12c64452 \ + --hash=sha256:3c81599befb4d4f3d7648ed3217e00d21a9341a9a688ecdd615ff72ffbed7336 \ + --hash=sha256:419c57d7b63f5ec38b1199a9521d77d7d1754eb97827bbb773162073ccd8c8d4 \ + --hash=sha256:46f4c544f6557a2fefa7ac8ac7d1b17bf9b647bd20b16decc8fbcab7117fbc15 \ + --hash=sha256:471e0d70201c069f74c837983189949aa0d24bb2d751b57e26e3761f2f782b8d \ + --hash=sha256:59b281eab51e1b6b6afa525af2bd93c16d49358404f814fe2c2410058623928c \ + --hash=sha256:731c8abd27693323b348518ed0e0705713a36d79fdbd969ad968fbef0979a7e0 \ + --hash=sha256:95e590dd70642eb2079d280420a888190aa040ad20f19ec8c6e097e38aa29e06 \ + --hash=sha256:a68254dd88021f24a68b613d8c51d5c5e74d735878b9e32cc0adf19d1f10aaf9 \ + --hash=sha256:a7d5137e556cc0ea418dca6186deabe9129cee318618eb1ffecbd35bee55ddc1 \ + --hash=sha256:aeaba7b5e756ea52c8861c133c596afe93dd716cbcacae23b80bc238202dc023 \ + --hash=sha256:dc26bb134452081859aa21d4990474ddb7e863aa39e60d1592800a8865a702de \ + --hash=sha256:e53258e69874a306fcecb88b7534d61820db8a98655662a3dd2ec7f1afd9132f \ + --hash=sha256:ef15c2df7656763b4ff20a9bc4381d8352e6640cfeb95c2972c38ef508e75181 \ + --hash=sha256:f224ad253cc9cea7568f49077007d2263efa57396a2f2f78114066fd54b5c68e \ + --hash=sha256:f8ec91983e638a9bcd75b39f1396e5c0dc2330cbd9ce4accefe68717e6779e0a + # via + # paramiko + # pypsrp + # pyspnego + # secretstorage +docutils==0.18.1 \ + --hash=sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c \ + --hash=sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06 + # via readme-renderer +idna==3.3 \ + --hash=sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff \ + --hash=sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d + # via requests +importlib-metadata==4.11.3 \ + --hash=sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6 \ + --hash=sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539 + # via + # keyring + # twine +jeepney==0.8.0 \ + --hash=sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806 \ + --hash=sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755 + # via + # keyring + # secretstorage +jmespath==1.0.0 \ + --hash=sha256:a490e280edd1f57d6de88636992d05b71e97d69a26a19f058ecf7d304474bf5e \ + --hash=sha256:e8dcd576ed616f14ec02eed0005c85973b5890083313860136657e24784e4c04 + # via + # boto3 + # botocore +keyring==23.5.0 \ + --hash=sha256:9012508e141a80bd1c0b6778d5c610dd9f8c464d75ac6774248500503f972fb9 \ + --hash=sha256:b0d28928ac3ec8e42ef4cc227822647a19f1d544f21f96457965dc01cf555261 + # via twine +paramiko==2.10.4 \ + --hash=sha256:3c9ed6084f4b671ab66dc3c729092d32d96c3258f1426071301cb33654b09027 \ + --hash=sha256:3d2e650b6812ce6d160abff701d6ef4434ec97934b13e95cf1ad3da70ffb5c58 + # via -r contrib/automation/requirements.txt.in +pkginfo==1.8.2 \ + --hash=sha256:542e0d0b6750e2e21c20179803e40ab50598d8066d51097a0e382cba9eb02bff \ + --hash=sha256:c24c487c6a7f72c66e816ab1796b96ac6c3d14d49338293d2141664330b55ffc + # via twine +pycparser==2.21 \ + --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \ + --hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206 + # via cffi +pygments==2.12.0 \ + --hash=sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb \ + --hash=sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519 + # via + # readme-renderer + # rich +pynacl==1.5.0 \ + --hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \ + --hash=sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d \ + --hash=sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93 \ + --hash=sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1 \ + --hash=sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92 \ + --hash=sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff \ + --hash=sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba \ + --hash=sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394 \ + --hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \ + --hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543 + # via paramiko +pypsrp==0.8.1 \ + --hash=sha256:0101345ceb415896fed9b056e7b77d65312089ddc73c4286247ccf1859d4bc4d \ + --hash=sha256:f5500acd11dfe742d51b7fbb61321ba721038a300d67763dc52babe709db65e7 + # via -r contrib/automation/requirements.txt.in +pyspnego==0.5.2 \ + --hash=sha256:1fed228edc4b1730844da8237b90489be28c55681cf3934cd04fceb2253e55bf \ + --hash=sha256:25fbc90fc6bd16881480316739bab820cc91364765e46340da17f861f89691f1 \ + --hash=sha256:274b3a2d37e45ad4567bc5754be04b5fefad3f7cdea7d205f739d8a26b5a9189 \ + --hash=sha256:36db7ec38023a23a545114dfd23825639571f135c72fb4b13a1ed559a0a4d93c \ + --hash=sha256:3b1ff3c1d5588b66f8e4ebafa3079a7bf0bdcc6fb144b944c5a101e688a5a280 \ + --hash=sha256:4b9bda51bd964f40322aa1b33dcfc5d68f23b0680b4b5158175f2e9a04119aa9 \ + --hash=sha256:5d6d91e35ee63a5de30eb70716bf25274bf16c2c472b046dd21fad60fe63b0b6 \ + --hash=sha256:7562bc640bf402bb2849f325b0bb41260bd2c0cb06e38b9a8c6f7021b452c873 \ + --hash=sha256:9c5bdb9f0207e2ce9e5410ee2205bf016755712018534c711ae6c1daff7fa7db \ + --hash=sha256:a5c135d20819db3c48f65054d648317f369a61b7b22dc17b9e5ec9c0169541a0 \ + --hash=sha256:bd95633e7dce69e267579bdbe992fc081a14310236b4e84c3d179b1cf6439ca5 \ + --hash=sha256:eb41b970dbda0dfe07b1da6fc83fe9f534a66d8dea38c06c0155377697407d9a + # via pypsrp +python-dateutil==2.8.2 \ + --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \ + --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9 + # via botocore +readme-renderer==35.0 \ + --hash=sha256:73b84905d091c31f36e50b4ae05ae2acead661f6a09a9abb4df7d2ddcdb6a698 \ + --hash=sha256:a727999acfc222fc21d82a12ed48c957c4989785e5865807c65a487d21677497 + # via twine +requests==2.27.1 \ + --hash=sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61 \ + --hash=sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d + # via + # pypsrp + # requests-toolbelt + # twine +requests-toolbelt==0.9.1 \ + --hash=sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f \ + --hash=sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0 + # via twine +rfc3986==2.0.0 \ + --hash=sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd \ + --hash=sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c + # via twine +rich==12.3.0 \ + --hash=sha256:0eb63013630c6ee1237e0e395d51cb23513de6b5531235e33889e8842bdf3a6f \ + --hash=sha256:7e8700cda776337036a712ff0495b04052fb5f957c7dfb8df997f88350044b64 + # via twine +s3transfer==0.5.2 \ + --hash=sha256:7a6f4c4d1fdb9a2b640244008e142cbc2cd3ae34b386584ef044dd0f27101971 \ + --hash=sha256:95c58c194ce657a5f4fb0b9e60a84968c808888aed628cd98ab8771fe1db98ed + # via boto3 +secretstorage==3.3.2 \ + --hash=sha256:0a8eb9645b320881c222e827c26f4cfcf55363e8b374a021981ef886657a912f \ + --hash=sha256:755dc845b6ad76dcbcbc07ea3da75ae54bb1ea529eb72d15f83d26499a5df319 + # via keyring +six==1.16.0 \ + --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ + --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 + # via + # bleach + # paramiko + # python-dateutil +twine==4.0.0 \ + --hash=sha256:6f7496cf14a3a8903474552d5271c79c71916519edb42554f23f42a8563498a9 \ + --hash=sha256:817aa0c0bdc02a5ebe32051e168e23c71a0608334e624c793011f120dbbc05b7 + # via -r contrib/automation/requirements.txt.in +urllib3==1.26.9 \ + --hash=sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14 \ + --hash=sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e + # via + # botocore + # requests + # twine +webencodings==0.5.1 \ + --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \ + --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923 + # via bleach +zipp==3.8.0 \ + --hash=sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad \ + --hash=sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099 + # via importlib-metadata diff --git a/contrib/automation/requirements.txt.in b/contrib/automation/requirements.txt.in new file mode 100644 index 0000000..d58887b --- /dev/null +++ b/contrib/automation/requirements.txt.in @@ -0,0 +1,4 @@ +boto3 +paramiko +pypsrp +twine diff --git a/contrib/base-revsets.txt b/contrib/base-revsets.txt new file mode 100644 index 0000000..0bfa90b --- /dev/null +++ b/contrib/base-revsets.txt @@ -0,0 +1,52 @@ +# Base Revsets to be used with revsetbenchmarks.py script +# +# The goal of this file is to gather a limited amount of revsets that allow a +# good coverage of the internal revsets mechanisms. Revsets included should not +# be selected for their individual implementation, but for what they reveal of +# the internal implementation of smartsets classes (and their interactions). +# +# Use and update this file when you change internal implementation of these +# smartsets classes. Please include a comment explaining what each of your +# addition is testing. Also check if your changes to the smartset class makes +# some of the tests inadequate and replace them with a new one testing the same +# behavior. +# +# If you want to benchmark revsets predicate itself, check 'all-revsets.txt'. +# +# The current content of this file is currently likely not reaching this goal +# entirely, feel free, to audit its content and comment on each revset to +# highlight what internal mechanisms they test. + +all() +draft() +::tip +draft() and ::tip +::tip and draft() +0::tip +roots(0::tip) +author(lmoscovicz) +author(olivia) +author(lmoscovicz) or author(olivia) +author(olivia) or author(lmoscovicz) +tip:0 +0:: +# those two `roots(...)` inputs are close to what phase movement use. +roots((tip~100::) - (tip~100::tip)) +roots((0::) - (0::tip)) +42:68 and roots(42:tip) +::p1(p1(tip)):: +public() +:10000 and public() +draft() +:10000 and draft() +roots((0:tip)::) +(not public() - obsolete()) +(_intlist('20000\x0020001')) and merge() +parents(20000) +(20000::) - (20000) +# The one below is used by rebase +(children(ancestor(tip~5, tip)) and ::(tip~5)):: +heads(commonancestors(last(head(), 2))) +heads(-10000:-1) +roots(-10000:-1) +only(max(head()), min(head())) diff --git a/contrib/bash_completion b/contrib/bash_completion new file mode 100644 index 0000000..a3ab980 --- /dev/null +++ b/contrib/bash_completion @@ -0,0 +1,659 @@ +# bash completion for the Mercurial distributed SCM -*- sh -*- + +# Docs: +# +# If you source this file from your .bashrc, bash should be able to +# complete a command line that uses hg with all the available commands +# and options and sometimes even arguments. +# +# Mercurial allows you to define additional commands through extensions. +# Bash should be able to automatically figure out the name of these new +# commands and their options. See below for how to define _hg_opt_foo +# and _hg_cmd_foo functions to fine-tune the completion for option and +# non-option arguments, respectively. +# +# +# Notes about completion for specific commands: +# +# - the completion function for the email command from the patchbomb +# extension will try to call _hg_emails to get a list of e-mail +# addresses. It's up to the user to define this function. For +# example, put the addresses of the lists that you usually patchbomb +# in ~/.patchbomb-to and the addresses that you usually use to send +# the patchbombs in ~/.patchbomb-from and use something like this: +# +# _hg_emails() +# { +# if [ -r ~/.patchbomb-$1 ]; then +# cat ~/.patchbomb-$1 +# fi +# } +# +# +# Writing completion functions for additional commands: +# +# If it exists, the function _hg_cmd_foo will be called without +# arguments to generate the completion candidates for the hg command +# "foo". If the command receives some arguments that aren't options +# even though they start with a "-", you can define a function called +# _hg_opt_foo to generate the completion candidates. If _hg_opt_foo +# doesn't return 0, regular completion for options is attempted. +# +# In addition to the regular completion variables provided by bash, +# the following variables are also set: +# - $hg - the hg program being used (e.g. /usr/bin/hg) +# - $cmd - the name of the hg command being completed +# - $cmd_index - the index of $cmd in $COMP_WORDS +# - $cur - the current argument being completed +# - $prev - the argument before $cur +# - $global_args - "|"-separated list of global options that accept +# an argument (e.g. '--cwd|-R|--repository') +# - $canonical - 1 if we canonicalized $cmd before calling the function +# 0 otherwise +# + +shopt -s extglob + +_hg_cmd() +{ + HGPLAIN=1 "$hg" "$@" 2>/dev/null +} + +_hg_commands() +{ + local commands + commands="$(HGPLAINEXCEPT=alias _hg_cmd debugcomplete "$cur")" || commands="" + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$commands' -- "$cur")) +} + +_hg_paths() +{ + local paths="$(_hg_cmd paths -q)" + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$paths' -- "$cur")) +} + +_hg_repos() +{ + local i + for i in $(compgen -d -- "$cur"); do + test ! -d "$i"/.hg || COMPREPLY=(${COMPREPLY[@]:-} "$i") + done +} + +_hg_debugpathcomplete() +{ + local files="$(_hg_cmd debugpathcomplete $1 "$cur")" + local IFS=$'\n' + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur")) +} + +_hg_status() +{ + if [ -z "$HGCOMPLETE_NOSTATUS" ]; then + local files="$(_hg_cmd status -n$1 "glob:$cur**")" + local IFS=$'\n' + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur")) + fi +} + +_hg_branches() +{ + local branches="$(_hg_cmd branches -q)" + local IFS=$'\n' + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$branches' -- "$cur")) +} + +_hg_bookmarks() +{ + local bookmarks="$(_hg_cmd bookmarks -q)" + local IFS=$'\n' + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$bookmarks' -- "$cur")) +} + +_hg_labels() +{ + local labels="$(_hg_cmd debugnamecomplete "$cur")" + local IFS=$'\n' + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$labels' -- "$cur")) +} + +# this is "kind of" ugly... +_hg_count_non_option() +{ + local i count=0 + local filters="$1" + + for ((i=1; $i<=$COMP_CWORD; i++)); do + if [[ "${COMP_WORDS[i]}" != -* ]]; then + if [[ ${COMP_WORDS[i-1]} == @($filters|$global_args) ]]; then + continue + fi + count=$(($count + 1)) + fi + done + + echo $(($count - 1)) +} + +_hg_fix_wordlist() +{ + local LASTCHAR=' ' + if [ ${#COMPREPLY[@]} = 1 ]; then + [ -d "$COMPREPLY" ] && LASTCHAR=/ + COMPREPLY=$(printf %q%s "$COMPREPLY" "$LASTCHAR") + else + for ((i=0; i < ${#COMPREPLY[@]}; i++)); do + [ -d "${COMPREPLY[$i]}" ] && COMPREPLY[$i]=${COMPREPLY[$i]}/ + done + fi +} + +_hg() +{ + local cur prev cmd cmd_index opts i aliashg + # global options that receive an argument + local global_args='--cwd|-R|--repository|--color|--config|--encoding|--encodingmode|--pager' + local hg="$1" + local canonical=0 + + aliashg=$(alias $hg 2>/dev/null) + if [[ -n "$aliashg" ]]; then + aliashg=${aliashg#"alias $hg='"} + aliashg=${aliashg%"'"} + # `source`d aliases break completion, so ignore them + if [[ "${aliashg:0:7}" != "source " ]]; then + hg=$aliashg + fi + fi + + COMPREPLY=() + cur="$2" + prev="$3" + + # searching for the command + # (first non-option argument that doesn't follow a global option that + # receives an argument) + for ((i=1; $i<=$COMP_CWORD; i++)); do + if [[ ${COMP_WORDS[i]} != -* ]]; then + if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then + cmd="${COMP_WORDS[i]}" + cmd_index=$i + break + fi + fi + done + + if [[ "$cur" == -* ]]; then + if [ "$(type -t "_hg_opt_$cmd")" = function ] && "_hg_opt_$cmd"; then + _hg_fix_wordlist + return + fi + + opts=$(HGPLAINEXCEPT=alias _hg_cmd debugcomplete --options "$cmd") + + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$opts' -- "$cur")) + _hg_fix_wordlist + return + fi + + # global options + case "$prev" in + -R|--repository) + _hg_paths + _hg_repos + _hg_fix_wordlist + return + ;; + --cwd) + # Stick with default bash completion + _hg_fix_wordlist + return + ;; + --color) + local choices='true false yes no always auto never debug' + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$choices' -- "$cur")) + _hg_fix_wordlist + return + ;; + --pager) + local choices='true false yes no always auto never' + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$choices' -- "$cur")) + _hg_fix_wordlist + return + ;; + esac + + if [ -z "$cmd" ] || [ $COMP_CWORD -eq $i ]; then + _hg_commands + _hg_fix_wordlist + return + fi + + # try to generate completion candidates for whatever command the user typed + local help + if _hg_command_specific; then + _hg_fix_wordlist + return + fi + + # canonicalize the command name and try again + help=$(_hg_cmd help "$cmd") + if [ $? -ne 0 ]; then + # Probably either the command doesn't exist or it's ambiguous + return + fi + cmd=${help#hg } + cmd=${cmd%%[$' \n']*} + canonical=1 + _hg_command_specific + _hg_fix_wordlist +} + +_hg_command_specific() +{ + if [ "$(type -t "_hg_cmd_$cmd")" = function ]; then + "_hg_cmd_$cmd" + return 0 + fi + + if [ "$cmd" != status ]; then + case "$prev" in + -r|--rev) + if [[ $canonical = 1 || status != "$cmd"* ]]; then + _hg_labels + return 0 + fi + return 1 + ;; + -B|--bookmark) + if [[ $canonical = 1 || status != "$cmd"* ]]; then + _hg_bookmarks + return 0 + fi + return 1 + ;; + -b|--branch) + if [[ $canonical = 1 || status != "$cmd"* ]]; then + _hg_branches + return 0 + fi + return 1 + ;; + esac + fi + + local aliascmd=$(_hg_cmd showconfig alias.$cmd | awk '{print $1}') + [ -n "$aliascmd" ] && cmd=$aliascmd + + case "$cmd" in + help) + _hg_commands + ;; + export) + if _hg_ext_mq_patchlist qapplied && [ "${COMPREPLY[*]}" ]; then + return 0 + fi + _hg_labels + ;; + manifest|update|up|checkout|co) + _hg_labels + ;; + pull|push|outgoing|incoming) + _hg_paths + _hg_repos + ;; + paths) + _hg_paths + ;; + add) + _hg_status "u" + ;; + merge) + _hg_labels + ;; + commit|ci|record|amend) + _hg_status "mar" + ;; + remove|rm) + _hg_debugpathcomplete -n + ;; + forget) + _hg_debugpathcomplete -fa + ;; + diff) + _hg_status "mar" + ;; + revert) + _hg_status "mard" + ;; + clone) + local count=$(_hg_count_non_option) + if [ $count = 1 ]; then + _hg_paths + fi + _hg_repos + ;; + debugindex|debugindexdot) + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.i" -- "$cur")) + ;; + debugdata) + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -f -X "!*.d" -- "$cur")) + ;; + *) + return 1 + ;; + esac + + return 0 +} + +complete -o bashdefault -o default -o nospace -F _hg hg \ + || complete -o default -o nospace -F _hg hg + + +# Completion for commands provided by extensions + +# bookmarks +_hg_cmd_bookmarks() +{ + _hg_bookmarks + return +} + +# mq +_hg_ext_mq_patchlist() +{ + local patches + patches=$(_hg_cmd $1) + if [ $? -eq 0 ] && [ "$patches" ]; then + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$patches' -- "$cur")) + return 0 + fi + return 1 +} + +_hg_ext_mq_queues() +{ + local root=$(_hg_cmd root) + local n + for n in $(cd "$root"/.hg && compgen -d -- "$cur"); do + # I think we're usually not interested in the regular "patches" queue + # so just filter it. + if [ "$n" != patches ] && [ -e "$root/.hg/$n/series" ]; then + COMPREPLY=(${COMPREPLY[@]:-} "$n") + fi + done +} + +_hg_cmd_qpop() +{ + if [[ "$prev" = @(-n|--name) ]]; then + _hg_ext_mq_queues + return + fi + _hg_ext_mq_patchlist qapplied +} + +_hg_cmd_qpush() +{ + if [[ "$prev" = @(-n|--name) ]]; then + _hg_ext_mq_queues + return + fi + _hg_ext_mq_patchlist qunapplied +} + +_hg_cmd_qgoto() +{ + if [[ "$prev" = @(-n|--name) ]]; then + _hg_ext_mq_queues + return + fi + _hg_ext_mq_patchlist qseries +} + +_hg_cmd_qdelete() +{ + local qcmd=qunapplied + if [[ "$prev" = @(-r|--rev) ]]; then + qcmd=qapplied + fi + _hg_ext_mq_patchlist $qcmd +} + +_hg_cmd_qfinish() +{ + if [[ "$prev" = @(-a|--applied) ]]; then + return + fi + _hg_ext_mq_patchlist qapplied +} + +_hg_cmd_qsave() +{ + if [[ "$prev" = @(-n|--name) ]]; then + _hg_ext_mq_queues + return + fi +} + +_hg_cmd_rebase() { + if [[ "$prev" = @(-s|--source|-d|--dest|-b|--base|-r|--rev) ]]; then + _hg_labels + return + fi +} + +_hg_cmd_strip() +{ + if [[ "$prev" = @(-B|--bookmark) ]]; then + _hg_bookmarks + return + fi + _hg_labels +} + +_hg_cmd_qcommit() +{ + local root=$(_hg_cmd root) + # this is run in a sub-shell, so we can't use _hg_status + local files=$(cd "$root/.hg/patches" && _hg_cmd status -nmar) + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$files' -- "$cur")) +} + +_hg_cmd_qfold() +{ + _hg_ext_mq_patchlist qunapplied +} + +_hg_cmd_qrename() +{ + _hg_ext_mq_patchlist qseries +} + +_hg_cmd_qheader() +{ + _hg_ext_mq_patchlist qseries +} + +_hg_cmd_qclone() +{ + local count=$(_hg_count_non_option) + if [ $count = 1 ]; then + _hg_paths + fi + _hg_repos +} + +_hg_ext_mq_guards() +{ + _hg_cmd qselect --series | sed -e 's/^.//' +} + +_hg_cmd_qselect() +{ + local guards=$(_hg_ext_mq_guards) + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$guards' -- "$cur")) +} + +_hg_cmd_qguard() +{ + local prefix='' + + if [[ "$cur" == +* ]]; then + prefix=+ + elif [[ "$cur" == -* ]]; then + prefix=- + fi + local ncur=${cur#[-+]} + + if ! [ "$prefix" ]; then + _hg_ext_mq_patchlist qseries + return + fi + + local guards=$(_hg_ext_mq_guards) + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -P $prefix -W '$guards' -- "$ncur")) +} + +_hg_opt_qguard() +{ + local i + for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do + if [[ ${COMP_WORDS[i]} != -* ]]; then + if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then + _hg_cmd_qguard + return 0 + fi + elif [ "${COMP_WORDS[i]}" = -- ]; then + _hg_cmd_qguard + return 0 + fi + done + return 1 +} + +_hg_cmd_qqueue() +{ + local q + local queues + local opts="--list --create --rename --delete --purge" + + queues=$( _hg_cmd qqueue --quiet ) + + COMPREPLY=( $( compgen -W "${opts} ${queues}" "${cur}" ) ) +} + + +# hbisect +_hg_cmd_bisect() +{ + local i subcmd + + # find the sub-command + for ((i=cmd_index+1; i<=COMP_CWORD; i++)); do + if [[ ${COMP_WORDS[i]} != -* ]]; then + if [[ ${COMP_WORDS[i-1]} != @($global_args) ]]; then + subcmd="${COMP_WORDS[i]}" + break + fi + fi + done + + if [ -z "$subcmd" ] || [ $COMP_CWORD -eq $i ] || [ "$subcmd" = help ]; then + COMPREPLY=(${COMPREPLY[@]:-} + $(compgen -W 'bad good help init next reset' -- "$cur")) + return + fi + + case "$subcmd" in + good|bad) + _hg_labels + ;; + esac + + return +} + + +# patchbomb +_hg_cmd_email() +{ + case "$prev" in + -c|--cc|-t|--to|-f|--from|--bcc) + # we need an e-mail address. let the user provide a function + # to get them + if [ "$(type -t _hg_emails)" = function ]; then + local arg=to + if [[ "$prev" == @(-f|--from) ]]; then + arg=from + fi + local addresses=$(_hg_emails $arg) + COMPREPLY=(${COMPREPLY[@]:-} + $(compgen -W '$addresses' -- "$cur")) + fi + return + ;; + -m|--mbox) + # fallback to standard filename completion + return + ;; + -s|--subject) + # free form string + return + ;; + esac + + _hg_labels + return +} + + +# gpg +_hg_cmd_sign() +{ + _hg_labels +} + + +# transplant +_hg_cmd_transplant() +{ + case "$prev" in + -s|--source) + _hg_paths + _hg_repos + return + ;; + --filter) + # standard filename completion + return + ;; + esac + + # all other transplant options values and command parameters are revisions + _hg_labels + return +} + +# shelve +_hg_shelves() +{ + local shelves="$(_hg_cmd shelve -ql)" + local IFS=$'\n' + COMPREPLY=(${COMPREPLY[@]:-} $(compgen -W '$shelves' -- "$cur")) +} + +_hg_cmd_shelve() +{ + if [[ "$prev" = @(-d|--delete|-l|--list|-p|--patch|--stat) ]]; then + _hg_shelves + else + _hg_status "mard" + fi +} + +_hg_cmd_unshelve() +{ + _hg_shelves +} diff --git a/contrib/bdiff-torture.py b/contrib/bdiff-torture.py new file mode 100644 index 0000000..36717bd --- /dev/null +++ b/contrib/bdiff-torture.py @@ -0,0 +1,107 @@ +# Randomized torture test generation for bdiff + +import random +import sys + +from mercurial import ( + mdiff, + pycompat, +) + + +def reducetest(a, b): + tries = 0 + reductions = 0 + print("reducing...") + while tries < 1000: + a2 = ( + "\n".join(l for l in a.splitlines() if random.randint(0, 100) > 0) + + "\n" + ) + b2 = ( + "\n".join(l for l in b.splitlines() if random.randint(0, 100) > 0) + + "\n" + ) + if a2 == a and b2 == b: + continue + if a2 == b2: + continue + tries += 1 + + try: + test1(a, b) + except Exception: + reductions += 1 + tries = 0 + a = a2 + b = b2 + + print("reduced:", reductions, len(a) + len(b), repr(a), repr(b)) + try: + test1(a, b) + except Exception as inst: + print("failed:", inst) + + sys.exit(0) + + +def test1(a, b): + d = mdiff.textdiff(a, b) + if not d: + raise ValueError("empty") + c = mdiff.patches(a, [d]) + if c != b: + raise ValueError("bad") + + +def testwrap(a, b): + try: + test1(a, b) + return + except Exception as inst: + print("exception:", inst) + reducetest(a, b) + + +def test(a, b): + testwrap(a, b) + testwrap(b, a) + + +def rndtest(size, noise): + a = [] + src = " aaaaaaaabbbbccd" + for x in pycompat.xrange(size): + a.append(src[random.randint(0, len(src) - 1)]) + + while True: + b = [c for c in a if random.randint(0, 99) > noise] + b2 = [] + for c in b: + b2.append(c) + while random.randint(0, 99) < noise: + b2.append(src[random.randint(0, len(src) - 1)]) + if b2 != a: + break + + a = "\n".join(a) + "\n" + b = "\n".join(b2) + "\n" + + test(a, b) + + +maxvol = 10000 +startsize = 2 +while True: + size = startsize + count = 0 + while size < maxvol: + print(size) + volume = 0 + while volume < maxvol: + rndtest(size, 2) + volume += size + count += 2 + size *= 2 + maxvol *= 4 + startsize *= 4 diff --git a/contrib/benchmarks/__init__.py b/contrib/benchmarks/__init__.py new file mode 100644 index 0000000..7b57cfd --- /dev/null +++ b/contrib/benchmarks/__init__.py @@ -0,0 +1,124 @@ +# __init__.py - asv benchmark suite +# +# Copyright 2016 Logilab SA +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +# "historical portability" policy of contrib/benchmarks: +# +# We have to make this code work correctly with current mercurial stable branch +# and if possible with reasonable cost with early Mercurial versions. + +'''ASV (https://asv.readthedocs.io) benchmark suite + +Benchmark are parameterized against reference repositories found in the +directory pointed by the REPOS_DIR environment variable. + +Invocation example: + + $ export REPOS_DIR=~/hgperf/repos + # run suite on given revision + $ asv --config contrib/asv.conf.json run REV + # run suite on new changesets found in stable and default branch + $ asv --config contrib/asv.conf.json run NEW + # display a comparative result table of benchmark results between two given + # revisions + $ asv --config contrib/asv.conf.json compare REV1 REV2 + # compute regression detection and generate ASV static website + $ asv --config contrib/asv.conf.json publish + # serve the static website + $ asv --config contrib/asv.conf.json preview +''' + + +import functools +import os +import re + +from mercurial import ( + extensions, + hg, + ui as uimod, +) + +basedir = os.path.abspath( + os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir) +) +reposdir = os.environ['REPOS_DIR'] +reposnames = [ + name + for name in os.listdir(reposdir) + if os.path.isdir(os.path.join(reposdir, name, ".hg")) +] +if not reposnames: + raise ValueError("No repositories found in $REPO_DIR") +outputre = re.compile( + ( + r'! wall (\d+.\d+) comb \d+.\d+ user \d+.\d+ sys ' + r'\d+.\d+ \(best of \d+\)' + ) +) + + +def runperfcommand(reponame, command, *args, **kwargs): + os.environ["HGRCPATH"] = os.environ.get("ASVHGRCPATH", "") + # for "historical portability" + # ui.load() has been available since d83ca85 + if hasattr(uimod.ui, "load"): + ui = uimod.ui.load() + else: + ui = uimod.ui() + repo = hg.repository(ui, os.path.join(reposdir, reponame)) + perfext = extensions.load( + ui, 'perfext', os.path.join(basedir, 'contrib', 'perf.py') + ) + cmd = getattr(perfext, command) + ui.pushbuffer() + cmd(ui, repo, *args, **kwargs) + output = ui.popbuffer() + match = outputre.search(output) + if not match: + raise ValueError("Invalid output {}".format(output)) + return float(match.group(1)) + + +def perfbench(repos=reposnames, name=None, params=None): + """decorator to declare ASV benchmark based on contrib/perf.py extension + + An ASV benchmark is a python function with the given attributes: + + __name__: should start with track_, time_ or mem_ to be collected by ASV + params and param_name: parameter matrix to display multiple graphs on the + same page. + pretty_name: If defined it's displayed in web-ui instead of __name__ + (useful for revsets) + the module name is prepended to the benchmark name and displayed as + "category" in webui. + + Benchmarks are automatically parameterized with repositories found in the + REPOS_DIR environment variable. + + `params` is the param matrix in the form of a list of tuple + (param_name, [value0, value1]) + + For example [(x, [a, b]), (y, [c, d])] declare benchmarks for + (a, c), (a, d), (b, c) and (b, d). + """ + params = list(params or []) + params.insert(0, ("repo", repos)) + + def decorator(func): + @functools.wraps(func) + def wrapped(repo, *args): + def perf(command, *a, **kw): + return runperfcommand(repo, command, *a, **kw) + + return func(perf, *args) + + wrapped.params = [p[1] for p in params] + wrapped.param_names = [p[0] for p in params] + wrapped.pretty_name = name + return wrapped + + return decorator diff --git a/contrib/benchmarks/perf.py b/contrib/benchmarks/perf.py new file mode 100644 index 0000000..0b1fc41 --- /dev/null +++ b/contrib/benchmarks/perf.py @@ -0,0 +1,29 @@ +# perf.py - asv benchmarks using contrib/perf.py extension +# +# Copyright 2016 Logilab SA +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + + +from . import perfbench + + +@perfbench() +def track_tags(perf): + return perf("perftags") + + +@perfbench() +def track_status(perf): + return perf("perfstatus", unknown=False) + + +@perfbench(params=[('rev', ['1000', '10000', 'tip'])]) +def track_manifest(perf, rev): + return perf("perfmanifest", rev) + + +@perfbench() +def track_heads(perf): + return perf("perfheads") diff --git a/contrib/benchmarks/revset.py b/contrib/benchmarks/revset.py new file mode 100644 index 0000000..fc41119 --- /dev/null +++ b/contrib/benchmarks/revset.py @@ -0,0 +1,56 @@ +# revset.py - asv revset benchmarks +# +# Copyright 2016 Logilab SA +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +'''ASV revset benchmarks generated from contrib/base-revsets.txt + +Each revset benchmark is parameterized with variants (first, last, sort, ...) +''' + + +import os +import string +import sys + +from . import basedir, perfbench + + +def createrevsetbenchmark(baseset, variants=None): + if variants is None: + # Default variants + variants = ["plain", "first", "last", "sort", "sort+first", "sort+last"] + fname = "track_" + "_".join( + "".join( + [c if c in string.digits + string.letters else " " for c in baseset] + ).split() + ) + + def wrap(fname, baseset): + @perfbench(name=baseset, params=[("variant", variants)]) + def f(perf, variant): + revset = baseset + if variant != "plain": + for var in variant.split("+"): + revset = "%s(%s)" % (var, revset) + return perf("perfrevset", revset) + + f.__name__ = fname + return f + + return wrap(fname, baseset) + + +def initializerevsetbenchmarks(): + mod = sys.modules[__name__] + with open(os.path.join(basedir, 'contrib', 'base-revsets.txt'), 'rb') as fh: + for line in fh: + baseset = line.strip() + if baseset and not baseset.startswith('#'): + func = createrevsetbenchmark(baseset) + setattr(mod, func.__name__, func) + + +initializerevsetbenchmarks() diff --git a/contrib/byteify-strings.py b/contrib/byteify-strings.py new file mode 100755 index 0000000..219e11a --- /dev/null +++ b/contrib/byteify-strings.py @@ -0,0 +1,338 @@ +#!/usr/bin/env python3 +# +# byteify-strings.py - transform string literals to be Python 3 safe +# +# Copyright 2015 Gregory Szorc +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + + +import argparse +import contextlib +import errno +import os +import sys +import tempfile +import token +import tokenize + + +def adjusttokenpos(t, ofs): + """Adjust start/end column of the given token""" + return t._replace( + start=(t.start[0], t.start[1] + ofs), end=(t.end[0], t.end[1] + ofs) + ) + + +def replacetokens(tokens, opts): + """Transform a stream of tokens from raw to Python 3. + + Returns a generator of possibly rewritten tokens. + + The input token list may be mutated as part of processing. However, + its changes do not necessarily match the output token stream. + """ + sysstrtokens = set() + + # The following utility functions access the tokens list and i index of + # the for i, t enumerate(tokens) loop below + def _isop(j, *o): + """Assert that tokens[j] is an OP with one of the given values""" + try: + return tokens[j].type == token.OP and tokens[j].string in o + except IndexError: + return False + + def _findargnofcall(n): + """Find arg n of a call expression (start at 0) + + Returns index of the first token of that argument, or None if + there is not that many arguments. + + Assumes that token[i + 1] is '('. + + """ + nested = 0 + for j in range(i + 2, len(tokens)): + if _isop(j, ')', ']', '}'): + # end of call, tuple, subscription or dict / set + nested -= 1 + if nested < 0: + return None + elif n == 0: + # this is the starting position of arg + return j + elif _isop(j, '(', '[', '{'): + nested += 1 + elif _isop(j, ',') and nested == 0: + n -= 1 + + return None + + def _ensuresysstr(j): + """Make sure the token at j is a system string + + Remember the given token so the string transformer won't add + the byte prefix. + + Ignores tokens that are not strings. Assumes bounds checking has + already been done. + + """ + k = j + currtoken = tokens[k] + while currtoken.type in (token.STRING, token.NEWLINE, tokenize.NL): + k += 1 + if currtoken.type == token.STRING and currtoken.string.startswith( + ("'", '"') + ): + sysstrtokens.add(currtoken) + try: + currtoken = tokens[k] + except IndexError: + break + + def _isitemaccess(j): + """Assert the next tokens form an item access on `tokens[j]` and that + `tokens[j]` is a name. + """ + try: + return ( + tokens[j].type == token.NAME + and _isop(j + 1, '[') + and tokens[j + 2].type == token.STRING + and _isop(j + 3, ']') + ) + except IndexError: + return False + + def _ismethodcall(j, *methodnames): + """Assert the next tokens form a call to `methodname` with a string + as first argument on `tokens[j]` and that `tokens[j]` is a name. + """ + try: + return ( + tokens[j].type == token.NAME + and _isop(j + 1, '.') + and tokens[j + 2].type == token.NAME + and tokens[j + 2].string in methodnames + and _isop(j + 3, '(') + and tokens[j + 4].type == token.STRING + ) + except IndexError: + return False + + coldelta = 0 # column increment for new opening parens + coloffset = -1 # column offset for the current line (-1: TBD) + parens = [(0, 0, 0, -1)] # stack of (line, end-column, column-offset, type) + ignorenextline = False # don't transform the next line + insideignoreblock = False # don't transform until turned off + for i, t in enumerate(tokens): + # Compute the column offset for the current line, such that + # the current line will be aligned to the last opening paren + # as before. + if coloffset < 0: + lastparen = parens[-1] + if t.start[1] == lastparen[1]: + coloffset = lastparen[2] + elif t.start[1] + 1 == lastparen[1] and lastparen[3] not in ( + token.NEWLINE, + tokenize.NL, + ): + # fix misaligned indent of s/util.Abort/error.Abort/ + coloffset = lastparen[2] + (lastparen[1] - t.start[1]) + else: + coloffset = 0 + + # Reset per-line attributes at EOL. + if t.type in (token.NEWLINE, tokenize.NL): + yield adjusttokenpos(t, coloffset) + coldelta = 0 + coloffset = -1 + if not insideignoreblock: + ignorenextline = ( + tokens[i - 1].type == token.COMMENT + and tokens[i - 1].string == "# no-py3-transform" + ) + continue + + if t.type == token.COMMENT: + if t.string == "# py3-transform: off": + insideignoreblock = True + if t.string == "# py3-transform: on": + insideignoreblock = False + + if ignorenextline or insideignoreblock: + yield adjusttokenpos(t, coloffset) + continue + + # Remember the last paren position. + if _isop(i, '(', '[', '{'): + parens.append(t.end + (coloffset + coldelta, tokens[i + 1].type)) + elif _isop(i, ')', ']', '}'): + parens.pop() + + # Convert most string literals to byte literals. String literals + # in Python 2 are bytes. String literals in Python 3 are unicode. + # Most strings in Mercurial are bytes and unicode strings are rare. + # Rather than rewrite all string literals to use ``b''`` to indicate + # byte strings, we apply this token transformer to insert the ``b`` + # prefix nearly everywhere. + if t.type == token.STRING and t not in sysstrtokens: + s = t.string + + # Preserve docstrings as string literals. This is inconsistent + # with regular unprefixed strings. However, the + # "from __future__" parsing (which allows a module docstring to + # exist before it) doesn't properly handle the docstring if it + # is b''' prefixed, leading to a SyntaxError. We leave all + # docstrings as unprefixed to avoid this. This means Mercurial + # components touching docstrings need to handle unicode, + # unfortunately. + if s[0:3] in ("'''", '"""'): + # If it's assigned to something, it's not a docstring + if not _isop(i - 1, '='): + yield adjusttokenpos(t, coloffset) + continue + + # If the first character isn't a quote, it is likely a string + # prefixing character (such as 'b', 'u', or 'r'. Ignore. + if s[0] not in ("'", '"'): + yield adjusttokenpos(t, coloffset) + continue + + # String literal. Prefix to make a b'' string. + yield adjusttokenpos(t._replace(string='b%s' % t.string), coloffset) + coldelta += 1 + continue + + # This looks like a function call. + if t.type == token.NAME and _isop(i + 1, '('): + fn = t.string + + # *attr() builtins don't accept byte strings to 2nd argument. + if fn in ( + 'getattr', + 'setattr', + 'hasattr', + 'safehasattr', + 'wrapfunction', + 'wrapclass', + 'addattr', + ): + arg1idx = _findargnofcall(1) + if arg1idx is not None: + _ensuresysstr(arg1idx) + + # .encode() and .decode() on str/bytes/unicode don't accept + # byte strings on Python 3. + elif fn in ('encode', 'decode') and _isop(i - 1, '.'): + for argn in range(2): + argidx = _findargnofcall(argn) + if argidx is not None: + _ensuresysstr(argidx) + + # It changes iteritems/values to items/values as they are not + # present in Python 3 world. + elif opts['dictiter'] and fn in ('iteritems', 'itervalues'): + yield adjusttokenpos(t._replace(string=fn[4:]), coloffset) + continue + + if t.type == token.NAME and t.string in opts['treat-as-kwargs']: + if _isitemaccess(i): + _ensuresysstr(i + 2) + if _ismethodcall(i, 'get', 'pop', 'setdefault', 'popitem'): + _ensuresysstr(i + 4) + + # Looks like "if __name__ == '__main__'". + if ( + t.type == token.NAME + and t.string == '__name__' + and _isop(i + 1, '==') + ): + _ensuresysstr(i + 2) + + # Emit unmodified token. + yield adjusttokenpos(t, coloffset) + + +def process(fin, fout, opts): + tokens = tokenize.tokenize(fin.readline) + tokens = replacetokens(list(tokens), opts) + fout.write(tokenize.untokenize(tokens)) + + +def tryunlink(fname): + try: + os.unlink(fname) + except OSError as err: + if err.errno != errno.ENOENT: + raise + + +@contextlib.contextmanager +def editinplace(fname): + n = os.path.basename(fname) + d = os.path.dirname(fname) + fp = tempfile.NamedTemporaryFile( + prefix='.%s-' % n, suffix='~', dir=d, delete=False + ) + try: + yield fp + fp.close() + if os.name == 'nt': + tryunlink(fname) + os.rename(fp.name, fname) + finally: + fp.close() + tryunlink(fp.name) + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument( + '--version', action='version', version='Byteify strings 1.0' + ) + ap.add_argument( + '-i', + '--inplace', + action='store_true', + default=False, + help='edit files in place', + ) + ap.add_argument( + '--dictiter', + action='store_true', + default=False, + help='rewrite iteritems() and itervalues()', + ), + ap.add_argument( + '--treat-as-kwargs', + nargs="+", + default=[], + help="ignore kwargs-like objects", + ), + ap.add_argument('files', metavar='FILE', nargs='+', help='source file') + args = ap.parse_args() + opts = { + 'dictiter': args.dictiter, + 'treat-as-kwargs': set(args.treat_as_kwargs), + } + for fname in args.files: + fname = os.path.realpath(fname) + if args.inplace: + with editinplace(fname) as fout: + with open(fname, 'rb') as fin: + process(fin, fout, opts) + else: + with open(fname, 'rb') as fin: + fout = sys.stdout.buffer + process(fin, fout, opts) + + +if __name__ == '__main__': + if sys.version_info[0:2] < (3, 7): + print('This script must be run under Python 3.7+') + sys.exit(3) + main() diff --git a/contrib/casesmash.py b/contrib/casesmash.py new file mode 100644 index 0000000..c8af16c --- /dev/null +++ b/contrib/casesmash.py @@ -0,0 +1,40 @@ +import __builtin__ +import os +from mercurial import util + + +def lowerwrap(scope, funcname): + f = getattr(scope, funcname) + + def wrap(fname, *args, **kwargs): + d, base = os.path.split(fname) + try: + files = os.listdir(d or '.') + except OSError: + files = [] + if base in files: + return f(fname, *args, **kwargs) + for fn in files: + if fn.lower() == base.lower(): + return f(os.path.join(d, fn), *args, **kwargs) + return f(fname, *args, **kwargs) + + scope.__dict__[funcname] = wrap + + +def normcase(path): + return path.lower() + + +os.path.normcase = normcase + +for f in 'file open'.split(): + lowerwrap(__builtin__, f) + +for f in "chmod chown open lstat stat remove unlink".split(): + lowerwrap(os, f) + +for f in "exists lexists".split(): + lowerwrap(os.path, f) + +lowerwrap(util, 'posixfile') diff --git a/contrib/catapipe.py b/contrib/catapipe.py new file mode 100755 index 0000000..1400a10 --- /dev/null +++ b/contrib/catapipe.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +# +# Copyright 2018 Google LLC. +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. +"""Tool read primitive events from a pipe to produce a catapult trace. + +Usage: + Terminal 1: $ catapipe.py /tmp/mypipe /tmp/trace.json + Terminal 2: $ HGCATAPULTSERVERPIPE=/tmp/mypipe hg root + + $ catapult/tracing/bin/trace2html /tmp/trace.json # produce /tmp/trace.html + + (catapult is located at https://github.com/catapult-project/catapult) + +For now the event stream supports + + START $SESSIONID ... + +and + + END $SESSIONID ... + +events. Everything after the SESSIONID (which must not contain spaces) +is used as a label for the event. Events are timestamped as of when +they arrive in this process and are then used to produce catapult +traces that can be loaded in Chrome's about:tracing utility. It's +important that the event stream *into* this process stay simple, +because we have to emit it from the shell scripts produced by +run-tests.py. + +Typically you'll want to place the path to the named pipe in the +HGCATAPULTSERVERPIPE environment variable, which both run-tests and hg +understand. To trace *only* run-tests, use HGTESTCATAPULTSERVERPIPE instead. +""" + +import argparse +import json +import os +import timeit + +_TYPEMAP = { + 'START': 'B', + 'END': 'E', + 'COUNTER': 'C', +} + +_threadmap = {} + +# Timeit already contains the whole logic about which timer to use based on +# Python version and OS +timer = timeit.default_timer + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument( + 'pipe', + type=str, + nargs=1, + help='Path of named pipe to create and listen on.', + ) + parser.add_argument( + 'output', + default='trace.json', + type=str, + nargs='?', + help='Path of json file to create where the traces ' 'will be stored.', + ) + parser.add_argument( + '--debug', + default=False, + action='store_true', + help='Print useful debug messages', + ) + args = parser.parse_args() + fn = args.pipe[0] + os.mkfifo(fn) + try: + with open(fn) as f, open(args.output, 'w') as out: + out.write('[\n') + start = timer() + while True: + ev = f.readline().strip() + if not ev: + continue + now = timer() + if args.debug: + print(ev) + verb, session, label = ev.split(' ', 2) + if session not in _threadmap: + _threadmap[session] = len(_threadmap) + if verb == 'COUNTER': + amount, label = label.split(' ', 1) + payload_args = {'value': int(amount)} + else: + payload_args = {} + pid = _threadmap[session] + ts_micros = (now - start) * 1000000 + out.write( + json.dumps( + { + "name": label, + "cat": "misc", + "ph": _TYPEMAP[verb], + "ts": ts_micros, + "pid": pid, + "tid": 1, + "args": payload_args, + } + ) + ) + out.write(',\n') + finally: + os.unlink(fn) + + +if __name__ == '__main__': + main() diff --git a/contrib/check-code.py b/contrib/check-code.py new file mode 100755 index 0000000..cc57a5f --- /dev/null +++ b/contrib/check-code.py @@ -0,0 +1,1083 @@ +#!/usr/bin/env python3 +# +# check-code - a style and portability checker for Mercurial +# +# Copyright 2010 Olivia Mackall +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +"""style and portability checker for Mercurial + +when a rule triggers wrong, do one of the following (prefer one from top): + * do the work-around the rule suggests + * doublecheck that it is a false match + * improve the rule pattern + * add an ignore pattern to the rule (3rd arg) which matches your good line + (you can append a short comment and match this, like: #re-raises) + * change the pattern to a warning and list the exception in test-check-code-hg + * ONLY use no--check-code for skipping entire files from external sources +""" + +import glob +import keyword +import optparse +import os +import re +import sys + +if sys.version_info[0] < 3: + opentext = open +else: + + def opentext(f): + return open(f, encoding='latin1') + + +try: + xrange +except NameError: + xrange = range +try: + import re2 +except ImportError: + re2 = None + +import testparseutil + + +def compilere(pat, multiline=False): + if multiline: + pat = '(?m)' + pat + if re2: + try: + return re2.compile(pat) + except re2.error: + pass + return re.compile(pat) + + +# check "rules depending on implementation of repquote()" in each +# patterns (especially pypats), before changing around repquote() +_repquotefixedmap = { + ' ': ' ', + '\n': '\n', + '.': 'p', + ':': 'q', + '%': '%', + '\\': 'b', + '*': 'A', + '+': 'P', + '-': 'M', +} + + +def _repquoteencodechr(i): + if i > 255: + return 'u' + c = chr(i) + if c in _repquotefixedmap: + return _repquotefixedmap[c] + if c.isalpha(): + return 'x' + if c.isdigit(): + return 'n' + return 'o' + + +_repquotett = ''.join(_repquoteencodechr(i) for i in xrange(256)) + + +def repquote(m): + t = m.group('text') + t = t.translate(_repquotett) + return m.group('quote') + t + m.group('quote') + + +def reppython(m): + comment = m.group('comment') + if comment: + l = len(comment.rstrip()) + return "#" * l + comment[l:] + return repquote(m) + + +def repcomment(m): + return m.group(1) + "#" * len(m.group(2)) + + +def repccomment(m): + t = re.sub(r"((?<=\n) )|\S", "x", m.group(2)) + return m.group(1) + t + "*/" + + +def repcallspaces(m): + t = re.sub(r"\n\s+", "\n", m.group(2)) + return m.group(1) + t + + +def repinclude(m): + return m.group(1) + "" + + +def rephere(m): + t = re.sub(r"\S", "x", m.group(2)) + return m.group(1) + t + + +testpats = [ + [ + (r'\b(push|pop)d\b', "don't use 'pushd' or 'popd', use 'cd'"), + (r'\W\$?\(\([^\)\n]*\)\)', "don't use (()) or $(()), use 'expr'"), + (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"), + (r'(?'"), + (r'sha1sum', "don't use sha1sum, use $TESTDIR/md5sum.py"), + (r'\bls\b.*-\w*R', "don't use 'ls -R', use 'find'"), + (r'printf.*[^\\]\\([1-9]|0\d)', r"don't use 'printf \NNN', use Python"), + (r'printf.*[^\\]\\x', "don't use printf \\x, use Python"), + (r'rm -rf \*', "don't use naked rm -rf, target a directory"), + ( + r'\[[^\]]+==', + '[ foo == bar ] is a bashism, use [ foo = bar ] instead', + ), + (r'(^|\|\s*)egrep', "use grep -E for extended grep syntax"), + (r'(^|\|\s*)fgrep', "use grep -F for fixed string grepping"), + (r'(^|\|\s*)e?grep .*\\S', "don't use \\S in regular expression"), + (r'(?\n]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"), + (r'^stop\(\)', "don't use 'stop' as a shell function name"), + (r'(\[|\btest\b).*-e ', "don't use 'test -e', use 'test -f'"), + (r'\[\[\s+[^\]]*\]\]', "don't use '[[ ]]', use '[ ]'"), + (r'^alias\b.*=', "don't use alias, use a function"), + (r'if\s*!', "don't use '!' to negate exit status"), + (r'/dev/u?random', "don't use entropy, use /dev/zero"), + (r'do\s*true;\s*done', "don't use true as loop body, use sleep 0"), + ( + r'sed (-e )?\'(\d+|/[^/]*/)i(?!\\\n)', + "put a backslash-escaped newline after sed 'i' command", + ), + (r'^diff *-\w*[uU].*$\n(^ \$ |^$)', "prefix diff -u/-U with cmp"), + (r'^\s+(if)? diff *-\w*[uU]', "prefix diff -u/-U with cmp"), + (r'[\s="`\']python\s(?!bindings)', "don't use 'python', use '$PYTHON'"), + (r'seq ', "don't use 'seq', use $TESTDIR/seq.py"), + (r'\butil\.Abort\b', "directly use error.Abort"), + (r'\|&', "don't use |&, use 2>&1"), + (r'\w = +\w', "only one space after = allowed"), + ( + r'\bsed\b.*[^\\]\\n', + "don't use 'sed ... \\n', use a \\ and a newline", + ), + (r'env.*-u', "don't use 'env -u VAR', use 'unset VAR'"), + (r'cp.* -r ', "don't use 'cp -r', use 'cp -R'"), + (r'grep.* -[ABC]', "don't use grep's context flags"), + ( + r'find.*-printf', + "don't use 'find -printf', it doesn't exist on BSD find(1)", + ), + (r'\$RANDOM ', "don't use bash-only $RANDOM to generate random values"), + ], + # warnings + [ + (r'^function', "don't use 'function', use old style"), + (r'^diff.*-\w*N', "don't use 'diff -N'"), + (r'\$PWD|\${PWD}', "don't use $PWD, use `pwd`", "no-pwd-check"), + (r'^([^"\'\n]|("[^"\n]*")|(\'[^\'\n]*\'))*\^', "^ must be quoted"), + (r'kill (`|\$\()', "don't use kill, use killdaemons.py"), + ], +] + +testfilters = [ + (r"( *)(#([^!][^\n]*\S)?)", repcomment), + (r"<<(\S+)((.|\n)*?\n\1)", rephere), +] + +uprefix = r"^ \$ " +utestpats = [ + [ + (r'^(\S.*|| [$>] \S.*)[ \t]\n', "trailing whitespace on non-output"), + ( + uprefix + r'.*\|\s*sed[^|>\n]*\n', + "use regex test output patterns instead of sed", + ), + (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"), + ( + uprefix + r'.*\|\| echo.*(fail|error)', + "explicit exit code checks unnecessary", + ), + (uprefix + r'set -e', "don't use set -e"), + (uprefix + r'(\s|fi\b|done\b)', "use > for continued lines"), + ( + uprefix + r'.*:\.\S*/', + "x:.y in a path does not work on msys, rewrite " + "as x://.y, or see `hg log -k msys` for alternatives", + r'-\S+:\.|' '# no-msys', # -Rxxx + ), # in test-pull.t which is skipped on windows + ( + r'^ [^$>].*27\.0\.0\.1', + 'use $LOCALIP not an explicit loopback address', + ), + ( + r'^ (?![>$] ).*\$LOCALIP.*[^)]$', + 'mark $LOCALIP output lines with (glob) to help tests in BSD jails', + ), + ( + r'^ (cat|find): .*: \$ENOENT\$', + 'use test -f to test for file existence', + ), + ( + r'^ diff -[^ -]*p', + "don't use (external) diff with -p for portability", + ), + (r' readlink ', 'use readlink.py instead of readlink'), + ( + r'^ [-+][-+][-+] .* [-+]0000 \(glob\)', + "glob timezone field in diff output for portability", + ), + ( + r'^ @@ -[0-9]+ [+][0-9]+,[0-9]+ @@', + "use '@@ -N* +N,n @@ (glob)' style chunk header for portability", + ), + ( + r'^ @@ -[0-9]+,[0-9]+ [+][0-9]+ @@', + "use '@@ -N,n +N* @@ (glob)' style chunk header for portability", + ), + ( + r'^ @@ -[0-9]+ [+][0-9]+ @@', + "use '@@ -N* +N* @@ (glob)' style chunk header for portability", + ), + ( + uprefix + r'hg( +-[^ ]+( +[^ ]+)?)* +extdiff' + r'( +(-[^ po-]+|--(?!program|option)[^ ]+|[^-][^ ]*))*$', + "use $RUNTESTDIR/pdiff via extdiff (or -o/-p for false-positives)", + ), + ], + # warnings + [ + ( + r'^ (?!.*\$LOCALIP)[^*?/\n]* \(glob\)$', + "glob match with no glob string (?, *, /, and $LOCALIP)", + ), + ], +] + +# transform plain test rules to unified test's +for i in [0, 1]: + for tp in testpats[i]: + p = tp[0] + m = tp[1] + if p.startswith('^'): + p = "^ [$>] (%s)" % p[1:] + else: + p = "^ [$>] .*(%s)" % p + utestpats[i].append((p, m) + tp[2:]) + +# don't transform the following rules: +# " > \t" and " \t" should be allowed in unified tests +testpats[0].append((r'^( *)\t', "don't use tabs to indent")) +utestpats[0].append((r'^( ?)\t', "don't use tabs to indent")) + +utestfilters = [ + (r"<<(\S+)((.|\n)*?\n > \1)", rephere), + (r"( +)(#([^!][^\n]*\S)?)", repcomment), +] + +# common patterns to check *.py +commonpypats = [ + [ + (r'\\$', 'Use () to wrap long lines in Python, not \\'), + ( + r'^\s*def\s*\w+\s*\(.*,\s*\(', + "tuple parameter unpacking not available in Python 3+", + ), + ( + r'lambda\s*\(.*,.*\)', + "tuple parameter unpacking not available in Python 3+", + ), + (r'(?\s', '<> operator is not available in Python 3+, use !='), + (r'^\s*\t', "don't use tabs"), + (r'\S;\s*\n', "semicolon"), + (r'[^_]_\([ \t\n]*(?:"[^"]+"[ \t\n+]*)+%', "don't use % inside _()"), + (r"[^_]_\([ \t\n]*(?:'[^']+'[ \t\n+]*)+%", "don't use % inside _()"), + (r'(\w|\)),\w', "missing whitespace after ,"), + (r'(\w|\))[+/*\-<>]\w', "missing whitespace in expression"), + (r'\w\s=\s\s+\w', "gratuitous whitespace after ="), + ( + ( + # a line ending with a colon, potentially with trailing comments + r':([ \t]*#[^\n]*)?\n' + # one that is not a pass and not only a comment + r'(?P[ \t]+)[^#][^\n]+\n' + # more lines at the same indent level + r'((?P=indent)[^\n]+\n)*' + # a pass at the same indent level, which is bogus + r'(?P=indent)pass[ \t\n#]' + ), + 'omit superfluous pass', + ), + (r'[^\n]\Z', "no trailing newline"), + (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"), + ( + r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+', + "linebreak after :", + ), + ( + r'\b(%s)\(' + % '|'.join(k for k in keyword.kwlist if k not in ('print', 'exec')), + "Python keyword is not a function", + ), + # (r'class\s[A-Z][^\(]*\((?!Exception)', + # "don't capitalize non-exception classes"), + # (r'in range\(', "use xrange"), + # (r'^\s*print\s+', "avoid using print in core and extensions"), + (r'[\x80-\xff]', "non-ASCII character literal"), + (r'("\')\.format\(', "str.format() has no bytes counterpart, use %"), + ( + r'([\(\[][ \t]\S)|(\S[ \t][\)\]])', + "gratuitous whitespace in () or []", + ), + # (r'\s\s=', "gratuitous whitespace before ="), + ( + r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S', + "missing whitespace around operator", + ), + ( + r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\s', + "missing whitespace around operator", + ), + ( + r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S', + "missing whitespace around operator", + ), + (r'[^^+=*/!<>&| %-](\s=|=\s)[^= ]', "wrong whitespace around ="), + ( + r'raise [^,(]+, (\([^\)]+\)|[^,\(\)]+)$', + "don't use old-style two-argument raise, use Exception(message)", + ), + (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"), + ( + r' [=!]=\s+(True|False|None)', + "comparison with singleton, use 'is' or 'is not' instead", + ), + ( + r'^\s*(while|if) [01]:', + "use True/False for constant Boolean expression", + ), + (r'^\s*if False(:| +and)', 'Remove code instead of using `if False`'), + (r'opener\([^)]*\).read\(', "use opener.read() instead"), + (r'opener\([^)]*\).write\(', "use opener.write() instead"), + (r'(?i)descend[e]nt', "the proper spelling is descendAnt"), + (r'\.debug\(\_', "don't mark debug messages for translation"), + (r'\.strip\(\)\.split\(\)', "no need to strip before splitting"), + (r'^\s*except\s*:', "naked except clause", r'#.*re-raises'), + ( + r'^\s*except\s([^\(,]+|\([^\)]+\))\s*,', + 'legacy exception syntax; use "as" instead of ","', + ), + (r'release\(.*wlock, .*lock\)', "wrong lock release order"), + (r'\bdef\s+__bool__\b', "__bool__ should be __nonzero__ in Python 2"), + ( + r'os\.path\.join\(.*, *(""|\'\')\)', + "use pathutil.normasprefix(path) instead of os.path.join(path, '')", + ), + (r'\s0[0-7]+\b', 'legacy octal syntax; use "0o" prefix instead of "0"'), + # XXX only catch mutable arguments on the first line of the definition + (r'def.*[( ]\w+=\{\}', "don't use mutable default arguments"), + (r'\butil\.Abort\b', "directly use error.Abort"), + ( + r'^@(\w*\.)?cachefunc', + "module-level @cachefunc is risky, please avoid", + ), + ( + r'^(from|import) mercurial\.(cext|pure|cffi)', + "use mercurial.policy.importmod instead", + ), + (r'\.next\(\)', "don't use .next(), use next(...)"), + ( + r'([a-z]*).revision\(\1\.node\(', + "don't convert rev to node before passing to revision(nodeorrev)", + ), + (r'platform\.system\(\)', "don't use platform.system(), use pycompat"), + ], + # warnings + [], +] + +# patterns to check normal *.py files +pypats = [ + [ + # Ideally, these should be placed in "commonpypats" for + # consistency of coding rules in Mercurial source tree. + # But on the other hand, these are not so seriously required for + # python code fragments embedded in test scripts. Fixing test + # scripts for these patterns requires many changes, and has less + # profit than effort. + (r'raise Exception', "don't raise generic exceptions"), + (r'[\s\(](open|file)\([^)]*\)\.read\(', "use util.readfile() instead"), + ( + r'[\s\(](open|file)\([^)]*\)\.write\(', + "use util.writefile() instead", + ), + ( + r'^[\s\(]*(open(er)?|file)\([^)]*\)(?!\.close\(\))', + "always assign an opened file to a variable, and close it afterwards", + ), + ( + r'[\s\(](open|file)\([^)]*\)\.(?!close\(\))', + "always assign an opened file to a variable, and close it afterwards", + ), + (r':\n( )*( ){1,3}[^ ]', "must indent 4 spaces"), + (r'^import atexit', "don't use atexit, use ui.atexit"), + # rules depending on implementation of repquote() + ( + r' x+[xpqo%APM][\'"]\n\s+[\'"]x', + 'string join across lines with no space', + ), + ( + r'''(?x)ui\.(status|progress|write|note|warn)\( + [ \t\n#]* + (?# any strings/comments might precede a string, which + # contains translatable message) + b?((['"]|\'\'\'|""")[ \npq%bAPMxno]*(['"]|\'\'\'|""")[ \t\n#]+)* + (?# sequence consisting of below might precede translatable message + # - formatting string: "% 10s", "%05d", "% -3.2f", "%*s", "%%" ... + # - escaped character: "\\", "\n", "\0" ... + # - character other than '%', 'b' as '\', and 'x' as alphabet) + (['"]|\'\'\'|""") + ((%([ n]?[PM]?([np]+|A))?x)|%%|b[bnx]|[ \nnpqAPMo])*x + (?# this regexp can't use [^...] style, + # because _preparepats forcibly adds "\n" into [^...], + # even though this regexp wants match it against "\n")''', + "missing _() in ui message (use () to hide false-positives)", + ), + ] + + commonpypats[0], + # warnings + [ + # rules depending on implementation of repquote() + (r'(^| )pp +xxxxqq[ \n][^\n]', "add two newlines after '.. note::'"), + ] + + commonpypats[1], +] + +# patterns to check *.py for embedded ones in test script +embeddedpypats = [ + [] + commonpypats[0], + # warnings + [] + commonpypats[1], +] + +# common filters to convert *.py +commonpyfilters = [ + ( + r"""(?msx)(?P\#.*?$)| + ((?P('''|\"\"\"|(?(([^\\]|\\.)*?)) + (?P=quote))""", + reppython, + ), +] + +# pattern only for mercurial and extensions +core_py_pats = [ + [ + # Windows tend to get confused about capitalization of the drive letter + # + # see mercurial.windows.abspath for details + ( + r'os\.path\.abspath', + "use util.abspath instead (windows)", + r'#.*re-exports', + ), + ], + # warnings + [], +] + +# filters to convert normal *.py files +pyfilters = [] + commonpyfilters + +# non-filter patterns +pynfpats = [ + [ + (r'pycompat\.osname\s*[=!]=\s*[\'"]nt[\'"]', "use pycompat.iswindows"), + (r'pycompat\.osname\s*[=!]=\s*[\'"]posix[\'"]', "use pycompat.isposix"), + ( + r'pycompat\.sysplatform\s*[!=]=\s*[\'"]darwin[\'"]', + "use pycompat.isdarwin", + ), + ], + # warnings + [], +] + +# filters to convert *.py for embedded ones in test script +embeddedpyfilters = [] + commonpyfilters + +# extension non-filter patterns +pyextnfpats = [ + [(r'^"""\n?[A-Z]', "don't capitalize docstring title")], + # warnings + [], +] + +txtfilters = [] + +txtpats = [ + [ + (r'\s$', 'trailing whitespace'), + ('.. note::[ \n][^\n]', 'add two newlines after note::'), + ], + [], +] + +cpats = [ + [ + (r'//', "don't use //-style comments"), + (r'\S\t', "don't use tabs except for indent"), + (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"), + (r'(while|if|do|for)\(', "use space after while/if/do/for"), + (r'return\(', "return is not a function"), + (r' ;', "no space before ;"), + (r'[^;] \)', "no space before )"), + (r'[)][{]', "space between ) and {"), + (r'\w+\* \w+', "use int *foo, not int* foo"), + (r'\W\([^\)]+\) \w+', "use (int)foo, not (int) foo"), + (r'\w+ (\+\+|--)', "use foo++, not foo ++"), + (r'\w,\w', "missing whitespace after ,"), + (r'^[^#]\w[+/*]\w', "missing whitespace in expression"), + (r'\w\s=\s\s+\w', "gratuitous whitespace after ="), + (r'^#\s+\w', "use #foo, not # foo"), + (r'[^\n]\Z', "no trailing newline"), + (r'^\s*#import\b', "use only #include in standard C code"), + (r'strcpy\(', "don't use strcpy, use strlcpy or memcpy"), + (r'strcat\(', "don't use strcat"), + # rules depending on implementation of repquote() + ], + # warnings + [ + # rules depending on implementation of repquote() + ], +] + +cfilters = [ + (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment), + (r'''(?P(?([^"]|\\")+)"(?!")''', repquote), + (r'''(#\s*include\s+<)([^>]+)>''', repinclude), + (r'(\()([^)]+\))', repcallspaces), +] + +inutilpats = [ + [ + (r'\bui\.', "don't use ui in util"), + ], + # warnings + [], +] + +inrevlogpats = [ + [ + (r'\brepo\.', "don't use repo in revlog"), + ], + # warnings + [], +] + +webtemplatefilters = [] + +webtemplatepats = [ + [], + [ + ( + r'{desc(\|(?!websub|firstline)[^\|]*)+}', + 'follow desc keyword with either firstline or websub', + ), + ], +] + +allfilesfilters = [] + +allfilespats = [ + [ + ( + r'(http|https)://[a-zA-Z0-9./]*selenic.com/', + 'use mercurial-scm.org domain URL', + ), + ( + r'mercurial@selenic\.com', + 'use mercurial-scm.org domain for mercurial ML address', + ), + ( + r'mercurial-devel@selenic\.com', + 'use mercurial-scm.org domain for mercurial-devel ML address', + ), + ], + # warnings + [], +] + +py3pats = [ + [ + ( + r'os\.environ', + "use encoding.environ instead (py3)", + r'#.*re-exports', + ), + (r'os\.name', "use pycompat.osname instead (py3)"), + (r'os\.getcwd', "use encoding.getcwd instead (py3)", r'#.*re-exports'), + (r'os\.sep', "use pycompat.ossep instead (py3)"), + (r'os\.pathsep', "use pycompat.ospathsep instead (py3)"), + (r'os\.altsep', "use pycompat.osaltsep instead (py3)"), + (r'sys\.platform', "use pycompat.sysplatform instead (py3)"), + (r'getopt\.getopt', "use pycompat.getoptb instead (py3)"), + (r'os\.getenv', "use encoding.environ.get instead"), + (r'os\.setenv', "modifying the environ dict is not preferred"), + (r'(? %s" % line) + self._lastseen = msgid + print(" " + msg) + + +_defaultlogger = norepeatlogger() + + +def getblame(f): + lines = [] + for l in os.popen('hg annotate -un %s' % f): + start, line = l.split(':', 1) + user, rev = start.split() + lines.append((line[1:-1], user, rev)) + return lines + + +def checkfile( + f, + logfunc=_defaultlogger.log, + maxerr=None, + warnings=False, + blame=False, + debug=False, + lineno=True, +): + """checks style and portability of a given file + + :f: filepath + :logfunc: function used to report error + logfunc(filename, linenumber, linecontent, errormessage) + :maxerr: number of error to display before aborting. + Set to false (default) to report all errors + + return True if no error is found, False otherwise. + """ + result = True + + try: + with opentext(f) as fp: + try: + pre = fp.read() + except UnicodeDecodeError as e: + print("%s while reading %s" % (e, f)) + return result + except IOError as e: + print("Skipping %s, %s" % (f, str(e).split(':', 1)[0])) + return result + + # context information shared while single checkfile() invocation + context = {'blamecache': None} + + for name, match, magic, filters, pats in checks: + if debug: + print(name, f) + if not (re.match(match, f) or (magic and re.search(magic, pre))): + if debug: + print( + "Skipping %s for %s it doesn't match %s" % (name, match, f) + ) + continue + if "no-" "check-code" in pre: + # If you're looking at this line, it's because a file has: + # no- check- code + # but the reason to output skipping is to make life for + # tests easier. So, instead of writing it with a normal + # spelling, we write it with the expected spelling from + # tests/test-check-code.t + print("Skipping %s it has no-che?k-code (glob)" % f) + return "Skip" # skip checking this file + + fc = _checkfiledata( + name, + f, + pre, + filters, + pats, + context, + logfunc, + maxerr, + warnings, + blame, + debug, + lineno, + ) + if fc: + result = False + + if f.endswith('.t') and "no-" "check-code" not in pre: + if debug: + print("Checking embedded code in %s" % f) + + prelines = pre.splitlines() + embeddederros = [] + for name, embedded, filters, pats in embeddedchecks: + # "reset curmax at each repetition" treats maxerr as "max + # nubmer of errors in an actual file per entry of + # (embedded)checks" + curmaxerr = maxerr + + for found in embedded(f, prelines, embeddederros): + filename, starts, ends, code = found + fc = _checkfiledata( + name, + f, + code, + filters, + pats, + context, + logfunc, + curmaxerr, + warnings, + blame, + debug, + lineno, + offset=starts - 1, + ) + if fc: + result = False + if curmaxerr: + if fc >= curmaxerr: + break + curmaxerr -= fc + + return result + + +def _checkfiledata( + name, + f, + filedata, + filters, + pats, + context, + logfunc, + maxerr, + warnings, + blame, + debug, + lineno, + offset=None, +): + """Execute actual error check for file data + + :name: of the checking category + :f: filepath + :filedata: content of a file + :filters: to be applied before checking + :pats: to detect errors + :context: a dict of information shared while single checkfile() invocation + Valid keys: 'blamecache'. + :logfunc: function used to report error + logfunc(filename, linenumber, linecontent, errormessage) + :maxerr: number of error to display before aborting, or False to + report all errors + :warnings: whether warning level checks should be applied + :blame: whether blame information should be displayed at error reporting + :debug: whether debug information should be displayed + :lineno: whether lineno should be displayed at error reporting + :offset: line number offset of 'filedata' in 'f' for checking + an embedded code fragment, or None (offset=0 is different + from offset=None) + + returns number of detected errors. + """ + blamecache = context['blamecache'] + if offset is None: + lineoffset = 0 + else: + lineoffset = offset + + fc = 0 + pre = post = filedata + + if True: # TODO: get rid of this redundant 'if' block + for p, r in filters: + post = re.sub(p, r, post) + nerrs = len(pats[0]) # nerr elements are errors + if warnings: + pats = pats[0] + pats[1] + else: + pats = pats[0] + # print post # uncomment to show filtered version + + if debug: + print("Checking %s for %s" % (name, f)) + + prelines = None + errors = [] + for i, pat in enumerate(pats): + if len(pat) == 3: + p, msg, ignore = pat + else: + p, msg = pat + ignore = None + if i >= nerrs: + msg = "warning: " + msg + + pos = 0 + n = 0 + for m in p.finditer(post): + if prelines is None: + prelines = pre.splitlines() + postlines = post.splitlines(True) + + start = m.start() + while n < len(postlines): + step = len(postlines[n]) + if pos + step > start: + break + pos += step + n += 1 + l = prelines[n] + + if ignore and re.search(ignore, l, re.MULTILINE): + if debug: + print( + "Skipping %s for %s:%s (ignore pattern)" + % (name, f, (n + lineoffset)) + ) + continue + bd = "" + if blame: + bd = 'working directory' + if blamecache is None: + blamecache = getblame(f) + context['blamecache'] = blamecache + if (n + lineoffset) < len(blamecache): + bl, bu, br = blamecache[(n + lineoffset)] + if offset is None and bl == l: + bd = '%s@%s' % (bu, br) + elif offset is not None and bl.endswith(l): + # "offset is not None" means "checking + # embedded code fragment". In this case, + # "l" does not have information about the + # beginning of an *original* line in the + # file (e.g. ' > '). + # Therefore, use "str.endswith()", and + # show "maybe" for a little loose + # examination. + bd = '%s@%s, maybe' % (bu, br) + + errors.append((f, lineno and (n + lineoffset + 1), l, msg, bd)) + + errors.sort() + for e in errors: + logfunc(*e) + fc += 1 + if maxerr and fc >= maxerr: + print(" (too many errors, giving up)") + break + + return fc + + +def main(): + parser = optparse.OptionParser("%prog [options] [files | -]") + parser.add_option( + "-w", + "--warnings", + action="store_true", + help="include warning-level checks", + ) + parser.add_option( + "-p", "--per-file", type="int", help="max warnings per file" + ) + parser.add_option( + "-b", + "--blame", + action="store_true", + help="use annotate to generate blame info", + ) + parser.add_option( + "", "--debug", action="store_true", help="show debug information" + ) + parser.add_option( + "", + "--nolineno", + action="store_false", + dest='lineno', + help="don't show line numbers", + ) + + parser.set_defaults( + per_file=15, warnings=False, blame=False, debug=False, lineno=True + ) + (options, args) = parser.parse_args() + + if len(args) == 0: + check = glob.glob("*") + elif args == ['-']: + # read file list from stdin + check = sys.stdin.read().splitlines() + else: + check = args + + _preparepats() + + ret = 0 + for f in check: + if not checkfile( + f, + maxerr=options.per_file, + warnings=options.warnings, + blame=options.blame, + debug=options.debug, + lineno=options.lineno, + ): + ret = 1 + return ret + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/contrib/check-commit b/contrib/check-commit new file mode 100755 index 0000000..2c7f008 --- /dev/null +++ b/contrib/check-commit @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 +# +# Copyright 2014 Olivia Mackall +# +# A tool/hook to run basic sanity checks on commits/patches for +# submission to Mercurial. Install by adding the following to your +# .hg/hgrc: +# +# [hooks] +# pretxncommit = contrib/check-commit +# +# The hook can be temporarily bypassed with: +# +# $ BYPASS= hg commit +# +# See also: https://mercurial-scm.org/wiki/ContributingChanges + + +import os +import re +import sys + +commitheader = r"^(?:# [^\n]*\n)*" +afterheader = commitheader + r"(?!#)" +beforepatch = afterheader + r"(?!\n(?!@@))" + +errors = [ + (beforepatch + r".*[(]bc[)]", "(BC) needs to be uppercase"), + ( + beforepatch + r".*[(]issue \d\d\d", + "no space allowed between issue and number", + ), + (beforepatch + r".*[(]bug(\d|\s)", "use (issueDDDD) instead of bug"), + (commitheader + r"# User [^@\n]+\n", "username is not an email address"), + ( + commitheader + r"(?!merge with )[^#]\S+[^:] ", + "summary line doesn't start with 'topic: '", + ), + (afterheader + r"[A-Z][a-z]\S+", "don't capitalize summary lines"), + (afterheader + r"^\S+: *[A-Z][a-z]\S+", "don't capitalize summary lines"), + ( + afterheader + r"\S*[^A-Za-z0-9-_]\S*: ", + "summary keyword should be most user-relevant one-word command or topic", + ), + (afterheader + r".*\.\s*\n", "don't add trailing period on summary line"), + (afterheader + r".{79,}", "summary line too long (limit is 78)"), +] + +word = re.compile(r'\S') + + +def nonempty(first, second): + if word.search(first): + return first + return second + + +def checkcommit(commit, node=None): + exitcode = 0 + printed = node is None + hits = [] + signtag = ( + afterheader + r'Added (tag [^ ]+|signature) for changeset [a-f0-9]{12}' + ) + if re.search(signtag, commit): + return 0 + for exp, msg in errors: + for m in re.finditer(exp, commit): + end = m.end() + trailing = re.search(r'(\\n)+$', exp) + if trailing: + end -= len(trailing.group()) / 2 + hits.append((end, exp, msg)) + if hits: + hits.sort() + pos = 0 + last = '' + for n, l in enumerate(commit.splitlines(True)): + pos += len(l) + while len(hits): + end, exp, msg = hits[0] + if pos < end: + break + if not printed: + printed = True + print("node: %s" % node) + print("%d: %s" % (n, msg)) + print(" %s" % nonempty(l, last)[:-1]) + if "BYPASS" not in os.environ: + exitcode = 1 + del hits[0] + last = nonempty(l, last) + + return exitcode + + +def readcommit(node): + return os.popen("hg export %s" % node).read() + + +if __name__ == "__main__": + exitcode = 0 + node = os.environ.get("HG_NODE") + + if node: + commit = readcommit(node) + exitcode = checkcommit(commit) + elif sys.argv[1:]: + for node in sys.argv[1:]: + exitcode |= checkcommit(readcommit(node), node) + else: + commit = sys.stdin.read() + exitcode = checkcommit(commit) + sys.exit(exitcode) diff --git a/contrib/check-config.py b/contrib/check-config.py new file mode 100755 index 0000000..924fa1a --- /dev/null +++ b/contrib/check-config.py @@ -0,0 +1,190 @@ +#!/usr/bin/env python3 +# +# check-config - a config flag documentation checker for Mercurial +# +# Copyright 2015 Olivia Mackall +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +import re +import sys + +foundopts = {} +documented = {} +allowinconsistent = set() + +configre = re.compile( + br''' + # Function call + ui\.config(?P|int|bool|list)\( + # First argument. + ['"](?P
\S+)['"],\s* + # Second argument + ['"](?P