Repository: sharkdp/fd (language: rust)

Issue:
Ambiguity in piped vs not piped output
**What version of `fd` are you using?**
[paste the output of `fd --version` here]
```
$ fd --version
fd 8.4.0
```

_A short journey_:

<details>
<summary><i>I am confused on why piped vs not piped output is different</i></summary>
Hmmm... Do I have other `.editorconfig` files I can reference for my new one?

```console
$ fd .editorconfig
$
```
WAT? 😕
(5 minutes) ... aaaah, okay, it's _a hidden file, and hidden files are not searched by default_:

```console
$ fd -H .editorconfig
kNBcDyXJi/ecRlRPv/BXM_Je/.rPDclZxNgYyr
XFxiJagnA/WJgbrTD/OiInoDSAgiINUnkk/.YZmDuFuCckIL
WIHkZjomi/yIqdYhH/rfdDVKTAUBWSiXAo/GfaHm/lFbq/.xIRDWCIvevaM
fFXOXmAWN/acInlfx/flMaBjiDVIYVYtBI/RsoTY/BbzL/bFr#OkB/zbHTfZ/ifKaY/SfUIW]iXniUyQ/.UgrGwPaQeGmV
.EzjFK/eNeAOoJwm/omvRBNUvZ5263.2/WQSEH/qlBKQv=DShLzMF/OjqIhM.GfUVw.dnXazN.DLIpSSPOdtxn.bVkXV.Gywp/
.EHDIh/wRWiXKLRB/levauwvgX9517.2/JrmiW/YUOpol~LuqpgqS/TojFxD.qwYdl.JEjimx.rKtTUXgepXFs.ZOpma.eIJR/onSvQh.oONnz.gwLsWe.YBfzuemHHpvL.sDbfk.mmnj}XcmJiJ:O.CRL
.iWbGU/bhMyenPRx/ymTRQutnp7866.6/Thawj/dcogoa%tLTmpLj/DKkGys.eRRii.CIdXph.rUtUHfPNGwzu.hKAKv.tHbJ/XSvwvG.TtCRa.iKGOlp.tGqEddLfvCKy.yeJGp.XtEj|JdVAdBg.tjjLfvx.MPsrbBppO.XHi
.zsAeh/ZcXjHpZXA/vVaFyYjIa7460.9/FTgNJ/bsqXby%nlcvMKY/XGLlCa.CMfCh.uSXfFl.pEzyalOgKxvy.HXOTU.wXrm/BpcSne.GjNMZ.rTSqyZ.NlBrgbPyWWrW.JBNTB.TGCK@SfGYrk.xLT
.LSaEq/INMPskppO/JgHjUtlOA9796.6/YqmAQ/wYqCpj,smjcPsb/MYvWBa.LJBtO.yuBOck.xtrLwWIfdigW.LhCyW.xQeL/TGgeon.rkLRD.qWOrwe.YBlrzbPqxjyr.LMrTm.UIUR(DZYvpjy.ADvUPBO}m.ZiL
.awHQa/VLuNyKFhc/bplIgFZBx6563.2/rThOI/EgJjtJ{KCgOMWK/DZrPqH.LCMVE.lODdEt.CsUdpdhPGYgS.zXLfV.gRxy/drCbol.yIjmn.HjSjFq.LhpJOjRJTgrU.vsBXZ.YXzY.GbSJMNQ.klQFcFO.eqr
...
$ fd -H .editorconfig | wc -l
233
$
```

😵 ... but hey, if I look closer, there are paths that _start with a dot_ (i.e. are hidden), and therefore "not mine". How about ...
```console
$ fd -H .editorconfig | grep -vP '^\.'
$
```
**WAT?** 🤯 

(15 minutes later) ... 
```console
$ fd -H .editorconfig | head
./kNBcDyXJi/ecRlRPv/BXM_Je/.rPDclZxNgYyr
./XFxiJagnA/WJgbrTD/OiInoDSAgiINUnkk/.YZmDuFuCckIL
./WIHkZjomi/yIqdYhH/rfdDVKTAUBWSiXAo/GfaHm/lFbq/.xIRDWCIvevaM
./fFXOXmAWN/acInlfx/flMaBjiDVIYVYtBI/RsoTY/BbzL/bFr#OkB/zbHTfZ/ifKaY/SfUIW]iXniUyQ/.UgrGwPaQeGmV
./.EzjFK/eNeAOoJwm/omvRBNUvZ5263.2/WQSEH/qlBKQv=DShLzMF/OjqIhM.GfUVw.dnXazN.DLIpSSPOdtxn.bVkXV.Gywp/
./.EHDIh/wRWiXKLRB/levauwvgX9517.2/JrmiW/YUOpol~LuqpgqS/TojFxD.qwYdl.JEjimx.rKtTUXgepXFs.ZOpma.eIJR/onSvQh.oONnz.gwLsWe.YBfzuemHHpvL.sDbfk.mmnj}XcmJiJ:O.CRL
./.iWbGU/bhMyenPRx/ymTRQutnp7866.6/Thawj/dcogoa%tLTmpLj/DKkGys.eRRii.CIdXph.rUtUHfPNGwzu.hKAKv.tHbJ/XSvwvG.TtCRa.iKGOlp.tGqEddLfvCKy.yeJGp.XtEj|JdVAdBg.tjjLfvx.MPsrbBppO.XHi
./.zsAeh/ZcXjHpZXA/vVaFyYjIa7460.9/FTgNJ/bsqXby%nlcvMKY/XGLlCa.CMfCh.uSXfFl.pEzyalOgKxvy.HXOTU.wXrm/BpcSne.GjNMZ.rTSqyZ.NlBrgbPyWWrW.JBNTB.TGCK@SfGYrk.xLT
./.LSaEq/INMPskppO/JgHjUtlOA9796.6/YqmAQ/wYqCpj,smjcPsb/MYvWBa.LJBtO.yuBOck.xtrLwWIfdigW.LhCyW.xQeL/TGgeon.rkLRD.qWOrwe.YBlrzbPqxjyr.LMrTm.UIUR(DZYvpjy.ADvUPBO}m.ZiL
./.awHQa/VLuNyKFhc/bplIgFZBx6563.2/rThOI/EgJjtJ{KCgOMWK/DZrPqH.LCMVE.lODdEt.CsUdpdhPGYgS.zXLfV.gRxy/drCbol.yIjmn.HjSjFq.LhpJOjRJTgrU.vsBXZ.YXzY.GbSJMNQ.klQFcFO.eqr
$
```

![wat wat wat](https://user-images.githubusercontent.com/81555/47361982-05028300-d6dc-11e8-8b37-b4321bed083c.jpg)
</details>

_I maybe get the reasoning_ behind this option, however, I think it's counter-intuitive (for me) to not be able to _parse_ things the way I am seeing them (unless I specifically `-print`, `-print0`, etc ...).

Is there any way I can reconcile things for myself?

It seems that `--strip-cwd-prefix` helps me do what I want, but then it's annoying to remember to type that as well all the time (and then `-H`, and then _sometimes_ `--glob` etc) ... 
Is there a config file that I can use for this purpose (instead of an alias hidden somewhere)?


Discussion / hints:
Right, this was kind of discussed in https://github.com/sharkdp/fd/issues/760, but not emphasized too much.  I'm very sympathetic to this:

```console
$ fd pattern
a/path/matching/pattern
$ fd pattern | grep '^a/path'
$ # ???
```

See https://github.com/sharkdp/fd/issues/362 for previous discussion about a config file.  Right now there isn't one.  A shell alias might be the best alternative.
> Right, this was kind of discussed in #760, but not emphasized too much. I'm very sympathetic to this:
> 
> ```
> $ fd pattern
> a/path/matching/pattern
> $ fd pattern | grep '^a/path'
> $ # ???
> ```

I also agree. This is not good. Do we want to change the behavior (again)? I'd hate to include the `./` part in the interactive output :slightly_frowning_face:.

In the past, I have strictly argued against a config file for `fd`. And think I would still like to avoid it. But if we're talking about purely "cosmetical" things (e.g. color settings, precise shape of the *interactive* output), I might be convinced to re-think my position :smile:.
My preference would be to disable the `./` in piped output by default.  It doesn't fully address the security issues anyway since newlines in paths are still an issue (`./foo\n--dangerous-option`).  Most pipes are not to `xargs` IMO.

I would keep the leading `./` in `-0` mode.
That sounds like a very good idea. It would be (another) breaking change, but I think I'm also in favor of doing that.

FYI: @jcaplan @ykonstant1
At least it's only breaking for one or two releases?
That seems ok to me too.

Fix patch:
diff --git a/src/app.rs b/src/app.rs
index a9eba45f9..5348ade2a 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -719,10 +719,10 @@ pub fn build_app() -> Command<'static> {
                 .long("strip-cwd-prefix")
                 .conflicts_with_all(&["path", "search-path"])
                 .hide_short_help(true)
-                .help("strip './' prefix from non-tty outputs")
+                .help("strip './' prefix from -0/--print0 output")
                 .long_help(
-                    "By default, relative paths are prefixed with './' when the output goes to a non \
-                     interactive terminal (TTY). Use this flag to disable this behaviour."
+                    "By default, relative paths are prefixed with './' when -0/--print0 is given, to \
+                     make them safer for use with xargs. Use this flag to disable this behaviour."
                 )
         );
 
diff --git a/src/main.rs b/src/main.rs
index f204d3187..dba6d4b31 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -385,7 +385,7 @@ fn construct_config(matches: clap::ArgMatches, pattern_regex: &str) -> Result<Co
             }),
         strip_cwd_prefix: (!matches.is_present("path")
             && !matches.is_present("search-path")
-            && (interactive_terminal || matches.is_present("strip-cwd-prefix"))),
+            && (!matches.is_present("null_separator") || matches.is_present("strip-cwd-prefix"))),
     })
 }
 


Test patch:
diff --git a/tests/tests.rs b/tests/tests.rs
index dab25d560..0bed40780 100644
--- a/tests/tests.rs
+++ b/tests/tests.rs
@@ -61,18 +61,18 @@ fn create_file_with_size<P: AsRef<Path>>(path: P, size_in_bytes: usize) {
 fn test_simple() {
     let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
 
-    te.assert_output(&["a.foo"], "./a.foo");
-    te.assert_output(&["b.foo"], "./one/b.foo");
-    te.assert_output(&["d.foo"], "./one/two/three/d.foo");
+    te.assert_output(&["a.foo"], "a.foo");
+    te.assert_output(&["b.foo"], "one/b.foo");
+    te.assert_output(&["d.foo"], "one/two/three/d.foo");
 
     te.assert_output(
         &["foo"],
-        "./a.foo
-        ./one/b.foo
-        ./one/two/c.foo
-        ./one/two/C.Foo2
-        ./one/two/three/d.foo
-        ./one/two/three/directory_foo/",
+        "a.foo
+        one/b.foo
+        one/two/c.foo
+        one/two/C.Foo2
+        one/two/three/d.foo
+        one/two/three/directory_foo/",
     );
 }
 
@@ -80,17 +80,17 @@ fn test_simple() {
 #[test]
 fn test_empty_pattern() {
     let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
-    let expected = "./a.foo
-    ./e1 e2
-    ./one/
-    ./one/b.foo
-    ./one/two/
-    ./one/two/c.foo
-    ./one/two/C.Foo2
-    ./one/two/three/
-    ./one/two/three/d.foo
-    ./one/two/three/directory_foo/
-    ./symlink";
+    let expected = "a.foo
+    e1 e2
+    one/
+    one/b.foo
+    one/two/
+    one/two/c.foo
+    one/two/C.Foo2
+    one/two/three/
+    one/two/three/d.foo
+    one/two/three/directory_foo/
+    symlink";
 
     te.assert_output(&["--regex"], expected);
     te.assert_output(&["--fixed-strings"], expected);
@@ -209,17 +209,17 @@ fn test_regex_searches() {
 
     te.assert_output(
         &["[a-c].foo"],
-        "./a.foo
-        ./one/b.foo
-        ./one/two/c.foo
-        ./one/two/C.Foo2",
+        "a.foo
+        one/b.foo
+        one/two/c.foo
+        one/two/C.Foo2",
     );
 
     te.assert_output(
         &["--case-sensitive", "[a-c].foo"],
-        "./a.foo
-        ./one/b.foo
-        ./one/two/c.foo",
+        "a.foo
+        one/b.foo
+        one/two/c.foo",
     );
 }
 
@@ -230,21 +230,21 @@ fn test_smart_case() {
 
     te.assert_output(
         &["c.foo"],
-        "./one/two/c.foo
-        ./one/two/C.Foo2",
+        "one/two/c.foo
+        one/two/C.Foo2",
     );
 
-    te.assert_output(&["C.Foo"], "./one/two/C.Foo2");
+    te.assert_output(&["C.Foo"], "one/two/C.Foo2");
 
-    te.assert_output(&["Foo"], "./one/two/C.Foo2");
+    te.assert_output(&["Foo"], "one/two/C.Foo2");
 
     // Only literal uppercase chars should trigger case sensitivity.
     te.assert_output(
         &["\\Ac"],
-        "./one/two/c.foo
-        ./one/two/C.Foo2",
+        "one/two/c.foo
+        one/two/C.Foo2",
     );
-    te.assert_output(&["\\AC"], "./one/two/C.Foo2");
+    te.assert_output(&["\\AC"], "one/two/C.Foo2");
 }
 
 /// Case sensitivity (--case-sensitive)
@@ -252,13 +252,13 @@ fn test_smart_case() {
 fn test_case_sensitive() {
     let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
 
-    te.assert_output(&["--case-sensitive", "c.foo"], "./one/two/c.foo");
+    te.assert_output(&["--case-sensitive", "c.foo"], "one/two/c.foo");
 
-    te.assert_output(&["--case-sensitive", "C.Foo"], "./one/two/C.Foo2");
+    te.assert_output(&["--case-sensitive", "C.Foo"], "one/two/C.Foo2");
 
     te.assert_output(
         &["--ignore-case", "--case-sensitive", "C.Foo"],
-        "./one/two/C.Foo2",
+        "one/two/C.Foo2",
     );
 }
 
@@ -269,14 +269,14 @@ fn test_case_insensitive() {
 
     te.assert_output(
         &["--ignore-case", "C.Foo"],
-        "./one/two/c.foo
-        ./one/two/C.Foo2",
+        "one/two/c.foo
+        one/two/C.Foo2",
     );
 
     te.assert_output(
         &["--case-sensitive", "--ignore-case", "C.Foo"],
-        "./one/two/c.foo
-        ./one/two/C.Foo2",
+        "one/two/c.foo
+        one/two/C.Foo2",
     );
 }
 
@@ -287,25 +287,25 @@ fn test_glob_searches() {
 
     te.assert_output(
         &["--glob", "*.foo"],
-        "./a.foo
-        ./one/b.foo
-        ./one/two/c.foo
-        ./one/two/three/d.foo",
+        "a.foo
+        one/b.foo
+        one/two/c.foo
+        one/two/three/d.foo",
     );
 
     te.assert_output(
         &["--glob", "[a-c].foo"],
-        "./a.foo
-        ./one/b.foo
-        ./one/two/c.foo",
+        "a.foo
+        one/b.foo
+        one/two/c.foo",
     );
 
     te.assert_output(
         &["--glob", "[a-c].foo*"],
-        "./a.foo
-        ./one/b.foo
-        ./one/two/C.Foo2
-        ./one/two/c.foo",
+        "a.foo
+        one/b.foo
+        one/two/C.Foo2
+        one/two/c.foo",
     );
 }
 
@@ -317,19 +317,19 @@ fn test_full_path_glob_searches() {
 
     te.assert_output(
         &["--glob", "--full-path", "**/one/**/*.foo"],
-        "./one/b.foo
-        ./one/two/c.foo
-        ./one/two/three/d.foo",
+        "one/b.foo
+        one/two/c.foo
+        one/two/three/d.foo",
     );
 
     te.assert_output(
         &["--glob", "--full-path", "**/one/*/*.foo"],
-        " ./one/two/c.foo",
+        " one/two/c.foo",
     );
 
     te.assert_output(
         &["--glob", "--full-path", "**/one/*/*/*.foo"],
-        " ./one/two/three/d.foo",
+        " one/two/three/d.foo",
     );
 }
 
@@ -339,11 +339,11 @@ fn test_smart_case_glob_searches() {
 
     te.assert_output(
         &["--glob", "c.foo*"],
-        "./one/two/C.Foo2
-        ./one/two/c.foo",
+        "one/two/C.Foo2
+        one/two/c.foo",
     );
 
-    te.assert_output(&["--glob", "C.Foo*"], "./one/two/C.Foo2");
+    te.assert_output(&["--glob", "C.Foo*"], "one/two/C.Foo2");
 }
 
 /// Glob-based searches (--glob) in combination with --case-sensitive
@@ -351,7 +351,7 @@ fn test_smart_case_glob_searches() {
 fn test_case_sensitive_glob_searches() {
     let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
 
-    te.assert_output(&["--glob", "--case-sensitive", "c.foo*"], "./one/two/c.foo");
+    te.assert_output(&["--glob", "--case-sensitive", "c.foo*"], "one/two/c.foo");
 }
 
 /// Glob-based searches (--glob) in combination with --extension
@@ -361,7 +361,7 @@ fn test_glob_searches_with_extension() {
 
     te.assert_output(
         &["--glob", "--extension", "foo2", "[a-z].*"],
-        "./one/two/C.Foo2",
+        "one/two/C.Foo2",
     );
 }
 
@@ -370,7 +370,7 @@ fn test_glob_searches_with_extension() {
 fn test_regex_overrides_glob() {
     let te = TestEnv::new(DEFAULT_DIRS, DEFAULT_FILES);
 
-    te.assert_output(&["--glob", "--regex", "Foo2$"], "./one/two/C.Foo2");
+    te.assert_output(&["--glob", "--regex", "Foo2$"], "one/two/C.Foo2");
 }
 
 /// Full path search (--full-path)
@@ -386,8 +386,8 @@ fn test_full_path() {
             "--full-path",
             &format!("^{prefix}.*three.*foo$", prefix = prefix),
         ],
-        "./one/two/three/d.foo
-        ./one/two/three/directory_foo/",
+        "one/two/three/d.foo
+        one/two/three/directory_foo/",
     );
 }
 
@@ -398,13 +398,13 @@ fn test_hidden() {
 
     te.assert_output(
         &["--hidden", "foo"],
-        "./.hidden.foo
-        ./a.foo
-        ./one/b.foo
-        ./one/two/c.foo
-        ./one/two/C.Foo2
-        ./one/two/three/d.foo
-        ./one/two/three/directory_foo/",
+        ".hidden.foo
+        a.foo
+        one/b.foo
+        one/two/c.foo
+        one/two/C.Foo2
+        one/two/three/d.foo
+        one/two/three/directory_foo/",
     );
 }
 
@@ -426,7 +426,7 @@ fn test_hidden_file_attribute() {
         .open(te.test_root().join("hidden-file.txt"))
         .unwrap();
 
-    te.assert_output(&["--hidden", "hidden-file.txt"], "./hidden-file.txt");
+    te.assert_output(&["--hidden", "hidden-file.txt"], "hidden-file.txt");
     te.assert_output(&["hidden-file.txt"], "");
 }
 
@@ -437,27 +437,27 @@ fn test_no_ignore() {
 
     te.assert_output(
         &["--no-ignore", "foo"],
-        "./a.foo
-        ./fdignored.foo
-        ./gitignored.foo
-        ./one/b.foo
-        ./one/two/c.foo
-        ./one/two/C.Foo2
-        ./one/two/three/d.foo
-        ./one/two/three/directory_foo/",
+        "a.foo
+        fdignored.foo
+        gitignored.foo
+        one/b.foo
+        one/two/c.foo
+        one/two/C.Foo2
+        one/two/three/d.foo
+        one/two/three/directory_foo/",
     );
 
     te.assert_output(
         &["--hidden", "--no-ignore", "foo"],
-        "./.hidden.foo
-        ./a.foo
-        ./fdignored.foo
-        ./gitignored.foo
-        ./one/b.foo
-        ./one/two/c.foo
-        ./one/two/C.Foo2
-        ./one/two/three/d.foo
-        ./one/two/three/directory_foo/",
+        ".hidden.foo
+        a.foo
+        fdignored.foo
+        gitignored.foo
+        one/b.foo
+        one/two/c.foo
+        one/two/C.Foo2
+        one/two/three/d.foo
+        one/two/three/directory_foo/",
     );
 }
 
@@ -482,20 +482,20 @@ fn test_gitignore_and_fdignore() {
         .write_all(b"ignored-by-gitignore\nignored-by-both")
         .unwrap();
 
-    te.assert_output(&["ignored"], "./ignored-by-nothing");
+    te.assert_output(&["ignored"], "ignored-by-nothing");
 
     te.assert_output(
         &["--no-ignore-vcs", "ignored"],
-        "./ignored-by-nothing
-        ./ignored-by-gitignore",
+        "ignored-by-nothing
+        ignored-by-gitignore",
     );
 
     te.assert_output(
         &["--no-ignore", "ignored"],
-        "./ignored-by-nothing
-        ./ignored-by-fdignore
-        ./ignored-by-gitignore
-        ./ignored-by-both",
+        "ignored-by-nothing
+        ignored-by-fdignore
+        ignored-by-gitignore
+        ignored-by-both",
     );
 }
 
@@ -521,13 +521,13 @@ fn test_no_ignore_parent() {
         .write_all(b"child-ignored")
         .unwrap();
 
-    te.assert_output_subdirectory("inner", &[], "./not-ignored");
+    te.assert_output_subdirectory("inner", &[], "not-ignored");
 
     te.assert_output_subdirectory(
         "inner",
         &["--no-ignore-parent"],
-        "./parent-ignored
-        ./not-ignored",
+        "parent-ignored
+        not-ignored",
     );
 }
 
@@ -559,15 +559,15 @@ fn test_no_ignore_parent_inner_git() {
     te.assert_output_subdirectory(
         "inner",
         &[],
-        "./not-ignored
-        ./parent-ignored",
+        "not-ignored
+        parent-ignored",
     );
 
     te.assert_output_subdirectory(
         "inner",
         &["--no-ignore-parent"],
-        "./not-ignored
-        ./parent-ignored",
+        "not-ignored
+        parent-ignored",
     );
 }
 
@@ -590,11 +590,11 @@ fn test_custom_ignore_precedence() {
         .write_all(b"!foo")
         .unwrap();
 
-    te.assert_output(&["foo"], "./inner/foo");
+    te.assert_output(&["foo"], "inner/foo");
 
-    te.assert_output(&["--no-ignore-vcs", "foo"], "./inner/foo");
+    te.assert_output(&["--no-ignore-vcs", "foo"], "inner/foo");
 
-    te.assert_output(&["--no-ignore", "foo"], "./inner/foo");
+    te.assert_output(&["--no-ignore", "foo"], "inner/foo");
 }
 
 /// VCS ignored files (--no-ignore-vcs)
@@ -604,13 +604,13 @@ fn test_no_ignore_vcs() {
 
     te.assert_output(
         &["--no-ignore-vcs", "foo"],
-        "./a.foo
-        ./gitignored.foo
-        ./one/b.foo
-        ./one/two/c.foo
-        ./one/two/C.Foo2
-        ./one/two/three/d.foo
-        ./one/two/three/directory_foo/",
+        "a.foo
+        gitignored.foo
+        one/b.foo
+        one/two/c.foo
+        one/two/C.Foo2
+        one/two/three/d.foo
+        one/two/three/directory_foo/",
     );
 }
 
@@ -625,8 +625,8 @@ fn test_no_ignore_vcs_child_dir() {
     te.assert_output_subdirectory(
         "inner",
         &["--no-ignore-vcs", "foo"],
-        "./foo
-        ./gitignored.foo",
+        "foo
+        gitignored.foo",
     );
 }
 
@@ -643,9 +643,9 @@ fn test_custom_ignore_files() {
 
     te.assert_output(
         &["--ignore-file", "custom.ignore", "foo"],
-        "./a.foo
-        ./one/b.foo
-        ./one/two/c.foo",
+        "a.foo
+        one/b.foo
+        one/two/c.foo",
     );
 }
 
@@ -656,15 +656,15 @@ fn test_no_ignore_aliases() {
 
     te.assert_output(
         &["-u", "foo"],
-        "./.hidden.foo
-        ./a.foo
-        ./fdignored.foo
-        ./gitignored.foo
-        ./one/b.foo
-        ./one/two/c.foo
-        ./one/two/C.Foo2
-        ./one/two/three/d.foo
-        ./one/two/three/directory_foo/",
+        ".hidden.foo
+        a.foo
+        fdignored.foo
+        gitignored.foo
+        one/b.foo
+        one/two/c.foo
+        one/two/C.Foo2
+        one/two/three/d.foo
+        one/two/three/directory_foo/",
     );
 }
 
@@ -675,10 +675,10 @@ fn test_follow() {
 
     te.assert_output(
         &["--follow", "c.foo"],
-        "./one/two/c.foo
-        ./one/two/C.Foo2
-        ./symlink/c.foo
-        ./symlink/C.Foo2",
+        "one/two/c.foo
+        one/two/C.Foo2
+        symlink/c.foo
+        symlink/C.Foo2",
     );
 }
 
@@ -733,20 +733,20 @@ fn test_follow_broken_symlink() {
 
     te.assert_output(
         &["symlink"],
-        "./broken_symlink
-        ./symlink",
+        "broken_symlink
+        symlink",
     );
     te.assert_output(
         &["--type", "symlink", "symlink"],
-        "./broken_symlink
-        ./symlink",
+        "broken_symlink
+        symlink",
     );
 
     te.assert_output(&["--type", "file", "symlink"], "");
 
     te.assert_output(
         &["--follow", "--type", "symlink", "symlink"],
-        "./broken_symlink",
+        "broken_symlink",
     );
     te.assert_output(&["--follow", "--type", "file", "symlink"], "");
 }
@@ -774,33 +774,33 @@ fn test_max_depth() {
 
     te.assert_output(
         &["--max-depth", "3"],
-        "./a.foo
-        ./e1 e2
-        ./one/
-        ./one/b.foo
-        ./one/two/
-        ./one/two/c.foo
-        ./one/two/C.Foo2
-        ./one/two/three/
-        ./symlink",
+        "a.foo
+        e1 e2
+        one/
+        one/b.foo
+        one/two/
+        one/two/c.foo
+        one/two/C.Foo2
+        one/two/three/
+        symlink",
     );
 
     te.assert_output(
         &["--max-depth", "2"],
-        "./a.foo
-        ./e1 e2
-        ./one/
-        ./one/b.foo
-        ./one/two/
-        ./symlink",
+        "a.foo
+        e1 e2
+        one/
+        one/b.foo
+        one/two/
+        symlink",
     );
 
     te.assert_output(
         &["--max-depth", "1"],
-        "./a.foo
-        ./e1 e2
-        ./one/
-        ./symlink",
+        "a.foo
+        e1 e2
+        one/
+        symlink",
     );
 }
 
@@ -811,17 +811,17 @@ fn test_min_depth() {
 
     te.assert_output(
         &["--min-depth", "3"],
-        "./one/two/c.foo
-        ./one/two/C.Foo2
-        ./one/two/three/
-        ./one/two/three/d.foo
-        ./one/two/three/directory_foo/",
+        "one/two/c.foo
+        one/two/C.Foo2
+        one/two/three/
+        one/two/three/d.foo
+        one/two/three/directory_foo/",
     );
 
     te.assert_output(
         &["--min-depth", "4"],
-        "./one/two/three/d.foo
-        ./one/two/three/directory_foo/",
+        "one/two/three/d.foo
+        one/two/three/directory_foo/",
     );
 }
 
@@ -832,9 +832,9 @@ fn test_exact_depth() {
 
     te.assert_output(
         &["--exact-depth", "3"],
-        "./one/two/c.foo
-        ./one/two/C.Foo2
-        ./one/two/three/",
+        "one/two/c.foo
+        one/two/C.Foo2
+        one/two/three/",
     );
 }
 
@@ -843,32 +843,32 @@ fn test_exact_depth() {
 fn test_prune() {
     let dirs = &["foo/bar", "bar/foo", "baz"];
     let files = &[
-        "./foo/foo.file",
-        "./foo/bar/foo.file",
-        "./bar/foo.file",
-        "./bar/foo/foo.file",
-        "./baz/foo.file",
+        "foo/foo.file",
+        "foo/bar/foo.file",
+        "bar/foo.file",
+        "bar/foo/foo.file",
+        "baz/foo.file",
     ];
 
     let te = TestEnv::new(dirs, files);
 
     te.assert_output(
         &["foo"],
-        "./foo/
-        ./foo/foo.file
-        ./foo/bar/foo.file
-        ./bar/foo.file
-        ./bar/foo/
-        ./bar/foo/foo.file
-        ./baz/foo.file",
+        "foo/
+        foo/foo.file
+        foo/bar/foo.file
+        bar/foo.file
+        bar/foo/
+        bar/foo/foo.file
+        baz/foo.file",
     );
 
     te.assert_output(
         &["--prune", "foo"],
-        "./foo/
-        ./bar/foo/
-        ./bar/foo.file
-        ./baz/foo.file",
+        "foo/
+        bar/foo/
+        bar/foo.file
+        baz/foo.file",
     );
 }
 
@@ -955,34 +955,34 @@ fn test_type() {
 
     te.assert_output(
         &["--type", "f"],
-        "./a.foo
-        ./e1 e2
-        ./one/b.foo
-        ./one/two/c.foo
-        ./one/two/C.Foo2
-        ./one/two/three/d.foo",
+        "a.foo
+        e1 e2
+        one/b.foo
+        one/two/c.foo
+        one/two/C.Foo2
+        one/two/three/d.foo",
     );
 
-    te.assert_output(&["--type", "f", "e1"], "./e1 e2");
+    te.assert_output(&["--type", "f", "e1"], "e1 e2");
 
     te.assert_output(
         &["--type", "d"],
-        "./one/
-        ./one/two/
-        ./one/two/three/
-        ./one/two/three/directory_foo/",
+        "one/
+        one/two/
+        one/two/three/
+        one/two/three/directory_foo/",
     );
 
     te.assert_output(
         &["--type", "d", "--type", "l"],
-        "./one/
-        ./one/two/
-        ./one/two/three/
-        ./one/two/three/directory_foo/
-        ./symlink",
+        "one/
+        one/two/
+        one/two/three/
+        one/two/three/directory_foo/
+        symlink",
     );
 
-    te.assert_output(&["--type", "l"], "./symlink");
+    te.assert_output(&["--type", "l"], "symlink");
 }
 
 /// Test `--type executable`
@@ -1000,15 +1000,15 @@ fn test_type_executable() {
         .open(te.test_root().join("executable-file.sh"))
         .unwrap();
 
-    te.assert_output(&["--type", "executable"], "./executable-file.sh");
+    te.assert_output(&["--type", "executable"], "executable-file.sh");
 
     te.assert_output(
         &["--type", "executable", "--type", "directory"],
-        "./executable-file.sh
-        ./one/
-        ./one/two/
-        ./one/two/three/
-        ./one/two/three/directory_foo/",
+        "executable-file.sh
+        one/
+        one/two/
+        one/two/three/
+        one/two/three/directory_foo/",
     );
 }
 
@@ -1024,19 +1024,19 @@ fn test_type_empty() {
 
     te.assert_output(
         &["--type", "empty"],
-        "./0_bytes.foo
-        ./dir_empty/",
+        "0_bytes.foo
+        dir_empty/",
     );
 
     te.assert_output(
         &["--type", "empty", "--type", "file", "--type", "directory"],
-        "./0_bytes.foo
-        ./dir_empty/",
+        "0_bytes.foo
+        dir_empty/",
     );
 
-    te.assert_output(&["--type", "empty", "--type", "file"], "./0_bytes.foo");
+    te.assert_output(&["--type", "empty", "--type", "file"], "0_bytes.foo");
 
-    te.assert_output(&["--type", "empty", "--type", "directory"], "./dir_empty/");
+    te.assert_output(&["--type", "empty", "--type", "directory"], "dir_empty/");
 }
 
 /// File extension (--extension)
@@ -1046,54 +1046,54 @@ fn test_extension() {
 
     te.assert_output(
         &["--extension", "foo"],
-        "./a.foo
-        ./one/b.foo
-        ./one/two/c.foo
-        ./one/two/three/d.foo",
+        "a.foo
+        one/b.foo
+        one/two/c.foo
+        one/two/three/d.foo",
     );
 
     te.assert_output(
         &["--extension", ".foo"],
-        "./a.foo
-        ./one/b.foo
-        ./one/two/c.foo
-        ./one/two/three/d.foo",
+        "a.foo
+        one/b.foo
+        one/two/c.foo
+        one/two/three/d.foo",
     );
 
     te.assert_output(
         &["--extension", ".foo", "--extension", "foo2"],
-        "./a.foo
-        ./one/b.foo
-        ./one/two/c.foo
-        ./one/two/three/d.foo
-        ./one/two/C.Foo2",
+        "a.foo
+        one/b.foo
+        one/two/c.foo
+        one/two/three/d.foo
+        one/two/C.Foo2",
     );
 
-    te.assert_output(&["--extension", ".foo", "a"], "./a.foo");
+    te.assert_output(&["--extension", ".foo", "a"], "a.foo");
 
-    te.assert_output(&["--extension", "foo2"], "./one/two/C.Foo2");
+    te.assert_output(&["--extension", "foo2"], "one/two/C.Foo2");
 
     let te2 = TestEnv::new(&[], &["spam.bar.baz", "egg.bar.baz", "yolk.bar.baz.sig"]);
 
     te2.assert_output(
         &["--extension", ".bar.baz"],
-        "./spam.bar.baz
-        ./egg.bar.baz",
+        "spam.bar.baz
+        egg.bar.baz",
     );
 
-    te2.assert_output(&["--extension", "sig"], "./yolk.bar.baz.sig");
+    te2.assert_output(&["--extension", "sig"], "yolk.bar.baz.sig");
 
-    te2.assert_output(&["--extension", "bar.baz.sig"], "./yolk.bar.baz.sig");
+    te2.assert_output(&["--extension", "bar.baz.sig"], "yolk.bar.baz.sig");
 
     let te3 = TestEnv::new(&[], &["latin1.e\u{301}xt", "smiley.☻"]);
 
-    te3.assert_output(&["--extension", "☻"], "./smiley.☻");
+    te3.assert_output(&["--extension", "☻"], "smiley.☻");
 
-    te3.assert_output(&["--extension", ".e\u{301}xt"], "./latin1.e\u{301}xt");
+    te3.assert_output(&["--extension", ".e\u{301}xt"], "latin1.e\u{301}xt");
 
     let te4 = TestEnv::new(&[], &[".hidden", "test.hidden"]);
 
-    te4.assert_output(&["--hidden", "--extension", ".hidden"], "./test.hidden");
+    te4.assert_output(&["--hidden", "--extension", ".hidden"], "test.hidden");
 }
 
 /// No file extension (test for the pattern provided in the --help text)
@@ -1106,21 +1106,21 @@ fn test_no_extension() {
 
     te.assert_output(
         &["^[^.]+$"],
-        "./aa
-        ./one/
-        ./one/bb
-        ./one/two/
-        ./one/two/three/
-        ./one/two/three/d
-        ./one/two/three/directory_foo/
-        ./symlink",
+        "aa
+        one/
+        one/bb
+        one/two/
+        one/two/three/
+        one/two/three/d
+        one/two/three/directory_foo/
+        symlink",
     );
 
     te.assert_output(
         &["^[^.]+$", "--type", "file"],
-        "./aa
-        ./one/bb
-        ./one/two/three/d",
+        "aa
+        one/bb
+        one/two/three/d",
     );
 }
 
@@ -1255,46 +1255,46 @@ fn test_excludes() {
 
     te.assert_output(
         &["--exclude", "*.foo"],
-        "./one/
-        ./one/two/
-        ./one/two/C.Foo2
-        ./one/two/three/
-        ./one/two/three/directory_foo/
-        ./e1 e2
-        ./symlink",
+        "one/
+        one/two/
+        one/two/C.Foo2
+        one/two/three/
+        one/two/three/directory_foo/
+        e1 e2
+        symlink",
     );
 
     te.assert_output(
         &["--exclude", "*.foo", "--exclude", "*.Foo2"],
-        "./one/
-        ./one/two/
-        ./one/two/three/
-        ./one/two/three/directory_foo/
-        ./e1 e2
-        ./symlink",
+        "one/
+        one/two/
+        one/two/three/
+        one/two/three/directory_foo/
+        e1 e2
+        symlink",
     );
 
     te.assert_output(
         &["--exclude", "*.foo", "--exclude", "*.Foo2", "foo"],
-        "./one/two/three/directory_foo/",
+        "one/two/three/directory_foo/",
     );
 
     te.assert_output(
         &["--exclude", "one/two/", "foo"],
-        "./a.foo
-        ./one/b.foo",
+        "a.foo
+        one/b.foo",
     );
 
     te.assert_output(
         &["--exclude", "one/**/*.foo"],
-        "./a.foo
-        ./e1 e2
-        ./one/
-        ./one/two/
-        ./one/two/C.Foo2
-        ./one/two/three/
-        ./one/two/three/directory_foo/
-        ./symlink",
+        "a.foo
+        e1 e2
+        one/
+        one/two/
+        one/two/C.Foo2
+        one/two/three/
+        one/two/three/directory_foo/
+        symlink",
     );
 }
 
@@ -1677,12 +1677,12 @@ fn test_fixed_strings() {
     // Regex search, dot is treated as "any character"
     te.assert_output(
         &["a.foo"],
-        "./test1/a.foo
-         ./test1/a_foo",
+        "test1/a.foo
+         test1/a_foo",
     );
 
     // Literal search, dot is treated as character
-    te.assert_output(&["--fixed-strings", "a.foo"], "./test1/a.foo");
+    te.assert_output(&["--fixed-strings", "a.foo"], "test1/a.foo");
 
     // Regex search, parens are treated as group
     te.assert_output(&["download (1)"], "");
@@ -1690,7 +1690,7 @@ fn test_fixed_strings() {
     // Literal search, parens are treated as characters
     te.assert_output(
         &["--fixed-strings", "download (1)"],
-        "./test2/Download (1).tar.gz",
+        "test2/Download (1).tar.gz",
     );
 
     // Combine with --case-sensitive
@@ -1736,81 +1736,69 @@ fn test_size() {
     // Zero and non-zero sized files.
     te.assert_output(
         &["", "--size", "+0B"],
-        "./0_bytes.foo
-        ./11_bytes.foo
-        ./30_bytes.foo
-        ./3_kilobytes.foo
-        ./4_kibibytes.foo",
+        "0_bytes.foo
+        11_bytes.foo
+        30_bytes.foo
+        3_kilobytes.foo
+        4_kibibytes.foo",
     );
 
     // Zero sized files.
-    te.assert_output(&["", "--size", "-0B"], "./0_bytes.foo");
-    te.assert_output(&["", "--size", "0B"], "./0_bytes.foo");
-    te.assert_output(&["", "--size=0B"], "./0_bytes.foo");
-    te.assert_output(&["", "-S", "0B"], "./0_bytes.foo");
+    te.assert_output(&["", "--size", "-0B"], "0_bytes.foo");
+    te.assert_output(&["", "--size", "0B"], "0_bytes.foo");
+    te.assert_output(&["", "--size=0B"], "0_bytes.foo");
+    te.assert_output(&["", "-S", "0B"], "0_bytes.foo");
 
     // Files with 2 bytes or more.
     te.assert_output(
         &["", "--size", "+2B"],
-        "./11_bytes.foo
-        ./30_bytes.foo
-        ./3_kilobytes.foo
-        ./4_kibibytes.foo",
+        "11_bytes.foo
+        30_bytes.foo
+        3_kilobytes.foo
+        4_kibibytes.foo",
     );
 
     // Files with 2 bytes or less.
-    te.assert_output(&["", "--size", "-2B"], "./0_bytes.foo");
+    te.assert_output(&["", "--size", "-2B"], "0_bytes.foo");
 
     // Files with size between 1 byte and 11 bytes.
-    te.assert_output(&["", "--size", "+1B", "--size", "-11B"], "./11_bytes.foo");
+    te.assert_output(&["", "--size", "+1B", "--size", "-11B"], "11_bytes.foo");
 
     // Files with size equal 11 bytes.
-    te.assert_output(&["", "--size", "11B"], "./11_bytes.foo");
+    te.assert_output(&["", "--size", "11B"], "11_bytes.foo");
 
     // Files with size between 1 byte and 30 bytes.
     te.assert_output(
         &["", "--size", "+1B", "--size", "-30B"],
-        "./11_bytes.foo
-        ./30_bytes.foo",
+        "11_bytes.foo
+        30_bytes.foo",
     );
 
     // Combine with a search pattern
-    te.assert_output(
-        &["^11_", "--size", "+1B", "--size", "-30B"],
-        "./11_bytes.foo",
-    );
+    te.assert_output(&["^11_", "--size", "+1B", "--size", "-30B"], "11_bytes.foo");
 
     // Files with size between 12 and 30 bytes.
-    te.assert_output(&["", "--size", "+12B", "--size", "-30B"], "./30_bytes.foo");
+    te.assert_output(&["", "--size", "+12B", "--size", "-30B"], "30_bytes.foo");
 
     // Files with size between 31 and 100 bytes.
     te.assert_output(&["", "--size", "+31B", "--size", "-100B"], "");
 
     // Files with size between 3 kibibytes and 5 kibibytes.
-    te.assert_output(
-        &["", "--size", "+3ki", "--size", "-5ki"],
-        "./4_kibibytes.foo",
-    );
+    te.assert_output(&["", "--size", "+3ki", "--size", "-5ki"], "4_kibibytes.foo");
 
     // Files with size between 3 kilobytes and 5 kilobytes.
     te.assert_output(
         &["", "--size", "+3k", "--size", "-5k"],
-        "./3_kilobytes.foo
-        ./4_kibibytes.foo",
+        "3_kilobytes.foo
+        4_kibibytes.foo",
     );
 
     // Files with size greater than 3 kilobytes and less than 3 kibibytes.
-    te.assert_output(
-        &["", "--size", "+3k", "--size", "-3ki"],
-        "./3_kilobytes.foo",
-    );
+    te.assert_output(&["", "--size", "+3k", "--size", "-3ki"], "3_kilobytes.foo");
 
     // Files with size equal 4 kibibytes.
-    te.assert_output(
-        &["", "--size", "+4ki", "--size", "-4ki"],
-        "./4_kibibytes.foo",
-    );
-    te.assert_output(&["", "--size", "4ki"], "./4_kibibytes.foo");
+    te.assert_output(&["", "--size", "+4ki", "--size", "-4ki"], "4_kibibytes.foo");
+    te.assert_output(&["", "--size", "4ki"], "4_kibibytes.foo");
 }
 
 #[cfg(test)]
@@ -1846,23 +1834,23 @@ fn test_modified_relative() {
 
     te.assert_output(
         &["", "--changed-within", "15min"],
-        "./foo_0_now
-        ./bar_1_min
-        ./foo_10_min",
+        "foo_0_now
+        bar_1_min
+        foo_10_min",
     );
 
     te.assert_output(
         &["", "--change-older-than", "15min"],
-        "./bar_1_h
-        ./foo_2_h
-        ./bar_1_day",
+        "bar_1_h
+        foo_2_h
+        bar_1_day",
     );
 
     te.assert_output(
         &["foo", "--changed-within", "12h"],
-        "./foo_0_now
-        ./foo_10_min
-        ./foo_2_h",
+        "foo_0_now
+        foo_10_min
+        foo_2_h",
     );
 }
 
@@ -1882,11 +1870,11 @@ fn test_modified_absolute() {
 
     te.assert_output(
         &["", "--change-newer-than", "2018-01-01 00:00:00"],
-        "./15mar2018",
+        "15mar2018",
     );
     te.assert_output(
         &["", "--changed-before", "2018-01-01 00:00:00"],
-        "./30dec2017",
+        "30dec2017",
     );
 }
 
@@ -1910,21 +1898,21 @@ fn test_base_directory() {
 
     te.assert_output(
         &["--base-directory", "one"],
-        "./b.foo
-        ./two/
-        ./two/c.foo
-        ./two/C.Foo2
-        ./two/three/
-        ./two/three/d.foo
-        ./two/three/directory_foo/",
+        "b.foo
+        two/
+        two/c.foo
+        two/C.Foo2
+        two/three/
+        two/three/d.foo
+        two/three/directory_foo/",
     );
 
     te.assert_output(
         &["--base-directory", "one/two/", "foo"],
-        "./c.foo
-        ./C.Foo2
-        ./three/d.foo
-        ./three/directory_foo/",
+        "c.foo
+        C.Foo2
+        three/d.foo
+        three/directory_foo/",
     );
 
     // Explicit root path
@@ -1960,15 +1948,15 @@ fn test_max_results() {
     // Unrestricted
     te.assert_output(
         &["--max-results=0", "c.foo"],
-        "./one/two/C.Foo2
-         ./one/two/c.foo",
+        "one/two/C.Foo2
+         one/two/c.foo",
     );
 
     // Limited to two results
     te.assert_output(
         &["--max-results=2", "c.foo"],
-        "./one/two/C.Foo2
-         ./one/two/c.foo",
+        "one/two/C.Foo2
+         one/two/c.foo",
     );
 
     // Limited to one result. We could find either C.Foo2 or c.foo
@@ -1977,7 +1965,7 @@ fn test_max_results() {
         let stdout = String::from_utf8_lossy(&output.stdout)
             .trim()
             .replace(&std::path::MAIN_SEPARATOR.to_string(), "/");
-        assert!(stdout == "./one/two/C.Foo2" || stdout == "./one/two/c.foo");
+        assert!(stdout == "one/two/C.Foo2" || stdout == "one/two/c.foo");
     };
     assert_just_one_result_with_option("--max-results=1");
     assert_just_one_result_with_option("-1");
@@ -2090,8 +2078,8 @@ fn test_error_if_hidden_not_set_and_pattern_starts_with_dot() {
     te.assert_failure(&["^\\.gitignore"]);
     te.assert_failure(&["--glob", ".gitignore"]);
 
-    te.assert_output(&["--hidden", "^\\.gitignore"], "./.gitignore");
-    te.assert_output(&["--hidden", "--glob", ".gitignore"], "./.gitignore");
+    te.assert_output(&["--hidden", "^\\.gitignore"], ".gitignore");
+    te.assert_output(&["--hidden", "--glob", ".gitignore"], ".gitignore");
     te.assert_output(&[".gitignore"], "");
 }