dirstate-tree: Add tree traversal/iteration
Like Python’s, Rust’s iterators are "external" in that they are driven
by a caller who calls a `next` method. This is as opposed to "internal"
iterators who drive themselves and call a callback for each item.
Writing an internal iterator traversing a tree is easy with recursion,
but internal iterators cannot rely on the call stack in that way,
they must save in an explicit object all state that they need to be
preserved across two `next` calls.
This algorithm uses a `Vec` as a stack that contains what would be
local variables on the call stack if we could use recursion.
Differential Revision: https://phab.mercurial-scm.org/D10370
#require no-reposimplestore
Test creating a consuming stream bundle v2
$ getmainid() {
> hg -R main log --template '{node}\n' --rev "$1"
> }
$ cp $HGRCPATH $TESTTMP/hgrc.orig
$ cat >> $HGRCPATH << EOF
> [experimental]
> evolution.createmarkers=True
> evolution.exchange=True
> bundle2-output-capture=True
> [ui]
> ssh="$PYTHON" "$TESTDIR/dummyssh"
> logtemplate={rev}:{node|short} {phase} {author} {bookmarks} {desc|firstline}
> [web]
> push_ssl = false
> allow_push = *
> [phases]
> publish=False
> [extensions]
> drawdag=$TESTDIR/drawdag.py
> clonebundles=
> EOF
The extension requires a repo (currently unused)
$ hg init main
$ cd main
$ hg debugdrawdag <<'EOF'
> E
> |
> D
> |
> C
> |
> B
> |
> A
> EOF
$ hg bundle -a --type="none-v2;stream=v2" bundle.hg
$ hg debugbundle bundle.hg
Stream params: {}
stream2 -- {bytecount: 1693, filecount: 11, requirements: dotencode%2Cfncache%2Cgeneraldelta%2Crevlogv1%2Csparserevlog%2Cstore} (mandatory: True) (no-zstd !)
stream2 -- {bytecount: 1693, filecount: 11, requirements: dotencode%2Cfncache%2Cgeneraldelta%2Crevlog-compression-zstd%2Crevlogv1%2Csparserevlog%2Cstore} (mandatory: True) (zstd no-rust !)
stream2 -- {bytecount: 1693, filecount: 11, requirements: dotencode%2Cfncache%2Cgeneraldelta%2Cpersistent-nodemap%2Crevlog-compression-zstd%2Crevlogv1%2Csparserevlog%2Cstore} (mandatory: True) (rust !)
$ hg debugbundle --spec bundle.hg
none-v2;stream=v2;requirements%3Ddotencode%2Cfncache%2Cgeneraldelta%2Crevlogv1%2Csparserevlog%2Cstore (no-zstd !)
none-v2;stream=v2;requirements%3Ddotencode%2Cfncache%2Cgeneraldelta%2Crevlog-compression-zstd%2Crevlogv1%2Csparserevlog%2Cstore (zstd no-rust !)
none-v2;stream=v2;requirements%3Ddotencode%2Cfncache%2Cgeneraldelta%2Cpersistent-nodemap%2Crevlog-compression-zstd%2Crevlogv1%2Csparserevlog%2Cstore (rust !)
Test that we can apply the bundle as a stream clone bundle
$ cat > .hg/clonebundles.manifest << EOF
> http://localhost:$HGPORT1/bundle.hg BUNDLESPEC=`hg debugbundle --spec bundle.hg`
> EOF
$ hg serve -d -p $HGPORT --pid-file hg.pid --accesslog access.log
$ cat hg.pid >> $DAEMON_PIDS
$ "$PYTHON" $TESTDIR/dumbhttp.py -p $HGPORT1 --pid http.pid
$ cat http.pid >> $DAEMON_PIDS
$ cd ..
$ hg clone http://localhost:$HGPORT streamv2-clone-implicit --debug
using http://localhost:$HGPORT/
sending capabilities command
sending clonebundles command
applying clone bundle from http://localhost:$HGPORT1/bundle.hg
bundle2-input-bundle: with-transaction
bundle2-input-part: "stream2" (params: 3 mandatory) supported
applying stream bundle
11 files to transfer, 1.65 KB of data
starting 4 threads for background file closing (?)
starting 4 threads for background file closing (?)
adding [s] data/A.i (66 bytes)
adding [s] data/B.i (66 bytes)
adding [s] data/C.i (66 bytes)
adding [s] data/D.i (66 bytes)
adding [s] data/E.i (66 bytes)
adding [s] 00manifest.i (584 bytes)
adding [s] 00changelog.i (595 bytes)
adding [s] phaseroots (43 bytes)
adding [c] branch2-served (94 bytes)
adding [c] rbc-names-v1 (7 bytes)
adding [c] rbc-revs-v1 (40 bytes)
transferred 1.65 KB in \d\.\d seconds \(.*/sec\) (re)
bundle2-input-part: total payload size 1840
bundle2-input-bundle: 1 parts total
updating the branch cache
finished applying clone bundle
query 1; heads
sending batch command
searching for changes
all remote heads known locally
no changes found
sending getbundle command
bundle2-input-bundle: with-transaction
bundle2-input-part: "listkeys" (params: 1 mandatory) supported
bundle2-input-part: "phase-heads" supported
bundle2-input-part: total payload size 24
bundle2-input-bundle: 2 parts total
checking for updated bookmarks
updating to branch default
resolving manifests
branchmerge: False, force: False, partial: False
ancestor: 000000000000, local: 000000000000+, remote: 9bc730a19041
A: remote created -> g
getting A
B: remote created -> g
getting B
C: remote created -> g
getting C
D: remote created -> g
getting D
E: remote created -> g
getting E
5 files updated, 0 files merged, 0 files removed, 0 files unresolved
updating the branch cache
(sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
$ hg clone --stream http://localhost:$HGPORT streamv2-clone-explicit --debug
using http://localhost:$HGPORT/
sending capabilities command
sending clonebundles command
applying clone bundle from http://localhost:$HGPORT1/bundle.hg
bundle2-input-bundle: with-transaction
bundle2-input-part: "stream2" (params: 3 mandatory) supported
applying stream bundle
11 files to transfer, 1.65 KB of data
starting 4 threads for background file closing (?)
starting 4 threads for background file closing (?)
adding [s] data/A.i (66 bytes)
adding [s] data/B.i (66 bytes)
adding [s] data/C.i (66 bytes)
adding [s] data/D.i (66 bytes)
adding [s] data/E.i (66 bytes)
adding [s] 00manifest.i (584 bytes)
adding [s] 00changelog.i (595 bytes)
adding [s] phaseroots (43 bytes)
adding [c] branch2-served (94 bytes)
adding [c] rbc-names-v1 (7 bytes)
adding [c] rbc-revs-v1 (40 bytes)
transferred 1.65 KB in *.* seconds (*/sec) (glob)
bundle2-input-part: total payload size 1840
bundle2-input-bundle: 1 parts total
updating the branch cache
finished applying clone bundle
query 1; heads
sending batch command
searching for changes
all remote heads known locally
no changes found
sending getbundle command
bundle2-input-bundle: with-transaction
bundle2-input-part: "listkeys" (params: 1 mandatory) supported
bundle2-input-part: "phase-heads" supported
bundle2-input-part: total payload size 24
bundle2-input-bundle: 2 parts total
checking for updated bookmarks
updating to branch default
resolving manifests
branchmerge: False, force: False, partial: False
ancestor: 000000000000, local: 000000000000+, remote: 9bc730a19041
A: remote created -> g
getting A
B: remote created -> g
getting B
C: remote created -> g
getting C
D: remote created -> g
getting D
E: remote created -> g
getting E
5 files updated, 0 files merged, 0 files removed, 0 files unresolved
updating the branch cache
(sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)