Comments
Patch
@@ -935,9 +935,22 @@ class ui(object):
This is separate in part so that extensions (like chg) can
override how a pager is invoked.
"""
- pager = subprocess.Popen(command, shell=True, bufsize=-1,
- close_fds=util.closefds, stdin=subprocess.PIPE,
- stdout=util.stdout, stderr=util.stderr)
+ # If the command doesn't contain any of these characters, we
+ # assume it's a binary and exec it directly. This means for
+ # simple pager command configurations, we can degrade
+ # gracefully and tell the user about their broken pager.
+ shell = any(c in command for c in "|&;<>()$`\\\"' \t\n*?[#~=%")
+ try:
+ pager = subprocess.Popen(
+ command, shell=shell, bufsize=-1,
+ close_fds=util.closefds, stdin=subprocess.PIPE,
+ stdout=util.stdout, stderr=util.stderr)
+ except OSError as e:
+ if e.errno == errno.ENOENT and not shell:
+ self.warn(_("missing pager command '%s', skipping pager\n")
+ % command)
+ return
+ raise
# back up original file descriptors
stdoutfd = os.dup(util.stdout.fileno())
@@ -121,6 +121,33 @@ even though stdout is no longer a tty.
paged! 'summary: modify a 8\n'
paged! '\n'
+An invalid pager command name is reported sensibly if we don't have to
+use shell=True in the subprocess call:
+ $ hg log --limit 3 --config pager.pager=this-command-better-never-exist
+ missing pager command 'this-command-better-never-exist', skipping pager
+ \x1b[0;33mchangeset: 10:46106edeeb38\x1b[0m (esc)
+ tag: tip
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: modify a 10
+
+ \x1b[0;33mchangeset: 9:6dd8ea7dd621\x1b[0m (esc)
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: modify a 9
+
+ \x1b[0;33mchangeset: 8:cff05a6312fe\x1b[0m (esc)
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: modify a 8
+
+
+A complicated pager command gets worse behavior. Bonus points if you can
+improve this.
+ $ hg log --limit 3 \
+ > --config pager.pager='this-command-better-never-exist --seriously' \
+ > 2>/dev/null || true
+
Pager works with shell aliases.
$ cat >> $HGRCPATH <<EOF