[PATCH] Travis: also test on 32-bit Linux

Subsystems: the rest

STALE3473d

11 messages, 5 authors, 2017-03-05 · open the first message on its own page

[PATCH] Travis: also test on 32-bit Linux

From: Johannes Schindelin <hidden>
Date: 2017-02-28 19:37:46

When Git v2.9.1 was released, it had a bug that showed only on Windows
and on 32-bit systems: our assumption that `unsigned long` can hold
64-bit values turned out to be wrong.

This could have been caught earlier if we had a Continuous Testing
set up that includes a build and test run on 32-bit Linux.

Let's do this (and take care of the Windows build later). This patch
asks Travis CI to install a Docker image with 32-bit libraries and then
goes on to build and test Git using this 32-bit setup.

A big thank you to Lars Schneider without whose help this patch would
not have happened.

Signed-off-by: Johannes Schindelin <redacted>
---
Published-As: https://github.com/dscho/git/releases/tag/travis-32-bit-v1
Fetch-It-Via: git fetch https://github.com/dscho/git travis-32-bit-v1

 .travis.yml | 11 +++++++++++
 1 file changed, 11 insertions(+)
diff --git a/.travis.yml b/.travis.yml
index 9c63c8c3f68..87d9e9051a6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -39,6 +39,17 @@ env:
 
 matrix:
   include:
+    - env: Linux32
+      os: linux
+      compiler: clang
+      sudo: required
+      services:
+        - docker
+      before_install:
+        - docker pull daald/ubuntu32:xenial
+      before_script:
+      script:
+        - "sudo docker run -i -v \"${PWD}:/usr/src/git\" daald/ubuntu32:xenial /bin/bash -c \"linux32 --32bit i386 sh -c 'apt update && apt install -y build-essential libcurl4-openssl-dev libssl-dev libexpat-dev gettext python && cd /usr/src/git && DEFAULT_TEST_TARGET=prove GIT_PROVE_OPTS=\\\"--timer --jobs 3 --state=failed,slow,save\\\" GIT_TEST_OPTS=--verbose-log GIT_TEST_CLONE_2GB=YesPlease make -j2 test'\""
     - env: Documentation
       os: linux
       compiler: clang
base-commit: 3bc53220cb2dcf709f7a027a3f526befd021d858
-- 
2.12.0.windows.1.3.g8a117c48243

Re: [PATCH] Travis: also test on 32-bit Linux

From: Johannes Schindelin <hidden>
Date: 2017-02-28 20:36:57

Hi,

On Tue, 28 Feb 2017, Johannes Schindelin wrote:
When Git v2.9.1 was released, it had a bug that showed only on Windows
and on 32-bit systems: our assumption that `unsigned long` can hold
64-bit values turned out to be wrong.

This could have been caught earlier if we had a Continuous Testing set
up that includes a build and test run on 32-bit Linux.

Let's do this (and take care of the Windows build later). This patch
asks Travis CI to install a Docker image with 32-bit libraries and then
goes on to build and test Git using this 32-bit setup.
For the record, I first tested this with the LONG_IS_32BIT flag forced to
`true` so that the date tests must fail. They did fail as expected (search
for "not ok" in this output):

	https://travis-ci.org/git/git/jobs/206199002

(I actually cannot see the log right now, Travis seems to be under heavy
load...)

A much cleaned up version that does not force that LONG_IS_32BIT produced
this log:

	https://travis-ci.org/git/git/jobs/206228708

(Same here, my browser fails to load the log, probably because Travis
experiences quite high a load...)

Please note that this approach is not without problems. It would appear
that Travis currently has serious problems to even *reach* the Docker Hub,
and therefore cannot download the Docker image:

	https://travis-ci.org/git/git/jobs/206292947#L6

Ciao,
Johannes

Re: [PATCH] Travis: also test on 32-bit Linux

From: Junio C Hamano <hidden>
Date: 2017-03-02 05:06:52

On Tue, Feb 28, 2017 at 11:17 AM, Johannes Schindelin
[off-list ref] wrote:
.... This patch
asks Travis CI to install a Docker image with 32-bit libraries and then
goes on to build and test Git using this 32-bit setup.

A big thank you to Lars Schneider without whose help this patch would
not have happened.
This has been in 'pu' for a few days, and
https://travis-ci.org/git/git/builds shows that we have
a new build job running successfully.

Good job ;-)

Thanks.

[PATCH v1] Travis: also test on 32-bit Linux

From: Lars Schneider <hidden>
Date: 2017-03-02 10:59:52

From: Johannes Schindelin <redacted>

When Git v2.9.1 was released, it had a bug that showed only on Windows
and on 32-bit systems: our assumption that `unsigned long` can hold
64-bit values turned out to be wrong.

This could have been caught earlier if we had a Continuous Testing
set up that includes a build and test run on 32-bit Linux.

Let's do this (and take care of the Windows build later). This patch
asks Travis CI to install a Docker image with 32-bit libraries and then
goes on to build and test Git using this 32-bit setup.

Signed-off-by: Johannes Schindelin <redacted>
Signed-off-by: Lars Schneider <redacted>
---

Thanks for the patch Dscho!

The patch looks good to me in general but I want to propose the following
changes:

(1) Move all the docker magic into a dedicated file "ci/run-linux-32-build.sh"
    This way people should be able to run this build on their local machines
    without TravisCI. However, I haven't tested this.

(2) The docker build command inherits the Git test environment variables.
    This way we use the same environment variables as in all other TravisCI
    builds (plus it would use *your* variables if you run it locally).

(3) Silence the apt update/git output as is it clutters the log.
    I did not silence stderr output!

(4) Remove (to my knowledge) superfluous "compiler: clang" in the Linux32 job.

I added my sign-off. I hope this is the right thing to do in this "I took your
patch and changed it to suggest an improvement" situation.

You can see a successful run here:
https://travis-ci.org/larsxschneider/git/jobs/206945950


One thing that still bugs me: In the Linux32 environment prove adds the
CPU times to every test run: ( 0.02 usr  0.00 sys +  0.00 cusr  0.00 csys ...
Has anyone an idea why that happens and how we can disable it?


Cheers,
Lars


Notes:
    Base Ref:
    Web-Diff: https://github.com/larsxschneider/git/commit/82995ed59c
    Checkout: git fetch https://github.com/larsxschneider/git travisci/linux32-v1 && git checkout 82995ed59c

 .travis.yml             |  9 +++++++++
 ci/run-linux32-build.sh | 21 +++++++++++++++++++++
 2 files changed, 30 insertions(+)
 create mode 100755 ci/run-linux32-build.sh
diff --git a/.travis.yml b/.travis.yml
index 9c63c8c3f6..c8c789c437 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -39,6 +39,15 @@ env:

 matrix:
   include:
+    - env: Linux32
+      os: linux
+      sudo: required
+      services:
+        - docker
+      before_install:
+        - docker pull daald/ubuntu32:xenial
+      before_script:
+      script: ci/run-linux32-build.sh
     - env: Documentation
       os: linux
       compiler: clang
diff --git a/ci/run-linux32-build.sh b/ci/run-linux32-build.sh
new file mode 100755
index 0000000000..b892fbdc9e
--- /dev/null
+++ b/ci/run-linux32-build.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# Build and test Git in a docker container running a 32-bit Ubuntu Linux
+#
+
+set -e
+
+APT_INSTALL="apt update >/dev/null && apt install -y build-essential "\
+"libcurl4-openssl-dev libssl-dev libexpat-dev gettext python >/dev/null"
+
+TEST_GIT_ENV="DEFAULT_TEST_TARGET=$DEFAULT_TEST_TARGET "\
+"GIT_PROVE_OPTS=\"$GIT_PROVE_OPTS\" "\
+"GIT_TEST_OPTS=\"$GIT_TEST_OPTS\" "\
+"GIT_TEST_CLONE_2GB=$GIT_TEST_CLONE_2GB"
+
+TEST_GIT_CMD="linux32 --32bit i386 sh -c "\
+"'$APT_INSTALL && cd /usr/src/git && $TEST_GIT_ENV make -j2 test'"
+
+sudo docker run \
+    --interactive --volume "${PWD}:/usr/src/git" \
+    daald/ubuntu32:xenial /bin/bash -c "$TEST_GIT_CMD"
base-commit: 3bc53220cb2dcf709f7a027a3f526befd021d858
--
2.11.1

Re: [PATCH v1] Travis: also test on 32-bit Linux

From: Johannes Schindelin <hidden>
Date: 2017-03-02 12:19:45

Hi Lars,

On Thu, 2 Mar 2017, Lars Schneider wrote:
The patch looks good to me in general but I want to propose the following
changes:
I know you are using your script to generate this mail, but I would have
liked to see v2 in the subject ;-)
(1) Move all the docker magic into a dedicated file
"ci/run-linux-32-build.sh" This way people should be able to run this
build on their local machines without TravisCI. However, I haven't
tested this.
I considered this, but there is serious overlap: the `docker pull` call
and the `docker run` call *have* to refer to the same image. It's very
easy for them to get out of sync if you have that information in two
files. Maybe make that an option of the script, defaulting to
daald/ubuntu32:xenial?

BTW speaking of Docker: it would be nicer if there was a Docker image that
already had the build-essentials installed, to save on startup time. But I
did not find any that was reasonably up-to-date.
(2) The docker build command inherits the Git test environment
variables.  This way we use the same environment variables as in all
other TravisCI builds (plus it would use *your* variables if you run it
locally).
Good!
(3) Silence the apt update/git output as is it clutters the log.  I did
not silence stderr output!
Also good!
(4) Remove (to my knowledge) superfluous "compiler: clang" in the
Linux32 job.
I copied that from one of your experimental .travis.yml patches ;-)
I added my sign-off. I hope this is the right thing to do in this "I
took your patch and changed it to suggest an improvement" situation.
Absolutely. Thank you for taking it from here.
One thing that still bugs me: In the Linux32 environment prove adds the
CPU times to every test run: ( 0.02 usr  0.00 sys +  0.00 cusr  0.00
csys ...  Has anyone an idea why that happens and how we can disable it?
I have no idea.
quoted hunk
diff --git a/ci/run-linux32-build.sh b/ci/run-linux32-build.sh
new file mode 100755
index 0000000000..b892fbdc9e
--- /dev/null
+++ b/ci/run-linux32-build.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+#
+# Build and test Git in a docker container running a 32-bit Ubuntu Linux
+#
+
+set -e
Is this really necessary? I really like to avoid `set -e`, in particular
when we do pretty much everything in && chains anyway.
+APT_INSTALL="apt update >/dev/null && apt install -y build-essential "\
+"libcurl4-openssl-dev libssl-dev libexpat-dev gettext python >/dev/null"
+
+TEST_GIT_ENV="DEFAULT_TEST_TARGET=$DEFAULT_TEST_TARGET "\
+"GIT_PROVE_OPTS=\"$GIT_PROVE_OPTS\" "\
+"GIT_TEST_OPTS=\"$GIT_TEST_OPTS\" "\
+"GIT_TEST_CLONE_2GB=$GIT_TEST_CLONE_2GB"
+
+TEST_GIT_CMD="linux32 --32bit i386 sh -c '"\
+"'$APT_INSTALL && cd /usr/src/git && $TEST_GIT_ENV make -j2 test'"
+
+sudo docker run \
+    --interactive --volume "${PWD}:/usr/src/git" \
+    daald/ubuntu32:xenial /bin/bash -c "$TEST_GIT_CMD"
Hmm. Since it is a script now, it would be more readable this way, I
think:

sudo docker run --volume "${PWD}:/usr/src/git" "${1:-daald/ubuntu32:xenial}" \
linux32 --32bit i386 sh -c '
	: update packages first &&
	apt update >/dev/null &&
	apt install -y build-essential libcurl4-openssl-dev libssl-dev \
		libexpat-dev gettext python >/dev/null &&

	: now build and test &&
	cd /usr/src/git &&
	DEFAULT_TEST_TARGET='"$DEFAULT_TEST_TARGET"' \
	GIT_PROVE_OPTS='"$GIT_PROVE_OPTS"' \
	GIT_TEST_OPTS='"$GIT_TEST_OPTS"' \
	GIT_TEST_CLONE_2GB='"$GIT_TEST_CLONE_2GB"' \
	make -j2 test
'

This is completely untested (pun intended ;-))...

Ciao,
Dscho

Re: [PATCH v1] Travis: also test on 32-bit Linux

From: Lars Schneider <hidden>
Date: 2017-03-02 14:52:30

On 02 Mar 2017, at 12:24, Johannes Schindelin [off-list ref] wrote:

Hi Lars,

On Thu, 2 Mar 2017, Lars Schneider wrote:
quoted
The patch looks good to me in general but I want to propose the following
changes:
I know you are using your script to generate this mail, but I would have
liked to see v2 in the subject ;-)
Yeah, sorry. I already had a "D'oh" moment *after* I saw the email in 
my email client. Now I am wondering... is the next version v2 or v3 :D

quoted
(1) Move all the docker magic into a dedicated file
"ci/run-linux-32-build.sh" This way people should be able to run this
build on their local machines without TravisCI. However, I haven't
tested this.
I considered this, but there is serious overlap: the `docker pull` call
and the `docker run` call *have* to refer to the same image. It's very
easy for them to get out of sync if you have that information in two
files. Maybe make that an option of the script, defaulting to
daald/ubuntu32:xenial?
Right. I missed that. How about something like that?

      before_install:
        - ci/run-linux32-build.sh --pull-container
      before_script:
      script: ci/run-linux32-build.sh

BTW speaking of Docker: it would be nicer if there was a Docker image that
already had the build-essentials installed, to save on startup time. But I
did not find any that was reasonably up-to-date.
True. But installing everything just takes a minute and we don't need to
maintain anything...

quoted
+set -e
Is this really necessary? I really like to avoid `set -e`, in particular
when we do pretty much everything in && chains anyway.
Agreed, not really necessary here as we just invoke one command.
Out of curiosity: Why do you try to avoid it? I set it by default in all 
my scripts.

quoted
+APT_INSTALL="apt update >/dev/null && apt install -y build-essential "\
+"libcurl4-openssl-dev libssl-dev libexpat-dev gettext python >/dev/null"
+
+TEST_GIT_ENV="DEFAULT_TEST_TARGET=$DEFAULT_TEST_TARGET "\
+"GIT_PROVE_OPTS=\"$GIT_PROVE_OPTS\" "\
+"GIT_TEST_OPTS=\"$GIT_TEST_OPTS\" "\
+"GIT_TEST_CLONE_2GB=$GIT_TEST_CLONE_2GB"
+
+TEST_GIT_CMD="linux32 --32bit i386 sh -c '"\
+"'$APT_INSTALL && cd /usr/src/git && $TEST_GIT_ENV make -j2 test'"
+
+sudo docker run \
+    --interactive --volume "${PWD}:/usr/src/git" \
+    daald/ubuntu32:xenial /bin/bash -c "$TEST_GIT_CMD"
Hmm. Since it is a script now, it would be more readable this way, I
think:

sudo docker run --volume "${PWD}:/usr/src/git" "${1:-daald/ubuntu32:xenial}" \
linux32 --32bit i386 sh -c '
	: update packages first &&
	apt update >/dev/null &&
	apt install -y build-essential libcurl4-openssl-dev libssl-dev \
		libexpat-dev gettext python >/dev/null &&

	: now build and test &&
	cd /usr/src/git &&
	DEFAULT_TEST_TARGET='"$DEFAULT_TEST_TARGET"' \
	GIT_PROVE_OPTS='"$GIT_PROVE_OPTS"' \
	GIT_TEST_OPTS='"$GIT_TEST_OPTS"' \
	GIT_TEST_CLONE_2GB='"$GIT_TEST_CLONE_2GB"' \
	make -j2 test
'
That looks better! I'll try it!

- Lars

Re: [PATCH v1] Travis: also test on 32-bit Linux

From: Johannes Schindelin <hidden>
Date: 2017-03-02 14:56:23

Hi Lars,


On Thu, 2 Mar 2017, Lars Schneider wrote:
quoted
On 02 Mar 2017, at 12:24, Johannes Schindelin [off-list ref] wrote:

On Thu, 2 Mar 2017, Lars Schneider wrote:
quoted
The patch looks good to me in general but I want to propose the
following changes:
I know you are using your script to generate this mail, but I would
have liked to see v2 in the subject ;-)
Yeah, sorry. I already had a "D'oh" moment *after* I saw the email in my
email client. Now I am wondering... is the next version v2 or v3 :D
Since there was no v2, the next one should *definitely* be v2... ;-)
quoted
quoted
(1) Move all the docker magic into a dedicated file
"ci/run-linux-32-build.sh" This way people should be able to run this
build on their local machines without TravisCI. However, I haven't
tested this.
I considered this, but there is serious overlap: the `docker pull`
call and the `docker run` call *have* to refer to the same image. It's
very easy for them to get out of sync if you have that information in
two files. Maybe make that an option of the script, defaulting to
daald/ubuntu32:xenial?
Right. I missed that. How about something like that?

      before_install:
        - ci/run-linux32-build.sh --pull-container
      before_script:
      script: ci/run-linux32-build.sh
I'd prefer

	before_install:
	  - docker pull daald/ubuntu32:xenial
	before_script:
	script: ci/run-linux32-build.sh daald/ubuntu32:xenial
quoted
BTW speaking of Docker: it would be nicer if there was a Docker image
that already had the build-essentials installed, to save on startup
time. But I did not find any that was reasonably up-to-date.
True. But installing everything just takes a minute and we don't need to
maintain anything...
And when there are network problems (like there were on Tuesday, right
when I developed the first v1 of this patch) then we have another set of
problems that make Travis fail. Even if the code in the PR or branch is
actually good. I'd like to avoid false positives, if possible.
quoted
quoted
+set -e
Is this really necessary? I really like to avoid `set -e`, in
particular when we do pretty much everything in && chains anyway.
Agreed, not really necessary here as we just invoke one command.  Out of
curiosity: Why do you try to avoid it? I set it by default in all my
scripts.
I try to avoid it because it encourages a style that omits helpful error
messages.
quoted
quoted
+APT_INSTALL="apt update >/dev/null && apt install -y build-essential "\
+"libcurl4-openssl-dev libssl-dev libexpat-dev gettext python >/dev/null"
+
+TEST_GIT_ENV="DEFAULT_TEST_TARGET=$DEFAULT_TEST_TARGET "\
+"GIT_PROVE_OPTS=\"$GIT_PROVE_OPTS\" "\
+"GIT_TEST_OPTS=\"$GIT_TEST_OPTS\" "\
+"GIT_TEST_CLONE_2GB=$GIT_TEST_CLONE_2GB"
+
+TEST_GIT_CMD="linux32 --32bit i386 sh -c '"\
+"'$APT_INSTALL && cd /usr/src/git && $TEST_GIT_ENV make -j2 test'"
+
+sudo docker run \
+    --interactive --volume "${PWD}:/usr/src/git" \
+    daald/ubuntu32:xenial /bin/bash -c "$TEST_GIT_CMD"
Hmm. Since it is a script now, it would be more readable this way, I
think:

sudo docker run --volume "${PWD}:/usr/src/git" "${1:-daald/ubuntu32:xenial}" \
linux32 --32bit i386 sh -c '
	: update packages first &&
	apt update >/dev/null &&
	apt install -y build-essential libcurl4-openssl-dev libssl-dev \
		libexpat-dev gettext python >/dev/null &&

	: now build and test &&
	cd /usr/src/git &&
	DEFAULT_TEST_TARGET='"$DEFAULT_TEST_TARGET"' \
	GIT_PROVE_OPTS='"$GIT_PROVE_OPTS"' \
	GIT_TEST_OPTS='"$GIT_TEST_OPTS"' \
	GIT_TEST_CLONE_2GB='"$GIT_TEST_CLONE_2GB"' \
	make -j2 test
'
That looks better! I'll try it!
Thanks!
Dscho

Re: [PATCH v1] Travis: also test on 32-bit Linux

From: Ramsay Jones <hidden>
Date: 2017-03-02 15:33:20


On 02/03/17 11:24, Johannes Schindelin wrote:
Hi Lars,

On Thu, 2 Mar 2017, Lars Schneider wrote:
[snip]
quoted
One thing that still bugs me: In the Linux32 environment prove adds the
CPU times to every test run: ( 0.02 usr  0.00 sys +  0.00 cusr  0.00
csys ...  Has anyone an idea why that happens and how we can disable it?
I have no idea.
I have no idea either, but it is not unique to this 32bit Linux, but
rather the version of prove. For example, I am seeing this on Linux
Mint 18.1 (64bit _and_ 32bit), whereas Linux Mint 17.x did not do
this. (They used different Ubuntu LTS releases).

[Mint 18.1 'prove --version' says: TAP::Harness v3.35 and Perl v5.22.1]

ATB,
Ramsay Jones

Re: [PATCH v1] Travis: also test on 32-bit Linux

From: Christian Couder <hidden>
Date: 2017-03-02 16:03:51

On Thu, Mar 2, 2017 at 3:22 PM, Johannes Schindelin
[off-list ref] wrote:
quoted
quoted
quoted
+set -e
Is this really necessary? I really like to avoid `set -e`, in
particular when we do pretty much everything in && chains anyway.
Agreed, not really necessary here as we just invoke one command.  Out of
curiosity: Why do you try to avoid it? I set it by default in all my
scripts.
I try to avoid it because it encourages a style that omits helpful error
messages.
Yeah, we prefer to define and use a die() function like this:

die () {
    printf >&2 '%s\n' "$*"
    exit 1
}

do_something || die "meaningful error message"

Re: [PATCH v1] Travis: also test on 32-bit Linux

From: Lars Schneider <hidden>
Date: 2017-03-05 17:45:20

On 02 Mar 2017, at 16:17, Ramsay Jones [off-list ref] wrote:



On 02/03/17 11:24, Johannes Schindelin wrote:
quoted
Hi Lars,

On Thu, 2 Mar 2017, Lars Schneider wrote:
[snip]
quoted
quoted
One thing that still bugs me: In the Linux32 environment prove adds the
CPU times to every test run: ( 0.02 usr  0.00 sys +  0.00 cusr  0.00
csys ...  Has anyone an idea why that happens and how we can disable it?
I have no idea.
I have no idea either, but it is not unique to this 32bit Linux, but
rather the version of prove. For example, I am seeing this on Linux
Mint 18.1 (64bit _and_ 32bit), whereas Linux Mint 17.x did not do
this. (They used different Ubuntu LTS releases).

[Mint 18.1 'prove --version' says: TAP::Harness v3.35 and Perl v5.22.1]
I think I found it. It was introduced in TAP::Harness v3.34:
https://github.com/Perl-Toolchain-Gang/Test-Harness/commit/66cbf6355928b4828db517a99f1099b7fed35e90

... and it is enabled with the "--timer" switch.

- Lars

Re: [PATCH v1] Travis: also test on 32-bit Linux

From: Ramsay Jones <hidden>
Date: 2017-03-05 22:16:37


On 05/03/17 17:38, Lars Schneider wrote:
quoted
On 02 Mar 2017, at 16:17, Ramsay Jones [off-list ref] wrote:
On 02/03/17 11:24, Johannes Schindelin wrote:
quoted
On Thu, 2 Mar 2017, Lars Schneider wrote:
[snip]
quoted
quoted
One thing that still bugs me: In the Linux32 environment prove adds the
CPU times to every test run: ( 0.02 usr  0.00 sys +  0.00 cusr  0.00
csys ...  Has anyone an idea why that happens and how we can disable it?
I have no idea.
I have no idea either, but it is not unique to this 32bit Linux, but
rather the version of prove. For example, I am seeing this on Linux
Mint 18.1 (64bit _and_ 32bit), whereas Linux Mint 17.x did not do
this. (They used different Ubuntu LTS releases).

[Mint 18.1 'prove --version' says: TAP::Harness v3.35 and Perl v5.22.1]
I think I found it. It was introduced in TAP::Harness v3.34:
https://github.com/Perl-Toolchain-Gang/Test-Harness/commit/66cbf6355928b4828db517a99f1099b7fed35e90

... and it is enabled with the "--timer" switch.
Yep, that looks like it.

When I updated to Mint 18, this broke a perl script of mine, so I had
a quick look to see what I could do to suppress it. The man page seemed
to imply that you could replace the output formatter, but that didn't
take me too far (search CPAN for TAP::Parser::Formatter: ;-) ). I suppose
you could replace Tap::Formatter::Base, or some such, but I didn't need
to go that far - I simply changed a couple of regex-es to ignore the
excess output! :-P

Do you really need to suppress that timing information or, like me, can
you simply ignore it?

ATB,
Ramsay Jones

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help