D5169: exchangev2: support fetching shallow files history
indygreg (Gregory Szorc)
phabricator at mercurial-scm.org
Mon Oct 22 11:49:47 EDT 2018
This revision was automatically updated to reflect the committed changes.
Closed by commit rHG229d23cdb203: exchangev2: support fetching shallow files history (authored by indygreg, committed by ).
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D5169?vs=12275&id=12305
REVISION DETAIL
https://phab.mercurial-scm.org/D5169
AFFECTED FILES
mercurial/exchangev2.py
tests/pullext.py
tests/test-wireproto-exchangev2-shallow.t
tests/test-wireproto-exchangev2.t
CHANGE DETAILS
diff --git a/tests/test-wireproto-exchangev2.t b/tests/test-wireproto-exchangev2.t
--- a/tests/test-wireproto-exchangev2.t
+++ b/tests/test-wireproto-exchangev2.t
@@ -1145,3 +1145,94 @@
client-stream-2/.hg/store/data/dir0/c.i
client-stream-2/.hg/store/data/dir0/d.i
#endif
+
+Shallow clone doesn't work with revlogs
+
+ $ hg --debug --config extensions.pullext=$TESTDIR/pullext.py clone --depth 1 -U http://localhost:$HGPORT client-shallow-revlogs
+ using http://localhost:$HGPORT/
+ sending capabilities command
+ query 1; heads
+ sending 2 commands
+ sending command heads: {}
+ sending command known: {
+ 'nodes': []
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
+ sending 1 commands
+ sending command changesetdata: {
+ 'fields': set([
+ 'bookmarks',
+ 'parents',
+ 'phase',
+ 'revision'
+ ]),
+ 'revisions': [
+ {
+ 'heads': [
+ '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
+ ],
+ 'roots': [],
+ 'type': 'changesetdagrange'
+ }
+ ]
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=783; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ add changeset 3390ef850073
+ add changeset b709380892b1
+ add changeset 47fe012ab237
+ add changeset 97765fc3cd62
+ checking for updated bookmarks
+ sending 1 commands
+ sending command manifestdata: {
+ 'fields': set([
+ 'parents',
+ 'revision'
+ ]),
+ 'haveparents': True,
+ 'nodes': [
+ '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
+ '|2 \x1a\xa3\xa1R\xa9\xe6\xa9"+?\xa8\xd0\xe3\x0f\xc2V\xe8',
+ '\x8d\xd0W<\x7f\xaf\xe2\x04F\xcc\xea\xac\x05N\xea\xa4x\x91M\xdb',
+ '113\x85\xf2!\x8b\x08^\xb2Z\x821\x1e*\xdd\x0e\xeb\x8c3'
+ ],
+ 'tree': ''
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=967; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ sending 1 commands
+ sending command filesdata: {
+ 'fields': set([
+ 'linknode',
+ 'parents',
+ 'revision'
+ ]),
+ 'haveparents': False,
+ 'revisions': [
+ {
+ 'nodes': [
+ '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
+ ],
+ 'type': 'changesetexplicit'
+ }
+ ]
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=1005; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ transaction abort!
+ rollback completed
+ (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
+ abort: revlog storage does not support missing parents write mode
+ [255]
diff --git a/tests/test-wireproto-exchangev2-shallow.t b/tests/test-wireproto-exchangev2-shallow.t
new file mode 100644
--- /dev/null
+++ b/tests/test-wireproto-exchangev2-shallow.t
@@ -0,0 +1,568 @@
+#require sqlite
+
+Tests for wire protocol version 2 exchange.
+Tests in this file should be folded into existing tests once protocol
+v2 has enough features that it can be enabled via #testcase in existing
+tests.
+
+ $ . $TESTDIR/wireprotohelpers.sh
+ $ enablehttpv2client
+ $ cat >> $HGRCPATH << EOF
+ > [extensions]
+ > sqlitestore =
+ > pullext = $TESTDIR/pullext.py
+ > [storage]
+ > new-repo-backend=sqlite
+ > EOF
+
+Configure a server
+
+ $ hg init server-basic
+ $ enablehttpv2 server-basic
+ $ cd server-basic
+ $ mkdir dir0 dir1
+ $ echo a0 > a
+ $ echo b0 > b
+ $ hg -q commit -A -m 'commit 0'
+ $ echo c0 > dir0/c
+ $ echo d0 > dir0/d
+ $ hg -q commit -A -m 'commit 1'
+ $ echo e0 > dir1/e
+ $ echo f0 > dir1/f
+ $ hg -q commit -A -m 'commit 2'
+ $ echo c1 > dir0/c
+ $ echo e1 > dir1/e
+ $ hg commit -m 'commit 3'
+ $ echo c2 > dir0/c
+ $ echo e2 > dir1/e
+ $ echo f1 > dir1/f
+ $ hg commit -m 'commit 4'
+ $ echo a1 > a
+ $ echo b1 > b
+ $ hg commit -m 'commit 5'
+
+ $ hg log -G -T '{node} {desc}'
+ @ 93a8bd067ed2840d9aa810ad598168383a3a2c3a commit 5
+ |
+ o dc666cf9ecf3d94e6b830f30e5f1272e2a9164d9 commit 4
+ |
+ o 97765fc3cd624fd1fa0176932c21ffd16adf432e commit 3
+ |
+ o 47fe012ab237a8c7fc0c78f9f26d5866eef3f825 commit 2
+ |
+ o b709380892b193c1091d3a817f706052e346821b commit 1
+ |
+ o 3390ef850073fbc2f0dfff2244342c8e9229013a commit 0
+
+ $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
+ $ cat hg.pid > $DAEMON_PIDS
+
+ $ cd ..
+
+Shallow clone pulls down latest revision of every file
+
+ $ hg --debug clone --depth 1 http://localhost:$HGPORT client-shallow-1
+ using http://localhost:$HGPORT/
+ sending capabilities command
+ query 1; heads
+ sending 2 commands
+ sending command heads: {}
+ sending command known: {
+ 'nodes': []
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
+ sending 1 commands
+ sending command changesetdata: {
+ 'fields': set([
+ 'bookmarks',
+ 'parents',
+ 'phase',
+ 'revision'
+ ]),
+ 'revisions': [
+ {
+ 'heads': [
+ '\x93\xa8\xbd\x06~\xd2\x84\r\x9a\xa8\x10\xadY\x81h8::,:'
+ ],
+ 'roots': [],
+ 'type': 'changesetdagrange'
+ }
+ ]
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=1170; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ add changeset 3390ef850073
+ add changeset b709380892b1
+ add changeset 47fe012ab237
+ add changeset 97765fc3cd62
+ add changeset dc666cf9ecf3
+ add changeset 93a8bd067ed2
+ checking for updated bookmarks
+ sending 1 commands
+ sending command manifestdata: {
+ 'fields': set([
+ 'parents',
+ 'revision'
+ ]),
+ 'haveparents': True,
+ 'nodes': [
+ '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
+ '|2 \x1a\xa3\xa1R\xa9\xe6\xa9"+?\xa8\xd0\xe3\x0f\xc2V\xe8',
+ '\x8d\xd0W<\x7f\xaf\xe2\x04F\xcc\xea\xac\x05N\xea\xa4x\x91M\xdb',
+ '113\x85\xf2!\x8b\x08^\xb2Z\x821\x1e*\xdd\x0e\xeb\x8c3',
+ 'H]O\xc2`\xef\\\xb9\xc0p6\x88K\x00k\x11\x0ej\xdby',
+ '\xd9;\xc4\x0b\x0e*GMp\xee\xf7}^\x91/f\x7fSd\x83'
+ ],
+ 'tree': ''
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=1515; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ sending 1 commands
+ sending command filesdata: {
+ 'fields': set([
+ 'linknode',
+ 'parents',
+ 'revision'
+ ]),
+ 'haveparents': False,
+ 'revisions': [
+ {
+ 'nodes': [
+ '\x93\xa8\xbd\x06~\xd2\x84\r\x9a\xa8\x10\xadY\x81h8::,:'
+ ],
+ 'type': 'changesetexplicit'
+ }
+ ]
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=1005; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ updating the branch cache
+ new changesets 3390ef850073:93a8bd067ed2
+ updating to branch default
+ resolving manifests
+ branchmerge: False, force: False, partial: False
+ ancestor: 000000000000, local: 000000000000+, remote: 93a8bd067ed2
+ a: remote created -> g
+ getting a
+ b: remote created -> g
+ getting b
+ dir0/c: remote created -> g
+ getting dir0/c
+ dir0/d: remote created -> g
+ getting dir0/d
+ dir1/e: remote created -> g
+ getting dir1/e
+ dir1/f: remote created -> g
+ getting dir1/f
+ 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
+
+ $ sqlite3 -line client-shallow-1/.hg/store/db.sqlite << EOF
+ > SELECT id, path, revnum, node, p1rev, p2rev, linkrev, flags FROM filedata ORDER BY id ASC;
+ > EOF
+ id = 1
+ path = a
+ revnum = 0
+ node = \x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc (esc)
+ p1rev = -1
+ p2rev = -1
+ linkrev = 5
+ flags = 2
+
+ id = 2
+ path = b
+ revnum = 0
+ node = \xb1zk\xd3g=\x9a\xb8\xce\xd5\x81\xa2 \xf6/=\xa5\xccEx (esc)
+ p1rev = -1
+ p2rev = -1
+ linkrev = 5
+ flags = 2
+
+ id = 3
+ path = dir0/c
+ revnum = 0
+ node = I\x1d\xa1\xbb\x89\xeax\xc0\xc0\xa2s[\x16\xce}\x93\x1d\xc8\xe2\r (esc)
+ p1rev = -1
+ p2rev = -1
+ linkrev = 4
+ flags = 2
+
+ id = 4
+ path = dir0/d
+ revnum = 0
+ node = S\x82\x06\xdc\x97\x1eR\x15@\xd6\x84:\xbf\xe6\xd1`2\xf6\xd4& (esc)
+ p1rev = -1
+ p2rev = -1
+ linkrev = 1
+ flags = 0
+
+ id = 5
+ path = dir1/e
+ revnum = 0
+ node = ]\xf3\xac\xd8\xd0\xc7\xfaP\x98\xd0'\x9a\x044\xc3\x02\x9e+x\xe1 (esc)
+ p1rev = -1
+ p2rev = -1
+ linkrev = 4
+ flags = 2
+
+ id = 6
+ path = dir1/f
+ revnum = 0
+ node = (\xc7v\xae\x08\xd0\xd5^\xb4\x06H\xb4\x01\xb9\x0f\xf5DH4\x8e (esc)
+ p1rev = -1
+ p2rev = -1
+ linkrev = 4
+ flags = 2
+
+Test a shallow clone with only some files
+
+ $ hg --debug clone --depth 1 --include dir0/ http://localhost:$HGPORT client-shallow-narrow-1
+ using http://localhost:$HGPORT/
+ sending capabilities command
+ query 1; heads
+ sending 2 commands
+ sending command heads: {}
+ sending command known: {
+ 'nodes': []
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
+ sending 1 commands
+ sending command changesetdata: {
+ 'fields': set([
+ 'bookmarks',
+ 'parents',
+ 'phase',
+ 'revision'
+ ]),
+ 'revisions': [
+ {
+ 'heads': [
+ '\x93\xa8\xbd\x06~\xd2\x84\r\x9a\xa8\x10\xadY\x81h8::,:'
+ ],
+ 'roots': [],
+ 'type': 'changesetdagrange'
+ }
+ ]
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=1170; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ add changeset 3390ef850073
+ add changeset b709380892b1
+ add changeset 47fe012ab237
+ add changeset 97765fc3cd62
+ add changeset dc666cf9ecf3
+ add changeset 93a8bd067ed2
+ checking for updated bookmarks
+ sending 1 commands
+ sending command manifestdata: {
+ 'fields': set([
+ 'parents',
+ 'revision'
+ ]),
+ 'haveparents': True,
+ 'nodes': [
+ '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
+ '|2 \x1a\xa3\xa1R\xa9\xe6\xa9"+?\xa8\xd0\xe3\x0f\xc2V\xe8',
+ '\x8d\xd0W<\x7f\xaf\xe2\x04F\xcc\xea\xac\x05N\xea\xa4x\x91M\xdb',
+ '113\x85\xf2!\x8b\x08^\xb2Z\x821\x1e*\xdd\x0e\xeb\x8c3',
+ 'H]O\xc2`\xef\\\xb9\xc0p6\x88K\x00k\x11\x0ej\xdby',
+ '\xd9;\xc4\x0b\x0e*GMp\xee\xf7}^\x91/f\x7fSd\x83'
+ ],
+ 'tree': ''
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=1515; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ sending 1 commands
+ sending command filesdata: {
+ 'fields': set([
+ 'linknode',
+ 'parents',
+ 'revision'
+ ]),
+ 'haveparents': False,
+ 'pathfilter': {
+ 'include': [
+ 'path:dir0'
+ ]
+ },
+ 'revisions': [
+ {
+ 'nodes': [
+ '\x93\xa8\xbd\x06~\xd2\x84\r\x9a\xa8\x10\xadY\x81h8::,:'
+ ],
+ 'type': 'changesetexplicit'
+ }
+ ]
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=355; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ updating the branch cache
+ new changesets 3390ef850073:93a8bd067ed2
+ updating to branch default
+ resolving manifests
+ branchmerge: False, force: False, partial: False
+ ancestor: 000000000000, local: 000000000000+, remote: 93a8bd067ed2
+ dir0/c: remote created -> g
+ getting dir0/c
+ dir0/d: remote created -> g
+ getting dir0/d
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
+
+ $ sqlite3 -line client-shallow-narrow-1/.hg/store/db.sqlite << EOF
+ > SELECT id, path, revnum, node, p1rev, p2rev, linkrev, flags FROM filedata ORDER BY id ASC;
+ > EOF
+ id = 1
+ path = dir0/c
+ revnum = 0
+ node = I\x1d\xa1\xbb\x89\xeax\xc0\xc0\xa2s[\x16\xce}\x93\x1d\xc8\xe2\r (esc)
+ p1rev = -1
+ p2rev = -1
+ linkrev = 4
+ flags = 2
+
+ id = 2
+ path = dir0/d
+ revnum = 0
+ node = S\x82\x06\xdc\x97\x1eR\x15@\xd6\x84:\xbf\xe6\xd1`2\xf6\xd4& (esc)
+ p1rev = -1
+ p2rev = -1
+ linkrev = 1
+ flags = 0
+
+Cloning an old revision with depth=1 works
+
+ $ hg --debug clone --depth 1 -r 97765fc3cd624fd1fa0176932c21ffd16adf432e http://localhost:$HGPORT client-shallow-2
+ using http://localhost:$HGPORT/
+ sending capabilities command
+ sending 1 commands
+ sending command lookup: {
+ 'key': '97765fc3cd624fd1fa0176932c21ffd16adf432e'
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=21; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ query 1; heads
+ sending 2 commands
+ sending command heads: {}
+ sending command known: {
+ 'nodes': []
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=1; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
+ sending 1 commands
+ sending command changesetdata: {
+ 'fields': set([
+ 'bookmarks',
+ 'parents',
+ 'phase',
+ 'revision'
+ ]),
+ 'revisions': [
+ {
+ 'heads': [
+ '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
+ ],
+ 'roots': [],
+ 'type': 'changesetdagrange'
+ }
+ ]
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=783; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ add changeset 3390ef850073
+ add changeset b709380892b1
+ add changeset 47fe012ab237
+ add changeset 97765fc3cd62
+ checking for updated bookmarks
+ sending 1 commands
+ sending command manifestdata: {
+ 'fields': set([
+ 'parents',
+ 'revision'
+ ]),
+ 'haveparents': True,
+ 'nodes': [
+ '\x99/Gy\x02\x9a=\xf8\xd0fm\x00\xbb\x92OicN&A',
+ '|2 \x1a\xa3\xa1R\xa9\xe6\xa9"+?\xa8\xd0\xe3\x0f\xc2V\xe8',
+ '\x8d\xd0W<\x7f\xaf\xe2\x04F\xcc\xea\xac\x05N\xea\xa4x\x91M\xdb',
+ '113\x85\xf2!\x8b\x08^\xb2Z\x821\x1e*\xdd\x0e\xeb\x8c3'
+ ],
+ 'tree': ''
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=967; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ sending 1 commands
+ sending command filesdata: {
+ 'fields': set([
+ 'linknode',
+ 'parents',
+ 'revision'
+ ]),
+ 'haveparents': False,
+ 'revisions': [
+ {
+ 'nodes': [
+ '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
+ ],
+ 'type': 'changesetexplicit'
+ }
+ ]
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=1005; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ updating the branch cache
+ new changesets 3390ef850073:97765fc3cd62
+ updating to branch default
+ resolving manifests
+ branchmerge: False, force: False, partial: False
+ ancestor: 000000000000, local: 000000000000+, remote: 97765fc3cd62
+ a: remote created -> g
+ getting a
+ b: remote created -> g
+ getting b
+ dir0/c: remote created -> g
+ getting dir0/c
+ dir0/d: remote created -> g
+ getting dir0/d
+ dir1/e: remote created -> g
+ getting dir1/e
+ dir1/f: remote created -> g
+ getting dir1/f
+ 6 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ (sent 6 HTTP requests and * bytes; received * bytes in responses) (glob)
+
+Incremental pull of shallow clone fetches new changesets
+
+ $ hg --cwd client-shallow-2 --debug pull http://localhost:$HGPORT
+ pulling from http://localhost:$HGPORT/
+ using http://localhost:$HGPORT/
+ sending capabilities command
+ query 1; heads
+ sending 2 commands
+ sending command heads: {}
+ sending command known: {
+ 'nodes': [
+ '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
+ ]
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=22; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ received frame(size=11; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=2; request=3; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
+ searching for changes
+ all local heads known remotely
+ sending 1 commands
+ sending command changesetdata: {
+ 'fields': set([
+ 'bookmarks',
+ 'parents',
+ 'phase',
+ 'revision'
+ ]),
+ 'revisions': [
+ {
+ 'heads': [
+ '\x93\xa8\xbd\x06~\xd2\x84\r\x9a\xa8\x10\xadY\x81h8::,:'
+ ],
+ 'roots': [
+ '\x97v_\xc3\xcdbO\xd1\xfa\x01v\x93,!\xff\xd1j\xdfC.'
+ ],
+ 'type': 'changesetdagrange'
+ }
+ ]
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=400; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ add changeset dc666cf9ecf3
+ add changeset 93a8bd067ed2
+ checking for updated bookmarks
+ sending 1 commands
+ sending command manifestdata: {
+ 'fields': set([
+ 'parents',
+ 'revision'
+ ]),
+ 'haveparents': True,
+ 'nodes': [
+ 'H]O\xc2`\xef\\\xb9\xc0p6\x88K\x00k\x11\x0ej\xdby',
+ '\xd9;\xc4\x0b\x0e*GMp\xee\xf7}^\x91/f\x7fSd\x83'
+ ],
+ 'tree': ''
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=561; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ sending 1 commands
+ sending command filesdata: {
+ 'fields': set([
+ 'linknode',
+ 'parents',
+ 'revision'
+ ]),
+ 'haveparents': False,
+ 'revisions': [
+ {
+ 'nodes': [
+ '\xdcfl\xf9\xec\xf3\xd9Nk\x83\x0f0\xe5\xf1\'.*\x91d\xd9',
+ '\x93\xa8\xbd\x06~\xd2\x84\r\x9a\xa8\x10\xadY\x81h8::,:'
+ ],
+ 'type': 'changesetexplicit'
+ }
+ ]
+ }
+ received frame(size=9; request=1; stream=2; streamflags=stream-begin; type=stream-settings; flags=eos)
+ received frame(size=11; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=1373; request=1; stream=2; streamflags=encoded; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ updating the branch cache
+ new changesets dc666cf9ecf3:93a8bd067ed2
+ (run 'hg update' to get a working copy)
+ (sent 5 HTTP requests and * bytes; received * bytes in responses) (glob)
+
+ $ hg --cwd client-shallow-2 up tip
+ merging dir0/c
+ merging dir1/e
+ 3 files updated, 2 files merged, 0 files removed, 0 files unresolved
diff --git a/tests/pullext.py b/tests/pullext.py
--- a/tests/pullext.py
+++ b/tests/pullext.py
@@ -10,6 +10,7 @@
from mercurial.i18n import _
from mercurial import (
commands,
+ error,
extensions,
localrepo,
repository,
@@ -19,6 +20,12 @@
if kwargs.get(r'include') or kwargs.get(r'exclude'):
kwargs[r'narrow'] = True
+ if kwargs.get(r'depth'):
+ try:
+ kwargs[r'depth'] = int(kwargs[r'depth'])
+ except ValueError:
+ raise error.Abort(_('--depth must be an integer'))
+
return orig(ui, repo, *args, **kwargs)
def featuresetup(ui, features):
@@ -28,11 +35,16 @@
entry = extensions.wrapcommand(commands.table, 'clone', clonecommand)
hasinclude = any(x[1] == 'include' for x in entry[1])
+ hasdepth = any(x[1] == 'depth' for x in entry[1])
if not hasinclude:
entry[1].append(('', 'include', [],
_('pattern of file/directory to clone')))
entry[1].append(('', 'exclude', [],
_('pattern of file/directory to not clone')))
+ if not hasdepth:
+ entry[1].append(('', 'depth', '',
+ _('ancestry depth of changesets to fetch')))
+
localrepo.featuresetupfuncs.add(featuresetup)
diff --git a/mercurial/exchangev2.py b/mercurial/exchangev2.py
--- a/mercurial/exchangev2.py
+++ b/mercurial/exchangev2.py
@@ -22,6 +22,7 @@
narrowspec,
phases,
pycompat,
+ repository,
setdiscovery,
)
@@ -91,6 +92,21 @@
manres = _fetchmanifests(repo, tr, remote, csetres['manifestnodes'])
+ # We don't properly support shallow changeset and manifest yet. So we apply
+ # depth limiting locally.
+ if pullop.depth:
+ relevantcsetnodes = set()
+ clnode = repo.changelog.node
+
+ for rev in repo.revs(b'ancestors(%ln, %d)',
+ pullheads, pullop.depth - 1):
+ relevantcsetnodes.add(clnode(rev))
+
+ csetrelevantfilter = lambda n: n in relevantcsetnodes
+
+ else:
+ csetrelevantfilter = lambda n: True
+
# If obtaining the raw store files, we need to scan the full repo to
# derive all the changesets, manifests, and linkrevs.
if usingrawchangelogandmanifest:
@@ -100,22 +116,27 @@
for rev in repo:
ctx = repo[rev]
+ node = ctx.node()
+
+ if not csetrelevantfilter(node):
+ continue
+
mnode = ctx.manifestnode()
- csetsforfiles.append(ctx.node())
+ csetsforfiles.append(node)
mnodesforfiles.append(mnode)
manifestlinkrevs[mnode] = rev
else:
- csetsforfiles = csetres['added']
+ csetsforfiles = [n for n in csetres['added'] if csetrelevantfilter(n)]
mnodesforfiles = manres['added']
manifestlinkrevs = manres['linkrevs']
# Find all file nodes referenced by added manifests and fetch those
# revisions.
fnodes = _derivefilesfrommanifests(repo, narrowmatcher, mnodesforfiles)
_fetchfilesfromcsets(repo, tr, remote, pathfilter, fnodes, csetsforfiles,
- manifestlinkrevs)
+ manifestlinkrevs, shallow=bool(pullop.depth))
def _checkuserawstorefiledata(pullop):
"""Check whether we should use rawstorefiledata command to retrieve data."""
@@ -564,7 +585,7 @@
weakref.proxy(tr))
def _fetchfilesfromcsets(repo, tr, remote, pathfilter, fnodes, csets,
- manlinkrevs):
+ manlinkrevs, shallow=False):
"""Fetch file data from explicit changeset revisions."""
def iterrevisions(objs, remaining, progress):
@@ -588,11 +609,16 @@
else:
continue
+ if b'linknode' in filerevision:
+ linknode = filerevision[b'linknode']
+ else:
+ linknode = node
+
yield (
node,
filerevision[b'parents'][0],
filerevision[b'parents'][1],
- node,
+ linknode,
basenode,
delta,
# Flags not yet supported.
@@ -609,6 +635,21 @@
commandmeta = remote.apidescriptor[b'commands'][b'filesdata']
batchsize = commandmeta.get(b'recommendedbatchsize', 50000)
+ shallowfiles = repository.REPO_FEATURE_SHALLOW_FILE_STORAGE in repo.features
+ fields = {b'parents', b'revision'}
+ clrev = repo.changelog.rev
+
+ # There are no guarantees that we'll have ancestor revisions if
+ # a) this repo has shallow file storage b) shallow data fetching is enabled.
+ # Force remote to not delta against possibly unknown revisions when these
+ # conditions hold.
+ haveparents = not (shallowfiles or shallow)
+
+ # Similarly, we may not have calculated linkrevs for all incoming file
+ # revisions. Ask the remote to do work for us in this case.
+ if not haveparents:
+ fields.add(b'linknode')
+
for i in pycompat.xrange(0, len(csets), batchsize):
batch = [x for x in csets[i:i + batchsize]]
if not batch:
@@ -620,8 +661,8 @@
b'type': b'changesetexplicit',
b'nodes': batch,
}],
- b'fields': {b'parents', b'revision'},
- b'haveparents': True,
+ b'fields': fields,
+ b'haveparents': haveparents,
}
if pathfilter:
@@ -643,7 +684,14 @@
fnode: manlinkrevs[mnode]
for fnode, mnode in fnodes[path].iteritems()}
+ def getlinkrev(node):
+ if node in linkrevs:
+ return linkrevs[node]
+ else:
+ return clrev(node)
+
store.addgroup(iterrevisions(objs, header[b'totalitems'],
progress),
- linkrevs.__getitem__,
- weakref.proxy(tr))
+ getlinkrev,
+ weakref.proxy(tr),
+ maybemissingparents=shallow)
To: indygreg, #hg-reviewers
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list