procutil: make stream detection in make_line_buffered more correct and strict
In make_line_buffered(), we don’t want to wrap the stream if we know that lines
get flushed to the underlying raw stream already.
Previously, the heuristic was too optimistic. It assumed that any stream which
is not an instance of io.BufferedIOBase doesn’t need wrapping. However, there
are buffered streams that aren’t instances of io.BufferedIOBase, like
Mercurial’s own winstdout.
The new logic is different in two ways:
First, only for the check, if unwraps any combination of WriteAllWrapper and
winstdout.
Second, it skips wrapping the stream only if it is an instance of io.RawIOBase
(or already wrapped). If it is an instance of io.BufferedIOBase, it gets
wrapped. In any other case, the function raises an exception. This ensures
that, if an unknown stream is passed or we add another wrapper in the future,
we don’t wrap the stream if it’s already line buffered or not wrap the stream
if it’s not line buffered. In fact, this was already helpful during development
of this change. Without it, I possibly would have forgot that WriteAllWrapper
needs to be ignored for the check, leading to unnecessary wrapping if stdout is
unbuffered.
The alternative would have been to always wrap unknown streams. However, I
don’t think that anyone would benefit from being less strict. We can expect
streams from the standard library to be subclassing either io.RawIOBase or
io.BufferedIOBase, so running Mercurial in the standard way should not regress
by this change. Py2exe might replace sys.stdout and sys.stderr, but that
currently breaks Mercurial anyway and also these streams don’t claim to be
interactive, so this function is not called for them.
$ hg init t
$ cd t
$ echo 1 > foo
$ hg ci -Am m
adding foo
$ cd ..
$ hg clone t tt
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd tt
$ echo 1.1 > foo
$ hg ci -Am m
$ cd ../t
$ echo 1.2 > foo
$ hg ci -Am m
Should respect config to disable dirty update
$ hg co -qC 0
$ echo 2 > foo
$ hg --config commands.update.check=abort pull -u ../tt
pulling from ../tt
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
new changesets 107cefe13e42
1 local changesets published
abort: uncommitted changes
[20]
$ hg --config extensions.strip= strip --no-backup tip
$ hg co -qC tip
Should not update to the other topological branch:
$ hg pull -u ../tt
pulling from ../tt
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
new changesets 107cefe13e42
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
updated to "800c91d5bfc1: m"
1 other heads for branch "default"
$ cd ../tt
Should not update to the other branch:
$ hg pull -u ../t
pulling from ../t
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
new changesets 800c91d5bfc1
1 local changesets published
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
updated to "107cefe13e42: m"
1 other heads for branch "default"
$ 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 -mm
$ cd ../t
Should work:
$ hg pull -u ../tt
pulling from ../tt
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (-1 heads)
new changesets 483b76ad4309
1 local changesets published
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
Similarity between "hg update" and "hg pull -u" in handling bookmark
====================================================================
Test that updating activates the bookmark, which matches with the
explicit destination of the update.
$ echo 4 >> foo
$ hg commit -m "#4"
$ hg bookmark active-after-pull
$ cd ../tt
(1) activating by --rev BOOKMARK
$ hg bookmark -f active-before-pull
$ hg bookmarks
* active-before-pull 3:483b76ad4309
$ hg pull -u -r active-after-pull
pulling from $TESTTMP/t
searching for changes
adding changesets
adding manifests
adding file changes
adding remote bookmark active-after-pull
added 1 changesets with 1 changes to 1 files
new changesets f815b3da6163
1 local changesets published
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(activating bookmark active-after-pull)
$ hg parents -q
4:f815b3da6163
$ hg bookmarks
* active-after-pull 4:f815b3da6163
active-before-pull 3:483b76ad4309
(discard pulled changes)
$ hg update -q 483b76ad4309
$ hg rollback -q
(2) activating by URL#BOOKMARK
$ hg bookmark -f active-before-pull
$ hg bookmarks
* active-before-pull 3:483b76ad4309
$ hg pull -u $TESTTMP/t#active-after-pull
pulling from $TESTTMP/t
searching for changes
adding changesets
adding manifests
adding file changes
adding remote bookmark active-after-pull
added 1 changesets with 1 changes to 1 files
new changesets f815b3da6163
1 local changesets published
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(activating bookmark active-after-pull)
$ hg parents -q
4:f815b3da6163
$ hg bookmarks
* active-after-pull 4:f815b3da6163
active-before-pull 3:483b76ad4309
(discard pulled changes)
$ hg update -q 483b76ad4309
$ hg rollback -q
Test that updating deactivates current active bookmark, if the
destination of the update is explicitly specified, and it doesn't
match with the name of any existing bookmarks.
$ cd ../t
$ hg bookmark -d active-after-pull
$ hg branch bar -q
$ hg commit -m "#5 (bar #1)"
$ cd ../tt
(1) deactivating by --rev REV
$ hg bookmark -f active-before-pull
$ hg bookmarks
* active-before-pull 3:483b76ad4309
$ hg pull -u -r b5e4babfaaa7
pulling from $TESTTMP/t
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 1 changes to 1 files
new changesets f815b3da6163:b5e4babfaaa7
1 local changesets published
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(leaving bookmark active-before-pull)
$ hg parents -q
5:b5e4babfaaa7
$ hg bookmarks
active-before-pull 3:483b76ad4309
(discard pulled changes)
$ hg update -q 483b76ad4309
$ hg rollback -q
(2) deactivating by --branch BRANCH
$ hg bookmark -f active-before-pull
$ hg bookmarks
* active-before-pull 3:483b76ad4309
$ hg pull -u -b bar
pulling from $TESTTMP/t
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 1 changes to 1 files
new changesets f815b3da6163:b5e4babfaaa7
1 local changesets published
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(leaving bookmark active-before-pull)
$ hg parents -q
5:b5e4babfaaa7
$ hg bookmarks
active-before-pull 3:483b76ad4309
(discard pulled changes)
$ hg update -q 483b76ad4309
$ hg rollback -q
(3) deactivating by URL#ANOTHER-BRANCH
$ hg bookmark -f active-before-pull
$ hg bookmarks
* active-before-pull 3:483b76ad4309
$ hg pull -u $TESTTMP/t#bar
pulling from $TESTTMP/t
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 1 changes to 1 files
new changesets f815b3da6163:b5e4babfaaa7
1 local changesets published
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(leaving bookmark active-before-pull)
$ hg parents -q
5:b5e4babfaaa7
$ hg bookmarks
active-before-pull 3:483b76ad4309
$ cd ..
Issue622: hg init && hg pull -u URL doesn't checkout default branch
$ hg init test
$ cd test
$ echo foo>foo
$ hg addremove
adding foo
$ hg commit -m 1
$ cd ..
$ hg init empty
$ cd empty
$ hg pull -u ../test
pulling from ../test
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
new changesets 340e38bdcde4
1 files updated, 0 files merged, 0 files removed, 0 files unresolved