summaryrefslogtreecommitdiff
path: root/t
AgeCommit message (Collapse)AuthorFilesLines
2015-09-28Sync with v2.5.4Libravatar Junio C Hamano8-0/+248
2015-09-28Sync with 2.4.10Libravatar Junio C Hamano8-0/+248
2015-09-28Sync with 2.3.10Libravatar Junio C Hamano8-0/+248
2015-09-25http: limit redirection depthLibravatar Blake Burkhart2-0/+7
By default, libcurl will follow circular http redirects forever. Let's put a cap on this so that somebody who can trigger an automated fetch of an arbitrary repository (e.g., for CI) cannot convince git to loop infinitely. The value chosen is 20, which is the same default that Firefox uses. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-09-25http: limit redirection to protocol-whitelistLibravatar Blake Burkhart2-0/+10
Previously, libcurl would follow redirection to any protocol it was compiled for support with. This is desirable to allow redirection from HTTP to HTTPS. However, it would even successfully allow redirection from HTTP to SFTP, a protocol that git does not otherwise support at all. Furthermore git's new protocol-whitelisting could be bypassed by following a redirect within the remote helper, as it was only enforced at transport selection time. This patch limits redirects within libcurl to HTTP, HTTPS, FTP and FTPS. If there is a protocol-whitelist present, this list is limited to those also allowed by the whitelist. As redirection happens from within libcurl, it is impossible for an HTTP redirect to a protocol implemented within another remote helper. When the curl version git was compiled with is too old to support restrictions on protocol redirection, we warn the user if GIT_ALLOW_PROTOCOL restrictions were requested. This is a little inaccurate, as even without that variable in the environment, we would still restrict SFTP, etc, and we do not warn in that case. But anything else means we would literally warn every time git accesses an http remote. This commit includes a test, but it is not as robust as we would hope. It redirects an http request to ftp, and checks that curl complained about the protocol, which means that we are relying on curl's specific error message to know what happened. Ideally we would redirect to a working ftp server and confirm that we can clone without protocol restrictions, and not with them. But we do not have a portable way of providing an ftp server, nor any other protocol that curl supports (https is the closest, but we would have to deal with certificates). [jk: added test and version warning] Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-09-23submodule: allow only certain protocols for submodule fetchesLibravatar Jeff King1-0/+43
Some protocols (like git-remote-ext) can execute arbitrary code found in the URL. The URLs that submodules use may come from arbitrary sources (e.g., .gitmodules files in a remote repository). Let's restrict submodules to fetching from a known-good subset of protocols. Note that we apply this restriction to all submodule commands, whether the URL comes from .gitmodules or not. This is more restrictive than we need to be; for example, in the tests we run: git submodule add ext::... which should be trusted, as the URL comes directly from the command line provided by the user. But doing it this way is simpler, and makes it much less likely that we would miss a case. And since such protocols should be an exception (especially because nobody who clones from them will be able to update the submodules!), it's not likely to inconvenience anyone in practice. Reported-by: Blake Burkhart <bburky@bburky.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-09-23transport: add a protocol-whitelist environment variableLibravatar Jeff King6-0/+188
If we are cloning an untrusted remote repository into a sandbox, we may also want to fetch remote submodules in order to get the complete view as intended by the other side. However, that opens us up to attacks where a malicious user gets us to clone something they would not otherwise have access to (this is not necessarily a problem by itself, but we may then act on the cloned contents in a way that exposes them to the attacker). Ideally such a setup would sandbox git entirely away from high-value items, but this is not always practical or easy to set up (e.g., OS network controls may block multiple protocols, and we would want to enable some but not others). We can help this case by providing a way to restrict particular protocols. We use a whitelist in the environment. This is more annoying to set up than a blacklist, but defaults to safety if the set of protocols git supports grows). If no whitelist is specified, we continue to default to allowing all protocols (this is an "unsafe" default, but since the minority of users will want this sandboxing effect, it is the only sensible one). A note on the tests: ideally these would all be in a single test file, but the git-daemon and httpd test infrastructure is an all-or-nothing proposition rather than a test-by-test prerequisite. By putting them all together, we would be unable to test the file-local code on machines without apache. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-09-17Merge branch 'dt/untracked-subdir' into maintLibravatar Junio C Hamano1-0/+215
The experimental untracked-cache feature were buggy when paths with a few levels of subdirectories are involved. * dt/untracked-subdir: untracked cache: fix entry invalidation untracked-cache: fix subdirectory handling t7063: use --force-untracked-cache to speed up a bit untracked-cache: support sparse checkout
2015-09-14Merge branch 'mp/t7060-diff-index-test'Libravatar Junio C Hamano1-1/+1
Fix an old test that was doing the same thing as another one. * mp/t7060-diff-index-test: t7060: actually test "git diff-index --cached -M"
2015-09-08Merge branch 'jc/builtin-am-signoff-regression-fix'Libravatar Junio C Hamano1-0/+48
Recent "git am" had regression when adding a Signed-off-by line with its "-s" option by an unintended tightening of how an existing trailer block is detected. * jc/builtin-am-signoff-regression-fix: am: match --signoff to the original scripted version
2015-09-06am: match --signoff to the original scripted versionLibravatar Junio C Hamano1-0/+48
Linus noticed that the recently reimplemented "git am -s" defines the trailer block too rigidly, resulting in an unnecessary blank line between the existing sign-offs and his new sign-off. An e-mail submission sent to Linus in real life ends with mixture of sign-offs and commentaries, e.g. title here message here Signed-off-by: Original Author <original@auth.or> [rv: tweaked frotz and nitfol] Signed-off-by: Re Viewer <rv@ew.er> Signed-off-by: Other Reviewer <other@rev.ewer> --- patch here Because the reimplementation reused append_signoff() helper that is used by other codepaths, which is unaware that people intermix such comments with their sign-offs in the trailer block, such a message was judged to end with a non-trailer, resulting in an extra blank line before adding a new sign-off. The original scripted version of "git am" used a lot looser definition, i.e. "if and only if there is no line that begins with Signed-off-by:, add a blank line before adding a new sign-off". For the upcoming release, stop using the append_signoff() in "git am" and reimplement the looser definition used by the scripted version to use only in "git am" to fix this regression in "am" while avoiding new regressions to other users of append_signoff(). In the longer term, we should look into loosening append_signoff() so that other codepaths that add a new sign-off behave the same way as "git am -s", but that is a task for post-release. Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-09-03Merge branch 'ee/clean-test-fixes' into maintLibravatar Junio C Hamano1-12/+4
* ee/clean-test-fixes: t7300: fix broken && chains
2015-09-03Merge branch 'jk/log-missing-default-HEAD' into maintLibravatar Junio C Hamano1-0/+14
"git init empty && git -C empty log" said "bad default revision 'HEAD'", which was found to be a bit confusing to new users. * jk/log-missing-default-HEAD: log: diagnose empty HEAD more clearly
2015-09-03Merge branch 'cc/trailers-corner-case-fix' into maintLibravatar Junio C Hamano1-1/+28
The "interpret-trailers" helper mistook a multi-paragraph title of a commit log message with a colon in it as the end of the trailer block. * cc/trailers-corner-case-fix: trailer: support multiline title trailer: retitle a test and correct an in-comment message trailer: ignore first line of message
2015-09-03Merge branch ↵Libravatar Junio C Hamano1-0/+10
'dt/commit-preserve-base-index-upon-opportunistic-cache-tree-update' into maint When re-priming the cache-tree opportunistically while committing the in-core index as-is, we mistakenly invalidated the in-core index too aggressively, causing the experimental split-index code to unnecessarily rewrite the on-disk index file(s). * dt/commit-preserve-base-index-upon-opportunistic-cache-tree-update: commit: don't rewrite shared index unnecessarily
2015-09-03Merge branch 'rs/archive-zip-many' into maintLibravatar Junio C Hamano1-0/+40
"git archive" did not use zip64 extension when creating an archive with more than 64k entries, which nobody should need, right ;-)? * rs/archive-zip-many: archive-zip: support more than 65535 entries archive-zip: use a local variable to store the creator version t5004: test ZIP archives with many entries
2015-09-03Merge branch 'sg/t3020-typofix' into maintLibravatar Junio C Hamano1-1/+1
* sg/t3020-typofix: t3020: fix typo in test description
2015-09-03Merge branch 'jk/fix-alias-pager-config-key-warnings' into maintLibravatar Junio C Hamano1-0/+9
Because the configuration system does not allow "alias.0foo" and "pager.0foo" as the configuration key, the user cannot use '0foo' as a custom command name anyway, but "git 0foo" tried to look these keys up and emitted useless warnings before saying '0foo is not a git command'. These warning messages have been squelched. * jk/fix-alias-pager-config-key-warnings: config: silence warnings for command names with invalid keys
2015-09-03Merge branch 'nd/dwim-wildcards-as-pathspecs' into maintLibravatar Junio C Hamano1-1/+1
Test updates for Windows. * nd/dwim-wildcards-as-pathspecs: t2019: skip test requiring '*' in a file name non Windows
2015-09-03Merge branch 'ps/t1509-chroot-test-fixup' into maintLibravatar Junio C Hamano1-4/+4
t1509 test that requires a dedicated VM environment had some bitrot, which has been corrected. * ps/t1509-chroot-test-fixup: tests: fix cleanup after tests in t1509-root-worktree tests: fix broken && chains in t1509-root-worktree
2015-09-03Merge branch 'jk/am-rerere-lock-fix'Libravatar Junio C Hamano1-0/+36
Recent "git am" introduced a double-locking failure when used with the "--3way" option that invokes rerere machinery. * jk/am-rerere-lock-fix: rerere: release lockfile in non-writing functions
2015-09-02Merge branch 'cc/trailers-corner-case-fix'Libravatar Junio C Hamano1-0/+14
The "interpret-trailers" helper mistook a multi-paragraph title of a commit log message with a colon in it as the end of the trailer block. * cc/trailers-corner-case-fix: trailer: support multiline title
2015-09-02Merge branch 'ee/clean-test-fixes'Libravatar Junio C Hamano1-12/+4
* ee/clean-test-fixes: t7300: fix broken && chains
2015-09-02Merge branch 'jk/log-missing-default-HEAD'Libravatar Junio C Hamano1-0/+14
"git init empty && git -C empty log" said "bad default revision 'HEAD'", which was found to be a bit confusing to new users. * jk/log-missing-default-HEAD: log: diagnose empty HEAD more clearly
2015-09-02t7060: actually test "git diff-index --cached -M"Libravatar Matthieu Prat1-1/+1
A test was designed for "git diff-index --cached -M" but the command is run without the "-M" option (which makes the test essentially identical to its preceding counterpart). Signed-off-by: Matthieu Prat <matthieuprat@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-09-01Merge branch ↵Libravatar Junio C Hamano1-0/+10
'dt/commit-preserve-base-index-upon-opportunistic-cache-tree-update' When re-priming the cache-tree opportunistically while committing the in-core index as-is, we mistakenly invalidated the in-core index too aggressively, causing the experimental split-index code to unnecessarily rewrite the on-disk index file(s). * dt/commit-preserve-base-index-upon-opportunistic-cache-tree-update: commit: don't rewrite shared index unnecessarily
2015-09-01Merge branch 'rs/archive-zip-many'Libravatar Junio C Hamano1-0/+40
"git archive" did not use zip64 extension when creating an archive with more than 64k entries, which nobody should need, right ;-)? * rs/archive-zip-many: archive-zip: support more than 65535 entries archive-zip: use a local variable to store the creator version t5004: test ZIP archives with many entries
2015-09-01Merge branch 'ls/p4-fold-case-client-specs'Libravatar Junio C Hamano1-0/+200
On case insensitive systems, "git p4" did not work well with client specs. * ls/p4-fold-case-client-specs: git-p4: honor core.ignorecase when using P4 client specs
2015-09-01rerere: release lockfile in non-writing functionsLibravatar Jeff King1-0/+36
There's a bug in builtin/am.c in which we take a lock on MERGE_RR recursively. But rather than fix am.c, this patch fixes the confusing interface from rerere.c that caused the bug. Read on for the gory details. The setup_rerere() function both reads the existing MERGE_RR file, and takes MERGE_RR.lock. In the rerere() and rerere_forget() functions, we end up in write_rr(), which will then commit the lock file. But for functions like rerere_clear() that do not write to MERGE_RR, we expect the caller to have handled setup_rerere(). That caller would then need to release the lockfile, but it can't; the lock struct is local to rerere.c. For builtin/rerere.c, this is OK. We run a single rerere operation and then exit immediately, which has the side effect of rolling back the lockfile. But in builtin/am.c, this is actively wrong. If we run "git am -3 --skip", we call setup-rerere twice without releasing the lock: 1. The "--skip" causes us to call am_rerere_clear(), which calls setup_rerere(), but never drops the lock. 2. We then proceed to the next patch. 3. The "--3way" may cause us to call rerere() to handle conflicts in that patch, but we are already holding the lock. The lockfile code dies with: BUG: prepare_tempfile_object called for active object We could fix this by having rerere_clear() call rollback_lock_file(). But it feels a bit odd for it to roll back a lockfile that it did not itself take. So let's simplify the interface further, and handle setup_rerere in the function itself, taking away the question from the caller over whether they need to do so. We can give rerere_gc() the same treatment, as well (even though it doesn't have any callers besides builtin/rerere.c at this point). Note that these functions don't take flags from their callers to pass along to setup_rerere; that's OK, because the flags would not be meaningful for what they are doing. Both of those functions need to hold the lock because even though they do not write to MERGE_RR, they are still writing and should be protected from a simultaneous "rerere" run. But rerere_remaining(), "rerere diff", and "rerere status" are all read-only operations. They want to setup_rerere(), but do not care about taking the lock in the first place. Since our update of MERGE_RR is the usual atomic rename done by commit_lock_file, they can just do a lockless read. For that, we teach setup_rerere a READONLY flag to avoid the lock. As a bonus, this pushes builtin/rerere.c's setup_rerere call closer to the functions that use it. Which means that "git rerere totally-bogus-command" will no longer silently exit(0) in a repository without rerere enabled. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-08-31Merge branch 'sg/describe-contains'Libravatar Junio C Hamano1-0/+8
"git describe" without argument defaulted to describe the HEAD commit, but "git describe --contains" didn't. Arguably, in a repository used for active development, such defaulting would not be very useful as the tip of branch is typically not tagged, but it is better to be consistent. * sg/describe-contains: describe --contains: default to HEAD when no commit-ish is given
2015-08-31Merge branch 'jk/notes-merge-config'Libravatar Junio C Hamano2-0/+91
"git notes merge" can be told with "--strategy=<how>" option how to automatically handle conflicts; this can now be configured by setting notes.mergeStrategy configuration variable. * jk/notes-merge-config: notes: teach git-notes about notes.<name>.mergeStrategy option notes: add notes.mergeStrategy option to select default strategy notes: add tests for --commit/--abort/--strategy exclusivity notes: extract parse_notes_merge_strategy to notes-utils notes: extract enum notes_merge_strategy to notes-utils.h notes: document cat_sort_uniq rewriteMode
2015-08-31Merge branch 'jk/fix-alias-pager-config-key-warnings'Libravatar Junio C Hamano1-0/+9
Because the configuration system does not allow "alias.0foo" and "pager.0foo" as the configuration key, the user cannot use '0foo' as a custom command name anyway, but "git 0foo" tried to look these keys up and emitted useless warnings before saying '0foo is not a git command'. These warning messages have been squelched. * jk/fix-alias-pager-config-key-warnings: config: silence warnings for command names with invalid keys
2015-08-31Merge branch 'hv/submodule-config'Libravatar Junio C Hamano1-0/+153
The gitmodules API accessed from the C code learned to cache stuff lazily. * hv/submodule-config: submodule: allow erroneous values for the fetchRecurseSubmodules option submodule: use new config API for worktree configurations submodule: extract functions for config set and lookup submodule: implement a config API for lookup of .gitmodules values
2015-08-31Merge branch 'sg/config-name-only'Libravatar Junio C Hamano1-0/+22
"git config --list" output was hard to parse when values consist of multiple lines. "--name-only" option is added to help this. * sg/config-name-only: get_urlmatch: avoid useless strbuf write format_config: simplify buffer handling format_config: don't init strbuf config: restructure format_config() for better control flow completion: list variable names reliably with 'git config --name-only' config: add '--name-only' option to list only variable names
2015-08-31trailer: support multiline titleLibravatar Christian Couder1-0/+14
We currently ignore the first line passed to `git interpret-trailers`, when looking for the beginning of the trailers. Unfortunately this does not work well when a commit is created with a line break in the title, using for example the following command: git commit -m 'place of code: change we made' That's why instead of ignoring only the first line, it is better to ignore the first paragraph. Signed-off-by: Christian Couder <christian.couder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-08-31t7300: fix broken && chainsLibravatar Erik Elfström1-12/+4
While we are here, remove some boilerplate by using test_commit. Signed-off-by: Erik Elfström <erik.elfstrom@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-08-31log: diagnose empty HEAD more clearlyLibravatar Jeff King1-0/+14
If you init or clone an empty repository, the initial message from running "git log" is not very friendly: $ git init Initialized empty Git repository in /home/peff/foo/.git/ $ git log fatal: bad default revision 'HEAD' Let's detect this situation and write a more friendly message: $ git log fatal: your current branch 'master' does not have any commits yet We also detect the case that 'HEAD' points to a broken ref; this should be even less common, but is easy to see. Note that we do not diagnose all possible cases. We rely on resolve_ref, which means we do not get information about complex cases. E.g., "--default master" would use dwim_ref to find "refs/heads/master", but we notice only that "master" does not exist. Similarly, a complex sha1 expression like "--default HEAD^2" will not resolve as a ref. But that's OK. We fall back to a generic error message in those cases, and they are unlikely to be used anyway. Catching an empty or broken "HEAD" improves the common case, and the other cases are not regressed. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-08-31commit: don't rewrite shared index unnecessarilyLibravatar David Turner1-0/+10
Remove a cache invalidation which would cause the shared index to be rewritten on as-is commits. When the cache-tree has changed, we need to update it. But we don't necessarily need to update the shared index. So setting active_cache_changed to SOMETHING_CHANGED is unnecessary. Instead, we let update_main_cache_tree just update the CACHE_TREE_CHANGED bit. In order to test this, make test-dump-split-index not segfault on missing replace_bitmap/delete_bitmap. This new codepath is not called now that the test passes, but is necessary to avoid a segfault when the new test is run with the old builtin/commit.c code. Signed-off-by: David Turner <dturner@twopensource.com> Acked-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-08-28Merge branch 'cc/trailers-corner-case-fix'Libravatar Junio C Hamano1-1/+14
"interpret-trailers" helper mistook a single-liner log message that has a colon as the end of existing trailer. * cc/trailers-corner-case-fix: trailer: retitle a test and correct an in-comment message trailer: ignore first line of message
2015-08-28Merge branch 'dt/untracked-subdir'Libravatar Junio C Hamano1-2/+98
The experimental untracked-cache feature were buggy when paths with a few levels of subdirectories are involved. * dt/untracked-subdir: untracked cache: fix entry invalidation untracked-cache: fix subdirectory handling
2015-08-28git-p4: honor core.ignorecase when using P4 client specsLibravatar Lars Schneider1-0/+200
Perforce depot may record paths in mixed cases, e.g. "p4 files" may show that there are these two paths: //depot/Path/to/file1 //depot/pATH/to/file2 and with "p4" or "p4v", these end up in the same directory, e.g. //depot/Path/to/file1 //depot/Path/to/file2 which is the desired outcome on case insensitive systems. If git-p4 is used with client spec "//depot/Path/...", however, then all files not matching the case in the client spec are ignored (in the example above "//depot/pATH/to/file2"). Fix this by using the path case that appears first in lexicographical order when core.ignorecase is set to true. This behavior is consistent with "p4" and "p4v". Signed-off-by: Lars Schneider <larsxschneider@gmail.com> Acked-by: Luke Diamand <luke@diamand.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-08-28archive-zip: support more than 65535 entriesLibravatar René Scharfe1-1/+1
Support more than 65535 entries cleanly by writing a "zip64 end of central directory record" (with a 64-bit field for the number of entries) before the usual "end of central directory record" (which contains only a 16-bit field). InfoZIP's zip does the same. Archives with 65535 or less entries are not affected. Programs that extract all files like InfoZIP's zip and 7-Zip ignored the field and could extract all files already. Software that relies on the ZIP file directory to show a list of contained files quickly to simulate to normal directory like Windows' built-in ZIP functionality only saw a subset of the included files. Windows supports ZIP64 since Vista according to https://en.wikipedia.org/wiki/Zip_%28file_format%29#ZIP64. Suggested-by: Johannes Schauer <josch@debian.org> Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-08-28t5004: test ZIP archives with many entriesLibravatar René Scharfe1-0/+40
A ZIP file directory has a 16-bit field for the number of entries it contains. There are 64-bit extensions to deal with that. Demonstrate that git archive --format=zip currently doesn't use them and instead overflows the field. InfoZIP's unzip doesn't care about this field and extracts all files anyway. Software that uses the directory for presenting a filesystem like view quickly -- notably Windows -- depends on it, but doesn't lend itself to an automatic test case easily. Use InfoZIP's zipinfo, which probably isn't available everywhere but at least can provides *some* way to check this field. To speed things up a bit create and commit only a subset of the files and build a fake tree out of duplicates and pass that to git archive. Signed-off-by: Rene Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-08-26Merge branch 'sg/t3020-typofix'Libravatar Junio C Hamano1-1/+1
* sg/t3020-typofix: t3020: fix typo in test description
2015-08-26Merge branch 'dt/untracked-sparse'Libravatar Junio C Hamano1-1/+1
Test update. * dt/untracked-sparse: t7063: use --force-untracked-cache to speed up a bit
2015-08-26Merge branch 'pt/am-builtin-abort-fix'Libravatar Junio C Hamano1-0/+24
"git am" that was recently reimplemented in C had a performance regression in "git am --abort" that goes back to the version before an attempted (and failed) patch application. * pt/am-builtin-abort-fix: am --skip/--abort: merge HEAD/ORIG_HEAD tree into index
2015-08-26trailer: retitle a test and correct an in-comment messageLibravatar Christian Couder1-1/+1
Signed-off-by: Christian Couder <christian.couder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2015-08-25Merge branch 'jk/guess-repo-name-regression-fix' into maintLibravatar Junio C Hamano1-0/+106
"git clone $URL" in recent releases of Git contains a regression in the code that invents a new repository name incorrectly based on the $URL. This has been corrected. * jk/guess-repo-name-regression-fix: clone: use computed length in guess_dir_name clone: add tests for output directory
2015-08-25Merge branch 'jk/test-with-x' into maintLibravatar Junio C Hamano1-2/+11
Running tests with the "-x" option to make them verbose had some unpleasant interactions with other features of the test suite. * jk/test-with-x: test-lib: disable trace when test is not verbose test-lib: turn off "-x" tracing during chain-lint check
2015-08-25Merge branch 'pt/am-builtin-options'Libravatar Junio C Hamano2-4/+130
After "git am --opt1" stops, running "git am --opt2" pays attention to "--opt2" only for the patch that caused the original invocation to stop. * pt/am-builtin-options: am: let --signoff override --no-signoff am: let command-line options override saved options test_terminal: redirect child process' stdin to a pty