sapling/tests/test-fb-hgext-pushrebase-hgsql-mfs.t
Durham Goode 3309a8090a pushrebase: read the manifest before looping through files
Summary:
pushrebase has logic that loops through all the files and builds a list
of what has changed. Unfortunately, Mercurial has some optimizations where if
the manifest isn't loaded already, it tries to only load the manifest delta, and
checks if this might be a good idea by first checking if the file is in the
commit metadata file list. The commit metadata is a list, which makes it a O(n)
scan to check containment. Since we do this for every file, it becomes O(n^2).

To avoid this, let's just make sure the actual manifest is loaded.

Once every repo is a tree repo, we can get rid of the manifest delta
optimization and get rid of the need to prefetch here.

Reviewed By: singhsrb

Differential Revision: D13944829

fbshipit-source-id: c0f33ca650b7956a1f39e961c94678a6f7f380b6
2019-02-05 16:05:50 -08:00

261 lines
7.1 KiB
Perl

TODO: Make this test work with obsstore
$ setconfig experimental.evolution=
$ . "$TESTDIR/hgsql/library.sh"
$ setconfig ui.ssh='python "$RUNTESTDIR/dummyssh"'
$ commit() {
> hg commit -Aq -m "$@"
> }
$ log() {
> hg log -G -T "{desc} [{phase}:{node|short}] {bookmarks} {remotenames}" "$@"
> }
$ config() {
> setconfig experimental.bundle2lazylocking=True
> setconfig pushrebase.debugprintmanifestreads=True
> setconfig pushrebase.debugprintmanifestreads.user=True
> enable pushrebase
> }
$ config_server() {
> config
> configureserver . foo
> }
$ clone() { # Usage: "clone <client directory> <source directory>
> SRC=${2:-server1}
> hg clone ssh://user@dummy/$SRC $1 -q
> cd $1
> hg up -q master
> config
> }
Set up server repository.
$ newrepo server1
$ config_server
$ echo foo > base
$ commit "base"
$ hg book -r . master
$ cd ..
$ newrepo server2
$ config_server
Clone client1 and client2 from the server repo.
$ cd ..
$ clone client1
$ cd ..
$ clone client2 server2
Make some non-conflicting commits in in the client repos.
$ cd ../client1
$ echo 'xxx' > c1
$ commit 'first commit'
*FULL* manifest read for 1e4ac5512124 (*inside* lock)
$ echo 'baz' > c1
$ commit 'second commit'
*FULL* manifest read for bef5a3bb1f24 (*inside* lock)
$ log
@ second commit [draft:0a57cb610829] master
|
o first commit [draft:679b2ce82944]
|
o base [public:4ced94c0a443]
$ hg push -q -r tip --to master
*FULL* manifest read for 8655e3409b0e (outside lock)
$ log
@ second commit [public:0a57cb610829] master
|
o first commit [public:679b2ce82944]
|
o base [public:4ced94c0a443]
$ cd ../client2
$ hg pull -q
$ log
o second commit [public:0a57cb610829] master
|
o first commit [public:679b2ce82944]
|
@ base [public:4ced94c0a443]
$ echo 'yyy' > c2
$ commit 'third commit'
*FULL* manifest read for 1e4ac5512124 (*inside* lock)
$ log
@ third commit [draft:8ee8e01cbc17]
|
| o second commit [public:0a57cb610829] master
| |
| o first commit [public:679b2ce82944]
|/
o base [public:4ced94c0a443]
$ hg push -r . --to master
pushing to ssh://user@dummy/server2
*FULL* manifest read for 46410a8f6645 (outside lock)
searching for changes
remote: *FULL* manifest read for 1e4ac5512124 (outside lock)
remote: cached manifest read for 1e4ac5512124 (outside lock)
remote: cached manifest read for 1e4ac5512124 (outside lock)
remote: *FULL* manifest read for 8655e3409b0e (outside lock)
remote: pushing 1 changeset:
remote: 8ee8e01cbc17 third commit
remote: 1 new changeset from the server will be downloaded
adding changesets
adding manifests
adding file changes
added 1 changesets with 0 changes to 1 files
$ hg pull -q
$ log
o third commit [public:e71dff9ebf0e]
|
| @ third commit [draft:8ee8e01cbc17]
| |
o | second commit [public:0a57cb610829] master
| |
o | first commit [public:679b2ce82944]
|/
o base [public:4ced94c0a443]
The two server repos should look identical:
$ cd ../server1
$ log
o third commit [public:e71dff9ebf0e]
|
o second commit [public:0a57cb610829] master
|
o first commit [public:679b2ce82944]
|
@ base [public:4ced94c0a443]
$ cd ../server2
$ log
o third commit [public:e71dff9ebf0e]
|
o second commit [public:0a57cb610829] master
|
o first commit [public:679b2ce82944]
|
o base [public:4ced94c0a443]
Add a hook to the server to make it spin until .hg/flag exists:
$ cd ../server1
$ cp .hg/hgrc .hg/hgrc.bak
$ echo "[hooks]" >> .hg/hgrc
$ echo "prepushrebase.wait=python:$TESTDIR/hgsql/waithook.py:waithook" >> .hg/hgrc
Push from client1 -> server1 and detach. The background job will wait for
.hg/flag.
$ cd ../client1
$ echo 'yyy' > d1
$ commit 'race loser'
*FULL* manifest read for 8655e3409b0e (*inside* lock)
$ log
@ race loser [draft:0ee934622ec8] master
|
o second commit [public:0a57cb610829]
|
o first commit [public:679b2ce82944]
|
o base [public:4ced94c0a443]
$ hg push --to master 2>&1 | \sed "s/^/[client1 push] /" &
Wait for the first push to actually enter the hook before removing it.
$ cd ../server1
$ while [ ! -f ".hg/hookrunning" ]; do sleep 0.01; done
Meanwhile, push from client2 -> server2.
$ cd ../client2
$ echo 'qqq' > d2
$ commit 'race winner'
*FULL* manifest read for 46410a8f6645 (*inside* lock)
$ log
@ race winner [draft:0e59db56ba07]
|
| o third commit [public:e71dff9ebf0e]
| |
o | third commit [draft:8ee8e01cbc17]
| |
| o second commit [public:0a57cb610829] master
| |
| o first commit [public:679b2ce82944]
|/
o base [public:4ced94c0a443]
$ hg push --to master 2>&1 | \sed "s/^/[client2 push] /"
[client2 push] pushing to ssh://user@dummy/server2
[client2 push] *FULL* manifest read for bb1129e7c430 (outside lock)
[client2 push] searching for changes
[client2 push] remote: *FULL* manifest read for 1e4ac5512124 (outside lock)
[client2 push] remote: cached manifest read for 1e4ac5512124 (outside lock)
[client2 push] remote: cached manifest read for 1e4ac5512124 (outside lock)
[client2 push] remote: *FULL* manifest read for 8655e3409b0e (outside lock)
[client2 push] remote: pushing 2 changesets:
[client2 push] remote: 8ee8e01cbc17 third commit
[client2 push] remote: 0e59db56ba07 race winner
[client2 push] remote: *FULL* manifest read for 0bf21a535a1f (*inside* lock)
[client2 push] remote: 1 new changeset from the server will be downloaded
[client2 push] adding changesets
[client2 push] adding manifests
[client2 push] adding file changes
[client2 push] added 1 changesets with 0 changes to 1 files
Check that the first push is still running/blocked...
$ jobs
[1]+ Running hg push --to master 2>&1 | \sed "s/^/[client1 push] /" & (wd: ~/client1)
...then allow it through.
$ cd ../server1
$ touch .hg/flag
$ wait
[client1 push] pushing to ssh://user@dummy/server1
[client1 push] *FULL* manifest read for 9210795ca8ad (outside lock)
[client1 push] searching for changes
[client1 push] remote: *FULL* manifest read for 8655e3409b0e (outside lock)
[client1 push] remote: cached manifest read for 8655e3409b0e (outside lock)
[client1 push] remote: cached manifest read for 8655e3409b0e (outside lock)
[client1 push] remote: pushing 1 changeset:
[client1 push] remote: 0ee934622ec8 race loser
[client1 push] remote: cached manifest read for 8655e3409b0e (*inside* lock)
[client1 push] updating bookmark master
$ log
o race loser [public:0ee934622ec8] master
|
| o race winner [public:f265c7c9f0c9]
| |
| o third commit [public:e71dff9ebf0e]
|/
o second commit [public:0a57cb610829]
|
o first commit [public:679b2ce82944]
|
@ base [public:4ced94c0a443]
$ cd ../server2
$ log
o race loser [public:0ee934622ec8] master
|
| o race winner [public:f265c7c9f0c9]
| |
| o third commit [public:e71dff9ebf0e]
|/
o second commit [public:0a57cb610829]
|
o first commit [public:679b2ce82944]
|
o base [public:4ced94c0a443]