Mercurial > hg
view tests/test-mq.t @ 42044:bb271ec2fbfb
compression: introduce a `storage.revlog.zstd.level` configuration
This option control the zstd compression level used when compressing revlog
chunk. The usage of zstd for revlog compression has not graduated from
experimental yet, but we intend to fix that soon.
The option name for the compression level is more straight forward to pick, so
this changesets comes first. Having a dedicated option for each compression
engine is useful because they don't support the same range of values.
I ran the same measurement as for the zlib compression level (in the parent
changesets). The variation in repository size is stay mostly in the same (small)
range. The "read/write" performance see smallish variation, but are overall much
better than zlib. Write performance show the same tend of having better write
performance for when reaching high-end compression.
Again, we don't intend to change the default zstd compression level (currently:
3) in this series. However this is worth investigating in the future.
The Performance comparison of zlib vs zstd is quite impressive. The repository
size stay in the same range, but the performance are much better in all
situations.
Comparison summary
==================
We are looking at:
- performance range for zlib
- performance range for zstd
- comparison of default zstd (level-3) to default zlib (level 6)
- comparison of the slowest zstd time to the fastest zlib time
Read performance:
-----------------
| zlib | zstd | cmp | f2s
mercurial | 0.170159 - 0.189219 | 0.144127 - 0.149624 | 80% | 88%
pypy | 2.679217 - 2.768691 | 1.532317 - 1.705044 | 60% | 63%
netbeans | 122.477027 - 141.620281 | 72.996346 - 89.731560 | 58% | 73%
mozilla | 147.867662 - 170.572118 | 91.700995 - 105.853099 | 56% | 71%
Write performance:
------------------
| zlib | zstd | cmp | f2s
mercurial | 53.250304 - 56.2936129 | 40.877025 - 45.677286 | 75% | 86%
pypy | 460.721984 - 476.589918 | 270.545409 - 301.002219 | 63% | 65%
netbeans | 520.560316 - 715.930400 | 370.356311 - 428.329652 | 55% | 82%
mozilla | 739.803002 - 987.056093 | 505.152906 - 591.930683 | 57% | 80%
Raw data
--------
repo alg lvl .hg/store size 00manifest.d read write
mercurial zlib 1 49,402,813 5,963,475 0.170159 53.250304
mercurial zlib 6 47,197,397 5,875,730 0.182820 56.264320
mercurial zlib 9 47,121,596 5,849,781 0.189219 56.293612
mercurial zstd 1 49,737,084 5,966,355 0.144127 40.877025
mercurial zstd 3 48,961,867 5,895,208 0.146376 42.268142
mercurial zstd 5 48,200,592 5,938,676 0.149624 43.162875
mercurial zstd 10 47,833,520 5,913,353 0.145185 44.012489
mercurial zstd 15 47,314,604 5,728,679 0.147686 45.677286
mercurial zstd 20 47,330,502 5,830,539 0.145789 45.025407
mercurial zstd 22 47,330,076 5,830,539 0.143996 44.690460
pypy zlib 1 370,830,572 28,462,425 2.679217 460.721984
pypy zlib 6 340,112,317 27,648,747 2.768691 467.537158
pypy zlib 9 338,360,736 27,639,003 2.763495 476.589918
pypy zstd 1 362,377,479 27,916,214 1.532317 270.545409
pypy zstd 3 354,137,693 27,905,988 1.686718 294.951509
pypy zstd 5 342,640,043 27,655,774 1.705044 301.002219
pypy zstd 10 334,224,327 27,164,493 1.567287 285.186239
pypy zstd 15 329,000,363 26,645,965 1.637729 299.561332
pypy zstd 20 324,534,039 26,199,547 1.526813 302.149827
pypy zstd 22 324,530,595 26,198,932 1.525718 307.821218
netbeans zlib 1 1,281,847,810 165,495,457 122.477027 520.560316
netbeans zlib 6 1,205,284,353 159,161,207 139.876147 715.930400
netbeans zlib 9 1,197,135,671 155,034,586 141.620281 678.297064
netbeans zstd 1 1,259,581,737 160,840,613 72.996346 370.356311
netbeans zstd 3 1,232,978,122 157,691,551 81.622317 396.733087
netbeans zstd 5 1,208,034,075 160,246,880 83.080549 364.342626
netbeans zstd 10 1,188,624,176 156,083,417 79.323935 403.594602
netbeans zstd 15 1,176,973,589 153,859,477 89.731560 428.329652
netbeans zstd 20 1,162,958,258 151,147,535 82.842667 392.335349
netbeans zstd 22 1,162,707,029 151,150,220 82.565695 402.840655
mozilla zlib 1 2,775,497,186 298,527,987 147.867662 751.263721
mozilla zlib 6 2,596,856,420 286,597,671 170.572118 987.056093
mozilla zlib 9 2,587,542,494 287,018,264 163.622338 739.803002
mozilla zstd 1 2,723,159,348 286,617,532 91.700995 570.042751
mozilla zstd 3 2,665,055,001 286,152,013 95.240155 561.412805
mozilla zstd 5 2,607,819,817 288,060,030 101.978048 505.152906
mozilla zstd 10 2,558,761,085 283,967,648 104.113481 497.771202
mozilla zstd 15 2,526,216,060 275,581,300 105.853099 591.930683
mozilla zstd 20 2,485,114,806 266,478,859 95.268795 576.515389
mozilla zstd 22 2,484,869,080 266,456,505 94.429282 572.785537
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Wed, 27 Mar 2019 18:35:59 +0100 |
parents | 251332dbf33d |
children | 1474f5d84662 |
line wrap: on
line source
$ checkundo() > { > if [ -f .hg/store/undo ]; then > echo ".hg/store/undo still exists after $1" > fi > } $ cat <<EOF >> $HGRCPATH > [extensions] > mq = > [mq] > plain = true > EOF help $ hg help mq mq extension - manage a stack of patches This extension lets you work with a stack of patches in a Mercurial repository. It manages two stacks of patches - all known patches, and applied patches (subset of known patches). Known patches are represented as patch files in the .hg/patches directory. Applied patches are both patch files and changesets. Common tasks (use 'hg help COMMAND' for more details): create new patch qnew import existing patch qimport print patch series qseries print applied patches qapplied add known patch to applied stack qpush remove patch from applied stack qpop refresh contents of top applied patch qrefresh By default, mq will automatically use git patches when required to avoid losing file mode changes, copy records, binary files or empty files creations or deletions. This behavior can be configured with: [mq] git = auto/keep/yes/no If set to 'keep', mq will obey the [diff] section configuration while preserving existing git patches upon qrefresh. If set to 'yes' or 'no', mq will override the [diff] section and always generate git or regular patches, possibly losing data in the second case. It may be desirable for mq changesets to be kept in the secret phase (see 'hg help phases'), which can be enabled with the following setting: [mq] secret = True You will by default be managing a patch queue named "patches". You can create other, independent patch queues with the 'hg qqueue' command. If the working directory contains uncommitted files, qpush, qpop and qgoto abort immediately. If -f/--force is used, the changes are discarded. Setting: [mq] keepchanges = True make them behave as if --keep-changes were passed, and non-conflicting local changes will be tolerated and preserved. If incompatible options such as -f/--force or --exact are passed, this setting is ignored. This extension used to provide a strip command. This command now lives in the strip extension. list of commands: Repository creation: qclone clone main and patch repository at same time Change creation: qnew create a new patch qrefresh update the current patch Change manipulation: qfold fold the named patches into the current patch Change organization: qapplied print the patches already applied qdelete remove patches from queue qfinish move applied patches into repository history qgoto push or pop patches until named patch is at top of stack qguard set or print guards for a patch qheader print the header of the topmost or specified patch qnext print the name of the next pushable patch qpop pop the current patch off the stack qprev print the name of the preceding applied patch qpush push the next patch onto the stack qqueue manage multiple patch queues qrename rename a patch qselect set or print guarded patches to push qseries print the entire series file qtop print the name of the current patch qunapplied print the patches not yet applied File content management: qdiff diff of the current patch and subsequent modifications Change import/export: qimport import a patch or existing changeset (use 'hg help -v mq' to show built-in aliases and global options) $ hg init a $ cd a $ echo a > a $ hg ci -Ama adding a $ hg clone . ../k updating to branch default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ mkdir b $ echo z > b/z $ hg ci -Ama adding b/z qinit $ hg qinit $ cd .. $ hg init b -R qinit $ hg -R b qinit $ hg init c qinit -c $ hg --cwd c qinit -c $ hg -R c/.hg/patches st A .hgignore A series qinit; qinit -c $ hg init d $ cd d $ hg qinit $ hg qinit -c qinit -c should create both files if they don't exist $ cat .hg/patches/.hgignore ^\.hg ^\.mq syntax: glob status guards $ cat .hg/patches/series $ hg qinit -c abort: repository $TESTTMP/d/.hg/patches already exists! [255] $ cd .. $ echo '% qinit; <stuff>; qinit -c' % qinit; <stuff>; qinit -c $ hg init e $ cd e $ hg qnew A $ checkundo qnew $ echo foo > foo $ hg phase -r qbase 0: draft $ hg add foo $ hg qrefresh $ hg phase -r qbase 0: draft $ hg qnew B $ echo >> foo $ hg qrefresh $ echo status >> .hg/patches/.hgignore $ echo bleh >> .hg/patches/.hgignore $ hg qinit -c adding .hg/patches/A adding .hg/patches/B $ hg -R .hg/patches status A .hgignore A A A B A series qinit -c shouldn't touch these files if they already exist $ cat .hg/patches/.hgignore status bleh $ cat .hg/patches/series A B add an untracked file $ echo >> .hg/patches/flaf status --mq with color (issue2096) $ hg status --mq --config extensions.color= --config color.mode=ansi --color=always \x1b[0;32;1mA \x1b[0m\x1b[0;32;1m.hgignore\x1b[0m (esc) \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mA\x1b[0m (esc) \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mB\x1b[0m (esc) \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mseries\x1b[0m (esc) \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mflaf\x1b[0m (esc) try the --mq option on a command provided by an extension $ hg purge --mq --verbose --config extensions.purge= removing file flaf $ cd .. #if no-outer-repo init --mq without repo $ mkdir f $ cd f $ hg init --mq abort: there is no Mercurial repository here (.hg not found) [255] $ cd .. #endif init --mq with repo path $ hg init g $ hg init --mq g $ test -d g/.hg/patches/.hg init --mq with nonexistent directory $ hg init --mq nonexistentdir abort: repository nonexistentdir not found! [255] init --mq with bundle (non "local") $ hg -R a bundle --all a.bundle >/dev/null $ hg init --mq a.bundle abort: only a local queue repository may be initialized [255] $ cd a $ hg qnew -m 'foo bar' test.patch $ echo '# comment' > .hg/patches/series.tmp $ echo >> .hg/patches/series.tmp # empty line $ cat .hg/patches/series >> .hg/patches/series.tmp $ mv .hg/patches/series.tmp .hg/patches/series qrefresh $ echo a >> a $ hg qrefresh $ cat .hg/patches/test.patch foo bar diff -r [a-f0-9]* a (re) --- a/a\t(?P<date>.*) (re) \+\+\+ b/a\t(?P<date2>.*) (re) @@ -1,1 +1,2 @@ a +a empty qrefresh $ hg qrefresh -X a revision: $ hg diff -r -2 -r -1 patch: $ cat .hg/patches/test.patch foo bar working dir diff: $ hg diff --nodates -q diff -r dde259bd5934 a --- a/a +++ b/a @@ -1,1 +1,2 @@ a +a restore things $ hg qrefresh $ checkundo qrefresh qpop $ hg qpop popping test.patch patch queue now empty $ checkundo qpop qpush with dump of tag cache Dump the tag cache to ensure that it has exactly one head after qpush. $ rm -f .hg/cache/tags2-visible $ hg tags > /dev/null .hg/cache/tags2-visible (pre qpush): $ cat .hg/cache/tags2-visible 1 [\da-f]{40} (re) $ hg qpush applying test.patch now at: test.patch $ hg phase -r qbase 2: draft $ hg tags > /dev/null .hg/cache/tags2-visible (post qpush): $ cat .hg/cache/tags2-visible 2 [\da-f]{40} (re) $ checkundo qpush $ cd .. pop/push outside repo $ hg -R a qpop popping test.patch patch queue now empty $ hg -R a qpush applying test.patch now at: test.patch $ cd a $ hg qnew test2.patch qrefresh in subdir $ cd b $ echo a > a $ hg add a $ hg qrefresh pop/push -a in subdir $ hg qpop -a popping test2.patch popping test.patch patch queue now empty $ hg --traceback qpush -a applying test.patch applying test2.patch now at: test2.patch setting columns & formatted tests truncating (issue1912) $ COLUMNS=4 hg qseries --config ui.formatted=true --color=no test.patch test2.patch $ COLUMNS=20 hg qseries --config ui.formatted=true -vs --color=no 0 A test.patch: f... 1 A test2.patch: $ hg qpop popping test2.patch now at: test.patch $ hg qseries -vs 0 A test.patch: foo bar 1 U test2.patch: $ hg sum | grep mq mq: 1 applied, 1 unapplied $ hg qpush applying test2.patch now at: test2.patch $ hg sum | grep mq mq: 2 applied $ hg qapplied test.patch test2.patch $ hg qtop test2.patch prev $ hg qapp -1 test.patch next $ hg qunapp -1 all patches applied [1] $ hg qpop popping test2.patch now at: test.patch commit should fail $ hg commit abort: cannot commit over an applied mq patch [255] push should fail if draft $ hg push ../../k pushing to ../../k abort: source has mq patches applied [255] import should fail $ hg st . $ echo foo >> ../a $ hg diff > ../../import.diff $ hg revert --no-backup ../a $ hg import ../../import.diff abort: cannot import over an applied patch [255] $ hg st import --no-commit should succeed $ hg import --no-commit ../../import.diff applying ../../import.diff $ hg st M a $ hg revert --no-backup ../a qunapplied $ hg qunapplied test2.patch qpush/qpop with index $ hg qnew test1b.patch $ echo 1b > 1b $ hg add 1b $ hg qrefresh $ hg qpush 2 applying test2.patch now at: test2.patch $ hg qpop 0 popping test2.patch popping test1b.patch now at: test.patch $ hg qpush test.patch+1 applying test1b.patch now at: test1b.patch $ hg qpush test.patch+2 applying test2.patch now at: test2.patch $ hg qpop test2.patch-1 popping test2.patch now at: test1b.patch $ hg qpop test2.patch-2 popping test1b.patch now at: test.patch $ hg qpush test1b.patch+1 applying test1b.patch applying test2.patch now at: test2.patch qpush --move $ hg qpop -a popping test2.patch popping test1b.patch popping test.patch patch queue now empty $ hg qguard test1b.patch -- -negguard $ hg qguard test2.patch -- +posguard $ hg qpush --move test2.patch # can't move guarded patch cannot push 'test2.patch' - guarded by '+posguard' [1] $ hg qselect posguard number of unguarded, unapplied patches has changed from 2 to 3 $ hg qpush --move test2.patch # move to front applying test2.patch now at: test2.patch $ hg qpush --move test1b.patch # negative guard unselected applying test1b.patch now at: test1b.patch $ hg qpush --move test.patch # noop move applying test.patch now at: test.patch $ hg qseries -v 0 A test2.patch 1 A test1b.patch 2 A test.patch $ hg qpop -a popping test.patch popping test1b.patch popping test2.patch patch queue now empty cleaning up $ hg qselect --none guards deactivated number of unguarded, unapplied patches has changed from 3 to 2 $ hg qguard --none test1b.patch $ hg qguard --none test2.patch $ hg qpush --move test.patch applying test.patch now at: test.patch $ hg qpush --move test1b.patch applying test1b.patch now at: test1b.patch $ hg qpush --move bogus # nonexistent patch abort: patch bogus not in series [255] $ hg qpush --move # no patch abort: please specify the patch to move [255] $ hg qpush --move test.patch # already applied abort: cannot push to a previous patch: test.patch [255] $ sed '2i\ > # make qtip index different in series and fullseries > ' `hg root`/.hg/patches/series > $TESTTMP/sedtmp $ cp $TESTTMP/sedtmp `hg root`/.hg/patches/series $ cat `hg root`/.hg/patches/series # comment # make qtip index different in series and fullseries test.patch test1b.patch test2.patch $ hg qpush --move test2.patch applying test2.patch now at: test2.patch series after move $ cat `hg root`/.hg/patches/series # comment # make qtip index different in series and fullseries test.patch test1b.patch test2.patch pop, qapplied, qunapplied $ hg qseries -v 0 A test.patch 1 A test1b.patch 2 A test2.patch qapplied -1 test.patch $ hg qapplied -1 test.patch only one patch applied [1] qapplied -1 test1b.patch $ hg qapplied -1 test1b.patch test.patch qapplied -1 test2.patch $ hg qapplied -1 test2.patch test1b.patch qapplied -1 $ hg qapplied -1 test1b.patch qapplied $ hg qapplied test.patch test1b.patch test2.patch qapplied test1b.patch $ hg qapplied test1b.patch test.patch test1b.patch qunapplied -1 $ hg qunapplied -1 all patches applied [1] qunapplied $ hg qunapplied popping $ hg qpop popping test2.patch now at: test1b.patch qunapplied -1 $ hg qunapplied -1 test2.patch qunapplied $ hg qunapplied test2.patch qunapplied test2.patch $ hg qunapplied test2.patch qunapplied -1 test2.patch $ hg qunapplied -1 test2.patch all patches applied [1] popping -a $ hg qpop -a popping test1b.patch popping test.patch patch queue now empty qapplied $ hg qapplied qapplied -1 $ hg qapplied -1 no patches applied [1] $ hg qpush applying test.patch now at: test.patch push should succeed $ hg qpop -a popping test.patch patch queue now empty $ hg push ../../k pushing to ../../k searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files we want to start with some patches applied $ hg qpush -a applying test.patch applying test1b.patch applying test2.patch now at: test2.patch % pops all patches and succeeds $ hg qpop -a popping test2.patch popping test1b.patch popping test.patch patch queue now empty % does nothing and succeeds $ hg qpop -a no patches applied % fails - nothing else to pop $ hg qpop no patches applied [1] % pushes a patch and succeeds $ hg qpush applying test.patch now at: test.patch % pops a patch and succeeds $ hg qpop popping test.patch patch queue now empty % pushes up to test1b.patch and succeeds $ hg qpush test1b.patch applying test.patch applying test1b.patch now at: test1b.patch % does nothing and succeeds $ hg qpush test1b.patch qpush: test1b.patch is already at the top % does nothing and succeeds $ hg qpop test1b.patch qpop: test1b.patch is already at the top % fails - can't push to this patch $ hg qpush test.patch abort: cannot push to a previous patch: test.patch [255] % fails - can't pop to this patch $ hg qpop test2.patch abort: patch test2.patch is not applied [255] % pops up to test.patch and succeeds $ hg qpop test.patch popping test1b.patch now at: test.patch % pushes all patches and succeeds $ hg qpush -a applying test1b.patch applying test2.patch now at: test2.patch % does nothing and succeeds $ hg qpush -a all patches are currently applied % fails - nothing else to push $ hg qpush patch series already fully applied [1] % does nothing and succeeds $ hg qpush test2.patch qpush: test2.patch is already at the top strip $ cd ../../b $ echo x>x $ hg ci -Ama adding x $ hg strip tip 0 files updated, 0 files merged, 1 files removed, 0 files unresolved saved backup bundle to $TESTTMP/b/.hg/strip-backup/*-backup.hg (glob) $ hg unbundle .hg/strip-backup/* adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files new changesets 770eb8fce608 (1 drafts) (run 'hg update' to get a working copy) strip with local changes, should complain $ hg up 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo y>y $ hg add y $ hg strip tip abort: local changes found [255] --force strip with local changes $ hg strip -f tip 0 files updated, 0 files merged, 1 files removed, 0 files unresolved saved backup bundle to $TESTTMP/b/.hg/strip-backup/770eb8fce608-0ddcae0f-backup.hg $ cd .. cd b; hg qrefresh $ hg init refresh $ cd refresh $ echo a > a $ hg ci -Ama adding a $ hg qnew -mfoo foo $ echo a >> a $ hg qrefresh $ mkdir b $ cd b $ echo f > f $ hg add f $ hg qrefresh $ cat ../.hg/patches/foo foo diff -r cb9a9f314b8b a --- a/a\t(?P<date>.*) (re) \+\+\+ b/a\t(?P<date>.*) (re) @@ -1,1 +1,2 @@ a +a diff -r cb9a9f314b8b b/f --- /dev/null\t(?P<date>.*) (re) \+\+\+ b/b/f\t(?P<date>.*) (re) @@ -0,0 +1,1 @@ +f hg qrefresh . $ hg qrefresh . $ cat ../.hg/patches/foo foo diff -r cb9a9f314b8b b/f --- /dev/null\t(?P<date>.*) (re) \+\+\+ b/b/f\t(?P<date>.*) (re) @@ -0,0 +1,1 @@ +f $ hg status M a qpush failure $ cd .. $ hg qrefresh $ hg qnew -mbar bar $ echo foo > foo $ echo bar > bar $ hg add foo bar $ hg qrefresh $ hg qpop -a popping bar popping foo patch queue now empty $ echo bar > foo $ hg qpush -a applying foo applying bar file foo already exists 1 out of 1 hunks FAILED -- saving rejects to file foo.rej patch failed, unable to continue (try -v) patch failed, rejects left in working directory errors during apply, please fix and qrefresh bar [2] $ hg st ? foo ? foo.rej mq tags $ hg log --template '{rev} {tags}\n' -r qparent:qtip 0 qparent 1 foo qbase 2 bar qtip tip mq revset $ hg log -r 'mq()' --template '{rev}\n' 1 2 $ hg help revisions.mq "mq()" Changesets managed by MQ. bad node in status $ hg qpop popping bar now at: foo $ hg strip -qn tip $ hg tip changeset: 0:cb9a9f314b8b tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: a $ hg branches default 0:cb9a9f314b8b $ hg qpop no patches applied [1] $ cd .. git patches $ cat >>$HGRCPATH <<EOF > [diff] > git = True > EOF $ hg init git $ cd git $ hg qinit $ hg qnew -m'new file' new $ echo foo > new #if execbit $ chmod +x new #endif $ hg add new $ hg qrefresh $ cat .hg/patches/new new file diff --git a/new b/new new file mode 100755 (execbit !) new file mode 100644 (no-execbit !) --- /dev/null +++ b/new @@ -0,0 +1,1 @@ +foo $ hg qnew -m'copy file' copy $ hg cp new copy $ hg qrefresh $ cat .hg/patches/copy copy file diff --git a/new b/copy copy from new copy to copy $ hg qpop popping copy now at: new $ hg qpush applying copy now at: copy $ hg qdiff diff --git a/new b/copy copy from new copy to copy $ cat >>$HGRCPATH <<EOF > [diff] > git = False > EOF $ hg qdiff --git diff --git a/new b/copy copy from new copy to copy $ cd .. empty lines in status $ hg init emptystatus $ cd emptystatus $ hg qinit $ printf '\n\n' > .hg/patches/status $ hg qser $ cd .. bad line in status (without ":") $ hg init badstatus $ cd badstatus $ hg qinit $ printf 'babar has no colon in this line\n' > .hg/patches/status $ hg qser malformated mq status line: ['babar has no colon in this line'] $ cd .. test file addition in slow path $ hg init slow $ cd slow $ hg qinit $ echo foo > foo $ hg add foo $ hg ci -m 'add foo' $ hg qnew bar $ echo bar > bar $ hg add bar $ hg mv foo baz $ hg qrefresh --git $ hg up -C 0 1 files updated, 0 files merged, 2 files removed, 0 files unresolved $ echo >> foo $ hg ci -m 'change foo' created new head $ hg up -C 1 2 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg qrefresh --git $ cat .hg/patches/bar diff --git a/bar b/bar new file mode 100644 --- /dev/null +++ b/bar @@ -0,0 +1,1 @@ +bar diff --git a/foo b/baz rename from foo rename to baz $ hg log -v --template '{rev} {file_copies}\n' -r . 2 baz (foo) $ hg qrefresh --git $ cat .hg/patches/bar diff --git a/bar b/bar new file mode 100644 --- /dev/null +++ b/bar @@ -0,0 +1,1 @@ +bar diff --git a/foo b/baz rename from foo rename to baz $ hg log -v --template '{rev} {file_copies}\n' -r . 2 baz (foo) $ hg qrefresh $ grep 'diff --git' .hg/patches/bar diff --git a/bar b/bar diff --git a/foo b/baz test file move chains in the slow path $ hg up -C 1 1 files updated, 0 files merged, 2 files removed, 0 files unresolved $ echo >> foo $ hg ci -m 'change foo again' $ hg up -C 2 2 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg mv bar quux $ hg mv baz bleh $ hg qrefresh --git $ cat .hg/patches/bar diff --git a/foo b/bleh rename from foo rename to bleh diff --git a/quux b/quux new file mode 100644 --- /dev/null +++ b/quux @@ -0,0 +1,1 @@ +bar $ hg log -v --template '{rev} {file_copies}\n' -r . 3 bleh (foo) $ hg mv quux fred $ hg mv bleh barney $ hg qrefresh --git $ cat .hg/patches/bar diff --git a/foo b/barney rename from foo rename to barney diff --git a/fred b/fred new file mode 100644 --- /dev/null +++ b/fred @@ -0,0 +1,1 @@ +bar $ hg log -v --template '{rev} {file_copies}\n' -r . 3 barney (foo) refresh omitting an added file $ hg qnew baz $ echo newfile > newfile $ hg add newfile $ hg qrefresh $ hg st -A newfile C newfile $ hg qrefresh -X newfile $ hg st -A newfile A newfile $ hg revert newfile $ rm newfile $ hg qpop popping baz now at: bar test qdel/qrm $ hg qdel baz $ echo p >> .hg/patches/series $ hg qrm p $ hg qser bar create a git patch $ echo a > alexander $ hg add alexander $ hg qnew -f --git addalexander $ grep diff .hg/patches/addalexander diff --git a/alexander b/alexander create a git binary patch $ cat > writebin.py <<EOF > import sys > path = sys.argv[1] > open(path, 'wb').write(b'BIN\x00ARY') > EOF $ "$PYTHON" writebin.py bucephalus $ "$PYTHON" "$TESTDIR/md5sum.py" bucephalus 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus $ hg add bucephalus $ hg qnew -f --git addbucephalus $ grep diff .hg/patches/addbucephalus diff --git a/bucephalus b/bucephalus check binary patches can be popped and pushed $ hg qpop popping addbucephalus now at: addalexander $ test -f bucephalus && echo % bucephalus should not be there [1] $ hg qpush applying addbucephalus now at: addbucephalus $ test -f bucephalus $ "$PYTHON" "$TESTDIR/md5sum.py" bucephalus 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus strip again $ cd .. $ hg init strip $ cd strip $ touch foo $ hg add foo $ hg ci -m 'add foo' $ echo >> foo $ hg ci -m 'change foo 1' $ hg up -C 0 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo 1 >> foo $ hg ci -m 'change foo 2' created new head $ HGMERGE=true hg merge merging foo 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg ci -m merge $ hg log changeset: 3:99615015637b tag: tip parent: 2:20cbbe65cff7 parent: 1:d2871fc282d4 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: merge changeset: 2:20cbbe65cff7 parent: 0:53245c60e682 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: change foo 2 changeset: 1:d2871fc282d4 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: change foo 1 changeset: 0:53245c60e682 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: add foo $ hg strip 1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved saved backup bundle to $TESTTMP/strip/.hg/strip-backup/*-backup.hg (glob) $ checkundo strip $ hg log changeset: 1:20cbbe65cff7 tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: change foo 2 changeset: 0:53245c60e682 user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: add foo $ cd .. qclone $ qlog() > { > echo 'main repo:' > hg log --template ' rev {rev}: {desc}\n' > echo 'patch repo:' > hg -R .hg/patches log --template ' rev {rev}: {desc}\n' > } $ hg init qclonesource $ cd qclonesource $ echo foo > foo $ hg add foo $ hg ci -m 'add foo' $ hg qinit $ hg qnew patch1 $ echo bar >> foo $ hg qrefresh -m 'change foo' $ cd .. repo with unversioned patch dir $ hg qclone qclonesource failure abort: versioned patch repository not found (see init --mq) [255] $ cd qclonesource $ hg qinit -c adding .hg/patches/patch1 $ hg qci -m checkpoint $ qlog main repo: rev 1: change foo rev 0: add foo patch repo: rev 0: checkpoint $ cd .. repo with patches applied $ hg qclone qclonesource qclonedest updating to branch default 3 files updated, 0 files merged, 0 files removed, 0 files unresolved 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd qclonedest $ qlog main repo: rev 0: add foo patch repo: rev 0: checkpoint $ cd .. repo with patches unapplied $ cd qclonesource $ hg qpop -a popping patch1 patch queue now empty $ qlog main repo: rev 0: add foo patch repo: rev 0: checkpoint $ cd .. $ hg qclone qclonesource qclonedest2 updating to branch default 3 files updated, 0 files merged, 0 files removed, 0 files unresolved 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd qclonedest2 $ qlog main repo: rev 0: add foo patch repo: rev 0: checkpoint $ cd .. Issue1033: test applying on an empty file $ hg init empty $ cd empty $ touch a $ hg ci -Am addempty adding a $ echo a > a $ hg qnew -f -e changea $ hg qpop popping changea patch queue now empty $ hg qpush applying changea now at: changea $ cd .. test qpush with --force, issue1087 $ hg init forcepush $ cd forcepush $ echo hello > hello.txt $ echo bye > bye.txt $ hg ci -Ama adding bye.txt adding hello.txt $ hg qnew -d '0 0' empty $ hg qpop popping empty patch queue now empty $ echo world >> hello.txt qpush should fail, local changes $ hg qpush abort: local changes found [255] apply force, should not discard changes with empty patch $ hg qpush -f applying empty patch empty is empty now at: empty $ hg diff --config diff.nodates=True diff -r d58265112590 hello.txt --- a/hello.txt +++ b/hello.txt @@ -1,1 +1,2 @@ hello +world $ hg qdiff --config diff.nodates=True diff -r 9ecee4f634e3 hello.txt --- a/hello.txt +++ b/hello.txt @@ -1,1 +1,2 @@ hello +world $ hg log -l1 -p changeset: 1:d58265112590 tag: empty tag: qbase tag: qtip tag: tip user: test date: Thu Jan 01 00:00:00 1970 +0000 summary: imported patch empty $ hg qref -d '0 0' $ hg qpop popping empty patch queue now empty $ echo universe >> hello.txt $ echo universe >> bye.txt qpush should fail, local changes $ hg qpush abort: local changes found [255] apply force, should discard changes in hello, but not bye $ hg qpush -f --verbose --config 'ui.origbackuppath=.hg/origbackups' applying empty creating directory: $TESTTMP/forcepush/.hg/origbackups saving current version of hello.txt as .hg/origbackups/hello.txt patching file hello.txt committing files: hello.txt committing manifest committing changelog now at: empty $ hg st M bye.txt $ hg diff --config diff.nodates=True diff -r ba252371dbc1 bye.txt --- a/bye.txt +++ b/bye.txt @@ -1,1 +1,2 @@ bye +universe $ hg qdiff --config diff.nodates=True diff -r 9ecee4f634e3 bye.txt --- a/bye.txt +++ b/bye.txt @@ -1,1 +1,2 @@ bye +universe diff -r 9ecee4f634e3 hello.txt --- a/hello.txt +++ b/hello.txt @@ -1,1 +1,3 @@ hello +world +universe test that the previous call to qpush with -f (--force) and --config actually put the orig files out of the working copy $ ls .hg/origbackups hello.txt test popping revisions not in working dir ancestry $ hg qseries -v 0 A empty $ hg up qparent 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg qpop popping empty patch queue now empty $ cd .. $ hg init deletion-order $ cd deletion-order $ touch a $ hg ci -Aqm0 $ hg qnew rename-dir $ hg rm a $ hg qrefresh $ mkdir a b $ touch a/a b/b $ hg add -q a b $ hg qrefresh test popping must remove files added in subdirectories first $ hg qpop popping rename-dir patch queue now empty $ cd .. test case preservation through patch pushing especially on case insensitive filesystem $ hg init casepreserve $ cd casepreserve $ hg qnew add-file1 $ echo a > TeXtFiLe.TxT $ hg add TeXtFiLe.TxT $ hg qrefresh $ hg qnew add-file2 $ echo b > AnOtHeRFiLe.TxT $ hg add AnOtHeRFiLe.TxT $ hg qrefresh $ hg qnew modify-file $ echo c >> AnOtHeRFiLe.TxT $ hg qrefresh $ hg qapplied add-file1 add-file2 modify-file $ hg qpop -a popping modify-file popping add-file2 popping add-file1 patch queue now empty this qpush causes problems below, if case preservation on case insensitive filesystem is not enough: (1) unexpected "adding ..." messages are shown (2) patching fails in modification of (1) files $ hg qpush -a applying add-file1 applying add-file2 applying modify-file now at: modify-file Proper phase default with mq: 1. mq.secret=false $ rm .hg/store/phaseroots $ hg phase 'qparent::' -1: public 0: draft 1: draft 2: draft $ echo '[mq]' >> $HGRCPATH $ echo 'secret=true' >> $HGRCPATH $ rm -f .hg/store/phaseroots $ hg phase 'qparent::' -1: public 0: secret 1: secret 2: secret Test that qfinish change phase when mq.secret=true $ hg qfinish qbase patch add-file1 finalized without changeset message $ hg phase 'all()' 0: draft 1: secret 2: secret Test that qfinish respect phases.new-commit setting $ echo '[phases]' >> $HGRCPATH $ echo 'new-commit=secret' >> $HGRCPATH $ hg qfinish qbase patch add-file2 finalized without changeset message $ hg phase 'all()' 0: draft 1: secret 2: secret (restore env for next test) $ sed -e 's/new-commit=secret//' $HGRCPATH > $TESTTMP/sedtmp $ cp $TESTTMP/sedtmp $HGRCPATH $ hg qimport -r 1 --name add-file2 Test that qfinish preserve phase when mq.secret=false $ sed -e 's/secret=true/secret=false/' $HGRCPATH > $TESTTMP/sedtmp $ cp $TESTTMP/sedtmp $HGRCPATH $ hg qfinish qbase patch add-file2 finalized without changeset message $ hg phase 'all()' 0: draft 1: secret 2: secret Test that secret mq patch does not break hgweb $ cat > hgweb.cgi <<HGWEB > from mercurial import demandimport; demandimport.enable() > from mercurial.hgweb import hgweb > from mercurial.hgweb import wsgicgi > import cgitb > cgitb.enable() > app = hgweb(b'.', b'test') > wsgicgi.launch(app) > HGWEB $ . "$TESTDIR/cgienv" #if msys $ PATH_INFO=//tags; export PATH_INFO #else $ PATH_INFO=/tags; export PATH_INFO #endif $ QUERY_STRING='style=raw' $ "$PYTHON" hgweb.cgi | grep '^tip' tip [0-9a-f]{40} (re) $ cd .. Test interaction with revset (issue4426) $ hg init issue4426 $ cd issue4426 $ echo a > a $ hg ci -Am a adding a $ echo a >> a $ hg ci -m a $ echo a >> a $ hg ci -m a $ hg qimport -r 0:: reimport things $ hg qimport -r 1:: abort: revision 2 is already managed [255] $ cd ..