{"thread":{"id":"60431","subject":"git bugreport with invalid CLI argument does not report error","startedAt":"2023-10-25T20:59:22Z","lastAt":"2023-11-01T23:20:00Z","messageCount":28,"participants":["Sheik","Emily Shaffer","Eric Sunshine","emilyshaffer@google.com","Dragan Simic","Phillip Wood","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"483872","messageId":"7a92b537-ba88-4667-bb18-2e8c74aa9915@gmail.com","threadId":"60431","inReplyTo":null,"subject":"git bugreport with invalid CLI argument does not report error","fromName":"Sheik","fromEmail":"sahibzone@gmail.com","sentAt":"2023-10-25T20:59:16Z","receivedAt":"2023-10-25T20:59:22Z","isPatch":false,"sender":{"key":"sahibzone@gmail.com","avatar":null},"body":"Hi Maintainers,\n\n\nRunning git bugreport with an invalid CLI argument in a valid Git \ndirectory does not report error. Expected behaviour would be that it \nreports an error.\n\n\n#Example git commands which should have reported an error but continues \nto succeed\n\ncd $ToAnyDirectory\n\ngit bugreport diagnose\n\n\nThanks\n\nSheik\n\n\n[System Info]\ngit version:\ngit version 2.42.0\ncpu: x86_64\nno commit associated with this build\nsizeof-long: 8\nsizeof-size_t: 8\nshell-path: /bin/sh\nuname: Linux 6.5.0-2-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.5.6-1 \n(2023-10-07) x86_64\ncompiler info: gnuc: 13.2\nlibc info: glibc: 2.37\n$SHELL (typically, interactive shell): /bin/bash\n\n\n[Enabled Hooks]\n\n\n"},{"id":"483875","messageId":"ZTmcVJaY2TjFCVyw@google.com","threadId":"60431","inReplyTo":"7a92b537-ba88-4667-bb18-2e8c74aa9915@gmail.com","subject":"Re: git bugreport with invalid CLI argument does not report error","fromName":"Emily Shaffer","fromEmail":"nasamuffin@google.com","sentAt":"2023-10-25T22:53:08Z","receivedAt":"2023-10-25T22:53:15Z","isPatch":false,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Thu, Oct 26, 2023 at 07:59:16AM +1100, Sheik wrote:\n> \n> Hi Maintainers,\n> \n> \n> Running git bugreport with an invalid CLI argument in a valid Git directory\n> does not report error. Expected behaviour would be that it reports an error.\n> \n> \n> #Example git commands which should have reported an error but continues to\n> succeed\n> \n> cd $ToAnyDirectory\n> \n> git bugreport diagnose\n\nIt looks like parse-options.[ch] helps us here for misspelled dashed\noptions, like `--diaggnose`. But it doesn't complain when there are\nunexpected positional arguments. I think we can just notice if there are\nany argc left over, complain, and print usage.\n\nI put together a quick patch; could be that we don't need to leave this\nerror about \"positional arguments\" and can leave it as an exercise to\nthe reader to compare their previous command to the usage text. I guess\nwe could also unroll remaining argv but it was just a hair more time\nthan I wanted to spend ;)\n\n - Emily\n\n--- 8< ---\n\nFrom 2031c7f55652559b8b4ec3c67ce4c4f94a355762 Mon Sep 17 00:00:00 2001\nFrom: Emily Shaffer <nasamuffin@google.com>\nDate: Wed, 25 Oct 2023 15:45:25 -0700\nSubject: [PATCH] bugreport: reject positional arguments\n\ngit-bugreport already rejected unrecognized flag arguments, like\n`--diaggnose`, but this doesn't help if the user's mistake was to forget\nthe `--` in front of the argument. This can result in a user's intended\nargument not being parsed with no indication to the user that something\nwent wrong. Since git-bugreport presently doesn't take any positionals\nat all, let's reject all positionals and give the user a usage hint.\n\nSigned-off-by: Emily Shaffer <nasamuffin@google.com>\n---\n builtin/bugreport.c  | 5 +++++\n t/t0091-bugreport.sh | 6 ++++++\n 2 files changed, 11 insertions(+)\n\ndiff --git a/builtin/bugreport.c b/builtin/bugreport.c\nindex d2ae5c305d..eb6234a50d 100644\n--- a/builtin/bugreport.c\n+++ b/builtin/bugreport.c\n@@ -126,6 +126,11 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)\n \targc = parse_options(argc, argv, prefix, bugreport_options,\n \t\t\t     bugreport_usage, 0);\n \n+\tif (argc) {\n+\t\terror(_(\"git bugreport does not take positional arguments\"));\n+\t\tusage(bugreport_usage[0]);\n+\t}\n+\n \t/* Prepare the path to put the result */\n \tprefixed_filename = prefix_filename(prefix,\n \t\t\t\t\t    option_output ? option_output : \"\");\ndiff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh\nindex f6998269be..2061d6f386 100755\n--- a/t/t0091-bugreport.sh\n+++ b/t/t0091-bugreport.sh\n@@ -69,6 +69,12 @@ test_expect_success 'incorrect arguments abort with usage' '\n \ttest_path_is_missing git-bugreport-*\n '\n \n+test_expect_success 'incorrect positional arguments abort with usage' '\n+\ttest_must_fail git bugreport false 2>output &&\n+\ttest_i18ngrep usage output &&\n+\ttest_path_is_missing git-bugreport-*\n+'\n+\n test_expect_success 'runs outside of a git dir' '\n \ttest_when_finished rm non-repo/git-bugreport-* &&\n \tnongit git bugreport\n-- \n2.42.0.758.gaed0368e0e-goog\n\n\n"},{"id":"483876","messageId":"CAPig+cQtoEpTDK1U5R+wUD4qovFtpcx6+zyOQE-SAYp5SE2q2Q@mail.gmail.com","threadId":"60431","inReplyTo":"ZTmcVJaY2TjFCVyw@google.com","subject":"Re: git bugreport with invalid CLI argument does not report error","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2023-10-25T23:11:12Z","receivedAt":"2023-10-25T23:11:27Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Oct 25, 2023 at 6:53 PM Emily Shaffer <nasamuffin@google.com> wrote:\n> On Thu, Oct 26, 2023 at 07:59:16AM +1100, Sheik wrote:\n> > Running git bugreport with an invalid CLI argument in a valid Git directory\n> > does not report error. Expected behaviour would be that it reports an error.\n>\n> It looks like parse-options.[ch] helps us here for misspelled dashed\n> options, like `--diaggnose`. But it doesn't complain when there are\n> unexpected positional arguments. I think we can just notice if there are\n> any argc left over, complain, and print usage.\n>\n> I put together a quick patch; could be that we don't need to leave this\n> error about \"positional arguments\" and can leave it as an exercise to\n> the reader to compare their previous command to the usage text. I guess\n> we could also unroll remaining argv but it was just a hair more time\n> than I wanted to spend ;)\n>\n> --- 8< ---\n> Subject: [PATCH] bugreport: reject positional arguments\n>\n> git-bugreport already rejected unrecognized flag arguments, like\n> `--diaggnose`, but this doesn't help if the user's mistake was to forget\n> the `--` in front of the argument. This can result in a user's intended\n> argument not being parsed with no indication to the user that something\n> went wrong. Since git-bugreport presently doesn't take any positionals\n> at all, let's reject all positionals and give the user a usage hint.\n>\n> Signed-off-by: Emily Shaffer <nasamuffin@google.com>\n> ---\n> diff --git a/builtin/bugreport.c b/builtin/bugreport.c\n> @@ -126,6 +126,11 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)\n> +       if (argc) {\n> +               error(_(\"git bugreport does not take positional arguments\"));\n> +               usage(bugreport_usage[0]);\n> +       }\n\nThis error message may be somewhat difficult to interpret. Providing\nadditional context could help the user understand the actual problem.\nFor instance:\n\n    % git bugreport diagnose\n    error: unrecognized argument \"diagnose\"\n"},{"id":"483877","messageId":"20231026005542.872301-1-nasamuffin@google.com","threadId":"60431","inReplyTo":"CAPig+cQtoEpTDK1U5R+wUD4qovFtpcx6+zyOQE-SAYp5SE2q2Q@mail.gmail.com","subject":"[PATCH v2] bugreport: reject positional arguments","fromName":"","fromEmail":"emilyshaffer@google.com","sentAt":"2023-10-26T00:55:41Z","receivedAt":"2023-10-26T00:56:00Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"From: Emily Shaffer <nasamuffin@google.com>\n\ngit-bugreport already rejected unrecognized flag arguments, like\n`--diaggnose`, but this doesn't help if the user's mistake was to forget\nthe `--` in front of the argument. This can result in a user's intended\nargument not being parsed with no indication to the user that something\nwent wrong. Since git-bugreport presently doesn't take any positionals\nat all, let's reject all positionals and give the user a usage hint.\n\nSigned-off-by: Emily Shaffer <nasamuffin@google.com>\n---\nPer Eric's suggestion, added a citation of the first positional arg\nfound. I don't think it's necessary to unroll the entire argv array\nhere, though.\n\n - Emily\n\n builtin/bugreport.c  | 6 ++++++\n t/t0091-bugreport.sh | 7 +++++++\n 2 files changed, 13 insertions(+)\n\ndiff --git a/builtin/bugreport.c b/builtin/bugreport.c\nindex d2ae5c305d..8a69a23397 100644\n--- a/builtin/bugreport.c\n+++ b/builtin/bugreport.c\n@@ -126,6 +126,12 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)\n \targc = parse_options(argc, argv, prefix, bugreport_options,\n \t\t\t     bugreport_usage, 0);\n \n+\tif (argc) {\n+\t\tif (argv[0])\n+\t\t\terror(_(\"unknown argument `%s'\"), argv[0]);\n+\t\tusage(bugreport_usage[0]);\n+\t}\n+\n \t/* Prepare the path to put the result */\n \tprefixed_filename = prefix_filename(prefix,\n \t\t\t\t\t    option_output ? option_output : \"\");\ndiff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh\nindex f6998269be..5b1b3e8d07 100755\n--- a/t/t0091-bugreport.sh\n+++ b/t/t0091-bugreport.sh\n@@ -69,6 +69,13 @@ test_expect_success 'incorrect arguments abort with usage' '\n \ttest_path_is_missing git-bugreport-*\n '\n \n+test_expect_success 'incorrect positional arguments abort with usage and hint' '\n+\ttest_must_fail git bugreport false 2>output &&\n+\ttest_i18ngrep usage output &&\n+\ttest_i18ngrep false output &&\n+\ttest_path_is_missing git-bugreport-*\n+'\n+\n test_expect_success 'runs outside of a git dir' '\n \ttest_when_finished rm non-repo/git-bugreport-* &&\n \tnongit git bugreport\n-- \n2.42.0.758.gaed0368e0e-goog\n\n"},{"id":"483879","messageId":"CAPig+cT4G9vdu+se9Fbbs0TRCyPoAYFgVtkSwph_U=sWf-kQ9g@mail.gmail.com","threadId":"60431","inReplyTo":"20231026005542.872301-1-nasamuffin@google.com","subject":"Re: [PATCH v2] bugreport: reject positional arguments","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2023-10-26T03:43:20Z","receivedAt":"2023-10-26T03:43:34Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Oct 25, 2023 at 8:55 PM <emilyshaffer@google.com> wrote:\n> git-bugreport already rejected unrecognized flag arguments, like\n> `--diaggnose`, but this doesn't help if the user's mistake was to forget\n> the `--` in front of the argument. This can result in a user's intended\n> argument not being parsed with no indication to the user that something\n> went wrong. Since git-bugreport presently doesn't take any positionals\n> at all, let's reject all positionals and give the user a usage hint.\n>\n> Signed-off-by: Emily Shaffer <nasamuffin@google.com>\n> ---\n> Per Eric's suggestion, added a citation of the first positional arg\n> found. I don't think it's necessary to unroll the entire argv array\n> here, though.\n\nThanks. I had the same thought about the first positional argument\nbeing sufficient since it should provide enough context on its own.\n\n> diff --git a/builtin/bugreport.c b/builtin/bugreport.c\n> @@ -126,6 +126,12 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)\n> +       if (argc) {\n> +               if (argv[0])\n> +                       error(_(\"unknown argument `%s'\"), argv[0]);\n> +               usage(bugreport_usage[0]);\n> +       }\n\nCan it actually happen that argc is non-zero but argv[0] is NULL? (I\ndon't have parse-options in front of me to check.) If not, then the\nextra `if (argv[0])` conditional may confuse future readers.\n"},{"id":"483880","messageId":"8c82a138faa28a3c5d15a52b1d9c2c0f@manjaro.org","threadId":"60431","inReplyTo":"CAPig+cT4G9vdu+se9Fbbs0TRCyPoAYFgVtkSwph_U=sWf-kQ9g@mail.gmail.com","subject":"Re: [PATCH v2] bugreport: reject positional arguments","fromName":"Dragan Simic","fromEmail":"dsimic@manjaro.org","sentAt":"2023-10-26T03:52:00Z","receivedAt":"2023-10-26T03:52:06Z","isPatch":true,"sender":{"key":"dsimic@manjaro.org","avatar":null},"body":"On 2023-10-26 05:43, Eric Sunshine wrote:\n> On Wed, Oct 25, 2023 at 8:55 PM <emilyshaffer@google.com> wrote:\n>> diff --git a/builtin/bugreport.c b/builtin/bugreport.c\n>> @@ -126,6 +126,12 @@ int cmd_bugreport(int argc, const char **argv, \n>> const char *prefix)\n>> +       if (argc) {\n>> +               if (argv[0])\n>> +                       error(_(\"unknown argument `%s'\"), argv[0]);\n>> +               usage(bugreport_usage[0]);\n>> +       }\n> \n> Can it actually happen that argc is non-zero but argv[0] is NULL? (I\n> don't have parse-options in front of me to check.) If not, then the\n> extra `if (argv[0])` conditional may confuse future readers.\n\nAccording to https://stackoverflow.com/a/2794171/22330192 it can't, but \nargv[0] can be a zero-length string.\n"},{"id":"483881","messageId":"CAPig+cTJFKp6RFdqJTpyL49V+M-zaTDbgpVd2OrgfWf4H-+K+g@mail.gmail.com","threadId":"60431","inReplyTo":"8c82a138faa28a3c5d15a52b1d9c2c0f@manjaro.org","subject":"Re: [PATCH v2] bugreport: reject positional arguments","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2023-10-26T04:03:30Z","receivedAt":"2023-10-26T04:03:47Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, Oct 25, 2023 at 11:52 PM Dragan Simic <dsimic@manjaro.org> wrote:\n> On 2023-10-26 05:43, Eric Sunshine wrote:\n> > On Wed, Oct 25, 2023 at 8:55 PM <emilyshaffer@google.com> wrote:\n> >> diff --git a/builtin/bugreport.c b/builtin/bugreport.c\n> >> @@ -126,6 +126,12 @@ int cmd_bugreport(int argc, const char **argv,\n> >> const char *prefix)\n> >> +       if (argc) {\n> >> +               if (argv[0])\n> >> +                       error(_(\"unknown argument `%s'\"), argv[0]);\n> >> +               usage(bugreport_usage[0]);\n> >> +       }\n> >\n> > Can it actually happen that argc is non-zero but argv[0] is NULL? (I\n> > don't have parse-options in front of me to check.) If not, then the\n> > extra `if (argv[0])` conditional may confuse future readers.\n>\n> According to https://stackoverflow.com/a/2794171/22330192 it can't, but\n> argv[0] can be a zero-length string.\n\nThis case is different, though, since, by this point, argv[] has been\nprocessed by Git's parse-options API. Here's the relevant comment from\nparse-options.h:\n\n   * parse_options() will filter out the processed options and leave the\n   * non-option arguments in argv[]. argv0 is assumed program name and\n   * skipped.\n   *\n   * Returns the number of arguments left in argv[].\n\nSo, I think the `if (argv[0])` conditional is unnecessary, thus\npotentially confusing.\n\nIt's possible that Emily meant `if (*argv[0])`, but even that seems\nundesirable since even a zero-length argv[0] provides some useful\ncontext.\n\n    % git bugreport \"\"\n    error: unknown argument `'\n"},{"id":"483882","messageId":"aa11162c3220304b91ef25f30600c231@manjaro.org","threadId":"60431","inReplyTo":"CAPig+cTJFKp6RFdqJTpyL49V+M-zaTDbgpVd2OrgfWf4H-+K+g@mail.gmail.com","subject":"Re: [PATCH v2] bugreport: reject positional arguments","fromName":"Dragan Simic","fromEmail":"dsimic@manjaro.org","sentAt":"2023-10-26T04:06:49Z","receivedAt":"2023-10-26T04:06:52Z","isPatch":true,"sender":{"key":"dsimic@manjaro.org","avatar":null},"body":"On 2023-10-26 06:03, Eric Sunshine wrote:\n> On Wed, Oct 25, 2023 at 11:52 PM Dragan Simic <dsimic@manjaro.org> \n> wrote:\n>> On 2023-10-26 05:43, Eric Sunshine wrote:\n>> > On Wed, Oct 25, 2023 at 8:55 PM <emilyshaffer@google.com> wrote:\n>> >> diff --git a/builtin/bugreport.c b/builtin/bugreport.c\n>> >> @@ -126,6 +126,12 @@ int cmd_bugreport(int argc, const char **argv,\n>> >> const char *prefix)\n>> >> +       if (argc) {\n>> >> +               if (argv[0])\n>> >> +                       error(_(\"unknown argument `%s'\"), argv[0]);\n>> >> +               usage(bugreport_usage[0]);\n>> >> +       }\n>> >\n>> > Can it actually happen that argc is non-zero but argv[0] is NULL? (I\n>> > don't have parse-options in front of me to check.) If not, then the\n>> > extra `if (argv[0])` conditional may confuse future readers.\n>> \n>> According to https://stackoverflow.com/a/2794171/22330192 it can't, \n>> but\n>> argv[0] can be a zero-length string.\n> \n> This case is different, though, since, by this point, argv[] has been\n> processed by Git's parse-options API. Here's the relevant comment from\n> parse-options.h:\n\nAh, I see, thanks for the clarification.\n\n>    * parse_options() will filter out the processed options and leave \n> the\n>    * non-option arguments in argv[]. argv0 is assumed program name and\n>    * skipped.\n>    *\n>    * Returns the number of arguments left in argv[].\n> \n> So, I think the `if (argv[0])` conditional is unnecessary, thus\n> potentially confusing.\n> \n> It's possible that Emily meant `if (*argv[0])`, but even that seems\n> undesirable since even a zero-length argv[0] provides some useful\n> context.\n> \n>     % git bugreport \"\"\n>     error: unknown argument `'\n"},{"id":"483924","messageId":"20231026155459.2234929-1-nasamuffin@google.com","threadId":"60431","inReplyTo":"20231026005542.872301-1-nasamuffin@google.com","subject":"[PATCH v3] bugreport: reject positional arguments","fromName":"","fromEmail":"emilyshaffer@google.com","sentAt":"2023-10-26T15:54:59Z","receivedAt":"2023-10-26T15:55:05Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"From: Emily Shaffer <nasamuffin@google.com>\n\ngit-bugreport already rejected unrecognized flag arguments, like\n`--diaggnose`, but this doesn't help if the user's mistake was to forget\nthe `--` in front of the argument. This can result in a user's intended\nargument not being parsed with no indication to the user that something\nwent wrong. Since git-bugreport presently doesn't take any positionals\nat all, let's reject all positionals and give the user a usage hint.\n\nSigned-off-by: Emily Shaffer <nasamuffin@google.com>\n---\nPer Eric's and Dragan's comments, dropped the null checking for argv[0].\nNo point in being too paranoid, I suppose :)\n\nNote that after this morning it's not likely that I'll be able to find\ntime to update this again so quickly, so if there are other nits,\nreviewers can feel free to send their own rerolls rather than waiting\nfor me to see it and turn the patch around.\n\n - Emily\n\n builtin/bugreport.c  | 5 +++++\n t/t0091-bugreport.sh | 7 +++++++\n 2 files changed, 12 insertions(+)\n\ndiff --git a/builtin/bugreport.c b/builtin/bugreport.c\nindex d2ae5c305d..3106e56a13 100644\n--- a/builtin/bugreport.c\n+++ b/builtin/bugreport.c\n@@ -126,6 +126,11 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)\n \targc = parse_options(argc, argv, prefix, bugreport_options,\n \t\t\t     bugreport_usage, 0);\n \n+\tif (argc) {\n+\t\terror(_(\"unknown argument `%s'\"), argv[0]);\n+\t\tusage(bugreport_usage[0]);\n+\t}\n+\n \t/* Prepare the path to put the result */\n \tprefixed_filename = prefix_filename(prefix,\n \t\t\t\t\t    option_output ? option_output : \"\");\ndiff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh\nindex f6998269be..5b1b3e8d07 100755\n--- a/t/t0091-bugreport.sh\n+++ b/t/t0091-bugreport.sh\n@@ -69,6 +69,13 @@ test_expect_success 'incorrect arguments abort with usage' '\n \ttest_path_is_missing git-bugreport-*\n '\n \n+test_expect_success 'incorrect positional arguments abort with usage and hint' '\n+\ttest_must_fail git bugreport false 2>output &&\n+\ttest_i18ngrep usage output &&\n+\ttest_i18ngrep false output &&\n+\ttest_path_is_missing git-bugreport-*\n+'\n+\n test_expect_success 'runs outside of a git dir' '\n \ttest_when_finished rm non-repo/git-bugreport-* &&\n \tnongit git bugreport\n-- \n2.42.0.758.gaed0368e0e-goog\n\n"},{"id":"483925","messageId":"CAPig+cTmYtWR=QN3LeN9yw3HmsKEmD2fUiRjKf=eJHhAZyT-yA@mail.gmail.com","threadId":"60431","inReplyTo":"20231026155459.2234929-1-nasamuffin@google.com","subject":"Re: [PATCH v3] bugreport: reject positional arguments","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2023-10-26T17:18:46Z","receivedAt":"2023-10-26T17:19:00Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, Oct 26, 2023 at 11:55 AM <emilyshaffer@google.com> wrote:\n> git-bugreport already rejected unrecognized flag arguments, like\n> `--diaggnose`, but this doesn't help if the user's mistake was to forget\n> the `--` in front of the argument. This can result in a user's intended\n> argument not being parsed with no indication to the user that something\n> went wrong. Since git-bugreport presently doesn't take any positionals\n> at all, let's reject all positionals and give the user a usage hint.\n>\n> Signed-off-by: Emily Shaffer <nasamuffin@google.com>\n> ---\n> Per Eric's and Dragan's comments, dropped the null checking for argv[0].\n> No point in being too paranoid, I suppose :)\n>\n> Note that after this morning it's not likely that I'll be able to find\n> time to update this again so quickly, so if there are other nits,\n> reviewers can feel free to send their own rerolls rather than waiting\n> for me to see it and turn the patch around.\n\nThanks. This version looks good enough to me. Just one minor comment below...\n\n> diff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh\n> @@ -69,6 +69,13 @@ test_expect_success 'incorrect arguments abort with usage' '\n> +test_expect_success 'incorrect positional arguments abort with usage and hint' '\n> +       test_must_fail git bugreport false 2>output &&\n> +       test_i18ngrep usage output &&\n> +       test_i18ngrep false output &&\n> +       test_path_is_missing git-bugreport-*\n> +'\n\nI didn't really pay attention to the test in earlier rounds so didn't\nnotice this, but these days we just use 'grep' rather than\n'test_i18ngrep'. (Indeed, the existing tests in this script use\n'grep'.)\n"},{"id":"483926","messageId":"20231026182231.3369370-1-nasamuffin@google.com","threadId":"60431","inReplyTo":"20231026155459.2234929-1-nasamuffin@google.com","subject":"[PATCH v4 0/2] bugreport: reject positional arguments","fromName":"","fromEmail":"emilyshaffer@google.com","sentAt":"2023-10-26T18:22:29Z","receivedAt":"2023-10-26T18:22:43Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"From: Emily Shaffer <nasamuffin@google.com>\n\nThe test I cribbed from for the newly added one in patch 2 was still\nusing test_i18ngrep, and Eric mentioned us not wanting i18ngrep at all\nanymore, so I went ahead and cleaned that up as well.\n\n - Emily\n\nEmily Shaffer (2):\n  t0091-bugreport: stop using i18ngrep\n  bugreport: reject positional arguments\n\n builtin/bugreport.c  | 5 +++++\n t/t0091-bugreport.sh | 9 ++++++++-\n 2 files changed, 13 insertions(+), 1 deletion(-)\n\n-- \n2.42.0.820.g83a721a137-goog\n\n"},{"id":"483927","messageId":"20231026182231.3369370-2-nasamuffin@google.com","threadId":"60431","inReplyTo":"20231026155459.2234929-1-nasamuffin@google.com","subject":"[PATCH v4 1/2] t0091-bugreport: stop using i18ngrep","fromName":"","fromEmail":"emilyshaffer@google.com","sentAt":"2023-10-26T18:22:30Z","receivedAt":"2023-10-26T18:22:47Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"From: Emily Shaffer <nasamuffin@google.com>\n\nSince e6545201ad (Merge branch 'ab/detox-config-gettext', 2021-04-13),\ntest_i18ngrep is no longer required. Quit using it in the bugreport\ntests, since it's setting a bad example for tests added later.\n\nSigned-off-by: Emily Shaffer <nasamuffin@google.com>\n---\n t/t0091-bugreport.sh | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh\nindex f6998269be..e1588f71b7 100755\n--- a/t/t0091-bugreport.sh\n+++ b/t/t0091-bugreport.sh\n@@ -65,7 +65,7 @@ test_expect_success '--output-directory puts the report in the provided dir' '\n \n test_expect_success 'incorrect arguments abort with usage' '\n \ttest_must_fail git bugreport --false 2>output &&\n-\ttest_i18ngrep usage output &&\n+\tgrep usage output &&\n \ttest_path_is_missing git-bugreport-*\n '\n \n-- \n2.42.0.820.g83a721a137-goog\n\n"},{"id":"483928","messageId":"20231026182231.3369370-3-nasamuffin@google.com","threadId":"60431","inReplyTo":"20231026155459.2234929-1-nasamuffin@google.com","subject":"[PATCH v4 2/2] bugreport: reject positional arguments","fromName":"","fromEmail":"emilyshaffer@google.com","sentAt":"2023-10-26T18:22:31Z","receivedAt":"2023-10-26T18:22:48Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"From: Emily Shaffer <nasamuffin@google.com>\n\ngit-bugreport already rejected unrecognized flag arguments, like\n`--diaggnose`, but this doesn't help if the user's mistake was to forget\nthe `--` in front of the argument. This can result in a user's intended\nargument not being parsed with no indication to the user that something\nwent wrong. Since git-bugreport presently doesn't take any positionals\nat all, let's reject all positionals and give the user a usage hint.\n\nSigned-off-by: Emily Shaffer <nasamuffin@google.com>\n---\n builtin/bugreport.c  | 5 +++++\n t/t0091-bugreport.sh | 7 +++++++\n 2 files changed, 12 insertions(+)\n\ndiff --git a/builtin/bugreport.c b/builtin/bugreport.c\nindex d2ae5c305d..3106e56a13 100644\n--- a/builtin/bugreport.c\n+++ b/builtin/bugreport.c\n@@ -126,6 +126,11 @@ int cmd_bugreport(int argc, const char **argv, const char *prefix)\n \targc = parse_options(argc, argv, prefix, bugreport_options,\n \t\t\t     bugreport_usage, 0);\n \n+\tif (argc) {\n+\t\terror(_(\"unknown argument `%s'\"), argv[0]);\n+\t\tusage(bugreport_usage[0]);\n+\t}\n+\n \t/* Prepare the path to put the result */\n \tprefixed_filename = prefix_filename(prefix,\n \t\t\t\t\t    option_output ? option_output : \"\");\ndiff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh\nindex e1588f71b7..ae5b7dc31f 100755\n--- a/t/t0091-bugreport.sh\n+++ b/t/t0091-bugreport.sh\n@@ -69,6 +69,13 @@ test_expect_success 'incorrect arguments abort with usage' '\n \ttest_path_is_missing git-bugreport-*\n '\n \n+test_expect_success 'incorrect positional arguments abort with usage and hint' '\n+\ttest_must_fail git bugreport false 2>output &&\n+\tgrep usage output &&\n+\tgrep false output &&\n+\ttest_path_is_missing git-bugreport-*\n+'\n+\n test_expect_success 'runs outside of a git dir' '\n \ttest_when_finished rm non-repo/git-bugreport-* &&\n \tnongit git bugreport\n-- \n2.42.0.820.g83a721a137-goog\n\n"},{"id":"483931","messageId":"CAPig+cTO+EUwWGCHtpXYukafd4v3DQjq1CQ7B3EC=vqiK3qFUA@mail.gmail.com","threadId":"60431","inReplyTo":"20231026182231.3369370-1-nasamuffin@google.com","subject":"Re: [PATCH v4 0/2] bugreport: reject positional arguments","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2023-10-26T20:13:33Z","receivedAt":"2023-10-26T20:13:47Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, Oct 26, 2023 at 2:22 PM <emilyshaffer@google.com> wrote:\n> The test I cribbed from for the newly added one in patch 2 was still\n> using test_i18ngrep, and Eric mentioned us not wanting i18ngrep at all\n> anymore, so I went ahead and cleaned that up as well.\n\nThanks for making the various tweaks in response to my review comments.\n"},{"id":"483993","messageId":"3e15f266-c790-4b71-84b6-1328339425c1@gmail.com","threadId":"60431","inReplyTo":"CAPig+cTmYtWR=QN3LeN9yw3HmsKEmD2fUiRjKf=eJHhAZyT-yA@mail.gmail.com","subject":"Re: [PATCH v3] bugreport: reject positional arguments","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2023-10-27T14:41:44Z","receivedAt":"2023-10-27T14:41:49Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 26/10/2023 18:18, Eric Sunshine wrote:\n> On Thu, Oct 26, 2023 at 11:55 AM <emilyshaffer@google.com> wrote:\n>> git-bugreport already rejected unrecognized flag arguments, like\n>> `--diaggnose`, but this doesn't help if the user's mistake was to forget\n>> the `--` in front of the argument. This can result in a user's intended\n>> argument not being parsed with no indication to the user that something\n>> went wrong. Since git-bugreport presently doesn't take any positionals\n>> at all, let's reject all positionals and give the user a usage hint.\n>>\n>> Signed-off-by: Emily Shaffer <nasamuffin@google.com>\n>> ---\n>> Per Eric's and Dragan's comments, dropped the null checking for argv[0].\n>> No point in being too paranoid, I suppose :)\n>>\n>> Note that after this morning it's not likely that I'll be able to find\n>> time to update this again so quickly, so if there are other nits,\n>> reviewers can feel free to send their own rerolls rather than waiting\n>> for me to see it and turn the patch around.\n> \n> Thanks. This version looks good enough to me. Just one minor comment below...\n> \n>> diff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh\n>> @@ -69,6 +69,13 @@ test_expect_success 'incorrect arguments abort with usage' '\n>> +test_expect_success 'incorrect positional arguments abort with usage and hint' '\n>> +       test_must_fail git bugreport false 2>output &&\n>> +       test_i18ngrep usage output &&\n>> +       test_i18ngrep false output &&\n>> +       test_path_is_missing git-bugreport-*\n>> +'\n> \n> I didn't really pay attention to the test in earlier rounds so didn't\n> notice this, but these days we just use 'grep' rather than\n> 'test_i18ngrep'. (Indeed, the existing tests in this script use\n> 'grep'.)\n\nIt is rather unfortunate that test_i18ngrep was deprecated without \nproviding an alternative that offers the same debugging experience. When \ntest_i18ngrep fails it prints a message with the pattern and text that \nfailed to match so it is easy to see where the test failed. If grep \nfails there is no output and so unless the test is run with \"-x\" it can \nbe hard to see which command caused the test to fail.\n\nBest Wishes\n\nPhillip\n\n"},{"id":"484060","messageId":"xmqqleblgeti.fsf@gitster.g","threadId":"60431","inReplyTo":"20231026182231.3369370-2-nasamuffin@google.com","subject":"Re: [PATCH v4 1/2] t0091-bugreport: stop using i18ngrep","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-10-29T23:59:53Z","receivedAt":"2023-10-30T00:00:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"emilyshaffer@google.com writes:\n\n> From: Emily Shaffer <nasamuffin@google.com>\n>\n> Since e6545201ad (Merge branch 'ab/detox-config-gettext', 2021-04-13),\n> test_i18ngrep is no longer required. Quit using it in the bugreport\n> tests, since it's setting a bad example for tests added later.\n>\n> Signed-off-by: Emily Shaffer <nasamuffin@google.com>\n> ---\n\nMakes sense.  Thanks.\n\n>  t/t0091-bugreport.sh | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n>\n> diff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh\n> index f6998269be..e1588f71b7 100755\n> --- a/t/t0091-bugreport.sh\n> +++ b/t/t0091-bugreport.sh\n> @@ -65,7 +65,7 @@ test_expect_success '--output-directory puts the report in the provided dir' '\n>  \n>  test_expect_success 'incorrect arguments abort with usage' '\n>  \ttest_must_fail git bugreport --false 2>output &&\n> -\ttest_i18ngrep usage output &&\n> +\tgrep usage output &&\n>  \ttest_path_is_missing git-bugreport-*\n>  '\n"},{"id":"484062","messageId":"xmqqbkchge3r.fsf@gitster.g","threadId":"60431","inReplyTo":"3e15f266-c790-4b71-84b6-1328339425c1@gmail.com","subject":"Re: [PATCH v3] bugreport: reject positional arguments","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-10-30T00:15:20Z","receivedAt":"2023-10-30T00:15:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":""},{"id":"484064","messageId":"xmqqv8apez0o.fsf@gitster.g","threadId":"60431","inReplyTo":"3e15f266-c790-4b71-84b6-1328339425c1@gmail.com","subject":"Re: [PATCH v3] bugreport: reject positional arguments","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-10-30T00:26:31Z","receivedAt":"2023-10-30T00:26:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> It is rather unfortunate that test_i18ngrep was deprecated without\n> providing an alternative that offers the same debugging\n> experience.\n\nThe primary thing test_i18ngrep did was to _SKIP_ certain test that\nlooked for an expected string in \"C\" locale from the output when the\ntests were run under a tainted localization mode.  The tests that\nlooked for strings in messages that are *not* to be localized used\n\"grep\".  Tests that (unfortunately) had to match human-readable\nmessages had to work around the tainted localization test to use\ntest_i18ngrep.\n\n> When test_i18ngrep fails it prints a message with the\n> pattern and text that failed to match so it is easy to see where the\n> test failed. If grep fails there is no output and so unless the test\n> is run with \"-x\" it can be hard to see which command caused the test\n> to fail.\n\nWe could rename test_i18ngrep to test_grep (and make test_i18ngrep\ninto a thin wrapper with warnings).\n\n\ttest_grep -e must-exist file &&\n\ttest_grep ! -e must-not-exist file\n\n"},{"id":"484065","messageId":"xmqqpm0xeyp9.fsf@gitster.g","threadId":"60431","inReplyTo":"xmqqv8apez0o.fsf@gitster.g","subject":"Re: [PATCH v3] bugreport: reject positional arguments","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-10-30T00:33:22Z","receivedAt":"2023-10-30T00:33:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Phillip Wood <phillip.wood123@gmail.com> writes:\n>\n>> It is rather unfortunate that test_i18ngrep was deprecated without\n>> providing an alternative that offers the same debugging\n>> experience.\n>\n> The primary thing test_i18ngrep did was to _SKIP_ certain test that\n> looked for an expected string in \"C\" locale from the output when the\n> tests were run under a tainted localization mode.  The tests that\n> looked for strings in messages that are *not* to be localized used\n> \"grep\".  Tests that (unfortunately) had to match human-readable\n> messages had to work around the tainted localization test to use\n> test_i18ngrep.\n>\n>> When test_i18ngrep fails it prints a message with the\n>> pattern and text that failed to match so it is easy to see where the\n>> test failed. If grep fails there is no output and so unless the test\n>> is run with \"-x\" it can be hard to see which command caused the test\n>> to fail.\n>\n> We could rename test_i18ngrep to test_grep (and make test_i18ngrep\n> into a thin wrapper with warnings).\n>\n> \ttest_grep -e must-exist file &&\n> \ttest_grep ! -e must-not-exist file\n\n... as the only remaining part in test_18ngrep has no hack to work\naround the tainted localization tests, so \"was deprecated without\"\nis a bit too strong.  There is nothing we have lost yet.\n\n\n\n t/test-lib-functions.sh | 10 ++++++----\n 1 file changed, 6 insertions(+), 4 deletions(-)\n\ndiff --git c/t/test-lib-functions.sh w/t/test-lib-functions.sh\nindex 2f8868caa1..c50bc18861 100644\n--- c/t/test-lib-functions.sh\n+++ w/t/test-lib-functions.sh\n@@ -1208,14 +1208,16 @@ test_cmp_bin () {\n \tcmp \"$@\"\n }\n \n-# Wrapper for grep which used to be used for\n-# GIT_TEST_GETTEXT_POISON=false. Only here as a shim for other\n-# in-flight changes. Should not be used and will be removed soon.\n+# Deprecated - do not use this in new code\n test_i18ngrep () {\n+\ttest_grep \"$@\"\n+}\n+\n+test_grep () {\n \teval \"last_arg=\\${$#}\"\n \n \ttest -f \"$last_arg\" ||\n-\tBUG \"test_i18ngrep requires a file to read as the last parameter\"\n+\tBUG \"test_grep requires a file to read as the last parameter\"\n \n \tif test $# -lt 2 ||\n \t   { test \"x!\" = \"x$1\" && test $# -lt 3 ; }\n"},{"id":"484068","messageId":"xmqqcywwg9am.fsf@gitster.g","threadId":"60431","inReplyTo":"xmqqpm0xeyp9.fsf@gitster.g","subject":"Re: [PATCH v3] bugreport: reject positional arguments","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-10-30T01:59:13Z","receivedAt":"2023-10-30T01:59:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> Phillip Wood <phillip.wood123@gmail.com> writes:\n>>\n>>> It is rather unfortunate that test_i18ngrep was deprecated without\n>>> providing an alternative that offers the same debugging\n>>> experience.\n>> ...\n>> We could rename test_i18ngrep to test_grep (and make test_i18ngrep\n>> into a thin wrapper with warnings).\n>>\n>> \ttest_grep -e must-exist file &&\n>> \ttest_grep ! -e must-not-exist file\n>\n> ... as the only remaining part in test_18ngrep has no hack to work\n> around the tainted localization tests, so \"was deprecated without\"\n> is a bit too strong.  There is nothing we have lost yet.\n\nHaving said all that, when re-reading the test_i18ngrep with a fresh\npair of eyes, I somehow doubt there was much upside in \"debugging\nexperience\" with test_i18ngrep in the first place, and I doubt if\nretaining it with a new name test_grep has much value.\n\nGiven that test_i18ngrep (hence test_grep) requires you to have the\nhaystack in a file, between\n\n    test_i18ngrep must-exist file &&\n    test_i18ngrep ! must-not-exist file\n\nand\n\n    grep must-exist file &&\n    ! grep must-not-exist file\n\nI do not see any difference in \"debugging experience\" when you run\nthe test with \"-i [-v] -d\".   The two cases you care about are\n\n (1) the test expects the string \"must-exist\" in the file \"file\" but\n     the string is not there.\n\n (2) the test expects the string \"must-not-exist\" missing from the\n     file \"file\", but the string is there.\n\nThe latter can clearly be seen in output from \"-i -v -d\" (the \"grep\"\noutputs a line with \"must-not-exist\" on it).  The former will show\nsilence but since you are debugging with \"-d\", and your haystack is\nin a file, after such a step fails, the test stops, and without\nremoving the \"file\" even if the test piece had test_when_finished\nto remove it (i.e. running tests in debugging mode \"-d\" and\nimmediately stopping upon failure \"-i\" behaves this way exactly to\nhelp you debugging), so you can go there to the TRASH_DIRECTORY\nyourself and inspect \"file\" to see what is going on anyway.\n\nSo, I dunno.  Surely with a long &&-chain of steps, where a grep\nthat expects lack of something is in the middle, it is hard to see\nif the lack of hit is because an earlier step failed (and the\ncontrol did not reach \"grep must-exist file\") or because the\nhaystack lacked the \"must-exist\" needle, so from that point of view,\nit may be nicer that \"did not find an expected match\" is explicitly\nstated.\n"},{"id":"484110","messageId":"881c7fea-47bb-45a9-b6e3-314f9ed9e0cd@gmail.com","threadId":"60431","inReplyTo":"xmqqcywwg9am.fsf@gitster.g","subject":"Re: [PATCH v3] bugreport: reject positional arguments","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2023-10-30T14:11:09Z","receivedAt":"2023-10-30T14:11:20Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 30/10/2023 01:59, Junio C Hamano wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n>> Junio C Hamano <gitster@pobox.com> writes:\n>>\n>>> Phillip Wood <phillip.wood123@gmail.com> writes:\n>>>\n>>>> It is rather unfortunate that test_i18ngrep was deprecated without\n>>>> providing an alternative that offers the same debugging\n>>>> experience.\n>>> ...\n>>> We could rename test_i18ngrep to test_grep (and make test_i18ngrep\n>>> into a thin wrapper with warnings).\n>>>\n>>> \ttest_grep -e must-exist file &&\n>>> \ttest_grep ! -e must-not-exist file\n>>\n>> ... as the only remaining part in test_18ngrep has no hack to work\n>> around the tainted localization tests, so \"was deprecated without\"\n>> is a bit too strong.  There is nothing we have lost yet.\n> \n> Having said all that, when re-reading the test_i18ngrep with a fresh\n> pair of eyes, I somehow doubt there was much upside in \"debugging\n> experience\" with test_i18ngrep in the first place, and I doubt if\n> retaining it with a new name test_grep has much value.\n> \n> Given that test_i18ngrep (hence test_grep) requires you to have the\n> haystack in a file, between\n> \n>      test_i18ngrep must-exist file &&\n>      test_i18ngrep ! must-not-exist file\n> \n> and\n> \n>      grep must-exist file &&\n>      ! grep must-not-exist file\n> \n> I do not see any difference in \"debugging experience\" when you run\n> the test with \"-i [-v] -d\".   The two cases you care about are\n> \n>   (1) the test expects the string \"must-exist\" in the file \"file\" but\n>       the string is not there.\n> \n>   (2) the test expects the string \"must-not-exist\" missing from the\n>       file \"file\", but the string is there.\n> \n> The latter can clearly be seen in output from \"-i -v -d\" (the \"grep\"\n> outputs a line with \"must-not-exist\" on it).  The former will show\n> silence but since you are debugging with \"-d\", and your haystack is\n> in a file, after such a step fails, the test stops, and without\n> removing the \"file\" even if the test piece had test_when_finished\n> to remove it (i.e. running tests in debugging mode \"-d\" and\n> immediately stopping upon failure \"-i\" behaves this way exactly to\n> help you debugging), so you can go there to the TRASH_DIRECTORY\n> yourself and inspect \"file\" to see what is going on anyway.\n>\n> So, I dunno.  Surely with a long &&-chain of steps, where a grep\n> that expects lack of something is in the middle, it is hard to see\n> if the lack of hit is because an earlier step failed (and the\n> control did not reach \"grep must-exist file\") or because the\n> haystack lacked the \"must-exist\" needle, so from that point of view,\n> it may be nicer that \"did not find an expected match\" is explicitly\n> stated.\n\nIt is this latter point that I had in mind. I find it much easier to \ndebug a test that says \"This command failed\" rather than looking at the \noutput to try and figure out which was the last successful command. I \ntake your point above that one can go and inspect the file when the test \nis run with \"-i -d\" but it is determining that grep failed in the first \nplace that I find annoying. I've also found the output from \ntest_i18ngrep is helpful when debugging CI test failures.\n\nBest Wishes\n\nPhillip\n"},{"id":"484164","messageId":"xmqqfs1radrj.fsf@gitster.g","threadId":"60431","inReplyTo":"881c7fea-47bb-45a9-b6e3-314f9ed9e0cd@gmail.com","subject":"Re: [PATCH v3] bugreport: reject positional arguments","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-10-30T23:31:28Z","receivedAt":"2023-10-30T23:31:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> ... it is determining that grep\n> failed in the first place that I find annoying. I've also found the\n> output from test_i18ngrep is helpful when debugging CI test failures.\n\nThanks, I agree with you that it is very useful for debugging to\nhave an explicit \"I did not find what I expected to see\".  On the\nother hand, the other side is not as severe a problem, I think.  If\n\"grep\" expects not to see an error message in the output but the\noutput has the error we do not want to see, we will see the message\nin the \"-v\" output when we run test.\n\nSo, when we retire test_i18ngrep, what we will primarily miss is\nthis form of its invocation:\n\n    test_i18ngrep ! <arguments>... <file>\n\nWe have a bit more than 100 of them in the t/ hierarchy.\n\nI wonder if it is better to drop support for the positive side,\nwhich allows us to lose the '!' and give it a name better than\n\"grep\", e.g.,  with only the negative match support, what we used to\nwrite:\n\n\ttest_must_fail git rebase -i primary >output 2>&1 &&\n\ttest_i18ngrep \"would be overwritten by checkout:\" output &&\n\ttest_i18ngrep ! \"BUG\" output\n\nwould become something like:\n\n\ttest_must_fail git rebase -i primary >output 2>&1 &&\n\tgrep \"would be overwritten by checkout:\" output &&\n\ttest_missing \"BUG\" output\n\nBut perhaps it is making it too limited for very little gain.  We\ncould add \"test_grep\" that does not do anything more than \"grep\",\nto complement, i.e.,\n\n\ttest_must_fail git rebase -i primary >output 2>&1 &&\n\ttest_grep \"would be overwritten by checkout:\" output &&\n\ttest_missing \"BUG\" output\n\nBut if we add \"test_grep\", those who have experience with writing\nand reading our tests will expect \"test_grep !\" to behave like how\ntest_i18ngrep behaved, so we will have to support its negation\nanyway, i.e. test_missing will either become unnecessary or become a\nthin wrapper,\n\n\ttest_missing () { test_grep ! \"$@\" }\n\nmerely for readability.\n\nI haven't made up my mind on the positive side, but the negative\nside (aka \"retiring use of 'test_i18ngrep !' from everywhere and use\ntest_missing instead\") would look like this:\n\n t/test-lib-functions.sh             | 18 ++++++++++++++++++\n t/t0041-usage.sh                    | 12 ++++++------\n t/t1060-object-corruption.sh        |  2 +-\n t/t1091-sparse-checkout-builtin.sh  | 14 +++++++-------\n t/t1430-bad-ref-name.sh             |  2 +-\n t/t1450-fsck.sh                     |  4 ++--\n t/t1506-rev-parse-diagnosis.sh      |  2 +-\n t/t2019-checkout-ambiguous-ref.sh   |  4 ++--\n t/t2020-checkout-detach.sh          |  4 ++--\n t/t2024-checkout-dwim.sh            |  4 ++--\n t/t2402-worktree-list.sh            |  2 +-\n t/t3404-rebase-interactive.sh       |  2 +-\n t/t3507-cherry-pick-conflict.sh     |  2 +-\n t/t3600-rm.sh                       |  2 +-\n t/t4001-diff-rename.sh              |  2 +-\n t/t4014-format-patch.sh             |  2 +-\n t/t4018-diff-funcname.sh            | 12 ++++++------\n t/t4153-am-resume-override-opts.sh  |  2 +-\n t/t5324-split-commit-graph.sh       |  2 +-\n t/t5505-remote.sh                   |  2 +-\n t/t5520-pull.sh                     |  2 +-\n t/t5523-push-upstream.sh            |  8 ++++----\n t/t5534-push-signed.sh              |  2 +-\n t/t5541-http-push-smart.sh          |  4 ++--\n t/t5574-fetch-output.sh             |  2 +-\n t/t5580-unc-paths.sh                |  2 +-\n t/t5606-clone-options.sh            |  2 +-\n t/t6001-rev-list-graft.sh           |  2 +-\n t/t6040-tracking-info.sh            |  4 ++--\n t/t6050-replace.sh                  |  2 +-\n t/t6423-merge-rename-directories.sh | 12 ++++++------\n t/t6433-merge-toplevel.sh           |  2 +-\n t/t6437-submodule-merge.sh          |  2 +-\n t/t6500-gc.sh                       |  2 +-\n t/t7400-submodule-basic.sh          | 16 ++++++++--------\n t/t7414-submodule-mistakes.sh       |  6 +++---\n t/t7416-submodule-dash-url.sh       |  2 +-\n t/t7450-bad-git-dotfiles.sh         |  2 +-\n t/t7502-commit-porcelain.sh         | 10 +++++-----\n t/t7508-status.sh                   |  8 ++++----\n t/t7518-ident-corner-cases.sh       |  2 +-\n t/t7519-status-fsmonitor.sh         |  4 ++--\n t/t7520-ignored-hook-warning.sh     |  6 +++---\n t/t7601-merge-pull-config.sh        | 38 ++++++++++++++++++-------------------\n t/t7810-grep.sh                     |  2 +-\n t/t7816-grep-binary-pattern.sh      |  2 +-\n t/t9800-git-p4-basic.sh             |  2 +-\n t/t9807-git-p4-submit.sh            |  2 +-\n 48 files changed, 132 insertions(+), 114 deletions(-)\n\ndiff --git i/t/test-lib-functions.sh w/t/test-lib-functions.sh\nindex 2f8868caa1..6cf08f6f7b 100644\n--- i/t/test-lib-functions.sh\n+++ w/t/test-lib-functions.sh\n@@ -1245,6 +1245,24 @@ test_i18ngrep () {\n \treturn 1\n }\n \n+test_missing () {\n+\teval \"last_arg=\\${$#}\"\n+\n+\ttest -f \"$last_arg\" ||\n+\tBUG \"test_missing requires a file to read as the last parameter\"\n+\n+\t! grep \"$@\" && return 0\n+\n+\techo >&4 \"error: '! grep $@' did find a match in:\"\n+\tif test -s \"$last_arg\"\n+\tthen\n+\t\tcat >&4 \"$last_arg\"\n+\telse\n+\t\techo >&4 \"<file '$last_arg' is empty>\"\n+\tfi\n+\treturn 1\n+}\n+\n # Check if the file expected to be empty is indeed empty, and barfs\n # otherwise.\n \ndiff --git i/t/t0041-usage.sh w/t/t0041-usage.sh\nindex 9ea974b0c6..292a79a484 100755\n--- i/t/t0041-usage.sh\n+++ w/t/t0041-usage.sh\n@@ -22,7 +22,7 @@ test_expect_success 'tag --contains <inexistent_tag>' '\n \ttest_must_fail git tag --contains \"notag\" >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n \ttest_i18ngrep \"error\" actual.err &&\n-\ttest_i18ngrep ! \"usage\" actual.err\n+\ttest_missing \"usage\" actual.err\n '\n \n test_expect_success 'tag --no-contains <existent_tag>' '\n@@ -35,7 +35,7 @@ test_expect_success 'tag --no-contains <inexistent_tag>' '\n \ttest_must_fail git tag --no-contains \"notag\" >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n \ttest_i18ngrep \"error\" actual.err &&\n-\ttest_i18ngrep ! \"usage\" actual.err\n+\ttest_missing \"usage\" actual.err\n '\n \n test_expect_success 'tag usage error' '\n@@ -54,7 +54,7 @@ test_expect_success 'branch --contains <inexistent_commit>' '\n \ttest_must_fail git branch --no-contains \"nocommit\" >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n \ttest_i18ngrep \"error\" actual.err &&\n-\ttest_i18ngrep ! \"usage\" actual.err\n+\ttest_missing \"usage\" actual.err\n '\n \n test_expect_success 'branch --no-contains <existent_commit>' '\n@@ -67,7 +67,7 @@ test_expect_success 'branch --no-contains <inexistent_commit>' '\n \ttest_must_fail git branch --no-contains \"nocommit\" >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n \ttest_i18ngrep \"error\" actual.err &&\n-\ttest_i18ngrep ! \"usage\" actual.err\n+\ttest_missing \"usage\" actual.err\n '\n \n test_expect_success 'branch usage error' '\n@@ -86,7 +86,7 @@ test_expect_success 'for-each-ref --contains <inexistent_object>' '\n \ttest_must_fail git for-each-ref --no-contains \"noobject\" >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n \ttest_i18ngrep \"error\" actual.err &&\n-\ttest_i18ngrep ! \"usage\" actual.err\n+\ttest_missing \"usage\" actual.err\n '\n \n test_expect_success 'for-each-ref --no-contains <existent_object>' '\n@@ -99,7 +99,7 @@ test_expect_success 'for-each-ref --no-contains <inexistent_object>' '\n \ttest_must_fail git for-each-ref --no-contains \"noobject\" >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n \ttest_i18ngrep \"error\" actual.err &&\n-\ttest_i18ngrep ! \"usage\" actual.err\n+\ttest_missing \"usage\" actual.err\n '\n \n test_expect_success 'for-each-ref usage error' '\ndiff --git i/t/t1060-object-corruption.sh w/t/t1060-object-corruption.sh\nindex 35261afc9d..8429990570 100755\n--- i/t/t1060-object-corruption.sh\n+++ w/t/t1060-object-corruption.sh\n@@ -125,7 +125,7 @@ test_expect_success 'fetch into corrupted repo with index-pack' '\n \t\tcd bit-error-cp &&\n \t\ttest_must_fail git -c transfer.unpackLimit=1 \\\n \t\t\tfetch ../no-bit-error 2>stderr &&\n-\t\ttest_i18ngrep ! -i collision stderr\n+\t\ttest_missing -i collision stderr\n \t)\n '\n \ndiff --git i/t/t1091-sparse-checkout-builtin.sh w/t/t1091-sparse-checkout-builtin.sh\nindex 9ceb17f911..a1ec29cb16 100755\n--- i/t/t1091-sparse-checkout-builtin.sh\n+++ w/t/t1091-sparse-checkout-builtin.sh\n@@ -230,7 +230,7 @@ test_expect_success 'cone mode: match patterns' '\n \tgit -C repo config --worktree core.sparseCheckoutCone true &&\n \trm -rf repo/a repo/folder1 repo/folder2 &&\n \tgit -C repo read-tree -mu HEAD 2>err &&\n-\ttest_i18ngrep ! \"disabling cone patterns\" err &&\n+\ttest_missing \"disabling cone patterns\" err &&\n \tgit -C repo reset --hard &&\n \tcheck_files repo a folder1 folder2\n '\n@@ -401,8 +401,8 @@ test_expect_success 'revert to old sparse-checkout on empty update' '\n \t\tgit add file &&\n \t\tgit commit -m \"test\" &&\n \t\tgit sparse-checkout set nothing 2>err &&\n-\t\ttest_i18ngrep ! \"Sparse checkout leaves no entry on working directory\" err &&\n-\t\ttest_i18ngrep ! \".git/index.lock\" err &&\n+\t\ttest_missing \"Sparse checkout leaves no entry on working directory\" err &&\n+\t\ttest_missing \".git/index.lock\" err &&\n \t\tgit sparse-checkout set --no-cone file\n \t)\n '\n@@ -418,7 +418,7 @@ test_expect_success '.gitignore should not warn about cone mode' '\n \tgit -C repo config --worktree core.sparseCheckoutCone true &&\n \techo \"**/bin/*\" >repo/.gitignore &&\n \tgit -C repo reset --hard 2>err &&\n-\ttest_i18ngrep ! \"disabling cone patterns\" err\n+\ttest_missing \"disabling cone patterns\" err\n '\n \n test_expect_success 'sparse-checkout (init|set|disable) warns with dirty status' '\n@@ -495,7 +495,7 @@ test_expect_failure 'sparse-checkout reapply' '\n \n \tgit -C tweak checkout HEAD deep/deeper2/a &&\n \tgit -C tweak sparse-checkout reapply 2>err &&\n-\ttest_i18ngrep ! \"warning.*The following paths are not up to date\" err &&\n+\ttest_missing \"warning.*The following paths are not up to date\" err &&\n \ttest_path_is_missing tweak/deep/deeper2/a &&\n \ttest_i18ngrep \"warning.*The following paths are unmerged\" err &&\n \ttest_path_is_file tweak/folder1/a &&\n@@ -578,7 +578,7 @@ test_expect_success 'check-rules interaction with submodules' '\n \tgit -C super ls-tree --name-only -r HEAD >all-files &&\n \tgit -C super sparse-checkout check-rules >check-rules-matches <all-files &&\n \n-\ttest_i18ngrep ! \"modules/\" check-rules-matches &&\n+\ttest_missing \"modules/\" check-rules-matches &&\n \ttest_i18ngrep \"folder1/\" check-rules-matches\n '\n \n@@ -947,7 +947,7 @@ test_expect_success 'check-rules cone mode' '\n \tgit -C repo sparse-checkout check-rules >check-rules-default <all-files &&\n \n \ttest_i18ngrep \"deep/deeper1/deepest/a\" check-rules-file &&\n-\ttest_i18ngrep ! \"deep/deeper2\" check-rules-file &&\n+\ttest_missing \"deep/deeper2\" check-rules-file &&\n \n \ttest_cmp check-rules-file ls-files &&\n \ttest_cmp check-rules-file check-rules-default\ndiff --git i/t/t1430-bad-ref-name.sh w/t/t1430-bad-ref-name.sh\nindex ff1c967d55..8953b65179 100755\n--- i/t/t1430-bad-ref-name.sh\n+++ w/t/t1430-bad-ref-name.sh\n@@ -173,7 +173,7 @@ test_expect_success 'for-each-ref emits warnings for broken names' '\n \t! grep -e \"badname\" output &&\n \t! grep -e \"broken\\.\\.\\.symref\" output &&\n \ttest_i18ngrep \"ignoring ref with broken name refs/heads/broken\\.\\.\\.ref\" error &&\n-\ttest_i18ngrep ! \"ignoring broken ref refs/heads/badname\" error &&\n+\ttest_missing \"ignoring broken ref refs/heads/badname\" error &&\n \ttest_i18ngrep \"ignoring ref with broken name refs/heads/broken\\.\\.\\.symref\" error\n '\n \ndiff --git i/t/t1450-fsck.sh w/t/t1450-fsck.sh\nindex 10a539158c..e8222bc9de 100755\n--- i/t/t1450-fsck.sh\n+++ w/t/t1450-fsck.sh\n@@ -343,7 +343,7 @@ test_expect_success 'unparseable tree object' '\n \ttest_must_fail git fsck 2>out &&\n \ttest_i18ngrep \"error: empty filename in tree entry\" out &&\n \ttest_i18ngrep \"$tree_sha1\" out &&\n-\ttest_i18ngrep ! \"fatal: empty filename in tree entry\" out\n+\ttest_missing \"fatal: empty filename in tree entry\" out\n '\n \n test_expect_success 'tree entry with type mismatch' '\n@@ -361,7 +361,7 @@ test_expect_success 'tree entry with type mismatch' '\n \tgit update-ref refs/heads/type_mismatch $commit &&\n \ttest_must_fail git fsck >out 2>&1 &&\n \ttest_i18ngrep \"is a blob, not a tree\" out &&\n-\ttest_i18ngrep ! \"dangling blob\" out\n+\ttest_missing \"dangling blob\" out\n '\n \n test_expect_success 'tree entry with bogus mode' '\ndiff --git i/t/t1506-rev-parse-diagnosis.sh w/t/t1506-rev-parse-diagnosis.sh\nindex 18688cae17..abd3019504 100755\n--- i/t/t1506-rev-parse-diagnosis.sh\n+++ w/t/t1506-rev-parse-diagnosis.sh\n@@ -171,7 +171,7 @@ test_expect_success 'relative path when cwd is outside worktree' '\n \n test_expect_success '<commit>:file correctly diagnosed after a pathname' '\n \ttest_must_fail git rev-parse file.txt HEAD:file.txt 1>actual 2>error &&\n-\ttest_i18ngrep ! \"exists on disk\" error &&\n+\ttest_missing \"exists on disk\" error &&\n \ttest_i18ngrep \"no such path in the working tree\" error &&\n \tcat >expect <<-\\EOF &&\n \tfile.txt\ndiff --git i/t/t2019-checkout-ambiguous-ref.sh w/t/t2019-checkout-ambiguous-ref.sh\nindex 9540588664..e87d2a5f13 100755\n--- i/t/t2019-checkout-ambiguous-ref.sh\n+++ w/t/t2019-checkout-ambiguous-ref.sh\n@@ -33,7 +33,7 @@ test_expect_success 'checkout chooses branch over tag' '\n \n test_expect_success 'checkout reports switch to branch' '\n \ttest_i18ngrep \"Switched to branch\" stderr &&\n-\ttest_i18ngrep ! \"^HEAD is now at\" stderr\n+\ttest_missing \"^HEAD is now at\" stderr\n '\n \n test_expect_success 'checkout vague ref succeeds' '\n@@ -55,7 +55,7 @@ test_expect_success VAGUENESS_SUCCESS 'checkout chooses branch over tag' '\n \n test_expect_success VAGUENESS_SUCCESS 'checkout reports switch to branch' '\n \ttest_i18ngrep \"Switched to branch\" stderr &&\n-\ttest_i18ngrep ! \"^HEAD is now at\" stderr\n+\ttest_missing \"^HEAD is now at\" stderr\n '\n \n test_done\ndiff --git i/t/t2020-checkout-detach.sh w/t/t2020-checkout-detach.sh\nindex 2eab6474f8..975d17c8a6 100755\n--- i/t/t2020-checkout-detach.sh\n+++ w/t/t2020-checkout-detach.sh\n@@ -18,10 +18,10 @@ check_not_detached () {\n PREV_HEAD_DESC='Previous HEAD position was'\n check_orphan_warning() {\n \ttest_i18ngrep \"you are leaving $2 behind\" \"$1\" &&\n-\ttest_i18ngrep ! \"$PREV_HEAD_DESC\" \"$1\"\n+\ttest_missing \"$PREV_HEAD_DESC\" \"$1\"\n }\n check_no_orphan_warning() {\n-\ttest_i18ngrep ! \"you are leaving .* commit.*behind\" \"$1\" &&\n+\ttest_missing \"you are leaving .* commit.*behind\" \"$1\" &&\n \ttest_i18ngrep \"$PREV_HEAD_DESC\" \"$1\"\n }\n \ndiff --git i/t/t2024-checkout-dwim.sh w/t/t2024-checkout-dwim.sh\nindex 74049a9812..b66b2baae6 100755\n--- i/t/t2024-checkout-dwim.sh\n+++ w/t/t2024-checkout-dwim.sh\n@@ -110,7 +110,7 @@ test_expect_success 'checkout of branch from multiple remotes fails with advice'\n \t\tcheckout foo 2>stderr &&\n \ttest_branch main &&\n \tstatus_uno_is_clean &&\n-\ttest_i18ngrep ! \"^hint: \" stderr\n+\ttest_missing \"^hint: \" stderr\n '\n \n test_expect_success PERL 'checkout -p with multiple remotes does not print advice' '\n@@ -118,7 +118,7 @@ test_expect_success PERL 'checkout -p with multiple remotes does not print advic\n \ttest_might_fail git branch -D foo &&\n \n \tgit checkout -p foo 2>stderr &&\n-\ttest_i18ngrep ! \"^hint: \" stderr &&\n+\ttest_missing \"^hint: \" stderr &&\n \tstatus_uno_is_clean\n '\n \ndiff --git i/t/t2402-worktree-list.sh w/t/t2402-worktree-list.sh\nindex 9ad9be0c20..ee00343ad1 100755\n--- i/t/t2402-worktree-list.sh\n+++ w/t/t2402-worktree-list.sh\n@@ -156,7 +156,7 @@ test_expect_success '\"list\" all worktrees with prunable consistent with \"prune\"'\n \t! grep \"/unprunable  *[0-9a-f].* unprunable$\" out &&\n \tgit worktree prune --verbose 2>out &&\n \ttest_i18ngrep \"^Removing worktrees/prunable\" out &&\n-\ttest_i18ngrep ! \"^Removing worktrees/unprunable\" out\n+\ttest_missing \"^Removing worktrees/unprunable\" out\n '\n \n test_expect_success '\"list\" --verbose and --porcelain mutually exclusive' '\ndiff --git i/t/t3404-rebase-interactive.sh w/t/t3404-rebase-interactive.sh\nindex 8ea2bf1302..77872cc56b 100755\n--- i/t/t3404-rebase-interactive.sh\n+++ w/t/t3404-rebase-interactive.sh\n@@ -605,7 +605,7 @@ test_expect_success 'clean error after failed \"exec\"' '\n \tgit add file7 &&\n \ttest_must_fail git rebase --continue 2>error &&\n \ttest_i18ngrep \"you have staged changes in your working tree\" error &&\n-\ttest_i18ngrep ! \"could not open.*for reading\" error\n+\ttest_missing \"could not open.*for reading\" error\n '\n \n test_expect_success 'rebase a detached HEAD' '\ndiff --git i/t/t3507-cherry-pick-conflict.sh w/t/t3507-cherry-pick-conflict.sh\nindex f32799e046..e91616ece7 100755\n--- i/t/t3507-cherry-pick-conflict.sh\n+++ w/t/t3507-cherry-pick-conflict.sh\n@@ -563,7 +563,7 @@ test_expect_success 'cherry-pick preserves sparse-checkout' '\n \techo /unrelated >.git/info/sparse-checkout &&\n \tgit read-tree --reset -u HEAD &&\n \ttest_must_fail git cherry-pick -Xours picked>actual &&\n-\ttest_i18ngrep ! \"Changes not staged for commit:\" actual\n+\ttest_missing \"Changes not staged for commit:\" actual\n '\n \n test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '\ndiff --git i/t/t3600-rm.sh w/t/t3600-rm.sh\nindex 0e8afe49ed..4de4d99464 100755\n--- i/t/t3600-rm.sh\n+++ w/t/t3600-rm.sh\n@@ -276,7 +276,7 @@ test_expect_success 'Resolving by removal is not a warning-worthy event' '\n \tblob=$(echo blob | git hash-object -w --stdin) &&\n \tprintf \"100644 $blob %d\\tblob\\n\" 1 2 3 | git update-index --index-info &&\n \tgit rm blob >msg 2>&1 &&\n-\ttest_i18ngrep ! \"needs merge\" msg &&\n+\ttest_missing \"needs merge\" msg &&\n \ttest_must_fail git ls-files -s --error-unmatch blob\n '\n \ndiff --git i/t/t4001-diff-rename.sh w/t/t4001-diff-rename.sh\nindex 3dc9047044..c0f6e1f242 100755\n--- i/t/t4001-diff-rename.sh\n+++ w/t/t4001-diff-rename.sh\n@@ -145,7 +145,7 @@ test_expect_success 'test diff.renames=true for git status' '\n \n test_expect_success 'test diff.renames=false for git status' '\n \tgit -c diff.renames=false status >out &&\n-\ttest_i18ngrep ! \"renamed: .*path1 -> subdir/path1\" out &&\n+\ttest_missing \"renamed: .*path1 -> subdir/path1\" out &&\n \ttest_i18ngrep \"new file: .*subdir/path1\" out &&\n \ttest_i18ngrep \"deleted: .*[^/]path1\" out\n '\ndiff --git i/t/t4014-format-patch.sh w/t/t4014-format-patch.sh\nindex 0a4ab36c3a..648992741a 100755\n--- i/t/t4014-format-patch.sh\n+++ w/t/t4014-format-patch.sh\n@@ -2404,7 +2404,7 @@ test_expect_success 'interdiff: cover-letter' '\n \tEOF\n \tgit format-patch --cover-letter --interdiff=boop~2 -1 boop &&\n \ttest_i18ngrep \"^Interdiff:$\" 0000-cover-letter.patch &&\n-\ttest_i18ngrep ! \"^Interdiff:$\" 0001-fleep.patch &&\n+\ttest_missing \"^Interdiff:$\" 0001-fleep.patch &&\n \tsed \"1,/^@@ /d; /^-- $/q\" 0000-cover-letter.patch >actual &&\n \ttest_cmp expect actual\n '\ndiff --git i/t/t4018-diff-funcname.sh w/t/t4018-diff-funcname.sh\nindex c8d555771d..35347e10bb 100755\n--- i/t/t4018-diff-funcname.sh\n+++ w/t/t4018-diff-funcname.sh\n@@ -53,15 +53,15 @@ do\n \t\techo \"*.java diff=$p\" >.gitattributes &&\n \t\ttest_expect_code 1 git diff --no-index \\\n \t\t\tA.java B.java 2>msg &&\n-\t\ttest_i18ngrep ! fatal msg &&\n-\t\ttest_i18ngrep ! error msg\n+\t\ttest_missing fatal msg &&\n+\t\ttest_missing error msg\n \t'\n \ttest_expect_success \"builtin $p wordRegex pattern compiles\" '\n \t\techo \"*.java diff=$p\" >.gitattributes &&\n \t\ttest_expect_code 1 git diff --no-index --word-diff \\\n \t\t\tA.java B.java 2>msg &&\n-\t\ttest_i18ngrep ! fatal msg &&\n-\t\ttest_i18ngrep ! error msg\n+\t\ttest_missing fatal msg &&\n+\t\ttest_missing error msg\n \t'\n \n \ttest_expect_success \"builtin $p pattern compiles on bare repo with --attr-source\" '\n@@ -79,8 +79,8 @@ do\n \t\tgit -C bare.git symbolic-ref HEAD refs/heads/master &&\n \t\ttest_expect_code 1 git -C bare.git --attr-source=branchA \\\n \t\t\tdiff --exit-code HEAD:A.java HEAD:B.java 2>msg &&\n-\t\ttest_i18ngrep ! fatal msg &&\n-\t\ttest_i18ngrep ! error msg\n+\t\ttest_missing fatal msg &&\n+\t\ttest_missing error msg\n \t'\n done\n \ndiff --git i/t/t4153-am-resume-override-opts.sh w/t/t4153-am-resume-override-opts.sh\nindex b7c3861407..664236914c 100755\n--- i/t/t4153-am-resume-override-opts.sh\n+++ w/t/t4153-am-resume-override-opts.sh\n@@ -53,7 +53,7 @@ test_expect_success '--no-quiet overrides --quiet' '\n \t# Applying side1 will be quiet.\n \ttest_must_fail git am --quiet side[123].eml >out &&\n \ttest_path_is_dir .git/rebase-apply &&\n-\ttest_i18ngrep ! \"^Applying: \" out &&\n+\ttest_missing \"^Applying: \" out &&\n \techo side1 >file &&\n \tgit add file &&\n \ndiff --git i/t/t5324-split-commit-graph.sh w/t/t5324-split-commit-graph.sh\nindex 97eb6d2e72..210039d9d5 100755\n--- i/t/t5324-split-commit-graph.sh\n+++ w/t/t5324-split-commit-graph.sh\n@@ -422,7 +422,7 @@ test_expect_success 'add octopus merge' '\n \tgit commit-graph verify --progress 2>err &&\n \ttest_line_count = 1 err &&\n \tgrep \"Verifying commits in commit graph: 100% (18/18)\" err &&\n-\ttest_i18ngrep ! warning err &&\n+\ttest_missing warning err &&\n \ttest_line_count = 3 $graphdir/commit-graph-chain\n '\n \ndiff --git i/t/t5505-remote.sh w/t/t5505-remote.sh\nindex 43b7bcd715..8e455d94f4 100755\n--- i/t/t5505-remote.sh\n+++ w/t/t5505-remote.sh\n@@ -1458,7 +1458,7 @@ test_expect_success 'unqualified <dst> refspec DWIM and advice' '\n \t\t\ttest_must_fail git -c advice.pushUnqualifiedRefName=false \\\n \t\t\t\tpush origin $oid:dst 2>err &&\n \t\t\ttest_i18ngrep \"error: The destination you\" err &&\n-\t\t\ttest_i18ngrep ! \"hint: Did you mean\" err ||\n+\t\t\ttest_missing \"hint: Did you mean\" err ||\n \t\t\texit 1\n \t\tdone\n \t)\ndiff --git i/t/t5520-pull.sh w/t/t5520-pull.sh\nindex 0b72112fb1..22ccf998f9 100755\n--- i/t/t5520-pull.sh\n+++ w/t/t5520-pull.sh\n@@ -530,7 +530,7 @@ test_expect_success 'pull --rebase does not warn on --no-verify-signatures' '\n \techo new >expect &&\n \tgit show HEAD:file2 >actual &&\n \ttest_cmp expect actual &&\n-\ttest_i18ngrep ! \"verify-signatures\" err\n+\ttest_missing \"verify-signatures\" err\n '\n \n # add a feature branch, keep-merge, that is merged into main, so the\ndiff --git i/t/t5523-push-upstream.sh w/t/t5523-push-upstream.sh\nindex 1b8d609879..8e89b279e8 100755\n--- i/t/t5523-push-upstream.sh\n+++ w/t/t5523-push-upstream.sh\n@@ -95,7 +95,7 @@ test_expect_success 'progress messages do not go to non-tty' '\n \n \t# skip progress messages, since stderr is non-tty\n \tgit push -u upstream main >out 2>err &&\n-\ttest_i18ngrep ! \"Writing objects\" err\n+\ttest_missing \"Writing objects\" err\n '\n \n test_expect_success 'progress messages go to non-tty (forced)' '\n@@ -110,15 +110,15 @@ test_expect_success TTY 'push -q suppresses progress' '\n \tensure_fresh_upstream &&\n \n \ttest_terminal git push -u -q upstream main >out 2>err &&\n-\ttest_i18ngrep ! \"Writing objects\" err\n+\ttest_missing \"Writing objects\" err\n '\n \n test_expect_success TTY 'push --no-progress suppresses progress' '\n \tensure_fresh_upstream &&\n \n \ttest_terminal git push -u --no-progress upstream main >out 2>err &&\n-\ttest_i18ngrep ! \"Unpacking objects\" err &&\n-\ttest_i18ngrep ! \"Writing objects\" err\n+\ttest_missing \"Unpacking objects\" err &&\n+\ttest_missing \"Writing objects\" err\n '\n \n test_expect_success TTY 'quiet push' '\ndiff --git i/t/t5534-push-signed.sh w/t/t5534-push-signed.sh\nindex 7c0a148e73..37870326e1 100755\n--- i/t/t5534-push-signed.sh\n+++ w/t/t5534-push-signed.sh\n@@ -378,7 +378,7 @@ test_expect_success GPG 'failed atomic push does not execute GPG' '\n \t\t\t--signed --atomic --porcelain \\\n \t\t\tdst noop ff noff >out 2>err &&\n \n-\ttest_i18ngrep ! \"gpg failed to sign\" err &&\n+\ttest_missing \"gpg failed to sign\" err &&\n \tcat >expect <<-EOF &&\n \tTo dst\n \t=\trefs/heads/noop:refs/heads/noop\t[up to date]\ndiff --git i/t/t5541-http-push-smart.sh w/t/t5541-http-push-smart.sh\nindex d0211cd8be..a3824af91c 100755\n--- i/t/t5541-http-push-smart.sh\n+++ w/t/t5541-http-push-smart.sh\n@@ -312,7 +312,7 @@ test_expect_success TTY 'push --no-progress silences progress but not status' '\n \ttest_commit no-progress &&\n \ttest_terminal git push --no-progress >output 2>&1 &&\n \ttest_i18ngrep \"^To http\" output &&\n-\ttest_i18ngrep ! \"^Writing objects\" output\n+\ttest_missing \"^Writing objects\" output\n '\n \n test_expect_success 'push --progress shows progress to non-tty' '\n@@ -492,7 +492,7 @@ test_expect_success 'colorize errors/hints' '\n \ttest_i18ngrep \"<RED>.*rejected.*<RESET>\" decoded &&\n \ttest_i18ngrep \"<RED>error: failed to push some refs\" decoded &&\n \ttest_i18ngrep \"<YELLOW>hint: \" decoded &&\n-\ttest_i18ngrep ! \"^hint: \" decoded\n+\ttest_missing \"^hint: \" decoded\n '\n \n test_expect_success 'report error server does not provide ref status' '\ndiff --git i/t/t5574-fetch-output.sh w/t/t5574-fetch-output.sh\nindex 90e6dcb9a7..95c105926e 100755\n--- i/t/t5574-fetch-output.sh\n+++ w/t/t5574-fetch-output.sh\n@@ -286,7 +286,7 @@ test_expect_success '--no-show-forced-updates' '\n \t(\n \t\tcd no-forced-update-clone &&\n \t\tgit fetch --no-show-forced-updates origin 2>output &&\n-\t\ttest_i18ngrep ! \"(forced update)\" output\n+\t\ttest_missing \"(forced update)\" output\n \t)\n '\n \ndiff --git i/t/t5580-unc-paths.sh w/t/t5580-unc-paths.sh\nindex cd7604fff9..07c24a463d 100755\n--- i/t/t5580-unc-paths.sh\n+++ w/t/t5580-unc-paths.sh\n@@ -75,7 +75,7 @@ test_expect_success push '\n test_expect_success MINGW 'remote nick cannot contain backslashes' '\n \tBACKSLASHED=\"$(winpwd | tr / \\\\\\\\)\" &&\n \tgit ls-remote \"$BACKSLASHED\" 2>err &&\n-\ttest_i18ngrep ! \"unable to access\" err\n+\ttest_missing \"unable to access\" err\n '\n \n test_expect_success 'unc alternates' '\ndiff --git i/t/t5606-clone-options.sh w/t/t5606-clone-options.sh\nindex 5890319b97..9c480c7734 100755\n--- i/t/t5606-clone-options.sh\n+++ w/t/t5606-clone-options.sh\n@@ -149,7 +149,7 @@ test_expect_success 'redirected clone does not show progress' '\n \n \tgit clone \"file://$(pwd)/parent\" clone-redirected >out 2>err &&\n \t! grep % err &&\n-\ttest_i18ngrep ! \"Checking connectivity\" err\n+\ttest_missing \"Checking connectivity\" err\n \n '\n \ndiff --git i/t/t6001-rev-list-graft.sh w/t/t6001-rev-list-graft.sh\nindex 16635ecc33..38565e68ff 100755\n--- i/t/t6001-rev-list-graft.sh\n+++ w/t/t6001-rev-list-graft.sh\n@@ -121,7 +121,7 @@ test_expect_success 'show advice that grafts are deprecated' '\n \ttest_i18ngrep \"git replace\" err &&\n \ttest_config advice.graftFileDeprecated false &&\n \tgit show HEAD 2>err &&\n-\ttest_i18ngrep ! \"git replace\" err\n+\ttest_missing \"git replace\" err\n '\n \n test_done\ndiff --git i/t/t6040-tracking-info.sh w/t/t6040-tracking-info.sh\nindex 7ddbd96e58..9034fd4b1e 100755\n--- i/t/t6040-tracking-info.sh\n+++ w/t/t6040-tracking-info.sh\n@@ -253,7 +253,7 @@ test_expect_success 'fail to track lightweight tags' '\n \tgit checkout main &&\n \tgit tag light &&\n \ttest_must_fail git branch --track lighttrack light >actual &&\n-\ttest_i18ngrep ! \"set up to track\" actual &&\n+\ttest_missing \"set up to track\" actual &&\n \ttest_must_fail git checkout lighttrack\n '\n \n@@ -261,7 +261,7 @@ test_expect_success 'fail to track annotated tags' '\n \tgit checkout main &&\n \tgit tag -m heavy heavy &&\n \ttest_must_fail git branch --track heavytrack heavy >actual &&\n-\ttest_i18ngrep ! \"set up to track\" actual &&\n+\ttest_missing \"set up to track\" actual &&\n \ttest_must_fail git checkout heavytrack\n '\n \ndiff --git i/t/t6050-replace.sh w/t/t6050-replace.sh\nindex c9925edf20..f71812ed14 100755\n--- i/t/t6050-replace.sh\n+++ w/t/t6050-replace.sh\n@@ -492,7 +492,7 @@ test_expect_success '--convert-graft-file' '\n \tgit status 2>stderr &&\n \ttest_i18ngrep \"hint:.*grafts is deprecated\" stderr &&\n \tgit replace --convert-graft-file 2>stderr &&\n-\ttest_i18ngrep ! \"hint:.*grafts is deprecated\" stderr &&\n+\ttest_missing \"hint:.*grafts is deprecated\" stderr &&\n \ttest_path_is_missing .git/info/grafts &&\n \n \t: verify that the history is now \"grafted\" &&\ndiff --git i/t/t6423-merge-rename-directories.sh w/t/t6423-merge-rename-directories.sh\nindex 944de75b80..bff2690b98 100755\n--- i/t/t6423-merge-rename-directories.sh\n+++ w/t/t6423-merge-rename-directories.sh\n@@ -591,7 +591,7 @@ test_expect_success '2b: Directory split into two on one side, with equal number\n \t\tgit rev-parse >expect \\\n \t\t\t O:z/b  O:z/c  B:x/d &&\n \t\ttest_cmp expect actual &&\n-\t\ttest_i18ngrep ! \"CONFLICT.*directory rename split\" out\n+\t\ttest_missing \"CONFLICT.*directory rename split\" out\n \t)\n '\n \n@@ -727,7 +727,7 @@ test_expect_success '3b: Avoid implicit rename if involved as source on current\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&\n \t\ttest_i18ngrep CONFLICT.*rename/rename.*z/d.*x/d.*w/d out &&\n-\t\ttest_i18ngrep ! CONFLICT.*rename/rename.*y/d out &&\n+\t\ttest_missing CONFLICT.*rename/rename.*y/d out &&\n \n \t\tgit ls-files -s >out &&\n \t\ttest_line_count = 5 out &&\n@@ -3606,7 +3606,7 @@ test_expect_merge_algorithm failure success '10e: Does git complain about untrac\n \t\techo random >z/c &&\n \n \t\tgit -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep ! \"following untracked working tree files would be overwritten by merge\" err &&\n+\t\ttest_missing \"following untracked working tree files would be overwritten by merge\" err &&\n \n \t\tgit ls-files -s >out &&\n \t\ttest_line_count = 3 out &&\n@@ -5821,9 +5821,9 @@ test_expect_success '13e: directory rename detection in recursive case' '\n \n \t\tgit -c merge.directoryRenames=conflict merge -s recursive C^0 >out 2>err &&\n \n-\t\ttest_i18ngrep ! CONFLICT out &&\n-\t\ttest_i18ngrep ! BUG: err &&\n-\t\ttest_i18ngrep ! core.dumped err &&\n+\t\ttest_missing CONFLICT out &&\n+\t\ttest_missing BUG: err &&\n+\t\ttest_missing core.dumped err &&\n \t\ttest_must_be_empty err &&\n \n \t\tgit ls-files >paths &&\ndiff --git i/t/t6433-merge-toplevel.sh w/t/t6433-merge-toplevel.sh\nindex 2b42f095dc..393d127006 100755\n--- i/t/t6433-merge-toplevel.sh\n+++ w/t/t6433-merge-toplevel.sh\n@@ -152,7 +152,7 @@ test_expect_success 'refuse two-project merge by default, quit before --autostas\n \techo change >>one.t &&\n \tgit diff >expect &&\n \ttest_must_fail git merge --autostash five 2>err &&\n-\ttest_i18ngrep ! \"stash\" err &&\n+\ttest_missing \"stash\" err &&\n \tgit diff >actual &&\n \ttest_cmp expect actual\n '\ndiff --git i/t/t6437-submodule-merge.sh w/t/t6437-submodule-merge.sh\nindex daa507862c..b675e15a11 100755\n--- i/t/t6437-submodule-merge.sh\n+++ w/t/t6437-submodule-merge.sh\n@@ -480,7 +480,7 @@ test_expect_merge_algorithm failure success !FAIL_PREREQS 'directory/submodule c\n \t\t# We do not want files within the submodule to prevent the\n \t\t# merge from starting; we should not be writing to such paths\n \t\t# anyway.\n-\t\ttest_i18ngrep ! \"refusing to lose untracked file at\" err\n+\t\ttest_missing \"refusing to lose untracked file at\" err\n \t)\n '\n \ndiff --git i/t/t6500-gc.sh w/t/t6500-gc.sh\nindex 04acf22d93..5f48720d9a 100755\n--- i/t/t6500-gc.sh\n+++ w/t/t6500-gc.sh\n@@ -155,7 +155,7 @@ test_expect_success 'auto gc with too many loose objects does not attempt to cre\n \ttest_commit \"$(test_oid obj4)\" &&\n \n \tgit gc --auto 2>err &&\n-\ttest_i18ngrep ! \"^warning:\" err &&\n+\ttest_missing \"^warning:\" err &&\n \tls .git/objects/pack/pack-*.pack | sort >post_packs &&\n \tcomm -1 -3 existing_packs post_packs >new &&\n \tcomm -2 -3 existing_packs post_packs >del &&\ndiff --git i/t/t7400-submodule-basic.sh w/t/t7400-submodule-basic.sh\nindex d9fbabb2b9..23038b3321 100755\n--- i/t/t7400-submodule-basic.sh\n+++ w/t/t7400-submodule-basic.sh\n@@ -196,7 +196,7 @@ test_expect_success 'redirected submodule add does not show progress' '\n \tgit -C addtest submodule add \"file://$submodurl/parent\" submod-redirected \\\n \t\t2>err &&\n \t! grep % err &&\n-\ttest_i18ngrep ! \"Checking connectivity\" err\n+\ttest_missing \"Checking connectivity\" err\n '\n \n test_expect_success 'redirected submodule add --progress does show progress' '\n@@ -1160,7 +1160,7 @@ test_expect_success 'submodule deinit deinits a submodule when its work tree is\n \tgit submodule deinit init example2 >actual &&\n \ttest -z \"$(git config --get-regexp \"submodule\\.example\\.\")\" &&\n \ttest -z \"$(git config --get-regexp \"submodule\\.example2\\.\")\" &&\n-\ttest_i18ngrep ! \"Cleared directory .init\" actual &&\n+\ttest_missing \"Cleared directory .init\" actual &&\n \ttest_i18ngrep \"Cleared directory .example2\" actual &&\n \trmdir init\n '\n@@ -1210,19 +1210,19 @@ test_expect_success 'submodule deinit is silent when used on an uninitialized su\n \ttest_i18ngrep \"Submodule .example. (.*) unregistered for path .init\" actual &&\n \ttest_i18ngrep \"Cleared directory .init\" actual &&\n \tgit submodule deinit init >actual &&\n-\ttest_i18ngrep ! \"Submodule .example. (.*) unregistered for path .init\" actual &&\n+\ttest_missing \"Submodule .example. (.*) unregistered for path .init\" actual &&\n \ttest_i18ngrep \"Cleared directory .init\" actual &&\n \tgit submodule deinit . >actual &&\n-\ttest_i18ngrep ! \"Submodule .example. (.*) unregistered for path .init\" actual &&\n+\ttest_missing \"Submodule .example. (.*) unregistered for path .init\" actual &&\n \ttest_i18ngrep \"Submodule .example2. (.*) unregistered for path .example2\" actual &&\n \ttest_i18ngrep \"Cleared directory .init\" actual &&\n \tgit submodule deinit . >actual &&\n-\ttest_i18ngrep ! \"Submodule .example. (.*) unregistered for path .init\" actual &&\n-\ttest_i18ngrep ! \"Submodule .example2. (.*) unregistered for path .example2\" actual &&\n+\ttest_missing \"Submodule .example. (.*) unregistered for path .init\" actual &&\n+\ttest_missing \"Submodule .example2. (.*) unregistered for path .example2\" actual &&\n \ttest_i18ngrep \"Cleared directory .init\" actual &&\n \tgit submodule deinit --all >actual &&\n-\ttest_i18ngrep ! \"Submodule .example. (.*) unregistered for path .init\" actual &&\n-\ttest_i18ngrep ! \"Submodule .example2. (.*) unregistered for path .example2\" actual &&\n+\ttest_missing \"Submodule .example. (.*) unregistered for path .init\" actual &&\n+\ttest_missing \"Submodule .example2. (.*) unregistered for path .example2\" actual &&\n \ttest_i18ngrep \"Cleared directory .init\" actual &&\n \trmdir init example2\n '\ndiff --git i/t/t7414-submodule-mistakes.sh w/t/t7414-submodule-mistakes.sh\nindex 101afff30f..7c0bd0bc28 100755\n--- i/t/t7414-submodule-mistakes.sh\n+++ w/t/t7414-submodule-mistakes.sh\n@@ -19,7 +19,7 @@ test_expect_success 'git-add on embedded repository warns' '\n test_expect_success '--no-warn-embedded-repo suppresses warning' '\n \ttest_when_finished \"git rm --cached -f embed\" &&\n \tgit add --no-warn-embedded-repo embed 2>stderr &&\n-\ttest_i18ngrep ! warning stderr\n+\ttest_missing warning stderr\n '\n \n test_expect_success 'no warning when updating entry' '\n@@ -27,14 +27,14 @@ test_expect_success 'no warning when updating entry' '\n \tgit add embed &&\n \tgit -C embed commit --allow-empty -m two &&\n \tgit add embed 2>stderr &&\n-\ttest_i18ngrep ! warning stderr\n+\ttest_missing warning stderr\n '\n \n test_expect_success 'submodule add does not warn' '\n \ttest_when_finished \"git rm -rf submodule .gitmodules\" &&\n \tgit -c protocol.file.allow=always \\\n \t\tsubmodule add ./embed submodule 2>stderr &&\n-\ttest_i18ngrep ! warning stderr\n+\ttest_missing warning stderr\n '\n \n test_done\ndiff --git i/t/t7416-submodule-dash-url.sh w/t/t7416-submodule-dash-url.sh\nindex 7cf72b9a07..d8a08f4852 100755\n--- i/t/t7416-submodule-dash-url.sh\n+++ w/t/t7416-submodule-dash-url.sh\n@@ -63,7 +63,7 @@ test_expect_success 'trailing backslash is handled correctly' '\n \tmv .new .gitmodules &&\n \tgit commit -am \"Add testmodule\" &&\n \ttest_must_fail git clone --verbose --recurse-submodules . dolly 2>err &&\n-\ttest_i18ngrep ! \"unknown option\" err\n+\ttest_missing \"unknown option\" err\n '\n \n test_expect_success 'fsck rejects missing URL scheme' '\ndiff --git i/t/t7450-bad-git-dotfiles.sh w/t/t7450-bad-git-dotfiles.sh\nindex 0d0c3f2c68..59a4c8f8e8 100755\n--- i/t/t7450-bad-git-dotfiles.sh\n+++ w/t/t7450-bad-git-dotfiles.sh\n@@ -253,7 +253,7 @@ test_expect_success 'fsck detects corrupt .gitmodules' '\n \n \t\tgit fsck 2>output &&\n \t\ttest_i18ngrep gitmodulesParse output &&\n-\t\ttest_i18ngrep ! \"bad config\" output\n+\t\ttest_missing \"bad config\" output\n \t)\n '\n \ndiff --git i/t/t7502-commit-porcelain.sh w/t/t7502-commit-porcelain.sh\nindex b5bf7de7cd..21436fc957 100755\n--- i/t/t7502-commit-porcelain.sh\n+++ w/t/t7502-commit-porcelain.sh\n@@ -860,7 +860,7 @@ try_commit () {\n \tGIT_EDITOR=.git/FAKE_EDITOR git commit -a $* $use_template &&\n \tcase \"$use_template\" in\n \t'')\n-\t\ttest_i18ngrep ! \"^## Custom template\" .git/COMMIT_EDITMSG ;;\n+\t\ttest_missing \"^## Custom template\" .git/COMMIT_EDITMSG ;;\n \t*)\n \t\ttest_i18ngrep \"^## Custom template\" .git/COMMIT_EDITMSG ;;\n \tesac\n@@ -880,7 +880,7 @@ try_commit_status_combo () {\n \n \ttest_expect_success 'commit --no-status' '\n \t\ttry_commit --no-status &&\n-\t\ttest_i18ngrep ! \"^# Changes to be committed:\" .git/COMMIT_EDITMSG\n+\t\ttest_missing \"^# Changes to be committed:\" .git/COMMIT_EDITMSG\n \t'\n \n \ttest_expect_success 'commit with commit.status = yes' '\n@@ -892,7 +892,7 @@ try_commit_status_combo () {\n \ttest_expect_success 'commit with commit.status = no' '\n \t\ttest_config commit.status no &&\n \t\ttry_commit \"\" &&\n-\t\ttest_i18ngrep ! \"^# Changes to be committed:\" .git/COMMIT_EDITMSG\n+\t\ttest_missing \"^# Changes to be committed:\" .git/COMMIT_EDITMSG\n \t'\n \n \ttest_expect_success 'commit --status with commit.status = yes' '\n@@ -904,7 +904,7 @@ try_commit_status_combo () {\n \ttest_expect_success 'commit --no-status with commit.status = yes' '\n \t\ttest_config commit.status yes &&\n \t\ttry_commit --no-status &&\n-\t\ttest_i18ngrep ! \"^# Changes to be committed:\" .git/COMMIT_EDITMSG\n+\t\ttest_missing \"^# Changes to be committed:\" .git/COMMIT_EDITMSG\n \t'\n \n \ttest_expect_success 'commit --status with commit.status = no' '\n@@ -916,7 +916,7 @@ try_commit_status_combo () {\n \ttest_expect_success 'commit --no-status with commit.status = no' '\n \t\ttest_config commit.status no &&\n \t\ttry_commit --no-status &&\n-\t\ttest_i18ngrep ! \"^# Changes to be committed:\" .git/COMMIT_EDITMSG\n+\t\ttest_missing \"^# Changes to be committed:\" .git/COMMIT_EDITMSG\n \t'\n \n }\ndiff --git i/t/t7508-status.sh w/t/t7508-status.sh\nindex 6c46648e11..c8c107825e 100755\n--- i/t/t7508-status.sh\n+++ w/t/t7508-status.sh\n@@ -1547,7 +1547,7 @@ test_expect_success 'git commit will commit a staged but ignored submodule' '\n \texport GIT_EDITOR &&\n \tgit commit -uno &&\n \tgit status -s --ignore-submodules=dirty >output &&\n-\ttest_i18ngrep ! \"^M. sm\" output\n+\ttest_missing \"^M. sm\" output\n '\n \n test_expect_success 'git commit --dry-run will show a staged but ignored submodule' '\n@@ -1578,7 +1578,7 @@ EOF\n test_expect_success 'git commit -m will commit a staged but ignored submodule' '\n \tgit commit -uno -m message &&\n \tgit status -s --ignore-submodules=dirty >output &&\n-\ttest_i18ngrep ! \"^M. sm\" output &&\n+\ttest_missing \"^M. sm\" output &&\n \tgit config --remove-section submodule.subname &&\n \tgit config -f .gitmodules  --remove-section submodule.subname\n '\n@@ -1625,7 +1625,7 @@ test_expect_success '\"No commits yet\" should not be noted in status output' '\n \tgit checkout --orphan empty-branch-2 &&\n \ttest_commit test-commit-1 &&\n \tgit status >output &&\n-\ttest_i18ngrep ! \"No commits yet\" output\n+\ttest_missing \"No commits yet\" output\n '\n \n test_expect_success '\"Initial commit\" should be noted in commit template' '\n@@ -1642,7 +1642,7 @@ test_expect_success '\"Initial commit\" should not be noted in commit template' '\n \ttouch to_be_committed_2 &&\n \tgit add to_be_committed_2 &&\n \tgit commit --dry-run >output &&\n-\ttest_i18ngrep ! \"Initial commit\" output\n+\ttest_missing \"Initial commit\" output\n '\n \n test_expect_success '--no-optional-locks prevents index update' '\ndiff --git i/t/t7518-ident-corner-cases.sh w/t/t7518-ident-corner-cases.sh\nindex 9ab2ae2f3b..99543c9770 100755\n--- i/t/t7518-ident-corner-cases.sh\n+++ w/t/t7518-ident-corner-cases.sh\n@@ -15,7 +15,7 @@ test_expect_success 'empty name and missing email' '\n \t\tsane_unset GIT_AUTHOR_EMAIL &&\n \t\tGIT_AUTHOR_NAME= &&\n \t\ttest_must_fail git commit --allow-empty -m foo 2>err &&\n-\t\ttest_i18ngrep ! \"(null)\" err\n+\t\ttest_missing \"(null)\" err\n \t)\n '\n \ndiff --git i/t/t7519-status-fsmonitor.sh w/t/t7519-status-fsmonitor.sh\nindex 8348e3ae7d..a6e4f16da4 100755\n--- i/t/t7519-status-fsmonitor.sh\n+++ w/t/t7519-status-fsmonitor.sh\n@@ -322,10 +322,10 @@ do\n \t\t\trm -f marker &&\n \t\t\tgit status >actual &&\n \t\t\ttest_path_is_file marker &&\n-\t\t\ttest_i18ngrep ! \"Changes not staged for commit:\" actual &&\n+\t\t\ttest_missing \"Changes not staged for commit:\" actual &&\n \t\t\tif test $uc_val = true\n \t\t\tthen\n-\t\t\t\ttest_i18ngrep ! \"Untracked files:\" actual\n+\t\t\t\ttest_missing \"Untracked files:\" actual\n \t\t\tfi &&\n \t\t\tif test $uc_val = false\n \t\t\tthen\ndiff --git i/t/t7520-ignored-hook-warning.sh w/t/t7520-ignored-hook-warning.sh\nindex 184b258989..936528ff33 100755\n--- i/t/t7520-ignored-hook-warning.sh\n+++ w/t/t7520-ignored-hook-warning.sh\n@@ -13,7 +13,7 @@ test_expect_success setup '\n \n test_expect_success 'no warning if hook is not ignored' '\n \tgit commit --allow-empty -m \"more\" 2>message &&\n-\ttest_i18ngrep ! -e \"hook was ignored\" message\n+\ttest_missing -e \"hook was ignored\" message\n '\n \n test_expect_success POSIXPERM 'warning if hook is ignored' '\n@@ -26,14 +26,14 @@ test_expect_success POSIXPERM 'no warning if advice.ignoredHook set to false' '\n \ttest_config advice.ignoredHook false &&\n \ttest_hook --disable pre-commit &&\n \tgit commit --allow-empty -m \"even more\" 2>message &&\n-\ttest_i18ngrep ! -e \"hook was ignored\" message\n+\ttest_missing -e \"hook was ignored\" message\n '\n \n test_expect_success 'no warning if unset advice.ignoredHook and hook removed' '\n \ttest_hook --remove pre-commit &&\n \ttest_unconfig advice.ignoredHook &&\n \tgit commit --allow-empty -m \"even more\" 2>message &&\n-\ttest_i18ngrep ! -e \"hook was ignored\" message\n+\ttest_missing -e \"hook was ignored\" message\n '\n \n test_done\ndiff --git i/t/t7601-merge-pull-config.sh w/t/t7601-merge-pull-config.sh\nindex e08767df66..0c49c752b0 100755\n--- i/t/t7601-merge-pull-config.sh\n+++ w/t/t7601-merge-pull-config.sh\n@@ -30,58 +30,58 @@ test_expect_success 'setup' '\n test_expect_success 'pull.rebase not set, ff possible' '\n \tgit reset --hard c0 &&\n \tgit pull . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and pull.ff=true' '\n \tgit reset --hard c0 &&\n \ttest_config pull.ff true &&\n \tgit pull . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and pull.ff=false' '\n \tgit reset --hard c0 &&\n \ttest_config pull.ff false &&\n \tgit pull . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and pull.ff=only' '\n \tgit reset --hard c0 &&\n \ttest_config pull.ff only &&\n \tgit pull . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and --rebase given' '\n \tgit reset --hard c0 &&\n \tgit pull --rebase . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and --no-rebase given' '\n \tgit reset --hard c0 &&\n \tgit pull --no-rebase . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and --ff given' '\n \tgit reset --hard c0 &&\n \tgit pull --ff . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and --no-ff given' '\n \tgit reset --hard c0 &&\n \tgit pull --no-ff . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and --ff-only given' '\n \tgit reset --hard c0 &&\n \tgit pull --ff-only . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set (not-fast-forward)' '\n@@ -96,51 +96,51 @@ test_expect_success 'pull.rebase not set and pull.ff=true (not-fast-forward)' '\n \tgit reset --hard c2 &&\n \ttest_config pull.ff true &&\n \tgit pull . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and pull.ff=false (not-fast-forward)' '\n \tgit reset --hard c2 &&\n \ttest_config pull.ff false &&\n \tgit pull . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and pull.ff=only (not-fast-forward)' '\n \tgit reset --hard c2 &&\n \ttest_config pull.ff only &&\n \ttest_must_fail git pull . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and --rebase given (not-fast-forward)' '\n \tgit reset --hard c2 &&\n \tgit pull --rebase . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and --no-rebase given (not-fast-forward)' '\n \tgit reset --hard c2 &&\n \tgit pull --no-rebase . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and --ff given (not-fast-forward)' '\n \tgit reset --hard c2 &&\n \tgit pull --ff . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and --no-ff given (not-fast-forward)' '\n \tgit reset --hard c2 &&\n \tgit pull --no-ff . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_expect_success 'pull.rebase not set and --ff-only given (not-fast-forward)' '\n \tgit reset --hard c2 &&\n \ttest_must_fail git pull --ff-only . c1 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err\n+\ttest_missing \"You have divergent branches\" err\n '\n \n test_does_rebase () {\n@@ -334,7 +334,7 @@ test_expect_success 'Multiple heads warns about inability to fast forward' '\n test_expect_success 'Multiple can never be fast forwarded' '\n \tgit reset --hard c0 &&\n \ttest_must_fail git -c pull.ff=only pull . c1 c2 c3 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err &&\n+\ttest_missing \"You have divergent branches\" err &&\n \t# In addition to calling out \"cannot fast-forward\", we very much\n \t# want the \"multiple branches\" piece to be called out to users.\n \ttest_i18ngrep \"Cannot fast-forward to multiple branches\" err\n@@ -343,7 +343,7 @@ test_expect_success 'Multiple can never be fast forwarded' '\n test_expect_success 'Cannot rebase with multiple heads' '\n \tgit reset --hard c0 &&\n \ttest_must_fail git -c pull.rebase=true pull . c1 c2 c3 2>err &&\n-\ttest_i18ngrep ! \"You have divergent branches\" err &&\n+\ttest_missing \"You have divergent branches\" err &&\n \ttest_i18ngrep \"Cannot rebase onto multiple branches.\" err\n '\n \ndiff --git i/t/t7810-grep.sh w/t/t7810-grep.sh\nindex 84838c0fe1..a9610e1b08 100755\n--- i/t/t7810-grep.sh\n+++ w/t/t7810-grep.sh\n@@ -1426,7 +1426,7 @@ test_expect_success 'grep --no-index prefers paths to revs' '\n \n test_expect_success 'grep --no-index does not \"diagnose\" revs' '\n \ttest_must_fail git grep --no-index o :1:hello.c 2>err &&\n-\ttest_i18ngrep ! -i \"did you mean\" err\n+\ttest_missing -i \"did you mean\" err\n '\n \n cat >expected <<EOF\ndiff --git i/t/t7816-grep-binary-pattern.sh w/t/t7816-grep-binary-pattern.sh\nindex fdb2355649..a22c88c8b3 100755\n--- i/t/t7816-grep-binary-pattern.sh\n+++ w/t/t7816-grep-binary-pattern.sh\n@@ -26,7 +26,7 @@ nul_match_internal () {\n \t\t\t>stderr &&\n \t\t\tprintf '$pattern' | q_to_nul >f &&\n \t\t\ttest_must_fail env LC_ALL=\\\"$lc_all\\\" git grep $extra_flags -f f $flags a 2>stderr &&\n-\t\t\ttest_i18ngrep ! 'This is only supported with -P under PCRE v2' stderr\n+\t\t\ttest_missing 'This is only supported with -P under PCRE v2' stderr\n \t\t\"\n \telif test \"$matches\" = P\n \tthen\ndiff --git i/t/t9800-git-p4-basic.sh w/t/t9800-git-p4-basic.sh\nindex a4b3cb9492..b44aa84b08 100755\n--- i/t/t9800-git-p4-basic.sh\n+++ w/t/t9800-git-p4-basic.sh\n@@ -290,7 +290,7 @@ test_expect_success 'exit when p4 fails to produce marshaled output' '\n \t\texport PATH &&\n \t\ttest_expect_code 1 git p4 clone --dest=\"$git\" //depot >errs 2>&1\n \t) &&\n-\ttest_i18ngrep ! Traceback errs\n+\ttest_missing Traceback errs\n '\n \n # Hide a file from p4d, make sure we catch its complaint.  This won't fail in\ndiff --git i/t/t9807-git-p4-submit.sh w/t/t9807-git-p4-submit.sh\nindex 7d4109f29d..dd0badd7f9 100755\n--- i/t/t9807-git-p4-submit.sh\n+++ w/t/t9807-git-p4-submit.sh\n@@ -463,7 +463,7 @@ test_expect_success 'submit --prepare-p4-only' '\n \t\tgit p4 submit --prepare-p4-only >out &&\n \t\ttest_i18ngrep \"prepared for submission\" out &&\n \t\ttest_i18ngrep \"must be deleted\" out &&\n-\t\ttest_i18ngrep ! \"everything below this line is just the diff\" out\n+\t\ttest_missing \"everything below this line is just the diff\" out\n \t) &&\n \t(\n \t\tcd \"$cli\" &&\n"},{"id":"484173","messageId":"xmqqzfzz5ydl.fsf@gitster.g","threadId":"60431","inReplyTo":"xmqqfs1radrj.fsf@gitster.g","subject":"Re: [PATCH v3] bugreport: reject positional arguments","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-10-31T02:17:26Z","receivedAt":"2023-10-31T02:17:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Phillip Wood <phillip.wood123@gmail.com> writes:\n>\n>> ... it is determining that grep\n>> failed in the first place that I find annoying. I've also found the\n>> output from test_i18ngrep is helpful when debugging CI test failures.\n>\n> Thanks, I agree with you that it is very useful for debugging to\n> have an explicit \"I did not find what I expected to see\".  On the\n> other hand, the other side is not as severe a problem, I think.  If\n> \"grep\" expects not to see an error message in the output but the\n> output has the error we do not want to see, we will see the message\n> in the \"-v\" output when we run test.\n\nEverything I wrote above makes sense, but what I continued this\nmessage with (below---omitted) is total opposite.  Let's discard and\nmaybe retry sometime later.\n"},{"id":"484187","messageId":"20231031052330.3762989-2-gitster@pobox.com","threadId":"60431","inReplyTo":"20231031052330.3762989-1-gitster@pobox.com","subject":"[PATCH 1/2] test framework: further deprecate test_i18ngrep","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-10-31T05:23:29Z","receivedAt":"2023-10-31T05:23:40Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"As an attempt to come up with a useful mechanism to ensure that\ncertain messages are left untranslated [*], we earlier wrote\nGIT_TEST_GETTEXT_POISON off as a failed experiment.\n\nBut the output from the test helper was easier to use while\ndebugging failed tests, compared to the same test writtein with the\nplain-vanilla \"grep\".  Especially when a test that expects a certain\nstring to appear in the output (e.g. \"this test must fail with this\nmessage\") fails, \"grep message output\" would just silently fail and\nin a &&-chained sequence of commands, it is hard to tell which step\nfailed.  test_i18ngrep explicitly said \"we wanted to see a line that\nmatch this pattern but did not see a hit in this file\".\n\nWhat we have as test_i18ngrep in our tree still retains this verbose\noutput (even though we got rid of the \"poison\" support).  Let's\nrename it to test_grep (because it is no longer about i18n at all)\nand then make test_i18ngrep a thin wrapper around it.  Existing\ncallers of test_i18ngrep can be mechanically rewritten to instead\nuse test_grep over time, but it does not have to be done in this\ncommit.\n\n[Footnote]\n\n * The idea was that human-facing messages are often translated, but\n   there are messages that should never be translated.  We use\n   \"grep\" only for the latter kind of messages, and then run tests\n   in \"poison\" mode that spew garbage for translatable messages.  If\n   such a test run fails, it means these messages tested with \"grep\"\n   were marked for translation by mistake.  test_i18ngrep was to be\n   used for other messages that are to be translated, and was to\n   always \"succeed\" when runing under the \"poison\" mode.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/test-lib-functions.sh | 10 ++++++----\n 1 file changed, 6 insertions(+), 4 deletions(-)\n\ndiff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh\nindex 2f8868caa1..c50bc18861 100644\n--- a/t/test-lib-functions.sh\n+++ b/t/test-lib-functions.sh\n@@ -1208,14 +1208,16 @@ test_cmp_bin () {\n \tcmp \"$@\"\n }\n \n-# Wrapper for grep which used to be used for\n-# GIT_TEST_GETTEXT_POISON=false. Only here as a shim for other\n-# in-flight changes. Should not be used and will be removed soon.\n+# Deprecated - do not use this in new code\n test_i18ngrep () {\n+\ttest_grep \"$@\"\n+}\n+\n+test_grep () {\n \teval \"last_arg=\\${$#}\"\n \n \ttest -f \"$last_arg\" ||\n-\tBUG \"test_i18ngrep requires a file to read as the last parameter\"\n+\tBUG \"test_grep requires a file to read as the last parameter\"\n \n \tif test $# -lt 2 ||\n \t   { test \"x!\" = \"x$1\" && test $# -lt 3 ; }\n-- \n2.42.0-530-g692be87cbb\n\n"},{"id":"484188","messageId":"20231031052330.3762989-3-gitster@pobox.com","threadId":"60431","inReplyTo":"20231031052330.3762989-1-gitster@pobox.com","subject":"[PATCH 2/2] tests: teach callers of test_i18ngrep to use test_grep","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-10-31T05:23:30Z","receivedAt":"2023-10-31T05:23:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"They are equivalents and the former still exists, so as long as the\nonly change this commit makes are to rewrite test_i18ngrep to\ntest_grep, there won't be any new bug, even if there still are\ncallers of test_i18ngrep remaining in the tree, or when merged to\nother topics that add new uses of test_i18ngrep.\n\nThis patch was produced more or less with\n\n    git grep -l -e 'test_i18ngrep ' 't/t[0-9][0-9][0-9][0-9]-*.sh' |\n    xargs perl -p -i -e 's/test_i18ngrep /test_grep /'\n\nand a good way to sanity check the result yourself is to run the\nabove in a checkout of c4603c1c (test framework: further deprecate\ntest_i18ngrep, 2023-10-31) and compare the resulting working tree\ncontents with the result of applying this patch to the same commit.\nYou'll see that test_i18ngrep in a few t/lib-*.sh files corrected,\nin addition to the manual reproduction.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/lib-httpd.sh                               |   2 +-\n t/lib-submodule-update.sh                    |   2 +-\n t/t0001-init.sh                              |  16 +--\n t/t0002-gitfile.sh                           |   4 +-\n t/t0003-attributes.sh                        |   4 +-\n t/t0008-ignores.sh                           |   4 +-\n t/t0012-help.sh                              |  16 +--\n t/t0013-sha1dc.sh                            |   2 +-\n t/t0014-alias.sh                             |   8 +-\n t/t0021-conversion.sh                        |   6 +-\n t/t0028-working-tree-encoding.sh             |  32 ++---\n t/t0040-parse-options.sh                     |   4 +-\n t/t0041-usage.sh                             |  32 ++---\n t/t0061-run-command.sh                       |   6 +-\n t/t0070-fundamental.sh                       |   4 +-\n t/t0091-bugreport.sh                         |   2 +-\n t/t0300-credentials.sh                       |   2 +-\n t/t1060-object-corruption.sh                 |   2 +-\n t/t1091-sparse-checkout-builtin.sh           |  68 ++++-----\n t/t1092-sparse-checkout-compatibility.sh     |   6 +-\n t/t1300-config.sh                            |  44 +++---\n t/t1307-config-blob.sh                       |   2 +-\n t/t1308-config-set.sh                        |  10 +-\n t/t1309-early-config.sh                      |   2 +-\n t/t1310-config-default.sh                    |   4 +-\n t/t1400-update-ref.sh                        |  22 +--\n t/t1404-update-ref-errors.sh                 |   4 +-\n t/t1410-reflog.sh                            |   6 +-\n t/t1416-ref-transaction-hooks.sh             |   2 +-\n t/t1430-bad-ref-name.sh                      |  22 +--\n t/t1450-fsck.sh                              |  80 +++++------\n t/t1506-rev-parse-diagnosis.sh               |  34 ++---\n t/t1512-rev-parse-disambiguation.sh          |   6 +-\n t/t2004-checkout-cache-temp.sh               |   2 +-\n t/t2006-checkout-index-basic.sh              |  14 +-\n t/t2010-checkout-ambiguous.sh                |   4 +-\n t/t2018-checkout-branch.sh                   |   4 +-\n t/t2019-checkout-ambiguous-ref.sh            |   8 +-\n t/t2020-checkout-detach.sh                   |   8 +-\n t/t2024-checkout-dwim.sh                     |   8 +-\n t/t2025-checkout-no-overlay.sh               |   2 +-\n t/t2026-checkout-pathspec-file.sh            |   8 +-\n t/t2027-checkout-track.sh                    |   2 +-\n t/t2030-unresolve-info.sh                    |   2 +-\n t/t2072-restore-pathspec-file.sh             |   8 +-\n t/t2106-update-index-assume-unchanged.sh     |   2 +-\n t/t2107-update-index-basic.sh                |   4 +-\n t/t2203-add-intent.sh                        |   6 +-\n t/t2204-add-ignored.sh                       |   8 +-\n t/t2401-worktree-prune.sh                    |  10 +-\n t/t2402-worktree-list.sh                     |   6 +-\n t/t2403-worktree-move.sh                     |   2 +-\n t/t2406-worktree-repair.sh                   |  24 ++--\n t/t3004-ls-files-basic.sh                    |   4 +-\n t/t3007-ls-files-recurse-submodules.sh       |   4 +-\n t/t3200-branch.sh                            |  18 +--\n t/t3202-show-branch.sh                       |   2 +-\n t/t3206-range-diff.sh                        |  22 +--\n t/t3210-pack-refs.sh                         |   2 +-\n t/t3301-notes.sh                             |   4 +-\n t/t3310-notes-merge-manual-resolve.sh        |  16 +--\n t/t3320-notes-merge-worktrees.sh             |   4 +-\n t/t3321-notes-stripspace.sh                  |   2 +-\n t/t3400-rebase.sh                            |   6 +-\n t/t3402-rebase-merge.sh                      |   2 +-\n t/t3403-rebase-skip.sh                       |  30 ++--\n t/t3404-rebase-interactive.sh                |  38 ++---\n t/t3406-rebase-message.sh                    |  18 +--\n t/t3418-rebase-continue.sh                   |   6 +-\n t/t3431-rebase-fork-point.sh                 |   2 +-\n t/t3501-revert-cherry-pick.sh                |   6 +-\n t/t3507-cherry-pick-conflict.sh              |   8 +-\n t/t3510-cherry-pick-sequence.sh              |   6 +-\n t/t3600-rm.sh                                |   8 +-\n t/t3601-rm-pathspec-file.sh                  |   6 +-\n t/t3700-add.sh                               |   6 +-\n t/t3701-add-interactive.sh                   |   8 +-\n t/t3704-add-pathspec-file.sh                 |  12 +-\n t/t3900-i18n-commit.sh                       |   8 +-\n t/t3901-i18n-patch.sh                        |   2 +-\n t/t3903-stash.sh                             |  10 +-\n t/t3905-stash-include-untracked.sh           |   2 +-\n t/t3909-stash-pathspec-file.sh               |   6 +-\n t/t4001-diff-rename.sh                       |  34 ++---\n t/t4013-diff-various.sh                      |   2 +-\n t/t4014-format-patch.sh                      |  12 +-\n t/t4015-diff-whitespace.sh                   |  20 +--\n t/t4018-diff-funcname.sh                     |  14 +-\n t/t4031-diff-rewrite-binary.sh               |   2 +-\n t/t4047-diff-dirstat.sh                      |  22 +--\n t/t4053-diff-no-index.sh                     |   2 +-\n t/t4055-diff-context.sh                      |   4 +-\n t/t4068-diff-symmetric-merge-base.sh         |  28 ++--\n t/t4115-apply-symlink.sh                     |   2 +-\n t/t4120-apply-popt.sh                        |   4 +-\n t/t4122-apply-symlink-inside.sh              |  14 +-\n t/t4129-apply-samemode.sh                    |   4 +-\n t/t4133-apply-filenames.sh                   |   8 +-\n t/t4150-am.sh                                |   4 +-\n t/t4151-am-abort.sh                          |   2 +-\n t/t4153-am-resume-override-opts.sh           |   2 +-\n t/t4200-rerere.sh                            |   4 +-\n t/t4201-shortlog.sh                          |   2 +-\n t/t4202-log.sh                               |  18 +--\n t/t4203-mailmap.sh                           |   2 +-\n t/t4208-log-magic-pathspec.sh                |   6 +-\n t/t4209-log-pickaxe.sh                       |   4 +-\n t/t4211-line-log.sh                          |   4 +-\n t/t4212-log-corrupt.sh                       |   2 +-\n t/t4256-am-format-flowed.sh                  |   2 +-\n t/t5300-pack-object.sh                       |   4 +-\n t/t5302-pack-index.sh                        |   4 +-\n t/t5304-prune.sh                             |   4 +-\n t/t5310-pack-bitmaps.sh                      |   8 +-\n t/t5318-commit-graph.sh                      |  18 +--\n t/t5319-multi-pack-index.sh                  |  10 +-\n t/t5324-split-commit-graph.sh                |  16 +--\n t/t5331-pack-objects-stdin.sh                |   4 +-\n t/t5411/test-0026-push-options.sh            |   2 +-\n t/t5411/test-0027-push-options--porcelain.sh |   2 +-\n t/t5500-fetch-pack.sh                        |  10 +-\n t/t5504-fetch-receive-strict.sh              |  26 ++--\n t/t5505-remote.sh                            |  22 +--\n t/t5510-fetch.sh                             |   8 +-\n t/t5512-ls-remote.sh                         |   2 +-\n t/t5514-fetch-multiple.sh                    |   4 +-\n t/t5516-fetch-push.sh                        |   8 +-\n t/t5520-pull.sh                              |  34 ++---\n t/t5521-pull-options.sh                      |   2 +-\n t/t5523-push-upstream.sh                     |  12 +-\n t/t5528-push-default.sh                      |   2 +-\n t/t5530-upload-pack-error.sh                 |   4 +-\n t/t5531-deep-submodule-push.sh               |   2 +-\n t/t5534-push-signed.sh                       |   6 +-\n t/t5536-fetch-conflicts.sh                   |   8 +-\n t/t5541-http-push-smart.sh                   |  20 +--\n t/t5545-push-options.sh                      |   2 +-\n t/t5550-http-fetch-dumb.sh                   |   8 +-\n t/t5551-http-fetch-smart.sh                  |   4 +-\n t/t5570-git-daemon.sh                        |  10 +-\n t/t5572-pull-submodule.sh                    |   2 +-\n t/t5573-pull-verify-signatures.sh            |  26 ++--\n t/t5574-fetch-output.sh                      |   4 +-\n t/t5580-unc-paths.sh                         |   2 +-\n t/t5601-clone.sh                             |   6 +-\n t/t5604-clone-reference.sh                   |   2 +-\n t/t5606-clone-options.sh                     |  10 +-\n t/t5607-clone-bundle.sh                      |   4 +-\n t/t5611-clone-config.sh                      |   4 +-\n t/t5616-partial-clone.sh                     |  22 +--\n t/t5701-git-serve.sh                         |   8 +-\n t/t5702-protocol-v2.sh                       |  34 ++---\n t/t5703-upload-pack-ref-in-want.sh           |   4 +-\n t/t5704-protocol-violations.sh               |   4 +-\n t/t5801-remote-helpers.sh                    |   8 +-\n t/t5812-proto-disable-http.sh                |   2 +-\n t/t6001-rev-list-graft.sh                    |   4 +-\n t/t6021-rev-list-exclude-hidden.sh           |   4 +-\n t/t6030-bisect-porcelain.sh                  |  24 ++--\n t/t6040-tracking-info.sh                     |  18 +--\n t/t6050-replace.sh                           |  14 +-\n t/t6102-rev-list-unexpected-objects.sh       |  16 +--\n t/t6112-rev-list-filters-objects.sh          |   2 +-\n t/t6120-describe.sh                          |   2 +-\n t/t6134-pathspec-in-submodule.sh             |   2 +-\n t/t6135-pathspec-with-attrs.sh               |   8 +-\n t/t6136-pathspec-in-bare.sh                  |   8 +-\n t/t6402-merge-rename.sh                      |  16 +--\n t/t6422-merge-rename-corner-cases.sh         |  16 +--\n t/t6423-merge-rename-directories.sh          | 140 +++++++++----------\n t/t6424-merge-unrelated-index-changes.sh     |   6 +-\n t/t6425-merge-rename-delete.sh               |   4 +-\n t/t6426-merge-skip-unneeded-updates.sh       |   2 +-\n t/t6430-merge-recursive.sh                   |   8 +-\n t/t6433-merge-toplevel.sh                    |   4 +-\n t/t6436-merge-overwrite.sh                   |   4 +-\n t/t6437-submodule-merge.sh                   |   2 +-\n t/t6500-gc.sh                                |  14 +-\n t/t7001-mv.sh                                |   4 +-\n t/t7105-reset-patch.sh                       |   6 +-\n t/t7106-reset-unborn-branch.sh               |   2 +-\n t/t7107-reset-pathspec-file.sh               |  10 +-\n t/t7110-reset-merge.sh                       |   6 +-\n t/t7201-co.sh                                |   4 +-\n t/t7300-clean.sh                             |   2 +-\n t/t7400-submodule-basic.sh                   |  64 ++++-----\n t/t7403-submodule-sync.sh                    |   4 +-\n t/t7406-submodule-update.sh                  |   6 +-\n t/t7411-submodule-config.sh                  |   4 +-\n t/t7414-submodule-mistakes.sh                |   8 +-\n t/t7416-submodule-dash-url.sh                |   4 +-\n t/t7417-submodule-path-url.sh                |   4 +-\n t/t7450-bad-git-dotfiles.sh                  |  12 +-\n t/t7500-commit-template-squash-signoff.sh    |   2 +-\n t/t7501-commit-basic-functionality.sh        |   6 +-\n t/t7502-commit-porcelain.sh                  |  32 ++---\n t/t7506-status-submodule.sh                  |  28 ++--\n t/t7507-commit-verbose.sh                    |   4 +-\n t/t7508-status.sh                            |  24 ++--\n t/t7509-commit-authorship.sh                 |   4 +-\n t/t7518-ident-corner-cases.sh                |  10 +-\n t/t7519-status-fsmonitor.sh                  |   6 +-\n t/t7520-ignored-hook-warning.sh              |   8 +-\n t/t7525-status-rename.sh                     |  54 +++----\n t/t7526-commit-pathspec-file.sh              |  14 +-\n t/t7600-merge.sh                             |  30 ++--\n t/t7601-merge-pull-config.sh                 |  50 +++----\n t/t7611-merge-abort.sh                       |   4 +-\n t/t7612-merge-verify-signatures.sh           |  24 ++--\n t/t7703-repack-geometric.sh                  |   4 +-\n t/t7800-difftool.sh                          |   4 +-\n t/t7810-grep.sh                              |   4 +-\n t/t7811-grep-open.sh                         |   2 +-\n t/t7814-grep-recurse-submodules.sh           |   2 +-\n t/t7816-grep-binary-pattern.sh               |   4 +-\n t/t7900-maintenance.sh                       |  24 ++--\n t/t8003-blame-corner-cases.sh                |   2 +-\n t/t8013-blame-ignore-revs.sh                 |   6 +-\n t/t9001-send-email.sh                        |   8 +-\n t/t9300-fast-import.sh                       |  26 ++--\n t/t9800-git-p4-basic.sh                      |  18 +--\n t/t9801-git-p4-branch.sh                     |   2 +-\n t/t9807-git-p4-submit.sh                     |  12 +-\n t/t9815-git-p4-submit-fail.sh                |  12 +-\n 224 files changed, 1190 insertions(+), 1190 deletions(-)\n\ndiff --git a/t/lib-httpd.sh b/t/lib-httpd.sh\nindex 2fb1b2ae56..5fe3c8ab69 100644\n--- a/t/lib-httpd.sh\n+++ b/t/lib-httpd.sh\n@@ -255,7 +255,7 @@ test_http_push_nonff () {\n \t'\n \n \ttest_expect_success 'non-fast-forward push shows help message' '\n-\t\ttest_i18ngrep \"Updates were rejected because\" output\n+\t\ttest_grep \"Updates were rejected because\" output\n \t'\n \n \ttest_expect_${EXPECT_CAS_RESULT} 'force with lease aka cas' '\ndiff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh\nindex 9acb0d5d19..36f767cb74 100644\n--- a/t/lib-submodule-update.sh\n+++ b/t/lib-submodule-update.sh\n@@ -830,7 +830,7 @@ test_submodule_recursing_with_args_common () {\n \t\t\tcd submodule_update &&\n \t\t\tgit branch -t invalid_sub1 origin/invalid_sub1 &&\n \t\t\ttest_must_fail $command invalid_sub1 2>err &&\n-\t\t\ttest_i18ngrep sub1 err &&\n+\t\t\ttest_grep sub1 err &&\n \t\t\ttest_superproject_content origin/add_sub1 &&\n \t\t\ttest_submodule_content sub1 origin/add_sub1\n \t\t)\ndiff --git a/t/t0001-init.sh b/t/t0001-init.sh\nindex 30a6edca1d..2b78e3be47 100755\n--- a/t/t0001-init.sh\n+++ b/t/t0001-init.sh\n@@ -168,8 +168,8 @@ test_expect_success 'reinit' '\n \t\tgit -c init.defaultBranch=initial init >out1 2>err1 &&\n \t\tgit init >out2 2>err2\n \t) &&\n-\ttest_i18ngrep \"Initialized empty\" again/out1 &&\n-\ttest_i18ngrep \"Reinitialized existing\" again/out2 &&\n+\ttest_grep \"Initialized empty\" again/out1 &&\n+\ttest_grep \"Reinitialized existing\" again/out2 &&\n \ttest_must_be_empty again/err1 &&\n \ttest_must_be_empty again/err2\n '\n@@ -332,7 +332,7 @@ test_expect_success 'init with separate gitdir' '\n \n test_expect_success 'explicit bare & --separate-git-dir incompatible' '\n \ttest_must_fail git init --bare --separate-git-dir goop.git bare.git 2>err &&\n-\ttest_i18ngrep \"cannot be used together\" err\n+\ttest_grep \"cannot be used together\" err\n '\n \n test_expect_success 'implicit bare & --separate-git-dir incompatible' '\n@@ -340,7 +340,7 @@ test_expect_success 'implicit bare & --separate-git-dir incompatible' '\n \tmkdir -p bare.git &&\n \ttest_must_fail env GIT_DIR=. \\\n \t\tgit -C bare.git init --separate-git-dir goop.git 2>err &&\n-\ttest_i18ngrep \"incompatible\" err\n+\ttest_grep \"incompatible\" err\n '\n \n test_expect_success 'bare & --separate-git-dir incompatible within worktree' '\n@@ -349,7 +349,7 @@ test_expect_success 'bare & --separate-git-dir incompatible within worktree' '\n \tgit clone --bare . bare.git &&\n \tgit -C bare.git worktree add --detach ../linkwt &&\n \ttest_must_fail git -C linkwt init --separate-git-dir seprepo 2>err &&\n-\ttest_i18ngrep \"incompatible\" err\n+\ttest_grep \"incompatible\" err\n '\n \n test_lazy_prereq GETCWD_IGNORES_PERMS '\n@@ -563,7 +563,7 @@ test_expect_success '--initial-branch' '\n \n \t: re-initializing should not change the branch name &&\n \tgit init --initial-branch=ignore initial-branch-option 2>err &&\n-\ttest_i18ngrep \"ignored --initial-branch\" err &&\n+\ttest_grep \"ignored --initial-branch\" err &&\n \tgit -C initial-branch-option symbolic-ref HEAD >actual &&\n \tgrep hello actual\n '\n@@ -579,7 +579,7 @@ test_expect_success 'advice on unconfigured init.defaultBranch' '\n \tGIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= git -c color.advice=always \\\n \t\tinit unconfigured-default-branch-name 2>err &&\n \ttest_decode_color <err >decoded &&\n-\ttest_i18ngrep \"<YELLOW>hint: \" decoded\n+\ttest_grep \"<YELLOW>hint: \" decoded\n '\n \n test_expect_success 'overridden default main branch name (env)' '\n@@ -592,7 +592,7 @@ test_expect_success 'overridden default main branch name (env)' '\n test_expect_success 'invalid default branch name' '\n \ttest_must_fail env GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=\"with space\" \\\n \t\tgit init initial-branch-invalid 2>err &&\n-\ttest_i18ngrep \"invalid branch name\" err\n+\ttest_grep \"invalid branch name\" err\n '\n \n test_expect_success 'branch -m with the initial branch' '\ndiff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh\nindex e013d38f48..736516cc6a 100755\n--- a/t/t0002-gitfile.sh\n+++ b/t/t0002-gitfile.sh\n@@ -22,13 +22,13 @@ test_expect_success 'initial setup' '\n test_expect_success 'bad setup: invalid .git file format' '\n \techo \"gitdir $REAL\" >.git &&\n \ttest_must_fail git rev-parse 2>.err &&\n-\ttest_i18ngrep \"invalid gitfile format\" .err\n+\ttest_grep \"invalid gitfile format\" .err\n '\n \n test_expect_success 'bad setup: invalid .git file path' '\n \techo \"gitdir: $REAL.not\" >.git &&\n \ttest_must_fail git rev-parse 2>.err &&\n-\ttest_i18ngrep \"not a git repository\" .err\n+\ttest_grep \"not a git repository\" .err\n '\n \n test_expect_success 'final setup + check rev-parse --git-dir' '\ndiff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh\nindex 26e082f05b..42695e143d 100755\n--- a/t/t0003-attributes.sh\n+++ b/t/t0003-attributes.sh\n@@ -259,7 +259,7 @@ test_expect_success 'root subdir attribute test' '\n test_expect_success 'negative patterns' '\n \techo \"!f test=bar\" >.gitattributes &&\n \tgit check-attr test -- '\"'\"'!f'\"'\"' 2>errors &&\n-\ttest_i18ngrep \"Negative patterns are ignored\" errors\n+\ttest_grep \"Negative patterns are ignored\" errors\n '\n \n test_expect_success 'patterns starting with exclamation' '\n@@ -424,7 +424,7 @@ test_expect_success SYMLINKS 'symlinks not respected in-tree' '\n \tmkdir subdir &&\n \tln -s ../attr subdir/.gitattributes &&\n \tattr_check_basic subdir/file unspecified &&\n-\ttest_i18ngrep \"unable to access.*gitattributes\" err\n+\ttest_grep \"unable to access.*gitattributes\" err\n '\n \n test_expect_success 'large attributes line ignored in tree' '\ndiff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh\nindex c70d11bc91..361446b2f4 100755\n--- a/t/t0008-ignores.sh\n+++ b/t/t0008-ignores.sh\n@@ -49,7 +49,7 @@ broken_c_unquote_verbose () {\n \n stderr_contains () {\n \tregexp=\"$1\"\n-\tif test_i18ngrep \"$regexp\" \"$HOME/stderr\"\n+\tif test_grep \"$regexp\" \"$HOME/stderr\"\n \tthen\n \t\treturn 0\n \telse\n@@ -942,7 +942,7 @@ test_expect_success SYMLINKS 'symlinks not respected in-tree' '\n \tln -s ignore subdir/.gitignore &&\n \ttest_must_fail git check-ignore subdir/file >actual 2>err &&\n \ttest_must_be_empty actual &&\n-\ttest_i18ngrep \"unable to access.*gitignore\" err\n+\ttest_grep \"unable to access.*gitignore\" err\n '\n \n test_done\ndiff --git a/t/t0012-help.sh b/t/t0012-help.sh\nindex dbfc5c8267..1d273d91c2 100755\n--- a/t/t0012-help.sh\n+++ b/t/t0012-help.sh\n@@ -100,17 +100,17 @@ test_expect_success \"--help does not work for guides\" \"\n \n test_expect_success 'git help' '\n \tgit help >help.output &&\n-\ttest_i18ngrep \"^   clone  \" help.output &&\n-\ttest_i18ngrep \"^   add    \" help.output &&\n-\ttest_i18ngrep \"^   log    \" help.output &&\n-\ttest_i18ngrep \"^   commit \" help.output &&\n-\ttest_i18ngrep \"^   fetch  \" help.output\n+\ttest_grep \"^   clone  \" help.output &&\n+\ttest_grep \"^   add    \" help.output &&\n+\ttest_grep \"^   log    \" help.output &&\n+\ttest_grep \"^   commit \" help.output &&\n+\ttest_grep \"^   fetch  \" help.output\n '\n \n test_expect_success 'git help -g' '\n \tgit help -g >help.output &&\n-\ttest_i18ngrep \"^   everyday   \" help.output &&\n-\ttest_i18ngrep \"^   tutorial   \" help.output\n+\ttest_grep \"^   everyday   \" help.output &&\n+\ttest_grep \"^   tutorial   \" help.output\n '\n \n test_expect_success 'git help fails for non-existing html pages' '\n@@ -257,7 +257,7 @@ do\n \t\t\texport GIT_CEILING_DIRECTORIES &&\n \t\t\ttest_expect_code 129 git -C sub $builtin -h >output 2>&1\n \t\t) &&\n-\t\ttest_i18ngrep usage output\n+\t\ttest_grep usage output\n \t'\n done <builtins\n \ndiff --git a/t/t0013-sha1dc.sh b/t/t0013-sha1dc.sh\nindex 5324047689..08814173cb 100755\n--- a/t/t0013-sha1dc.sh\n+++ b/t/t0013-sha1dc.sh\n@@ -16,7 +16,7 @@ fi\n \n test_expect_success 'test-sha1 detects shattered pdf' '\n \ttest_must_fail test-tool sha1 <\"$TEST_DATA/shattered-1.pdf\" 2>err &&\n-\ttest_i18ngrep collision err &&\n+\ttest_grep collision err &&\n \tgrep 38762cf7f55934b34d179ae6a4c80cadccbb7f0a err\n '\n \ndiff --git a/t/t0014-alias.sh b/t/t0014-alias.sh\nindex 8d3d9144c0..95568342be 100755\n--- a/t/t0014-alias.sh\n+++ b/t/t0014-alias.sh\n@@ -8,7 +8,7 @@ test_expect_success 'nested aliases - internal execution' '\n \tgit config alias.nested-internal-1 nested-internal-2 &&\n \tgit config alias.nested-internal-2 status &&\n \tgit nested-internal-1 >output &&\n-\ttest_i18ngrep \"^On branch \" output\n+\ttest_grep \"^On branch \" output\n '\n \n test_expect_success 'nested aliases - mixed execution' '\n@@ -16,7 +16,7 @@ test_expect_success 'nested aliases - mixed execution' '\n \tgit config alias.nested-external-2 \"!git nested-external-3\" &&\n \tgit config alias.nested-external-3 status &&\n \tgit nested-external-1 >output &&\n-\ttest_i18ngrep \"^On branch \" output\n+\ttest_grep \"^On branch \" output\n '\n \n test_expect_success 'looping aliases - internal execution' '\n@@ -24,7 +24,7 @@ test_expect_success 'looping aliases - internal execution' '\n \tgit config alias.loop-internal-2 loop-internal-3 &&\n \tgit config alias.loop-internal-3 loop-internal-2 &&\n \ttest_must_fail git loop-internal-1 2>output &&\n-\ttest_i18ngrep \"^fatal: alias loop detected: expansion of\" output\n+\ttest_grep \"^fatal: alias loop detected: expansion of\" output\n '\n \n # This test is disabled until external loops are fixed, because would block\n@@ -34,7 +34,7 @@ test_expect_success 'looping aliases - internal execution' '\n #\tgit config alias.loop-mixed-1 loop-mixed-2 &&\n #\tgit config alias.loop-mixed-2 \"!git loop-mixed-1\" &&\n #\ttest_must_fail git loop-mixed-1 2>output &&\n-#\ttest_i18ngrep \"^fatal: alias loop detected: expansion of\" output\n+#\ttest_grep \"^fatal: alias loop detected: expansion of\" output\n #'\n \n test_expect_success 'run-command formats empty args properly' '\ndiff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh\nindex 46abbeed68..0b4997022b 100755\n--- a/t/t0021-conversion.sh\n+++ b/t/t0021-conversion.sh\n@@ -263,7 +263,7 @@ test_expect_success 'required filter with absent clean field' '\n \n \techo test >test.ac &&\n \ttest_must_fail git add test.ac 2>stderr &&\n-\ttest_i18ngrep \"fatal: test.ac: clean filter .absentclean. failed\" stderr\n+\ttest_grep \"fatal: test.ac: clean filter .absentclean. failed\" stderr\n '\n \n test_expect_success 'required filter with absent smudge field' '\n@@ -276,7 +276,7 @@ test_expect_success 'required filter with absent smudge field' '\n \tgit add test.as &&\n \trm -f test.as &&\n \ttest_must_fail git checkout -- test.as 2>stderr &&\n-\ttest_i18ngrep \"fatal: test.as: smudge filter absentsmudge failed\" stderr\n+\ttest_grep \"fatal: test.as: smudge filter absentsmudge failed\" stderr\n '\n \n test_expect_success 'filtering large input to small output should use little memory' '\n@@ -733,7 +733,7 @@ test_expect_success 'process filter should restart after unexpected write failur\n \t\tgit checkout --quiet --no-progress . 2>git-stderr.log &&\n \n \t\tgrep \"smudge write error\" git-stderr.log &&\n-\t\ttest_i18ngrep \"error: external filter\" git-stderr.log &&\n+\t\ttest_grep \"error: external filter\" git-stderr.log &&\n \n \t\tcat >expected.log <<-EOF &&\n \t\t\tSTART\ndiff --git a/t/t0028-working-tree-encoding.sh b/t/t0028-working-tree-encoding.sh\nindex c196fdb0ee..1b55f59c23 100755\n--- a/t/t0028-working-tree-encoding.sh\n+++ b/t/t0028-working-tree-encoding.sh\n@@ -92,23 +92,23 @@ do\n \t\t# In these cases the BOM is prohibited.\n \t\tcp bebom.utf${i}be.raw bebom.utf${i}be &&\n \t\ttest_must_fail git add bebom.utf${i}be 2>err.out &&\n-\t\ttest_i18ngrep \"fatal: BOM is prohibited .* utf-${i}be\" err.out &&\n-\t\ttest_i18ngrep \"use UTF-${i} as working-tree-encoding\" err.out &&\n+\t\ttest_grep \"fatal: BOM is prohibited .* utf-${i}be\" err.out &&\n+\t\ttest_grep \"use UTF-${i} as working-tree-encoding\" err.out &&\n \n \t\tcp lebom.utf${i}le.raw lebom.utf${i}be &&\n \t\ttest_must_fail git add lebom.utf${i}be 2>err.out &&\n-\t\ttest_i18ngrep \"fatal: BOM is prohibited .* utf-${i}be\" err.out &&\n-\t\ttest_i18ngrep \"use UTF-${i} as working-tree-encoding\" err.out &&\n+\t\ttest_grep \"fatal: BOM is prohibited .* utf-${i}be\" err.out &&\n+\t\ttest_grep \"use UTF-${i} as working-tree-encoding\" err.out &&\n \n \t\tcp bebom.utf${i}be.raw bebom.utf${i}le &&\n \t\ttest_must_fail git add bebom.utf${i}le 2>err.out &&\n-\t\ttest_i18ngrep \"fatal: BOM is prohibited .* utf-${i}LE\" err.out &&\n-\t\ttest_i18ngrep \"use UTF-${i} as working-tree-encoding\" err.out &&\n+\t\ttest_grep \"fatal: BOM is prohibited .* utf-${i}LE\" err.out &&\n+\t\ttest_grep \"use UTF-${i} as working-tree-encoding\" err.out &&\n \n \t\tcp lebom.utf${i}le.raw lebom.utf${i}le &&\n \t\ttest_must_fail git add lebom.utf${i}le 2>err.out &&\n-\t\ttest_i18ngrep \"fatal: BOM is prohibited .* utf-${i}LE\" err.out &&\n-\t\ttest_i18ngrep \"use UTF-${i} as working-tree-encoding\" err.out\n+\t\ttest_grep \"fatal: BOM is prohibited .* utf-${i}LE\" err.out &&\n+\t\ttest_grep \"use UTF-${i} as working-tree-encoding\" err.out\n \t'\n \n \ttest_expect_success \"check required UTF-${i} BOM\" '\n@@ -118,13 +118,13 @@ do\n \n \t\tcp nobom.utf${i}be.raw nobom.utf${i} &&\n \t\ttest_must_fail git add nobom.utf${i} 2>err.out &&\n-\t\ttest_i18ngrep \"fatal: BOM is required .* utf-${i}\" err.out &&\n-\t\ttest_i18ngrep \"use UTF-${i}BE or UTF-${i}LE\" err.out &&\n+\t\ttest_grep \"fatal: BOM is required .* utf-${i}\" err.out &&\n+\t\ttest_grep \"use UTF-${i}BE or UTF-${i}LE\" err.out &&\n \n \t\tcp nobom.utf${i}le.raw nobom.utf${i} &&\n \t\ttest_must_fail git add nobom.utf${i} 2>err.out &&\n-\t\ttest_i18ngrep \"fatal: BOM is required .* utf-${i}\" err.out &&\n-\t\ttest_i18ngrep \"use UTF-${i}BE or UTF-${i}LE\" err.out\n+\t\ttest_grep \"fatal: BOM is required .* utf-${i}\" err.out &&\n+\t\ttest_grep \"use UTF-${i}BE or UTF-${i}LE\" err.out\n \t'\n \n \ttest_expect_success \"eol conversion for UTF-${i} encoded files on checkout\" '\n@@ -169,7 +169,7 @@ test_expect_success 'check unsupported encodings' '\n \techo \"*.set text working-tree-encoding\" >.gitattributes &&\n \tprintf \"set\" >t.set &&\n \ttest_must_fail git add t.set 2>err.out &&\n-\ttest_i18ngrep \"true/false are no valid working-tree-encodings\" err.out &&\n+\ttest_grep \"true/false are no valid working-tree-encodings\" err.out &&\n \n \techo \"*.unset text -working-tree-encoding\" >.gitattributes &&\n \tprintf \"unset\" >t.unset &&\n@@ -182,7 +182,7 @@ test_expect_success 'check unsupported encodings' '\n \techo \"*.garbage text working-tree-encoding=garbage\" >.gitattributes &&\n \tprintf \"garbage\" >t.garbage &&\n \ttest_must_fail git add t.garbage 2>err.out &&\n-\ttest_i18ngrep \"failed to encode\" err.out\n+\ttest_grep \"failed to encode\" err.out\n '\n \n test_expect_success 'error if encoding round trip is not the same during refresh' '\n@@ -201,7 +201,7 @@ test_expect_success 'error if encoding round trip is not the same during refresh\n \tgit update-ref refs/heads/main $COMMIT &&\n \n \ttest_must_fail git checkout HEAD^ 2>err.out &&\n-\ttest_i18ngrep \"error: .* overwritten by checkout:\" err.out\n+\ttest_grep \"error: .* overwritten by checkout:\" err.out\n '\n \n test_expect_success 'error if encoding garbage is already in Git' '\n@@ -217,7 +217,7 @@ test_expect_success 'error if encoding garbage is already in Git' '\n \tgit update-ref refs/heads/main $COMMIT &&\n \n \tgit diff 2>err.out &&\n-\ttest_i18ngrep \"error: BOM is required\" err.out\n+\ttest_grep \"error: BOM is required\" err.out\n '\n \n test_lazy_prereq ICONV_SHIFT_JIS '\ndiff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh\nindex e19a199636..c8cc0fd8d0 100755\n--- a/t/t0040-parse-options.sh\n+++ b/t/t0040-parse-options.sh\n@@ -366,13 +366,13 @@ test_expect_success 'OPT_CMDMODE() works' '\n test_expect_success 'OPT_CMDMODE() detects incompatibility' '\n \ttest_must_fail test-tool parse-options --mode1 --mode2 >output 2>output.err &&\n \ttest_must_be_empty output &&\n-\ttest_i18ngrep \"incompatible with --mode\" output.err\n+\ttest_grep \"incompatible with --mode\" output.err\n '\n \n test_expect_success 'OPT_CMDMODE() detects incompatibility with something else' '\n \ttest_must_fail test-tool parse-options --set23 --mode2 >output 2>output.err &&\n \ttest_must_be_empty output &&\n-\ttest_i18ngrep \"incompatible with something else\" output.err\n+\ttest_grep \"incompatible with something else\" output.err\n '\n \n test_expect_success 'OPT_COUNTUP() with PARSE_OPT_NODASH works' '\ndiff --git a/t/t0041-usage.sh b/t/t0041-usage.sh\nindex 9ea974b0c6..1464294bd1 100755\n--- a/t/t0041-usage.sh\n+++ b/t/t0041-usage.sh\n@@ -21,8 +21,8 @@ test_expect_success 'tag --contains <existent_tag>' '\n test_expect_success 'tag --contains <inexistent_tag>' '\n \ttest_must_fail git tag --contains \"notag\" >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n-\ttest_i18ngrep \"error\" actual.err &&\n-\ttest_i18ngrep ! \"usage\" actual.err\n+\ttest_grep \"error\" actual.err &&\n+\ttest_grep ! \"usage\" actual.err\n '\n \n test_expect_success 'tag --no-contains <existent_tag>' '\n@@ -34,27 +34,27 @@ test_expect_success 'tag --no-contains <existent_tag>' '\n test_expect_success 'tag --no-contains <inexistent_tag>' '\n \ttest_must_fail git tag --no-contains \"notag\" >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n-\ttest_i18ngrep \"error\" actual.err &&\n-\ttest_i18ngrep ! \"usage\" actual.err\n+\ttest_grep \"error\" actual.err &&\n+\ttest_grep ! \"usage\" actual.err\n '\n \n test_expect_success 'tag usage error' '\n \ttest_must_fail git tag --noopt >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n-\ttest_i18ngrep \"usage\" actual.err\n+\ttest_grep \"usage\" actual.err\n '\n \n test_expect_success 'branch --contains <existent_commit>' '\n \tgit branch --contains \"main\" >actual 2>actual.err &&\n-\ttest_i18ngrep \"main\" actual &&\n+\ttest_grep \"main\" actual &&\n \ttest_line_count = 0 actual.err\n '\n \n test_expect_success 'branch --contains <inexistent_commit>' '\n \ttest_must_fail git branch --no-contains \"nocommit\" >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n-\ttest_i18ngrep \"error\" actual.err &&\n-\ttest_i18ngrep ! \"usage\" actual.err\n+\ttest_grep \"error\" actual.err &&\n+\ttest_grep ! \"usage\" actual.err\n '\n \n test_expect_success 'branch --no-contains <existent_commit>' '\n@@ -66,14 +66,14 @@ test_expect_success 'branch --no-contains <existent_commit>' '\n test_expect_success 'branch --no-contains <inexistent_commit>' '\n \ttest_must_fail git branch --no-contains \"nocommit\" >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n-\ttest_i18ngrep \"error\" actual.err &&\n-\ttest_i18ngrep ! \"usage\" actual.err\n+\ttest_grep \"error\" actual.err &&\n+\ttest_grep ! \"usage\" actual.err\n '\n \n test_expect_success 'branch usage error' '\n \ttest_must_fail git branch --noopt >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n-\ttest_i18ngrep \"usage\" actual.err\n+\ttest_grep \"usage\" actual.err\n '\n \n test_expect_success 'for-each-ref --contains <existent_object>' '\n@@ -85,8 +85,8 @@ test_expect_success 'for-each-ref --contains <existent_object>' '\n test_expect_success 'for-each-ref --contains <inexistent_object>' '\n \ttest_must_fail git for-each-ref --no-contains \"noobject\" >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n-\ttest_i18ngrep \"error\" actual.err &&\n-\ttest_i18ngrep ! \"usage\" actual.err\n+\ttest_grep \"error\" actual.err &&\n+\ttest_grep ! \"usage\" actual.err\n '\n \n test_expect_success 'for-each-ref --no-contains <existent_object>' '\n@@ -98,14 +98,14 @@ test_expect_success 'for-each-ref --no-contains <existent_object>' '\n test_expect_success 'for-each-ref --no-contains <inexistent_object>' '\n \ttest_must_fail git for-each-ref --no-contains \"noobject\" >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n-\ttest_i18ngrep \"error\" actual.err &&\n-\ttest_i18ngrep ! \"usage\" actual.err\n+\ttest_grep \"error\" actual.err &&\n+\ttest_grep ! \"usage\" actual.err\n '\n \n test_expect_success 'for-each-ref usage error' '\n \ttest_must_fail git for-each-ref --noopt >actual 2>actual.err &&\n \ttest_line_count = 0 actual &&\n-\ttest_i18ngrep \"usage\" actual.err\n+\ttest_grep \"usage\" actual.err\n '\n \n test_done\ndiff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh\nindex e2411f6a9b..20986b693c 100755\n--- a/t/t0061-run-command.sh\n+++ b/t/t0061-run-command.sh\n@@ -19,12 +19,12 @@ test_expect_success MINGW 'subprocess inherits only std handles' '\n \n test_expect_success 'start_command reports ENOENT (slash)' '\n \ttest-tool run-command start-command-ENOENT ./does-not-exist 2>err &&\n-\ttest_i18ngrep \"\\./does-not-exist\" err\n+\ttest_grep \"\\./does-not-exist\" err\n '\n \n test_expect_success 'start_command reports ENOENT (no slash)' '\n \ttest-tool run-command start-command-ENOENT does-not-exist 2>err &&\n-\ttest_i18ngrep \"does-not-exist\" err\n+\ttest_grep \"does-not-exist\" err\n '\n \n test_expect_success 'run_command can run a command' '\n@@ -49,7 +49,7 @@ test_expect_success !RUNS_COMMANDS_FROM_PWD 'run_command is restricted to PATH'\n \techo yikes\n \tEOF\n \ttest_must_fail test-tool run-command run-command should-not-run 2>err &&\n-\ttest_i18ngrep \"should-not-run\" err\n+\ttest_grep \"should-not-run\" err\n '\n \n test_expect_success !MINGW 'run_command can run a script without a #! line' '\ndiff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh\nindex 574de34198..487bc8d905 100755\n--- a/t/t0070-fundamental.sh\n+++ b/t/t0070-fundamental.sh\n@@ -44,13 +44,13 @@ test_expect_success 'incomplete sideband messages are reassembled' '\n test_expect_success 'eof on sideband message is reported' '\n \tprintf 1234 >input &&\n \ttest-tool pkt-line receive-sideband <input 2>err &&\n-\ttest_i18ngrep \"unexpected disconnect\" err\n+\ttest_grep \"unexpected disconnect\" err\n '\n \n test_expect_success 'missing sideband designator is reported' '\n \tprintf 0004 >input &&\n \ttest-tool pkt-line receive-sideband <input 2>err &&\n-\ttest_i18ngrep \"missing sideband\" err\n+\ttest_grep \"missing sideband\" err\n '\n \n test_done\ndiff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh\nindex f6998269be..150cc1dea2 100755\n--- a/t/t0091-bugreport.sh\n+++ b/t/t0091-bugreport.sh\n@@ -65,7 +65,7 @@ test_expect_success '--output-directory puts the report in the provided dir' '\n \n test_expect_success 'incorrect arguments abort with usage' '\n \ttest_must_fail git bugreport --false 2>output &&\n-\ttest_i18ngrep usage output &&\n+\ttest_grep usage output &&\n \ttest_path_is_missing git-bugreport-*\n '\n \ndiff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh\nindex a4f5bba507..400f6bdbca 100755\n--- a/t/t0300-credentials.sh\n+++ b/t/t0300-credentials.sh\n@@ -827,7 +827,7 @@ test_expect_success 'credential config with partial URLs' '\n \tgit -c credential.$partial.helper=yep \\\n \t\t-c credential.with%0anewline.username=uh-oh \\\n \t\tcredential fill <stdin 2>stderr &&\n-\ttest_i18ngrep \"skipping credential lookup for key\" stderr\n+\ttest_grep \"skipping credential lookup for key\" stderr\n '\n \n test_done\ndiff --git a/t/t1060-object-corruption.sh b/t/t1060-object-corruption.sh\nindex 35261afc9d..5e0f0a334f 100755\n--- a/t/t1060-object-corruption.sh\n+++ b/t/t1060-object-corruption.sh\n@@ -125,7 +125,7 @@ test_expect_success 'fetch into corrupted repo with index-pack' '\n \t\tcd bit-error-cp &&\n \t\ttest_must_fail git -c transfer.unpackLimit=1 \\\n \t\t\tfetch ../no-bit-error 2>stderr &&\n-\t\ttest_i18ngrep ! -i collision stderr\n+\t\ttest_grep ! -i collision stderr\n \t)\n '\n \ndiff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh\nindex 9ceb17f911..f67611da28 100755\n--- a/t/t1091-sparse-checkout-builtin.sh\n+++ b/t/t1091-sparse-checkout-builtin.sh\n@@ -47,7 +47,7 @@ test_expect_success 'setup' '\n test_expect_success 'git sparse-checkout list (not sparse)' '\n \ttest_must_fail git -C repo sparse-checkout list >list 2>err &&\n \ttest_must_be_empty list &&\n-\ttest_i18ngrep \"this worktree is not sparse\" err\n+\ttest_grep \"this worktree is not sparse\" err\n '\n \n test_expect_success 'git sparse-checkout list (not sparse)' '\n@@ -55,7 +55,7 @@ test_expect_success 'git sparse-checkout list (not sparse)' '\n \trm repo/.git/info/sparse-checkout &&\n \tgit -C repo sparse-checkout list >list 2>err &&\n \ttest_must_be_empty list &&\n-\ttest_i18ngrep \"this worktree is not sparse (sparse-checkout file may not exist)\" err\n+\ttest_grep \"this worktree is not sparse (sparse-checkout file may not exist)\" err\n '\n \n test_expect_success 'git sparse-checkout list (populated)' '\n@@ -230,7 +230,7 @@ test_expect_success 'cone mode: match patterns' '\n \tgit -C repo config --worktree core.sparseCheckoutCone true &&\n \trm -rf repo/a repo/folder1 repo/folder2 &&\n \tgit -C repo read-tree -mu HEAD 2>err &&\n-\ttest_i18ngrep ! \"disabling cone patterns\" err &&\n+\ttest_grep ! \"disabling cone patterns\" err &&\n \tgit -C repo reset --hard &&\n \tcheck_files repo a folder1 folder2\n '\n@@ -240,7 +240,7 @@ test_expect_success 'cone mode: warn on bad pattern' '\n \tcp repo/.git/info/sparse-checkout . &&\n \techo \"!/deep/deeper/*/\" >>repo/.git/info/sparse-checkout &&\n \tgit -C repo read-tree -mu HEAD 2>err &&\n-\ttest_i18ngrep \"unrecognized negative pattern\" err\n+\ttest_grep \"unrecognized negative pattern\" err\n '\n \n test_expect_success 'sparse-checkout disable' '\n@@ -283,7 +283,7 @@ test_expect_success 'sparse-index enabled and disabled' '\n test_expect_success 'cone mode: init and set' '\n \tgit -C repo sparse-checkout init --cone &&\n \tgit -C repo config --list >config &&\n-\ttest_i18ngrep \"core.sparsecheckoutcone=true\" config &&\n+\ttest_grep \"core.sparsecheckoutcone=true\" config &&\n \tlist_files repo >dir  &&\n \techo a >expect &&\n \ttest_cmp expect dir &&\n@@ -386,7 +386,7 @@ test_expect_success 'not-up-to-date does not block rest of sparsification' '\n \n \tgit -C repo sparse-checkout set deep/deeper1 2>err &&\n \n-\ttest_i18ngrep \"The following paths are not up to date\" err &&\n+\ttest_grep \"The following paths are not up to date\" err &&\n \ttest_cmp expect repo/.git/info/sparse-checkout &&\n \tcheck_files repo/deep a deeper1 deeper2 &&\n \tcheck_files repo/deep/deeper1 a deepest &&\n@@ -401,8 +401,8 @@ test_expect_success 'revert to old sparse-checkout on empty update' '\n \t\tgit add file &&\n \t\tgit commit -m \"test\" &&\n \t\tgit sparse-checkout set nothing 2>err &&\n-\t\ttest_i18ngrep ! \"Sparse checkout leaves no entry on working directory\" err &&\n-\t\ttest_i18ngrep ! \".git/index.lock\" err &&\n+\t\ttest_grep ! \"Sparse checkout leaves no entry on working directory\" err &&\n+\t\ttest_grep ! \".git/index.lock\" err &&\n \t\tgit sparse-checkout set --no-cone file\n \t)\n '\n@@ -411,14 +411,14 @@ test_expect_success 'fail when lock is taken' '\n \ttest_when_finished rm -rf repo/.git/info/sparse-checkout.lock &&\n \ttouch repo/.git/info/sparse-checkout.lock &&\n \ttest_must_fail git -C repo sparse-checkout set deep 2>err &&\n-\ttest_i18ngrep \"Unable to create .*\\.lock\" err\n+\ttest_grep \"Unable to create .*\\.lock\" err\n '\n \n test_expect_success '.gitignore should not warn about cone mode' '\n \tgit -C repo config --worktree core.sparseCheckoutCone true &&\n \techo \"**/bin/*\" >repo/.gitignore &&\n \tgit -C repo reset --hard 2>err &&\n-\ttest_i18ngrep ! \"disabling cone patterns\" err\n+\ttest_grep ! \"disabling cone patterns\" err\n '\n \n test_expect_success 'sparse-checkout (init|set|disable) warns with dirty status' '\n@@ -426,10 +426,10 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with dirty status'\n \techo dirty >dirty/folder1/a &&\n \n \tgit -C dirty sparse-checkout init --no-cone 2>err &&\n-\ttest_i18ngrep \"warning.*The following paths are not up to date\" err &&\n+\ttest_grep \"warning.*The following paths are not up to date\" err &&\n \n \tgit -C dirty sparse-checkout set /folder2/* /deep/deeper1/* 2>err &&\n-\ttest_i18ngrep \"warning.*The following paths are not up to date\" err &&\n+\ttest_grep \"warning.*The following paths are not up to date\" err &&\n \ttest_path_is_file dirty/folder1/a &&\n \n \tgit -C dirty sparse-checkout disable 2>err &&\n@@ -453,14 +453,14 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with unmerged stat\n \tgit -C unmerged update-index --index-info <input &&\n \n \tgit -C unmerged sparse-checkout init --no-cone 2>err &&\n-\ttest_i18ngrep \"warning.*The following paths are unmerged\" err &&\n+\ttest_grep \"warning.*The following paths are unmerged\" err &&\n \n \tgit -C unmerged sparse-checkout set /folder2/* /deep/deeper1/* 2>err &&\n-\ttest_i18ngrep \"warning.*The following paths are unmerged\" err &&\n+\ttest_grep \"warning.*The following paths are unmerged\" err &&\n \ttest_path_is_file dirty/folder1/a &&\n \n \tgit -C unmerged sparse-checkout disable 2>err &&\n-\ttest_i18ngrep \"warning.*The following paths are unmerged\" err &&\n+\ttest_grep \"warning.*The following paths are unmerged\" err &&\n \n \tgit -C unmerged reset --hard &&\n \tgit -C unmerged sparse-checkout init --no-cone &&\n@@ -480,24 +480,24 @@ test_expect_failure 'sparse-checkout reapply' '\n \tgit -C tweak update-index --index-info <input &&\n \n \tgit -C tweak sparse-checkout init --cone 2>err &&\n-\ttest_i18ngrep \"warning.*The following paths are not up to date\" err &&\n-\ttest_i18ngrep \"warning.*The following paths are unmerged\" err &&\n+\ttest_grep \"warning.*The following paths are not up to date\" err &&\n+\ttest_grep \"warning.*The following paths are unmerged\" err &&\n \n \tgit -C tweak sparse-checkout set folder2 deep/deeper1 2>err &&\n-\ttest_i18ngrep \"warning.*The following paths are not up to date\" err &&\n-\ttest_i18ngrep \"warning.*The following paths are unmerged\" err &&\n+\ttest_grep \"warning.*The following paths are not up to date\" err &&\n+\ttest_grep \"warning.*The following paths are unmerged\" err &&\n \n \tgit -C tweak sparse-checkout reapply 2>err &&\n-\ttest_i18ngrep \"warning.*The following paths are not up to date\" err &&\n+\ttest_grep \"warning.*The following paths are not up to date\" err &&\n \ttest_path_is_file tweak/deep/deeper2/a &&\n-\ttest_i18ngrep \"warning.*The following paths are unmerged\" err &&\n+\ttest_grep \"warning.*The following paths are unmerged\" err &&\n \ttest_path_is_file tweak/folder1/a &&\n \n \tgit -C tweak checkout HEAD deep/deeper2/a &&\n \tgit -C tweak sparse-checkout reapply 2>err &&\n-\ttest_i18ngrep ! \"warning.*The following paths are not up to date\" err &&\n+\ttest_grep ! \"warning.*The following paths are not up to date\" err &&\n \ttest_path_is_missing tweak/deep/deeper2/a &&\n-\ttest_i18ngrep \"warning.*The following paths are unmerged\" err &&\n+\ttest_grep \"warning.*The following paths are unmerged\" err &&\n \ttest_path_is_file tweak/folder1/a &&\n \n \t# NEEDSWORK: We are asking to update a file outside of the\n@@ -578,8 +578,8 @@ test_expect_success 'check-rules interaction with submodules' '\n \tgit -C super ls-tree --name-only -r HEAD >all-files &&\n \tgit -C super sparse-checkout check-rules >check-rules-matches <all-files &&\n \n-\ttest_i18ngrep ! \"modules/\" check-rules-matches &&\n-\ttest_i18ngrep \"folder1/\" check-rules-matches\n+\ttest_grep ! \"modules/\" check-rules-matches &&\n+\ttest_grep \"folder1/\" check-rules-matches\n '\n \n test_expect_success 'different sparse-checkouts with worktrees' '\n@@ -616,7 +616,7 @@ check_read_tree_errors () {\n \tthen\n \t\ttest_must_be_empty err\n \telse\n-\t\ttest_i18ngrep \"$ERRORS\" err\n+\t\ttest_grep \"$ERRORS\" err\n \tfi &&\n \tcheck_files $REPO $FILES\n }\n@@ -898,32 +898,32 @@ test_expect_success 'setup bare repo' '\n '\n test_expect_success 'list fails outside work tree' '\n \ttest_must_fail git -C bare sparse-checkout list 2>err &&\n-\ttest_i18ngrep \"this operation must be run in a work tree\" err\n+\ttest_grep \"this operation must be run in a work tree\" err\n '\n \n test_expect_success 'add fails outside work tree' '\n \ttest_must_fail git -C bare sparse-checkout add deeper 2>err &&\n-\ttest_i18ngrep \"this operation must be run in a work tree\" err\n+\ttest_grep \"this operation must be run in a work tree\" err\n '\n \n test_expect_success 'set fails outside work tree' '\n \ttest_must_fail git -C bare sparse-checkout set deeper 2>err &&\n-\ttest_i18ngrep \"this operation must be run in a work tree\" err\n+\ttest_grep \"this operation must be run in a work tree\" err\n '\n \n test_expect_success 'init fails outside work tree' '\n \ttest_must_fail git -C bare sparse-checkout init 2>err &&\n-\ttest_i18ngrep \"this operation must be run in a work tree\" err\n+\ttest_grep \"this operation must be run in a work tree\" err\n '\n \n test_expect_success 'reapply fails outside work tree' '\n \ttest_must_fail git -C bare sparse-checkout reapply 2>err &&\n-\ttest_i18ngrep \"this operation must be run in a work tree\" err\n+\ttest_grep \"this operation must be run in a work tree\" err\n '\n \n test_expect_success 'disable fails outside work tree' '\n \ttest_must_fail git -C bare sparse-checkout disable 2>err &&\n-\ttest_i18ngrep \"this operation must be run in a work tree\" err\n+\ttest_grep \"this operation must be run in a work tree\" err\n '\n \n test_expect_success 'setup clean' '\n@@ -946,8 +946,8 @@ test_expect_success 'check-rules cone mode' '\n \n \tgit -C repo sparse-checkout check-rules >check-rules-default <all-files &&\n \n-\ttest_i18ngrep \"deep/deeper1/deepest/a\" check-rules-file &&\n-\ttest_i18ngrep ! \"deep/deeper2\" check-rules-file &&\n+\ttest_grep \"deep/deeper1/deepest/a\" check-rules-file &&\n+\ttest_grep ! \"deep/deeper2\" check-rules-file &&\n \n \ttest_cmp check-rules-file ls-files &&\n \ttest_cmp check-rules-file check-rules-default\ndiff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh\nindex 8a95adf4b5..12e971b1d1 100755\n--- a/t/t1092-sparse-checkout-compatibility.sh\n+++ b/t/t1092-sparse-checkout-compatibility.sh\n@@ -337,8 +337,8 @@ test_expect_success 'status reports sparse-checkout' '\n \tinit_repos &&\n \tgit -C sparse-checkout status >full &&\n \tgit -C sparse-index status >sparse &&\n-\ttest_i18ngrep \"You are in a sparse checkout with \" full &&\n-\ttest_i18ngrep \"You are in a sparse checkout.\" sparse\n+\ttest_grep \"You are in a sparse checkout with \" full &&\n+\ttest_grep \"You are in a sparse checkout.\" sparse\n '\n \n test_expect_success 'add, commit, checkout' '\n@@ -1182,7 +1182,7 @@ test_expect_success 'checkout-index outside sparse definition' '\n \t# Without --ignore-skip-worktree-bits, outside-of-cone files will trigger\n \t# an error\n \ttest_sparse_match test_must_fail git checkout-index -- folder1/a &&\n-\ttest_i18ngrep \"folder1/a has skip-worktree enabled\" sparse-checkout-err &&\n+\ttest_grep \"folder1/a has skip-worktree enabled\" sparse-checkout-err &&\n \ttest_path_is_missing folder1/a &&\n \n \t# With --ignore-skip-worktree-bits, outside-of-cone files are checked out\ndiff --git a/t/t1300-config.sh b/t/t1300-config.sh\nindex 387d336c91..f4e2752134 100755\n--- a/t/t1300-config.sh\n+++ b/t/t1300-config.sh\n@@ -453,7 +453,7 @@ test_expect_success 'get bool variable with empty value' '\n \n test_expect_success 'no arguments, but no crash' '\n \ttest_must_fail git config >output 2>&1 &&\n-\ttest_i18ngrep usage output\n+\ttest_grep usage output\n '\n \n cat > .git/config << EOF\n@@ -720,25 +720,25 @@ test_expect_success 'invalid unit' '\n \tgit config aninvalid.unit \"1auto\" &&\n \ttest_cmp_config 1auto aninvalid.unit &&\n \ttest_must_fail git config --int --get aninvalid.unit 2>actual &&\n-\ttest_i18ngrep \"bad numeric config value .1auto. for .aninvalid.unit. in file .git/config: invalid unit\" actual\n+\ttest_grep \"bad numeric config value .1auto. for .aninvalid.unit. in file .git/config: invalid unit\" actual\n '\n \n test_expect_success 'invalid unit boolean' '\n \tgit config commit.gpgsign \"1true\" &&\n \ttest_cmp_config 1true commit.gpgsign &&\n \ttest_must_fail git config --bool --get commit.gpgsign 2>actual &&\n-\ttest_i18ngrep \"bad boolean config value .1true. for .commit.gpgsign.\" actual\n+\ttest_grep \"bad boolean config value .1true. for .commit.gpgsign.\" actual\n '\n \n test_expect_success 'line number is reported correctly' '\n \tprintf \"[bool]\\n\\tvar\\n\" >invalid &&\n \ttest_must_fail git config -f invalid --path bool.var 2>actual &&\n-\ttest_i18ngrep \"line 2\" actual\n+\ttest_grep \"line 2\" actual\n '\n \n test_expect_success 'invalid stdin config' '\n \techo \"[broken\" | test_must_fail git config --list --file - >output 2>&1 &&\n-\ttest_i18ngrep \"bad config line 1 in standard input\" output\n+\ttest_grep \"bad config line 1 in standard input\" output\n '\n \n cat > expect << EOF\n@@ -919,7 +919,7 @@ test_expect_success !MINGW 'get --path copes with unset $HOME' '\n \t\tgit config --get --path path.normal >>result &&\n \t\tgit config --get --path path.trailingtilde >>result\n \t) &&\n-\ttest_i18ngrep \"[Ff]ailed to expand.*~/\" msg &&\n+\ttest_grep \"[Ff]ailed to expand.*~/\" msg &&\n \ttest_cmp expect result\n '\n \n@@ -986,7 +986,7 @@ test_expect_success 'get --type=color barfs on non-color' '\n \n test_expect_success 'set --type=color barfs on non-color' '\n \ttest_must_fail git config --type=color foo.color \"not-a-color\" 2>error &&\n-\ttest_i18ngrep \"cannot parse color\" error\n+\ttest_grep \"cannot parse color\" error\n '\n \n cat > expect << EOF\n@@ -1447,12 +1447,12 @@ test_expect_success 'git --config-env with missing value' '\n \n test_expect_success 'git --config-env fails with invalid parameters' '\n \ttest_must_fail git --config-env=foo.flag config --bool foo.flag 2>error &&\n-\ttest_i18ngrep \"invalid config format: foo.flag\" error &&\n+\ttest_grep \"invalid config format: foo.flag\" error &&\n \ttest_must_fail git --config-env=foo.flag= config --bool foo.flag 2>error &&\n-\ttest_i18ngrep \"missing environment variable name for configuration ${SQ}foo.flag${SQ}\" error &&\n+\ttest_grep \"missing environment variable name for configuration ${SQ}foo.flag${SQ}\" error &&\n \tsane_unset NONEXISTENT &&\n \ttest_must_fail git --config-env=foo.flag=NONEXISTENT config --bool foo.flag 2>error &&\n-\ttest_i18ngrep \"missing environment variable ${SQ}NONEXISTENT${SQ} for configuration ${SQ}foo.flag${SQ}\" error\n+\ttest_grep \"missing environment variable ${SQ}NONEXISTENT${SQ} for configuration ${SQ}foo.flag${SQ}\" error\n '\n \n test_expect_success 'git -c and --config-env work together' '\n@@ -1533,21 +1533,21 @@ test_expect_success 'git config ignores pairs with empty count' '\n \n test_expect_success 'git config fails with invalid count' '\n \ttest_must_fail env GIT_CONFIG_COUNT=10a git config --list 2>error &&\n-\ttest_i18ngrep \"bogus count\" error &&\n+\ttest_grep \"bogus count\" error &&\n \ttest_must_fail env GIT_CONFIG_COUNT=9999999999999999 git config --list 2>error &&\n-\ttest_i18ngrep \"too many entries\" error\n+\ttest_grep \"too many entries\" error\n '\n \n test_expect_success 'git config fails with missing config key' '\n \ttest_must_fail env GIT_CONFIG_COUNT=1 GIT_CONFIG_VALUE_0=\"value\" \\\n \t\tgit config --list 2>error &&\n-\ttest_i18ngrep \"missing config key\" error\n+\ttest_grep \"missing config key\" error\n '\n \n test_expect_success 'git config fails with missing config value' '\n \ttest_must_fail env GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=\"pair.one\" \\\n \t\tgit config --list 2>error &&\n-\ttest_i18ngrep \"missing config value\" error\n+\ttest_grep \"missing config value\" error\n '\n \n test_expect_success 'git config fails with invalid config pair key' '\n@@ -1617,7 +1617,7 @@ test_expect_success 'barf on syntax error' '\n \tkey garbage\n \tEOF\n \ttest_must_fail git config --get section.key 2>error &&\n-\ttest_i18ngrep \" line 3 \" error\n+\ttest_grep \" line 3 \" error\n '\n \n test_expect_success 'barf on incomplete section header' '\n@@ -1627,7 +1627,7 @@ test_expect_success 'barf on incomplete section header' '\n \tkey = value\n \tEOF\n \ttest_must_fail git config --get section.key 2>error &&\n-\ttest_i18ngrep \" line 2 \" error\n+\ttest_grep \" line 2 \" error\n '\n \n test_expect_success 'barf on incomplete string' '\n@@ -1637,7 +1637,7 @@ test_expect_success 'barf on incomplete string' '\n \tkey = \"value string\n \tEOF\n \ttest_must_fail git config --get section.key 2>error &&\n-\ttest_i18ngrep \" line 3 \" error\n+\ttest_grep \" line 3 \" error\n '\n \n test_expect_success 'urlmatch' '\n@@ -2266,17 +2266,17 @@ test_expect_success 'identical mixed --type specifiers are allowed' '\n \n test_expect_success 'non-identical modern --type specifiers are not allowed' '\n \ttest_must_fail git config --type=int --type=bool section.big 2>error &&\n-\ttest_i18ngrep \"only one type at a time\" error\n+\ttest_grep \"only one type at a time\" error\n '\n \n test_expect_success 'non-identical legacy --type specifiers are not allowed' '\n \ttest_must_fail git config --int --bool section.big 2>error &&\n-\ttest_i18ngrep \"only one type at a time\" error\n+\ttest_grep \"only one type at a time\" error\n '\n \n test_expect_success 'non-identical mixed --type specifiers are not allowed' '\n \ttest_must_fail git config --type=int --bool section.big 2>error &&\n-\ttest_i18ngrep \"only one type at a time\" error\n+\ttest_grep \"only one type at a time\" error\n '\n \n test_expect_success '--type allows valid type specifiers' '\n@@ -2293,7 +2293,7 @@ test_expect_success 'unset type specifiers may be reset to conflicting ones' '\n \n test_expect_success '--type rejects unknown specifiers' '\n \ttest_must_fail git config --type=nonsense section.foo 2>error &&\n-\ttest_i18ngrep \"unrecognized --type argument\" error\n+\ttest_grep \"unrecognized --type argument\" error\n '\n \n test_expect_success '--type=int requires at least one digit' '\n@@ -2339,7 +2339,7 @@ test_expect_success 'set all config with value-pattern' '\n \n \t# multiple matches => failure\n \ttest_must_fail git config --file=config abc.key three o+ 2>err &&\n-\ttest_i18ngrep \"has multiple values\" err &&\n+\ttest_grep \"has multiple values\" err &&\n \n \t# multiple values, no match => add\n \tgit config --file=config abc.key three a+ &&\ndiff --git a/t/t1307-config-blob.sh b/t/t1307-config-blob.sh\nindex 0a7099d6f5..b9852fe40e 100755\n--- a/t/t1307-config-blob.sh\n+++ b/t/t1307-config-blob.sh\n@@ -63,7 +63,7 @@ test_expect_success 'parse errors in blobs are properly attributed' '\n \tgit commit -m broken &&\n \n \ttest_must_fail git config --blob=HEAD:config some.value 2>err &&\n-\ttest_i18ngrep \"HEAD:config\" err\n+\ttest_grep \"HEAD:config\" err\n '\n \n test_expect_success 'can parse blob ending with CR' '\ndiff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh\nindex 777648722c..3bfec07f1a 100755\n--- a/t/t1308-config-set.sh\n+++ b/t/t1308-config-set.sh\n@@ -172,7 +172,7 @@ test_expect_success 'find string value for a key' '\n \n test_expect_success 'check line error when NULL string is queried' '\n \ttest_expect_code 128 test-tool config get_string case.foo 2>result &&\n-\ttest_i18ngrep \"fatal: .*case\\.foo.*\\.git/config.*line 7\" result\n+\ttest_grep \"fatal: .*case\\.foo.*\\.git/config.*line 7\" result\n '\n \n test_expect_success 'find integer if value is non parse-able' '\n@@ -342,14 +342,14 @@ test_expect_success 'check line errors for malformed values' '\n \t\tbr\n \tEOF\n \ttest_expect_code 128 git br 2>result &&\n-\ttest_i18ngrep \"missing value for .alias\\.br\" result &&\n-\ttest_i18ngrep \"fatal: .*\\.git/config\" result &&\n-\ttest_i18ngrep \"fatal: .*line 2\" result\n+\ttest_grep \"missing value for .alias\\.br\" result &&\n+\ttest_grep \"fatal: .*\\.git/config\" result &&\n+\ttest_grep \"fatal: .*line 2\" result\n '\n \n test_expect_success 'error on modifying repo config without repo' '\n \tnongit test_must_fail git config a.b c 2>err &&\n-\ttest_i18ngrep \"not in a git directory\" err\n+\ttest_grep \"not in a git directory\" err\n '\n \n cmdline_config=\"'foo.bar=from-cmdline'\"\ndiff --git a/t/t1309-early-config.sh b/t/t1309-early-config.sh\nindex 537435b90a..523aa99a1e 100755\n--- a/t/t1309-early-config.sh\n+++ b/t/t1309-early-config.sh\n@@ -78,7 +78,7 @@ test_with_config () {\n \n test_expect_success 'ignore .git/ with incompatible repository version' '\n \ttest_with_config \"[core]repositoryformatversion = 999999\" 2>err &&\n-\ttest_i18ngrep \"warning:.* Expected git repo version <= [1-9]\" err\n+\ttest_grep \"warning:.* Expected git repo version <= [1-9]\" err\n '\n \n test_expect_failure 'ignore .git/ with invalid repository version' '\ndiff --git a/t/t1310-config-default.sh b/t/t1310-config-default.sh\nindex 09b10c144b..1a90d31201 100755\n--- a/t/t1310-config-default.sh\n+++ b/t/t1310-config-default.sh\n@@ -26,12 +26,12 @@ test_expect_success 'canonicalizes --default with appropriate type' '\n test_expect_success 'dies when --default cannot be parsed' '\n \ttest_must_fail git config -f config --type=expiry-date --default=x --get \\\n \t\tnot.a.section 2>error &&\n-\ttest_i18ngrep \"failed to format default config value\" error\n+\ttest_grep \"failed to format default config value\" error\n '\n \n test_expect_success 'does not allow --default without --get' '\n \ttest_must_fail git config --default=quux --unset a.section >output 2>&1 &&\n-\ttest_i18ngrep \"\\-\\-default is only applicable to\" output\n+\ttest_grep \"\\-\\-default is only applicable to\" output\n '\n \n test_done\ndiff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh\nindex 4d66cd7f4a..9ac4b7036b 100755\n--- a/t/t1400-update-ref.sh\n+++ b/t/t1400-update-ref.sh\n@@ -410,7 +410,7 @@ test_expect_success 'Query \"main@{2005-05-26 23:33:01}\" (middle of history with\n \tgit rev-parse --verify \"main@{2005-05-26 23:33:01}\" >o 2>e &&\n \techo \"$B\" >expect &&\n \ttest_cmp expect o &&\n-\ttest_i18ngrep -F \"warning: log for ref $m has gap after $gd\" e\n+\ttest_grep -F \"warning: log for ref $m has gap after $gd\" e\n '\n test_expect_success 'Query \"main@{2005-05-26 23:38:00}\" (middle of history)' '\n \ttest_when_finished \"rm -f o e\" &&\n@@ -431,7 +431,7 @@ test_expect_success 'Query \"main@{2005-05-28}\" (past end of history)' '\n \tgit rev-parse --verify \"main@{2005-05-28}\" >o 2>e &&\n \techo \"$D\" >expect &&\n \ttest_cmp expect o &&\n-\ttest_i18ngrep -F \"warning: log for ref $m unexpectedly ended on $ld\" e\n+\ttest_grep -F \"warning: log for ref $m unexpectedly ended on $ld\" e\n '\n \n rm -f .git/$m .git/logs/$m expect\n@@ -486,7 +486,7 @@ test_expect_success 'git cat-file blob main@{2005-05-26 23:42}:F (expect OTHER)'\n test_expect_success 'given old value for missing pseudoref, do not create' '\n \ttest_must_fail git update-ref PSEUDOREF $A $B 2>err &&\n \ttest_must_fail git rev-parse PSEUDOREF &&\n-\ttest_i18ngrep \"unable to resolve reference\" err\n+\ttest_grep \"unable to resolve reference\" err\n '\n \n test_expect_success 'create pseudoref' '\n@@ -507,7 +507,7 @@ test_expect_success 'overwrite pseudoref with correct old value' '\n test_expect_success 'do not overwrite pseudoref with wrong old value' '\n \ttest_must_fail git update-ref PSEUDOREF $D $E 2>err &&\n \ttest $C = $(git rev-parse PSEUDOREF) &&\n-\ttest_i18ngrep \"cannot lock ref.*expected\" err\n+\ttest_grep \"cannot lock ref.*expected\" err\n '\n \n test_expect_success 'delete pseudoref' '\n@@ -519,7 +519,7 @@ test_expect_success 'do not delete pseudoref with wrong old value' '\n \tgit update-ref PSEUDOREF $A &&\n \ttest_must_fail git update-ref -d PSEUDOREF $B 2>err &&\n \ttest $A = $(git rev-parse PSEUDOREF) &&\n-\ttest_i18ngrep \"cannot lock ref.*expected\" err\n+\ttest_grep \"cannot lock ref.*expected\" err\n '\n \n test_expect_success 'delete pseudoref with correct old value' '\n@@ -536,7 +536,7 @@ test_expect_success 'do not overwrite pseudoref with old OID zero' '\n \ttest_when_finished git update-ref -d PSEUDOREF &&\n \ttest_must_fail git update-ref PSEUDOREF $B $Z 2>err &&\n \ttest $A = $(git rev-parse PSEUDOREF) &&\n-\ttest_i18ngrep \"already exists\" err\n+\ttest_grep \"already exists\" err\n '\n \n # Test --stdin\n@@ -556,7 +556,7 @@ test_expect_success 'stdin test setup' '\n \n test_expect_success '-z fails without --stdin' '\n \ttest_must_fail git update-ref -z $m $m $m 2>err &&\n-\ttest_i18ngrep \"usage: git update-ref\" err\n+\ttest_grep \"usage: git update-ref\" err\n '\n \n test_expect_success 'stdin works with no input' '\n@@ -674,7 +674,7 @@ test_expect_success 'stdin fails with duplicate refs' '\n \tcreate $a $m\n \tEOF\n \ttest_must_fail git update-ref --stdin <stdin 2>err &&\n-\ttest_i18ngrep \"fatal: multiple updates for ref '\"'\"'$a'\"'\"' not allowed\" err\n+\ttest_grep \"fatal: multiple updates for ref '\"'\"'$a'\"'\"' not allowed\" err\n '\n \n test_expect_success 'stdin create ref works' '\n@@ -1107,7 +1107,7 @@ test_expect_success 'stdin -z fails option with unknown name' '\n test_expect_success 'stdin -z fails with duplicate refs' '\n \tprintf $F \"create $a\" \"$m\" \"create $b\" \"$m\" \"create $a\" \"$m\" >stdin &&\n \ttest_must_fail git update-ref -z --stdin <stdin 2>err &&\n-\ttest_i18ngrep \"fatal: multiple updates for ref '\"'\"'$a'\"'\"' not allowed\" err\n+\ttest_grep \"fatal: multiple updates for ref '\"'\"'$a'\"'\"' not allowed\" err\n '\n \n test_expect_success 'stdin -z create ref works' '\n@@ -1338,7 +1338,7 @@ test_expect_success 'fails with duplicate HEAD update' '\n \tupdate HEAD $B\n \tEOF\n \ttest_must_fail git update-ref --stdin <stdin 2>err &&\n-\ttest_i18ngrep \"fatal: multiple updates for '\\''HEAD'\\'' (including one via its referent .refs/heads/target1.) are not allowed\" err &&\n+\ttest_grep \"fatal: multiple updates for '\\''HEAD'\\'' (including one via its referent .refs/heads/target1.) are not allowed\" err &&\n \techo \"refs/heads/target1\" >expect &&\n \tgit symbolic-ref HEAD >actual &&\n \ttest_cmp expect actual &&\n@@ -1355,7 +1355,7 @@ test_expect_success 'fails with duplicate ref update via symref' '\n \tupdate refs/heads/symref2 $B\n \tEOF\n \ttest_must_fail git update-ref --stdin <stdin 2>err &&\n-\ttest_i18ngrep \"fatal: multiple updates for '\\''refs/heads/target2'\\'' (including one via symref .refs/heads/symref2.) are not allowed\" err &&\n+\ttest_grep \"fatal: multiple updates for '\\''refs/heads/target2'\\'' (including one via symref .refs/heads/symref2.) are not allowed\" err &&\n \techo \"refs/heads/target2\" >expect &&\n \tgit symbolic-ref refs/heads/symref2 >actual &&\n \ttest_cmp expect actual &&\ndiff --git a/t/t1404-update-ref-errors.sh b/t/t1404-update-ref-errors.sh\nindex 937ae0d733..0369beea33 100755\n--- a/t/t1404-update-ref-errors.sh\n+++ b/t/t1404-update-ref-errors.sh\n@@ -29,7 +29,7 @@ test_update_rejected () {\n \tfi &&\n \tprintf \"create $prefix/%s $C\\n\" $create >input &&\n \ttest_must_fail git update-ref --stdin <input 2>output.err &&\n-\ttest_i18ngrep -F \"$error\" output.err &&\n+\ttest_grep -F \"$error\" output.err &&\n \tgit for-each-ref $prefix >actual &&\n \ttest_cmp unchanged actual\n }\n@@ -613,7 +613,7 @@ test_expect_success REFFILES 'delete fails cleanly if packed-refs file is locked\n \ttest_when_finished \"rm -f .git/packed-refs.lock\" &&\n \ttest_must_fail git update-ref -d $prefix/foo >out 2>err &&\n \tgit for-each-ref $prefix >actual &&\n-\ttest_i18ngrep \"Unable to create $SQ.*packed-refs.lock$SQ: \" err &&\n+\ttest_grep \"Unable to create $SQ.*packed-refs.lock$SQ: \" err &&\n \ttest_cmp unchanged actual\n '\n \ndiff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh\nindex 6c45965b1e..e1fc949f9a 100755\n--- a/t/t1410-reflog.sh\n+++ b/t/t1410-reflog.sh\n@@ -29,7 +29,7 @@ check_fsck () {\n \t'')\n \t\ttest_must_be_empty fsck.output ;;\n \t*)\n-\t\ttest_i18ngrep \"$1\" fsck.output ;;\n+\t\ttest_grep \"$1\" fsck.output ;;\n \tesac\n }\n \n@@ -308,9 +308,9 @@ test_expect_success 'git reflog expire unknown reference' '\n \ttest_config gc.reflogexpireunreachable never &&\n \n \ttest_must_fail git reflog expire main@{123} 2>stderr &&\n-\ttest_i18ngrep \"points nowhere\" stderr &&\n+\ttest_grep \"points nowhere\" stderr &&\n \ttest_must_fail git reflog expire does-not-exist 2>stderr &&\n-\ttest_i18ngrep \"points nowhere\" stderr\n+\ttest_grep \"points nowhere\" stderr\n '\n \n test_expect_success 'checkout should not delete log for packed ref' '\ndiff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh\nindex b32ca798f9..2092488090 100755\n--- a/t/t1416-ref-transaction-hooks.sh\n+++ b/t/t1416-ref-transaction-hooks.sh\n@@ -37,7 +37,7 @@ test_expect_success 'hook aborts updating ref in prepared state' '\n \t\tfi\n \tEOF\n \ttest_must_fail git update-ref HEAD POST 2>err &&\n-\ttest_i18ngrep \"ref updates aborted by hook\" err\n+\ttest_grep \"ref updates aborted by hook\" err\n '\n \n test_expect_success 'hook gets all queued updates in prepared state' '\ndiff --git a/t/t1430-bad-ref-name.sh b/t/t1430-bad-ref-name.sh\nindex ff1c967d55..4da539cf50 100755\n--- a/t/t1430-bad-ref-name.sh\n+++ b/t/t1430-bad-ref-name.sh\n@@ -47,7 +47,7 @@ test_expect_success 'git branch shows badly named ref as warning' '\n \ttest-tool ref-store main update-ref msg \"refs/heads/broken...ref\" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&\n \ttest_when_finished \"test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref\" &&\n \tgit branch >output 2>error &&\n-\ttest_i18ngrep -e \"ignoring ref with broken name refs/heads/broken\\.\\.\\.ref\" error &&\n+\ttest_grep -e \"ignoring ref with broken name refs/heads/broken\\.\\.\\.ref\" error &&\n \t! grep -e \"broken\\.\\.\\.ref\" output\n '\n \n@@ -158,7 +158,7 @@ test_expect_success 'rev-parse skips symref pointing to broken name' '\n \tgit rev-parse --verify one >expect &&\n \tgit rev-parse --verify shadow >actual 2>err &&\n \ttest_cmp expect actual &&\n-\ttest_i18ngrep \"ignoring dangling symref refs/tags/shadow\" err\n+\ttest_grep \"ignoring dangling symref refs/tags/shadow\" err\n '\n \n test_expect_success 'for-each-ref emits warnings for broken names' '\n@@ -172,9 +172,9 @@ test_expect_success 'for-each-ref emits warnings for broken names' '\n \t! grep -e \"broken\\.\\.\\.ref\" output &&\n \t! grep -e \"badname\" output &&\n \t! grep -e \"broken\\.\\.\\.symref\" output &&\n-\ttest_i18ngrep \"ignoring ref with broken name refs/heads/broken\\.\\.\\.ref\" error &&\n-\ttest_i18ngrep ! \"ignoring broken ref refs/heads/badname\" error &&\n-\ttest_i18ngrep \"ignoring ref with broken name refs/heads/broken\\.\\.\\.symref\" error\n+\ttest_grep \"ignoring ref with broken name refs/heads/broken\\.\\.\\.ref\" error &&\n+\ttest_grep ! \"ignoring broken ref refs/heads/badname\" error &&\n+\ttest_grep \"ignoring ref with broken name refs/heads/broken\\.\\.\\.symref\" error\n '\n \n test_expect_success 'update-ref -d can delete broken name' '\n@@ -192,7 +192,7 @@ test_expect_success 'branch -d can delete broken name' '\n \ttest-tool ref-store main update-ref msg \"refs/heads/broken...ref\" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION &&\n \ttest_when_finished \"test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref\" &&\n \tgit branch -d broken...ref >output 2>error &&\n-\ttest_i18ngrep \"Deleted branch broken...ref (was broken)\" output &&\n+\ttest_grep \"Deleted branch broken...ref (was broken)\" output &&\n \ttest_must_be_empty error &&\n \tgit branch >output 2>error &&\n \t! grep -e \"broken\\.\\.\\.ref\" error &&\n@@ -218,7 +218,7 @@ test_expect_success 'branch -d can delete symref to broken name' '\n \ttest_when_finished \"test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname\" &&\n \tgit branch -d badname >output 2>error &&\n \ttest_path_is_missing .git/refs/heads/badname &&\n-\ttest_i18ngrep \"Deleted branch badname (was refs/heads/broken\\.\\.\\.ref)\" output &&\n+\ttest_grep \"Deleted branch badname (was refs/heads/broken\\.\\.\\.ref)\" output &&\n \ttest_must_be_empty error\n '\n \n@@ -236,7 +236,7 @@ test_expect_success 'branch -d can delete dangling symref to broken name' '\n \ttest_when_finished \"test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname\" &&\n \tgit branch -d badname >output 2>error &&\n \ttest_path_is_missing .git/refs/heads/badname &&\n-\ttest_i18ngrep \"Deleted branch badname (was refs/heads/broken\\.\\.\\.ref)\" output &&\n+\ttest_grep \"Deleted branch badname (was refs/heads/broken\\.\\.\\.ref)\" output &&\n \ttest_must_be_empty error\n '\n \n@@ -265,7 +265,7 @@ test_expect_success 'branch -d can delete symref with broken name' '\n \ttest_when_finished \"test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref\" &&\n \tgit branch -d broken...symref >output 2>error &&\n \ttest_path_is_missing .git/refs/heads/broken...symref &&\n-\ttest_i18ngrep \"Deleted branch broken...symref (was refs/heads/main)\" output &&\n+\ttest_grep \"Deleted branch broken...symref (was refs/heads/main)\" output &&\n \ttest_must_be_empty error\n '\n \n@@ -283,7 +283,7 @@ test_expect_success 'branch -d can delete dangling symref with broken name' '\n \ttest_when_finished \"test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref\" &&\n \tgit branch -d broken...symref >output 2>error &&\n \ttest_path_is_missing .git/refs/heads/broken...symref &&\n-\ttest_i18ngrep \"Deleted branch broken...symref (was refs/heads/idonotexist)\" output &&\n+\ttest_grep \"Deleted branch broken...symref (was refs/heads/idonotexist)\" output &&\n \ttest_must_be_empty error\n '\n \n@@ -292,7 +292,7 @@ test_expect_success 'update-ref -d cannot delete non-ref in .git dir' '\n \techo precious >expect &&\n \ttest_must_fail git update-ref -d my-private-file >output 2>error &&\n \ttest_must_be_empty output &&\n-\ttest_i18ngrep -e \"refusing to update ref with bad name\" error &&\n+\ttest_grep -e \"refusing to update ref with bad name\" error &&\n \ttest_cmp expect .git/my-private-file\n '\n \ndiff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh\nindex 5805d47eb9..e2b30fb75e 100755\n--- a/t/t1450-fsck.sh\n+++ b/t/t1450-fsck.sh\n@@ -118,7 +118,7 @@ test_expect_success 'branch pointing to non-commit' '\n \tgit rev-parse HEAD^{tree} >.git/refs/heads/invalid &&\n \ttest_when_finished \"git update-ref -d refs/heads/invalid\" &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"not a commit\" out\n+\ttest_grep \"not a commit\" out\n '\n \n test_expect_success 'HEAD link pointing at a funny object' '\n@@ -127,7 +127,7 @@ test_expect_success 'HEAD link pointing at a funny object' '\n \techo $ZERO_OID >.git/HEAD &&\n \t# avoid corrupt/broken HEAD from interfering with repo discovery\n \ttest_must_fail env GIT_DIR=.git git fsck 2>out &&\n-\ttest_i18ngrep \"detached HEAD points\" out\n+\ttest_grep \"detached HEAD points\" out\n '\n \n test_expect_success 'HEAD link pointing at a funny place' '\n@@ -136,7 +136,7 @@ test_expect_success 'HEAD link pointing at a funny place' '\n \techo \"ref: refs/funny/place\" >.git/HEAD &&\n \t# avoid corrupt/broken HEAD from interfering with repo discovery\n \ttest_must_fail env GIT_DIR=.git git fsck 2>out &&\n-\ttest_i18ngrep \"HEAD points to something strange\" out\n+\ttest_grep \"HEAD points to something strange\" out\n '\n \n test_expect_success 'HEAD link pointing at a funny object (from different wt)' '\n@@ -147,7 +147,7 @@ test_expect_success 'HEAD link pointing at a funny object (from different wt)' '\n \techo $ZERO_OID >.git/HEAD &&\n \t# avoid corrupt/broken HEAD from interfering with repo discovery\n \ttest_must_fail git -C wt fsck 2>out &&\n-\ttest_i18ngrep \"main-worktree/HEAD: detached HEAD points\" out\n+\ttest_grep \"main-worktree/HEAD: detached HEAD points\" out\n '\n \n test_expect_success 'other worktree HEAD link pointing at a funny object' '\n@@ -155,7 +155,7 @@ test_expect_success 'other worktree HEAD link pointing at a funny object' '\n \tgit worktree add other &&\n \techo $ZERO_OID >.git/worktrees/other/HEAD &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"worktrees/other/HEAD: detached HEAD points\" out\n+\ttest_grep \"worktrees/other/HEAD: detached HEAD points\" out\n '\n \n test_expect_success 'other worktree HEAD link pointing at missing object' '\n@@ -163,7 +163,7 @@ test_expect_success 'other worktree HEAD link pointing at missing object' '\n \tgit worktree add other &&\n \techo \"Contents missing from repo\" | git hash-object --stdin >.git/worktrees/other/HEAD &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"worktrees/other/HEAD: invalid sha1 pointer\" out\n+\ttest_grep \"worktrees/other/HEAD: invalid sha1 pointer\" out\n '\n \n test_expect_success 'other worktree HEAD link pointing at a funny place' '\n@@ -171,7 +171,7 @@ test_expect_success 'other worktree HEAD link pointing at a funny place' '\n \tgit worktree add other &&\n \techo \"ref: refs/funny/place\" >.git/worktrees/other/HEAD &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"worktrees/other/HEAD points to something strange\" out\n+\ttest_grep \"worktrees/other/HEAD points to something strange\" out\n '\n \n test_expect_success 'commit with multiple signatures is okay' '\n@@ -217,7 +217,7 @@ test_expect_success 'email with embedded > is not okay' '\n \tgit update-ref refs/heads/bogus \"$new\" &&\n \ttest_when_finished \"git update-ref -d refs/heads/bogus\" &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"error in commit $new\" out\n+\ttest_grep \"error in commit $new\" out\n '\n \n test_expect_success 'missing < email delimiter is reported nicely' '\n@@ -228,7 +228,7 @@ test_expect_success 'missing < email delimiter is reported nicely' '\n \tgit update-ref refs/heads/bogus \"$new\" &&\n \ttest_when_finished \"git update-ref -d refs/heads/bogus\" &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"error in commit $new.* - bad name\" out\n+\ttest_grep \"error in commit $new.* - bad name\" out\n '\n \n test_expect_success 'missing email is reported nicely' '\n@@ -239,7 +239,7 @@ test_expect_success 'missing email is reported nicely' '\n \tgit update-ref refs/heads/bogus \"$new\" &&\n \ttest_when_finished \"git update-ref -d refs/heads/bogus\" &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"error in commit $new.* - missing email\" out\n+\ttest_grep \"error in commit $new.* - missing email\" out\n '\n \n test_expect_success '> in name is reported' '\n@@ -250,7 +250,7 @@ test_expect_success '> in name is reported' '\n \tgit update-ref refs/heads/bogus \"$new\" &&\n \ttest_when_finished \"git update-ref -d refs/heads/bogus\" &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"error in commit $new\" out\n+\ttest_grep \"error in commit $new\" out\n '\n \n # date is 2^64 + 1\n@@ -263,7 +263,7 @@ test_expect_success 'integer overflow in timestamps is reported' '\n \tgit update-ref refs/heads/bogus \"$new\" &&\n \ttest_when_finished \"git update-ref -d refs/heads/bogus\" &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"error in commit $new.*integer overflow\" out\n+\ttest_grep \"error in commit $new.*integer overflow\" out\n '\n \n test_expect_success 'commit with NUL in header' '\n@@ -274,7 +274,7 @@ test_expect_success 'commit with NUL in header' '\n \tgit update-ref refs/heads/bogus \"$new\" &&\n \ttest_when_finished \"git update-ref -d refs/heads/bogus\" &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"error in commit $new.*unterminated header: NUL at offset\" out\n+\ttest_grep \"error in commit $new.*unterminated header: NUL at offset\" out\n '\n \n test_expect_success 'tree object with duplicate entries' '\n@@ -295,7 +295,7 @@ test_expect_success 'tree object with duplicate entries' '\n \t\tgit hash-object --literally -w -t tree --stdin\n \t) &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"error in tree .*contains duplicate file entries\" out\n+\ttest_grep \"error in tree .*contains duplicate file entries\" out\n '\n \n check_duplicate_names () {\n@@ -318,8 +318,8 @@ check_duplicate_names () {\n \t\tdone >badtree &&\n \t\tbadtree=$(git mktree <badtree) &&\n \t\ttest_must_fail git fsck 2>out &&\n-\t\ttest_i18ngrep \"$badtree\" out &&\n-\t\ttest_i18ngrep \"error in tree .*contains duplicate file entries\" out\n+\t\ttest_grep \"$badtree\" out &&\n+\t\ttest_grep \"error in tree .*contains duplicate file entries\" out\n \t'\n }\n \n@@ -341,9 +341,9 @@ test_expect_success 'unparseable tree object' '\n \tcommit_sha1=$(git commit-tree $tree_sha1) &&\n \tgit update-ref refs/heads/wrong $commit_sha1 &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"error: empty filename in tree entry\" out &&\n-\ttest_i18ngrep \"$tree_sha1\" out &&\n-\ttest_i18ngrep ! \"fatal: empty filename in tree entry\" out\n+\ttest_grep \"error: empty filename in tree entry\" out &&\n+\ttest_grep \"$tree_sha1\" out &&\n+\ttest_grep ! \"fatal: empty filename in tree entry\" out\n '\n \n test_expect_success 'tree entry with type mismatch' '\n@@ -360,8 +360,8 @@ test_expect_success 'tree entry with type mismatch' '\n \tcommit=$(git commit-tree $tree) &&\n \tgit update-ref refs/heads/type_mismatch $commit &&\n \ttest_must_fail git fsck >out 2>&1 &&\n-\ttest_i18ngrep \"is a blob, not a tree\" out &&\n-\ttest_i18ngrep ! \"dangling blob\" out\n+\ttest_grep \"is a blob, not a tree\" out &&\n+\ttest_grep ! \"dangling blob\" out\n '\n \n test_expect_success 'tree entry with bogus mode' '\n@@ -394,7 +394,7 @@ test_expect_success 'tag pointing to nonexistent' '\n \techo $tag >.git/refs/tags/invalid &&\n \ttest_when_finished \"git update-ref -d refs/tags/invalid\" &&\n \ttest_must_fail git fsck --tags >out &&\n-\ttest_i18ngrep \"broken link\" out\n+\ttest_grep \"broken link\" out\n '\n \n test_expect_success 'tag pointing to something else than its type' '\n@@ -455,7 +455,7 @@ test_expect_success 'tag with bad tagger' '\n \techo $tag >.git/refs/tags/wrong &&\n \ttest_when_finished \"git update-ref -d refs/tags/wrong\" &&\n \ttest_must_fail git fsck --tags 2>out &&\n-\ttest_i18ngrep \"error in tag .*: invalid author/committer\" out\n+\ttest_grep \"error in tag .*: invalid author/committer\" out\n '\n \n test_expect_success 'tag with NUL in header' '\n@@ -474,7 +474,7 @@ test_expect_success 'tag with NUL in header' '\n \techo $tag >.git/refs/tags/wrong &&\n \ttest_when_finished \"git update-ref -d refs/tags/wrong\" &&\n \ttest_must_fail git fsck --tags 2>out &&\n-\ttest_i18ngrep \"error in tag $tag.*unterminated header: NUL at offset\" out\n+\ttest_grep \"error in tag $tag.*unterminated header: NUL at offset\" out\n '\n \n test_expect_success 'cleaned up' '\n@@ -504,7 +504,7 @@ test_expect_success 'rev-list --verify-objects with bad sha1' '\n \ttest_when_finished \"git update-ref -d refs/heads/bogus\" &&\n \n \ttest_might_fail git rev-list --verify-objects refs/heads/bogus >/dev/null 2>out &&\n-\ttest_i18ngrep -q \"error: hash mismatch $(dirname $new)$(test_oid ff_2)\" out\n+\ttest_grep -q \"error: hash mismatch $(dirname $new)$(test_oid ff_2)\" out\n '\n \n # An actual bit corruption is more likely than swapped commits, but\n@@ -575,7 +575,7 @@ test_expect_success 'fsck notices blob entry pointing to null sha1' '\n \t sha=$(printf \"100644 file$_bz$_bzoid\" |\n \t       git hash-object --literally -w --stdin -t tree) &&\n \t  git fsck 2>out &&\n-\t  test_i18ngrep \"warning.*null sha1\" out\n+\t  test_grep \"warning.*null sha1\" out\n \t)\n '\n \n@@ -585,7 +585,7 @@ test_expect_success 'fsck notices submodule entry pointing to null sha1' '\n \t sha=$(printf \"160000 submodule$_bz$_bzoid\" |\n \t       git hash-object --literally -w --stdin -t tree) &&\n \t  git fsck 2>out &&\n-\t  test_i18ngrep \"warning.*null sha1\" out\n+\t  test_grep \"warning.*null sha1\" out\n \t)\n '\n \n@@ -606,7 +606,7 @@ while read name path pretty; do\n \t\t\tprintf \"$mode $type %s\\t%s\" \"$value\" \"$path\" >bad &&\n \t\t\tbad_tree=$(git mktree <bad) &&\n \t\t\tgit fsck 2>out &&\n-\t\t\ttest_i18ngrep \"warning.*tree $bad_tree\" out\n+\t\t\ttest_grep \"warning.*tree $bad_tree\" out\n \t\t)'\n \tdone <<-\\EOF\n \t100644 blob\n@@ -652,9 +652,9 @@ test_expect_success 'NUL in commit' '\n \t\tgit branch bad $(cat name) &&\n \n \t\ttest_must_fail git -c fsck.nulInCommit=error fsck 2>warn.1 &&\n-\t\ttest_i18ngrep nulInCommit warn.1 &&\n+\t\ttest_grep nulInCommit warn.1 &&\n \t\tgit fsck 2>warn.2 &&\n-\t\ttest_i18ngrep nulInCommit warn.2\n+\t\ttest_grep nulInCommit warn.2\n \t)\n '\n \n@@ -774,7 +774,7 @@ test_expect_success 'fsck --name-objects' '\n \t\ttree=$(git rev-parse --verify julius:) &&\n \t\tgit tag -d julius &&\n \t\ttest_must_fail git fsck --name-objects >out &&\n-\t\ttest_i18ngrep \"$tree (refs/tags/augustus44\\\\^:\" out\n+\t\ttest_grep \"$tree (refs/tags/augustus44\\\\^:\" out\n \t)\n '\n \n@@ -787,7 +787,7 @@ test_expect_success 'alternate objects are correctly blamed' '\n \tmkdir alt.git/objects/$(dirname $path) &&\n \t>alt.git/objects/$(dirname $path)/$(basename $path) &&\n \ttest_must_fail git fsck >out 2>&1 &&\n-\ttest_i18ngrep alt.git out\n+\ttest_grep alt.git out\n '\n \n test_expect_success 'fsck errors in packed objects' '\n@@ -806,8 +806,8 @@ test_expect_success 'fsck errors in packed objects' '\n \tremove_object $one &&\n \tremove_object $two &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"error in commit $one.* - bad name\" out &&\n-\ttest_i18ngrep \"error in commit $two.* - bad name\" out &&\n+\ttest_grep \"error in commit $one.* - bad name\" out &&\n+\ttest_grep \"error in commit $two.* - bad name\" out &&\n \t! grep corrupt out\n '\n \n@@ -824,7 +824,7 @@ test_expect_success 'fsck fails on corrupt packfile' '\n \ttest_when_finished \"rm -f .git/objects/pack/pack-$pack.*\" &&\n \tremove_object $hsh &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"checksum mismatch\" out\n+\ttest_grep \"checksum mismatch\" out\n '\n \n test_expect_success 'fsck finds problems in duplicate loose objects' '\n@@ -861,7 +861,7 @@ test_expect_success 'fsck detects trailing loose garbage (commit)' '\n \tchmod +w \"$file\" &&\n \techo garbage >>\"$file\" &&\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep \"garbage.*$commit\" out\n+\ttest_grep \"garbage.*$commit\" out\n '\n \n test_expect_success 'fsck detects trailing loose garbage (large blob)' '\n@@ -871,7 +871,7 @@ test_expect_success 'fsck detects trailing loose garbage (large blob)' '\n \tchmod +w \"$file\" &&\n \techo garbage >>\"$file\" &&\n \ttest_must_fail git -c core.bigfilethreshold=5 fsck 2>out &&\n-\ttest_i18ngrep \"garbage.*$blob\" out\n+\ttest_grep \"garbage.*$blob\" out\n '\n \n test_expect_success 'fsck detects truncated loose object' '\n@@ -887,10 +887,10 @@ test_expect_success 'fsck detects truncated loose object' '\n \n \t# check both regular and streaming code paths\n \ttest_must_fail git fsck 2>out &&\n-\ttest_i18ngrep corrupt.*$blob out &&\n+\ttest_grep corrupt.*$blob out &&\n \n \ttest_must_fail git -c core.bigfilethreshold=128 fsck 2>out &&\n-\ttest_i18ngrep corrupt.*$blob out\n+\ttest_grep corrupt.*$blob out\n '\n \n # for each of type, we have one version which is referenced by another object\n@@ -979,7 +979,7 @@ test_expect_success 'detect corrupt index file in fsck' '\n \ttest_when_finished \"mv .git/index.backup .git/index\" &&\n \tcorrupt_index_checksum &&\n \ttest_must_fail git fsck --cache 2>errors &&\n-\ttest_i18ngrep \"bad index file\" errors\n+\ttest_grep \"bad index file\" errors\n '\n \n test_expect_success 'fsck error and recovery on invalid object type' '\ndiff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh\nindex 18688cae17..ef40511d89 100755\n--- a/t/t1506-rev-parse-diagnosis.sh\n+++ b/t/t1506-rev-parse-diagnosis.sh\n@@ -107,16 +107,16 @@ test_expect_success 'correct relative file objects (6)' '\n \n test_expect_success 'incorrect revision id' '\n \ttest_must_fail git rev-parse foobar:file.txt 2>error &&\n-\ttest_i18ngrep \"invalid object name .foobar.\" error &&\n+\ttest_grep \"invalid object name .foobar.\" error &&\n \ttest_must_fail git rev-parse foobar 2>error &&\n-\ttest_i18ngrep \"unknown revision or path not in the working tree.\" error\n+\ttest_grep \"unknown revision or path not in the working tree.\" error\n '\n \n test_expect_success 'incorrect file in sha1:path' '\n \ttest_must_fail git rev-parse HEAD:nothing.txt 2>error &&\n-\ttest_i18ngrep \"path .nothing.txt. does not exist in .HEAD.\" error &&\n+\ttest_grep \"path .nothing.txt. does not exist in .HEAD.\" error &&\n \ttest_must_fail git rev-parse HEAD:index-only.txt 2>error &&\n-\ttest_i18ngrep \"path .index-only.txt. exists on disk, but not in .HEAD.\" error &&\n+\ttest_grep \"path .index-only.txt. exists on disk, but not in .HEAD.\" error &&\n \t(cd subdir &&\n \t test_must_fail git rev-parse HEAD:file2.txt 2>error &&\n \t test_did_you_mean HEAD subdir/ file2.txt exists )\n@@ -124,9 +124,9 @@ test_expect_success 'incorrect file in sha1:path' '\n \n test_expect_success 'incorrect file in :path and :N:path' '\n \ttest_must_fail git rev-parse :nothing.txt 2>error &&\n-\ttest_i18ngrep \"path .nothing.txt. does not exist (neither on disk nor in the index)\" error &&\n+\ttest_grep \"path .nothing.txt. does not exist (neither on disk nor in the index)\" error &&\n \ttest_must_fail git rev-parse :1:nothing.txt 2>error &&\n-\ttest_i18ngrep \"path .nothing.txt. does not exist (neither on disk nor in the index)\" error &&\n+\ttest_grep \"path .nothing.txt. does not exist (neither on disk nor in the index)\" error &&\n \ttest_must_fail git rev-parse :1:file.txt 2>error &&\n \ttest_did_you_mean \":0\" \"\" file.txt \"is in the index\" \"at stage 1\" &&\n \t(cd subdir &&\n@@ -137,42 +137,42 @@ test_expect_success 'incorrect file in :path and :N:path' '\n \t test_must_fail git rev-parse :2:file2.txt 2>error &&\n \t test_did_you_mean :0 subdir/ file2.txt \"is in the index\") &&\n \ttest_must_fail git rev-parse :disk-only.txt 2>error &&\n-\ttest_i18ngrep \"path .disk-only.txt. exists on disk, but not in the index\" error\n+\ttest_grep \"path .disk-only.txt. exists on disk, but not in the index\" error\n '\n \n test_expect_success 'invalid @{n} reference' '\n \ttest_must_fail git rev-parse main@{99999} >output 2>error &&\n \ttest_must_be_empty output &&\n-\ttest_i18ngrep \"log for [^ ]* only has [0-9][0-9]* entries\" error  &&\n+\ttest_grep \"log for [^ ]* only has [0-9][0-9]* entries\" error  &&\n \ttest_must_fail git rev-parse --verify main@{99999} >output 2>error &&\n \ttest_must_be_empty output &&\n-\ttest_i18ngrep \"log for [^ ]* only has [0-9][0-9]* entries\" error\n+\ttest_grep \"log for [^ ]* only has [0-9][0-9]* entries\" error\n '\n \n test_expect_success 'relative path not found' '\n \t(\n \t\tcd subdir &&\n \t\ttest_must_fail git rev-parse HEAD:./nonexistent.txt 2>error &&\n-\t\ttest_i18ngrep subdir/nonexistent.txt error\n+\t\ttest_grep subdir/nonexistent.txt error\n \t)\n '\n \n test_expect_success 'relative path outside worktree' '\n \ttest_must_fail git rev-parse HEAD:../file.txt >output 2>error &&\n \ttest_must_be_empty output &&\n-\ttest_i18ngrep \"outside repository\" error\n+\ttest_grep \"outside repository\" error\n '\n \n test_expect_success 'relative path when cwd is outside worktree' '\n \ttest_must_fail git --git-dir=.git --work-tree=subdir rev-parse HEAD:./file.txt >output 2>error &&\n \ttest_must_be_empty output &&\n-\ttest_i18ngrep \"relative path syntax can.t be used outside working tree\" error\n+\ttest_grep \"relative path syntax can.t be used outside working tree\" error\n '\n \n test_expect_success '<commit>:file correctly diagnosed after a pathname' '\n \ttest_must_fail git rev-parse file.txt HEAD:file.txt 1>actual 2>error &&\n-\ttest_i18ngrep ! \"exists on disk\" error &&\n-\ttest_i18ngrep \"no such path in the working tree\" error &&\n+\ttest_grep ! \"exists on disk\" error &&\n+\ttest_grep \"no such path in the working tree\" error &&\n \tcat >expect <<-\\EOF &&\n \tfile.txt\n \tHEAD:file.txt\n@@ -214,13 +214,13 @@ test_expect_success 'dotdot does not peel endpoints' '\n \n test_expect_success 'arg before dashdash must be a revision (missing)' '\n \ttest_must_fail git rev-parse foobar -- 2>stderr &&\n-\ttest_i18ngrep \"bad revision\" stderr\n+\ttest_grep \"bad revision\" stderr\n '\n \n test_expect_success 'arg before dashdash must be a revision (file)' '\n \t>foobar &&\n \ttest_must_fail git rev-parse foobar -- 2>stderr &&\n-\ttest_i18ngrep \"bad revision\" stderr\n+\ttest_grep \"bad revision\" stderr\n '\n \n test_expect_success 'arg before dashdash must be a revision (ambiguous)' '\n@@ -269,7 +269,7 @@ test_expect_success 'arg after dashdash not interpreted as option' '\n \n test_expect_success 'arg after end-of-options not interpreted as option' '\n \ttest_must_fail git rev-parse --end-of-options --not-real -- 2>err &&\n-\ttest_i18ngrep bad.revision.*--not-real err\n+\ttest_grep bad.revision.*--not-real err\n '\n \n test_expect_success 'end-of-options still allows --' '\ndiff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh\nindex 98cefe3b70..70f1e0a998 100755\n--- a/t/t1512-rev-parse-disambiguation.sh\n+++ b/t/t1512-rev-parse-disambiguation.sh\n@@ -129,7 +129,7 @@ test_expect_success 'blob and tree' '\n \n test_expect_success 'warn ambiguity when no candidate matches type hint' '\n \ttest_must_fail git rev-parse --verify 000000000^{commit} 2>actual &&\n-\ttest_i18ngrep \"short object ID 000000000 is ambiguous\" actual\n+\ttest_grep \"short object ID 000000000 is ambiguous\" actual\n '\n \n test_expect_success 'disambiguate tree-ish' '\n@@ -470,10 +470,10 @@ test_expect_success 'cat-file --batch and --batch-check show ambiguous' '\n \techo \"0000 ambiguous\" >expect &&\n \techo 0000 | git cat-file --batch-check >actual 2>err &&\n \ttest_cmp expect actual &&\n-\ttest_i18ngrep hint: err &&\n+\ttest_grep hint: err &&\n \techo 0000 | git cat-file --batch >actual 2>err &&\n \ttest_cmp expect actual &&\n-\ttest_i18ngrep hint: err\n+\ttest_grep hint: err\n '\n \n test_done\ndiff --git a/t/t2004-checkout-cache-temp.sh b/t/t2004-checkout-cache-temp.sh\nindex b16d69ca4a..4c0fd856b3 100755\n--- a/t/t2004-checkout-cache-temp.sh\n+++ b/t/t2004-checkout-cache-temp.sh\n@@ -93,7 +93,7 @@ test_expect_success 'checkout all stages of unknown path' '\n \trm -f path* .merge_* actual &&\n \ttest_must_fail git checkout-index --stage=all --temp \\\n \t\t-- does-not-exist 2>stderr &&\n-\ttest_i18ngrep not.in.the.cache stderr\n+\ttest_grep not.in.the.cache stderr\n '\n \n test_expect_success 'checkout all stages/one file to nothing' '\ndiff --git a/t/t2006-checkout-index-basic.sh b/t/t2006-checkout-index-basic.sh\nindex 5d119871d4..570ba38580 100755\n--- a/t/t2006-checkout-index-basic.sh\n+++ b/t/t2006-checkout-index-basic.sh\n@@ -8,7 +8,7 @@ TEST_PASSES_SANITIZE_LEAK=true\n \n test_expect_success 'checkout-index --gobbledegook' '\n \ttest_expect_code 129 git checkout-index --gobbledegook 2>err &&\n-\ttest_i18ngrep \"[Uu]sage\" err\n+\ttest_grep \"[Uu]sage\" err\n '\n \n test_expect_success 'checkout-index -h in broken repository' '\n@@ -19,18 +19,18 @@ test_expect_success 'checkout-index -h in broken repository' '\n \t\t>.git/index &&\n \t\ttest_expect_code 129 git checkout-index -h >usage 2>&1\n \t) &&\n-\ttest_i18ngrep \"[Uu]sage\" broken/usage\n+\ttest_grep \"[Uu]sage\" broken/usage\n '\n \n test_expect_success 'checkout-index reports errors (cmdline)' '\n \ttest_must_fail git checkout-index -- does-not-exist 2>stderr &&\n-\ttest_i18ngrep not.in.the.cache stderr\n+\ttest_grep not.in.the.cache stderr\n '\n \n test_expect_success 'checkout-index reports errors (stdin)' '\n \techo does-not-exist |\n \ttest_must_fail git checkout-index --stdin 2>stderr &&\n-\ttest_i18ngrep not.in.the.cache stderr\n+\ttest_grep not.in.the.cache stderr\n '\n for mode in 'case' 'utf-8'\n do\n@@ -88,8 +88,8 @@ test_expect_success 'checkout-index --temp correctly reports error on missing bl\n \tgit update-index --index-info <objs &&\n \n \ttest_must_fail git checkout-index --temp symlink file 2>stderr &&\n-\ttest_i18ngrep \"unable to read sha1 file of file ($missing_blob)\" stderr &&\n-\ttest_i18ngrep \"unable to read sha1 file of symlink ($missing_blob)\" stderr\n+\ttest_grep \"unable to read sha1 file of file ($missing_blob)\" stderr &&\n+\ttest_grep \"unable to read sha1 file of symlink ($missing_blob)\" stderr\n '\n \n test_expect_success 'checkout-index --temp correctly reports error for submodules' '\n@@ -98,7 +98,7 @@ test_expect_success 'checkout-index --temp correctly reports error for submodule\n \tgit submodule add ./sub &&\n \tgit commit -m sub &&\n \ttest_must_fail git checkout-index --temp sub 2>stderr &&\n-\ttest_i18ngrep \"cannot create temporary submodule sub\" stderr\n+\ttest_grep \"cannot create temporary submodule sub\" stderr\n '\n \n test_done\ndiff --git a/t/t2010-checkout-ambiguous.sh b/t/t2010-checkout-ambiguous.sh\nindex 9d4b37526a..82c3bfeac1 100755\n--- a/t/t2010-checkout-ambiguous.sh\n+++ b/t/t2010-checkout-ambiguous.sh\n@@ -62,8 +62,8 @@ test_expect_success 'disambiguate checking out from a tree-ish' '\n \n test_expect_success 'accurate error message with more than one ref' '\n \ttest_must_fail git checkout HEAD main -- 2>actual &&\n-\ttest_i18ngrep 2 actual &&\n-\ttest_i18ngrep \"one reference expected, 2 given\" actual\n+\ttest_grep 2 actual &&\n+\ttest_grep \"one reference expected, 2 given\" actual\n '\n \n test_done\ndiff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh\nindex 8581ad3437..43551cc148 100755\n--- a/t/t2018-checkout-branch.sh\n+++ b/t/t2018-checkout-branch.sh\n@@ -278,12 +278,12 @@ test_expect_success 'checkout -b to a new branch preserves mergeable changes des\n \n test_expect_success 'checkout -b rejects an invalid start point' '\n \ttest_must_fail git checkout -b branch4 file1 2>err &&\n-\ttest_i18ngrep \"is not a commit\" err\n+\ttest_grep \"is not a commit\" err\n '\n \n test_expect_success 'checkout -b rejects an extra path argument' '\n \ttest_must_fail git checkout -b branch5 branch1 file1 2>err &&\n-\ttest_i18ngrep \"Cannot update paths and switch to branch\" err\n+\ttest_grep \"Cannot update paths and switch to branch\" err\n '\n \n test_done\ndiff --git a/t/t2019-checkout-ambiguous-ref.sh b/t/t2019-checkout-ambiguous-ref.sh\nindex 9540588664..c67261e2b6 100755\n--- a/t/t2019-checkout-ambiguous-ref.sh\n+++ b/t/t2019-checkout-ambiguous-ref.sh\n@@ -32,8 +32,8 @@ test_expect_success 'checkout chooses branch over tag' '\n '\n \n test_expect_success 'checkout reports switch to branch' '\n-\ttest_i18ngrep \"Switched to branch\" stderr &&\n-\ttest_i18ngrep ! \"^HEAD is now at\" stderr\n+\ttest_grep \"Switched to branch\" stderr &&\n+\ttest_grep ! \"^HEAD is now at\" stderr\n '\n \n test_expect_success 'checkout vague ref succeeds' '\n@@ -54,8 +54,8 @@ test_expect_success VAGUENESS_SUCCESS 'checkout chooses branch over tag' '\n '\n \n test_expect_success VAGUENESS_SUCCESS 'checkout reports switch to branch' '\n-\ttest_i18ngrep \"Switched to branch\" stderr &&\n-\ttest_i18ngrep ! \"^HEAD is now at\" stderr\n+\ttest_grep \"Switched to branch\" stderr &&\n+\ttest_grep ! \"^HEAD is now at\" stderr\n '\n \n test_done\ndiff --git a/t/t2020-checkout-detach.sh b/t/t2020-checkout-detach.sh\nindex 2eab6474f8..8202ef8c74 100755\n--- a/t/t2020-checkout-detach.sh\n+++ b/t/t2020-checkout-detach.sh\n@@ -17,12 +17,12 @@ check_not_detached () {\n \n PREV_HEAD_DESC='Previous HEAD position was'\n check_orphan_warning() {\n-\ttest_i18ngrep \"you are leaving $2 behind\" \"$1\" &&\n-\ttest_i18ngrep ! \"$PREV_HEAD_DESC\" \"$1\"\n+\ttest_grep \"you are leaving $2 behind\" \"$1\" &&\n+\ttest_grep ! \"$PREV_HEAD_DESC\" \"$1\"\n }\n check_no_orphan_warning() {\n-\ttest_i18ngrep ! \"you are leaving .* commit.*behind\" \"$1\" &&\n-\ttest_i18ngrep \"$PREV_HEAD_DESC\" \"$1\"\n+\ttest_grep ! \"you are leaving .* commit.*behind\" \"$1\" &&\n+\ttest_grep \"$PREV_HEAD_DESC\" \"$1\"\n }\n \n reset () {\ndiff --git a/t/t2024-checkout-dwim.sh b/t/t2024-checkout-dwim.sh\nindex 74049a9812..a97416ce65 100755\n--- a/t/t2024-checkout-dwim.sh\n+++ b/t/t2024-checkout-dwim.sh\n@@ -93,7 +93,7 @@ test_expect_success 'when arg matches multiple remotes, do not fallback to inter\n \n \ttest_must_fail git checkout ambiguous_branch_and_file 2>err &&\n \n-\ttest_i18ngrep \"matched multiple (2) remote tracking branches\" err &&\n+\ttest_grep \"matched multiple (2) remote tracking branches\" err &&\n \n \t# file must not be altered\n \ttest_cmp expect ambiguous_branch_and_file\n@@ -105,12 +105,12 @@ test_expect_success 'checkout of branch from multiple remotes fails with advice'\n \ttest_must_fail git checkout foo 2>stderr &&\n \ttest_branch main &&\n \tstatus_uno_is_clean &&\n-\ttest_i18ngrep \"^hint: \" stderr &&\n+\ttest_grep \"^hint: \" stderr &&\n \ttest_must_fail git -c advice.checkoutAmbiguousRemoteBranchName=false \\\n \t\tcheckout foo 2>stderr &&\n \ttest_branch main &&\n \tstatus_uno_is_clean &&\n-\ttest_i18ngrep ! \"^hint: \" stderr\n+\ttest_grep ! \"^hint: \" stderr\n '\n \n test_expect_success PERL 'checkout -p with multiple remotes does not print advice' '\n@@ -118,7 +118,7 @@ test_expect_success PERL 'checkout -p with multiple remotes does not print advic\n \ttest_might_fail git branch -D foo &&\n \n \tgit checkout -p foo 2>stderr &&\n-\ttest_i18ngrep ! \"^hint: \" stderr &&\n+\ttest_grep ! \"^hint: \" stderr &&\n \tstatus_uno_is_clean\n '\n \ndiff --git a/t/t2025-checkout-no-overlay.sh b/t/t2025-checkout-no-overlay.sh\nindex 3832c3de81..246609d54d 100755\n--- a/t/t2025-checkout-no-overlay.sh\n+++ b/t/t2025-checkout-no-overlay.sh\n@@ -26,7 +26,7 @@ test_expect_success 'checkout --no-overlay removing last file from directory' '\n \n test_expect_success 'checkout -p --overlay is disallowed' '\n \ttest_must_fail git checkout -p --overlay HEAD 2>actual &&\n-\ttest_i18ngrep \"fatal: options .-p. and .--overlay. cannot be used together\" actual\n+\ttest_grep \"fatal: options .-p. and .--overlay. cannot be used together\" actual\n '\n \n test_expect_success '--no-overlay --theirs with D/F conflict deletes file' '\ndiff --git a/t/t2026-checkout-pathspec-file.sh b/t/t2026-checkout-pathspec-file.sh\nindex 9c651aefbc..acd55217a6 100755\n--- a/t/t2026-checkout-pathspec-file.sh\n+++ b/t/t2026-checkout-pathspec-file.sh\n@@ -149,16 +149,16 @@ test_expect_success 'error conditions' '\n \techo fileA.t >list &&\n \n \ttest_must_fail git checkout --pathspec-from-file=list --detach 2>err &&\n-\ttest_i18ngrep -e \"options .--pathspec-from-file. and .--detach. cannot be used together\" err &&\n+\ttest_grep -e \"options .--pathspec-from-file. and .--detach. cannot be used together\" err &&\n \n \ttest_must_fail git checkout --pathspec-from-file=list --patch 2>err &&\n-\ttest_i18ngrep -e \"options .--pathspec-from-file. and .--patch. cannot be used together\" err &&\n+\ttest_grep -e \"options .--pathspec-from-file. and .--patch. cannot be used together\" err &&\n \n \ttest_must_fail git checkout --pathspec-from-file=list -- fileA.t 2>err &&\n-\ttest_i18ngrep -e \".--pathspec-from-file. and pathspec arguments cannot be used together\" err &&\n+\ttest_grep -e \".--pathspec-from-file. and pathspec arguments cannot be used together\" err &&\n \n \ttest_must_fail git checkout --pathspec-file-nul 2>err &&\n-\ttest_i18ngrep -e \"the option .--pathspec-file-nul. requires .--pathspec-from-file.\" err\n+\ttest_grep -e \"the option .--pathspec-file-nul. requires .--pathspec-from-file.\" err\n '\n \n test_done\ndiff --git a/t/t2027-checkout-track.sh b/t/t2027-checkout-track.sh\nindex a8bbc60954..98f16c7239 100755\n--- a/t/t2027-checkout-track.sh\n+++ b/t/t2027-checkout-track.sh\n@@ -22,7 +22,7 @@ test_expect_success 'checkout --track -b creates a new tracking branch' '\n \n test_expect_success 'checkout --track -b rejects an extra path argument' '\n \ttest_must_fail git checkout --track -b branch2 main one.t 2>err &&\n-\ttest_i18ngrep \"cannot be used with updating paths\" err\n+\ttest_grep \"cannot be used with updating paths\" err\n '\n \n test_expect_success 'checkout --track -b overrides autoSetupMerge=inherit' '\ndiff --git a/t/t2030-unresolve-info.sh b/t/t2030-unresolve-info.sh\nindex 2d8c70b03a..102023ed57 100755\n--- a/t/t2030-unresolve-info.sh\n+++ b/t/t2030-unresolve-info.sh\n@@ -191,7 +191,7 @@ test_expect_success 'rerere forget (add-add conflict)' '\n \tgit commit -m \"add differently\" &&\n \ttest_must_fail git merge fifth &&\n \tgit rerere forget add-differently 2>actual &&\n-\ttest_i18ngrep \"no remembered\" actual\n+\ttest_grep \"no remembered\" actual\n '\n \n test_expect_success 'resolve-undo keeps blobs from gc' '\ndiff --git a/t/t2072-restore-pathspec-file.sh b/t/t2072-restore-pathspec-file.sh\nindex c22669b39f..8198a1e578 100755\n--- a/t/t2072-restore-pathspec-file.sh\n+++ b/t/t2072-restore-pathspec-file.sh\n@@ -152,16 +152,16 @@ test_expect_success 'error conditions' '\n \t>empty_list &&\n \n \ttest_must_fail git restore --pathspec-from-file=list --patch --source=HEAD^1 2>err &&\n-\ttest_i18ngrep -e \"options .--pathspec-from-file. and .--patch. cannot be used together\" err &&\n+\ttest_grep -e \"options .--pathspec-from-file. and .--patch. cannot be used together\" err &&\n \n \ttest_must_fail git restore --pathspec-from-file=list --source=HEAD^1 -- fileA.t 2>err &&\n-\ttest_i18ngrep -e \".--pathspec-from-file. and pathspec arguments cannot be used together\" err &&\n+\ttest_grep -e \".--pathspec-from-file. and pathspec arguments cannot be used together\" err &&\n \n \ttest_must_fail git restore --pathspec-file-nul --source=HEAD^1 2>err &&\n-\ttest_i18ngrep -e \"the option .--pathspec-file-nul. requires .--pathspec-from-file.\" err &&\n+\ttest_grep -e \"the option .--pathspec-file-nul. requires .--pathspec-from-file.\" err &&\n \n \ttest_must_fail git restore --pathspec-from-file=empty_list --source=HEAD^1 2>err &&\n-\ttest_i18ngrep -e \"you must specify path(s) to restore\" err\n+\ttest_grep -e \"you must specify path(s) to restore\" err\n '\n \n test_expect_success 'wildcard pathspec matches file in subdirectory' '\ndiff --git a/t/t2106-update-index-assume-unchanged.sh b/t/t2106-update-index-assume-unchanged.sh\nindex d943ddf47e..95c004dc5c 100755\n--- a/t/t2106-update-index-assume-unchanged.sh\n+++ b/t/t2106-update-index-assume-unchanged.sh\n@@ -22,7 +22,7 @@ test_expect_success 'do not switch branches with dirty file' '\n \techo dirt >file &&\n \tgit update-index --assume-unchanged file &&\n \ttest_must_fail git checkout - 2>err &&\n-\ttest_i18ngrep overwritten err\n+\ttest_grep overwritten err\n '\n \n test_done\ndiff --git a/t/t2107-update-index-basic.sh b/t/t2107-update-index-basic.sh\nindex 89b285fa3a..3d7ca5792e 100755\n--- a/t/t2107-update-index-basic.sh\n+++ b/t/t2107-update-index-basic.sh\n@@ -14,7 +14,7 @@ test_expect_success 'update-index --nonsense fails' '\n \n test_expect_success 'update-index --nonsense dumps usage' '\n \ttest_expect_code 129 git update-index --nonsense 2>err &&\n-\ttest_i18ngrep \"[Uu]sage: git update-index\" err\n+\ttest_grep \"[Uu]sage: git update-index\" err\n '\n \n test_expect_success 'update-index -h with corrupt index' '\n@@ -25,7 +25,7 @@ test_expect_success 'update-index -h with corrupt index' '\n \t\t>.git/index &&\n \t\ttest_expect_code 129 git update-index -h >usage 2>&1\n \t) &&\n-\ttest_i18ngrep \"[Uu]sage: git update-index\" broken/usage\n+\ttest_grep \"[Uu]sage: git update-index\" broken/usage\n '\n \n test_expect_success '--cacheinfo complains of missing arguments' '\ndiff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh\nindex ebf58db2d1..8fa44a92a2 100755\n--- a/t/t2203-add-intent.sh\n+++ b/t/t2203-add-intent.sh\n@@ -173,7 +173,7 @@ test_expect_success 'rename detection finds the right names' '\n \t\tgit add -N third &&\n \n \t\tgit status | grep -v \"^?\" >actual.1 &&\n-\t\ttest_i18ngrep \"renamed: *first -> third\" actual.1 &&\n+\t\ttest_grep \"renamed: *first -> third\" actual.1 &&\n \n \t\tgit status --porcelain | grep -v \"^?\" >actual.2 &&\n \t\tcat >expected.2 <<-\\EOF &&\n@@ -213,8 +213,8 @@ test_expect_success 'double rename detection in status' '\n \t\tgit add -N third &&\n \n \t\tgit status | grep -v \"^?\" >actual.1 &&\n-\t\ttest_i18ngrep \"renamed: *first -> second\" actual.1 &&\n-\t\ttest_i18ngrep \"renamed: *second -> third\" actual.1 &&\n+\t\ttest_grep \"renamed: *first -> second\" actual.1 &&\n+\t\ttest_grep \"renamed: *second -> third\" actual.1 &&\n \n \t\tgit status --porcelain | grep -v \"^?\" >actual.2 &&\n \t\tcat >expected.2 <<-\\EOF &&\ndiff --git a/t/t2204-add-ignored.sh b/t/t2204-add-ignored.sh\nindex 89424abccd..b7cf1e492c 100755\n--- a/t/t2204-add-ignored.sh\n+++ b/t/t2204-add-ignored.sh\n@@ -36,7 +36,7 @@ do\n \t'\n \n \ttest_expect_success \"complaints for ignored $i output\" '\n-\t\ttest_i18ngrep -e \"Use -f if\" err\n+\t\ttest_grep -e \"Use -f if\" err\n \t'\n \n \ttest_expect_success \"complaints for ignored $i with unignored file\" '\n@@ -46,7 +46,7 @@ do\n \t\ttest_must_be_empty out\n \t'\n \ttest_expect_success \"complaints for ignored $i with unignored file output\" '\n-\t\ttest_i18ngrep -e \"Use -f if\" err\n+\t\ttest_grep -e \"Use -f if\" err\n \t'\n done\n \n@@ -65,7 +65,7 @@ do\n \ttest_expect_success \"complaints for ignored $i in dir output\" '\n \t\t(\n \t\t\tcd dir &&\n-\t\t\ttest_i18ngrep -e \"Use -f if\" err\n+\t\t\ttest_grep -e \"Use -f if\" err\n \t\t)\n \t'\n done\n@@ -85,7 +85,7 @@ do\n \ttest_expect_success \"complaints for ignored $i in sub output\" '\n \t\t(\n \t\t\tcd sub &&\n-\t\t\ttest_i18ngrep -e \"Use -f if\" err\n+\t\t\ttest_grep -e \"Use -f if\" err\n \t\t)\n \t'\n done\ndiff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh\nindex 568a47ec42..71aa9bcd62 100755\n--- a/t/t2401-worktree-prune.sh\n+++ b/t/t2401-worktree-prune.sh\n@@ -47,7 +47,7 @@ test_expect_success SANITY 'prune directories with unreadable gitdir' '\n \t: >.git/worktrees/def/gitdir &&\n \tchmod u-r .git/worktrees/def/gitdir &&\n \tgit worktree prune --verbose 2>actual &&\n-\ttest_i18ngrep \"Removing worktrees/def: unable to read gitdir file\" actual &&\n+\ttest_grep \"Removing worktrees/def: unable to read gitdir file\" actual &&\n \t! test -d .git/worktrees/def &&\n \t! test -d .git/worktrees\n '\n@@ -57,7 +57,7 @@ test_expect_success 'prune directories with invalid gitdir' '\n \t: >.git/worktrees/def/def &&\n \t: >.git/worktrees/def/gitdir &&\n \tgit worktree prune --verbose 2>actual &&\n-\ttest_i18ngrep \"Removing worktrees/def: invalid gitdir file\" actual &&\n+\ttest_grep \"Removing worktrees/def: invalid gitdir file\" actual &&\n \t! test -d .git/worktrees/def &&\n \t! test -d .git/worktrees\n '\n@@ -67,7 +67,7 @@ test_expect_success 'prune directories with gitdir pointing to nowhere' '\n \t: >.git/worktrees/def/def &&\n \techo \"$(pwd)\"/nowhere >.git/worktrees/def/gitdir &&\n \tgit worktree prune --verbose 2>actual &&\n-\ttest_i18ngrep \"Removing worktrees/def: gitdir file points to non-existent location\" actual &&\n+\ttest_grep \"Removing worktrees/def: gitdir file points to non-existent location\" actual &&\n \t! test -d .git/worktrees/def &&\n \t! test -d .git/worktrees\n '\n@@ -103,7 +103,7 @@ test_expect_success 'prune duplicate (linked/linked)' '\n \tsed \"s/w2/w1/\" .git/worktrees/w2/gitdir >.git/worktrees/w2/gitdir.new &&\n \tmv .git/worktrees/w2/gitdir.new .git/worktrees/w2/gitdir &&\n \tgit worktree prune --verbose 2>actual &&\n-\ttest_i18ngrep \"duplicate entry\" actual &&\n+\ttest_grep \"duplicate entry\" actual &&\n \ttest -d .git/worktrees/w1 &&\n \t! test -d .git/worktrees/w2\n '\n@@ -116,7 +116,7 @@ test_expect_success 'prune duplicate (main/linked)' '\n \trm -fr wt &&\n \tmv repo wt &&\n \tgit -C wt worktree prune --verbose 2>actual &&\n-\ttest_i18ngrep \"duplicate entry\" actual &&\n+\ttest_grep \"duplicate entry\" actual &&\n \t! test -d .git/worktrees/wt\n '\n \ndiff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh\nindex 9ad9be0c20..33ea9cb21b 100755\n--- a/t/t2402-worktree-list.sh\n+++ b/t/t2402-worktree-list.sh\n@@ -143,7 +143,7 @@ test_expect_success '\"list\" all worktrees --porcelain with prunable' '\n \trm -rf prunable &&\n \tgit worktree list --porcelain >out &&\n \tsed -n \"/^worktree .*\\/prunable$/,/^$/p\" <out >only_prunable &&\n-\ttest_i18ngrep \"^prunable gitdir file points to non-existent location$\" only_prunable\n+\ttest_grep \"^prunable gitdir file points to non-existent location$\" only_prunable\n '\n \n test_expect_success '\"list\" all worktrees with prunable consistent with \"prune\"' '\n@@ -155,8 +155,8 @@ test_expect_success '\"list\" all worktrees with prunable consistent with \"prune\"'\n \tgrep \"/prunable  *[0-9a-f].* prunable$\" out &&\n \t! grep \"/unprunable  *[0-9a-f].* unprunable$\" out &&\n \tgit worktree prune --verbose 2>out &&\n-\ttest_i18ngrep \"^Removing worktrees/prunable\" out &&\n-\ttest_i18ngrep ! \"^Removing worktrees/unprunable\" out\n+\ttest_grep \"^Removing worktrees/prunable\" out &&\n+\ttest_grep ! \"^Removing worktrees/unprunable\" out\n '\n \n test_expect_success '\"list\" --verbose and --porcelain mutually exclusive' '\ndiff --git a/t/t2403-worktree-move.sh b/t/t2403-worktree-move.sh\nindex 230a55e99a..901342ea09 100755\n--- a/t/t2403-worktree-move.sh\n+++ b/t/t2403-worktree-move.sh\n@@ -202,7 +202,7 @@ test_expect_success 'proper error when worktree not found' '\n \tfor i in noodle noodle/bork\n \tdo\n \t\ttest_must_fail git worktree lock $i 2>err &&\n-\t\ttest_i18ngrep \"not a working tree\" err || return 1\n+\t\ttest_grep \"not a working tree\" err || return 1\n \tdone\n '\n \ndiff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh\nindex 8970780efc..edbf502ec5 100755\n--- a/t/t2406-worktree-repair.sh\n+++ b/t/t2406-worktree-repair.sh\n@@ -25,7 +25,7 @@ test_expect_success 'worktree path not directory' '\n \t>notdir &&\n \ttest_must_fail git worktree repair >out 2>err &&\n \ttest_must_be_empty out &&\n-\ttest_i18ngrep \"not a directory\" err\n+\ttest_grep \"not a directory\" err\n '\n \n test_expect_success \"don't clobber .git repo\" '\n@@ -35,7 +35,7 @@ test_expect_success \"don't clobber .git repo\" '\n \ttest_create_repo repo &&\n \ttest_must_fail git worktree repair >out 2>err &&\n \ttest_must_be_empty out &&\n-\ttest_i18ngrep \".git is not a file\" err\n+\ttest_grep \".git is not a file\" err\n '\n \n test_corrupt_gitfile () {\n@@ -47,7 +47,7 @@ test_corrupt_gitfile () {\n \tgit -C corrupt rev-parse --absolute-git-dir >expect &&\n \teval \"$butcher\" &&\n \tgit -C \"$repairdir\" worktree repair 2>err &&\n-\ttest_i18ngrep \"$problem\" err &&\n+\ttest_grep \"$problem\" err &&\n \tgit -C corrupt rev-parse --absolute-git-dir >actual &&\n \ttest_cmp expect actual\n }\n@@ -93,7 +93,7 @@ test_expect_success 'repair .git file from bare.git' '\n test_expect_success 'invalid worktree path' '\n \ttest_must_fail git worktree repair /notvalid >out 2>err &&\n \ttest_must_be_empty out &&\n-\ttest_i18ngrep \"not a valid path\" err\n+\ttest_grep \"not a valid path\" err\n '\n \n test_expect_success 'repo not found; .git not file' '\n@@ -101,7 +101,7 @@ test_expect_success 'repo not found; .git not file' '\n \ttest_create_repo not-a-worktree &&\n \ttest_must_fail git worktree repair not-a-worktree >out 2>err &&\n \ttest_must_be_empty out &&\n-\ttest_i18ngrep \".git is not a file\" err\n+\ttest_grep \".git is not a file\" err\n '\n \n test_expect_success 'repo not found; .git not referencing repo' '\n@@ -111,7 +111,7 @@ test_expect_success 'repo not found; .git not referencing repo' '\n \tmv side/.newgit side/.git &&\n \tmkdir not-a-repo &&\n \ttest_must_fail git worktree repair side 2>err &&\n-\ttest_i18ngrep \".git file does not reference a repository\" err\n+\ttest_grep \".git file does not reference a repository\" err\n '\n \n test_expect_success 'repo not found; .git file broken' '\n@@ -121,7 +121,7 @@ test_expect_success 'repo not found; .git file broken' '\n \tmv orig moved &&\n \ttest_must_fail git worktree repair moved >out 2>err &&\n \ttest_must_be_empty out &&\n-\ttest_i18ngrep \".git file broken\" err\n+\ttest_grep \".git file broken\" err\n '\n \n test_expect_success 'repair broken gitdir' '\n@@ -132,7 +132,7 @@ test_expect_success 'repair broken gitdir' '\n \tmv orig moved &&\n \tgit worktree repair moved 2>err &&\n \ttest_cmp expect .git/worktrees/orig/gitdir &&\n-\ttest_i18ngrep \"gitdir unreadable\" err\n+\ttest_grep \"gitdir unreadable\" err\n '\n \n test_expect_success 'repair incorrect gitdir' '\n@@ -142,7 +142,7 @@ test_expect_success 'repair incorrect gitdir' '\n \tmv orig moved &&\n \tgit worktree repair moved 2>err &&\n \ttest_cmp expect .git/worktrees/orig/gitdir &&\n-\ttest_i18ngrep \"gitdir incorrect\" err\n+\ttest_grep \"gitdir incorrect\" err\n '\n \n test_expect_success 'repair gitdir (implicit) from linked worktree' '\n@@ -152,7 +152,7 @@ test_expect_success 'repair gitdir (implicit) from linked worktree' '\n \tmv orig moved &&\n \tgit -C moved worktree repair 2>err &&\n \ttest_cmp expect .git/worktrees/orig/gitdir &&\n-\ttest_i18ngrep \"gitdir incorrect\" err\n+\ttest_grep \"gitdir incorrect\" err\n '\n \n test_expect_success 'unable to repair gitdir (implicit) from main worktree' '\n@@ -177,8 +177,8 @@ test_expect_success 'repair multiple gitdir files' '\n \tgit worktree repair moved1 moved2 2>err &&\n \ttest_cmp expect1 .git/worktrees/orig1/gitdir &&\n \ttest_cmp expect2 .git/worktrees/orig2/gitdir &&\n-\ttest_i18ngrep \"gitdir incorrect:.*orig1/gitdir$\" err &&\n-\ttest_i18ngrep \"gitdir incorrect:.*orig2/gitdir$\" err\n+\ttest_grep \"gitdir incorrect:.*orig1/gitdir$\" err &&\n+\ttest_grep \"gitdir incorrect:.*orig2/gitdir$\" err\n '\n \n test_expect_success 'repair moved main and linked worktrees' '\ndiff --git a/t/t3004-ls-files-basic.sh b/t/t3004-ls-files-basic.sh\nindex a16e25c79b..12e41a7b40 100755\n--- a/t/t3004-ls-files-basic.sh\n+++ b/t/t3004-ls-files-basic.sh\n@@ -21,7 +21,7 @@ test_expect_success 'ls-files with nonexistent path' '\n \n test_expect_success 'ls-files with nonsense option' '\n \ttest_expect_code 129 git ls-files --nonsense 2>actual &&\n-\ttest_i18ngrep \"[Uu]sage: git ls-files\" actual\n+\ttest_grep \"[Uu]sage: git ls-files\" actual\n '\n \n test_expect_success 'ls-files -h in corrupt repository' '\n@@ -32,7 +32,7 @@ test_expect_success 'ls-files -h in corrupt repository' '\n \t\t>.git/index &&\n \t\ttest_expect_code 129 git ls-files -h >usage 2>&1\n \t) &&\n-\ttest_i18ngrep \"[Uu]sage: git ls-files \" broken/usage\n+\ttest_grep \"[Uu]sage: git ls-files \" broken/usage\n '\n \n test_expect_success SYMLINKS 'ls-files with absolute paths to symlinks' '\ndiff --git a/t/t3007-ls-files-recurse-submodules.sh b/t/t3007-ls-files-recurse-submodules.sh\nindex 7308a3d4e2..61771eec83 100755\n--- a/t/t3007-ls-files-recurse-submodules.sh\n+++ b/t/t3007-ls-files-recurse-submodules.sh\n@@ -296,7 +296,7 @@ test_expect_success '--recurse-submodules and relative paths' '\n \n test_expect_success '--recurse-submodules does not support --error-unmatch' '\n \ttest_must_fail git ls-files --recurse-submodules --error-unmatch 2>actual &&\n-\ttest_i18ngrep \"does not support --error-unmatch\" actual\n+\ttest_grep \"does not support --error-unmatch\" actual\n '\n \n test_expect_success '--recurse-submodules parses submodule repo config' '\n@@ -335,7 +335,7 @@ test_expect_success '--recurse-submodules submodules ignore super project worktr\n test_incompatible_with_recurse_submodules () {\n \ttest_expect_success \"--recurse-submodules and $1 are incompatible\" \"\n \t\ttest_must_fail git ls-files --recurse-submodules $1 2>actual &&\n-\t\ttest_i18ngrep 'unsupported mode' actual\n+\t\ttest_grep 'unsupported mode' actual\n \t\"\n }\n \ndiff --git a/t/t3200-branch.sh b/t/t3200-branch.sh\nindex daf1666df7..649d9dcba5 100755\n--- a/t/t3200-branch.sh\n+++ b/t/t3200-branch.sh\n@@ -36,7 +36,7 @@ test_expect_success 'branch -h in broken repository' '\n \t\t>.git/refs/heads/main &&\n \t\ttest_expect_code 129 git branch -h >usage 2>&1\n \t) &&\n-\ttest_i18ngrep \"[Uu]sage\" broken/usage\n+\ttest_grep \"[Uu]sage\" broken/usage\n '\n \n test_expect_success 'git branch abc should create a branch' '\n@@ -103,7 +103,7 @@ test_expect_success 'git branch l should work after branch l/m has been deleted'\n \n test_expect_success 'git branch -m dumps usage' '\n \ttest_expect_code 128 git branch -m 2>err &&\n-\ttest_i18ngrep \"branch name required\" err\n+\ttest_grep \"branch name required\" err\n '\n \n test_expect_success 'git branch -m m broken_symref should work' '\n@@ -581,12 +581,12 @@ EOF\n \n test_expect_success 'git branch -c dumps usage' '\n \ttest_expect_code 128 git branch -c 2>err &&\n-\ttest_i18ngrep \"branch name required\" err\n+\ttest_grep \"branch name required\" err\n '\n \n test_expect_success 'git branch --copy dumps usage' '\n \ttest_expect_code 128 git branch --copy 2>err &&\n-\ttest_i18ngrep \"branch name required\" err\n+\ttest_grep \"branch name required\" err\n '\n \n test_expect_success 'git branch -c d e should work' '\n@@ -1025,7 +1025,7 @@ test_expect_success '--set-upstream-to fails on a missing dst branch' '\n \n test_expect_success '--set-upstream-to fails on a missing src branch' '\n \ttest_must_fail git branch --set-upstream-to does-not-exist main 2>err &&\n-\ttest_i18ngrep \"the requested upstream branch '\"'\"'does-not-exist'\"'\"' does not exist\" err\n+\ttest_grep \"the requested upstream branch '\"'\"'does-not-exist'\"'\"' does not exist\" err\n '\n \n test_expect_success '--set-upstream-to fails on a non-ref' '\n@@ -1039,7 +1039,7 @@ test_expect_success '--set-upstream-to fails on locked config' '\n \t>.git/config.lock &&\n \tgit branch locked &&\n \ttest_must_fail git branch --set-upstream-to locked 2>err &&\n-\ttest_i18ngrep \"could not lock config file .git/config\" err\n+\ttest_grep \"could not lock config file .git/config\" err\n '\n \n test_expect_success 'use --set-upstream-to modify HEAD' '\n@@ -1070,7 +1070,7 @@ test_expect_success '--unset-upstream should fail if config is locked' '\n \tgit branch --set-upstream-to locked &&\n \t>.git/config.lock &&\n \ttest_must_fail git branch --unset-upstream 2>err &&\n-\ttest_i18ngrep \"could not lock config file .git/config\" err\n+\ttest_grep \"could not lock config file .git/config\" err\n '\n \n test_expect_success 'test --unset-upstream on HEAD' '\n@@ -1506,7 +1506,7 @@ test_expect_success '--list during rebase' '\n \tset_fake_editor &&\n \tgit rebase -i HEAD~2 &&\n \tgit branch --list >actual &&\n-\ttest_i18ngrep \"rebasing main\" actual\n+\ttest_grep \"rebasing main\" actual\n '\n \n test_expect_success '--list during rebase from detached HEAD' '\n@@ -1518,7 +1518,7 @@ test_expect_success '--list during rebase from detached HEAD' '\n \tset_fake_editor &&\n \tgit rebase -i HEAD~2 &&\n \tgit branch --list >actual &&\n-\ttest_i18ngrep \"rebasing detached HEAD $oid\" actual\n+\ttest_grep \"rebasing detached HEAD $oid\" actual\n '\n \n test_expect_success 'tracking with unexpected .fetch refspec' '\ndiff --git a/t/t3202-show-branch.sh b/t/t3202-show-branch.sh\nindex b17f388f56..235c68fb02 100755\n--- a/t/t3202-show-branch.sh\n+++ b/t/t3202-show-branch.sh\n@@ -253,7 +253,7 @@ test_expect_success 'error descriptions on orphan branch' '\n \ttest_branch_op_in_wt() {\n \t\ttest_orphan_error() {\n \t\t\ttest_must_fail git $* 2>actual &&\n-\t\t\ttest_i18ngrep \"No commit on branch .orphan-branch. yet.$\" actual\n+\t\t\ttest_grep \"No commit on branch .orphan-branch. yet.$\" actual\n \t\t} &&\n \t\ttest_orphan_error -C wt branch $1 $2 &&                # implicit branch\n \t\ttest_orphan_error -C wt branch $1 orphan-branch $2 &&  # explicit branch\ndiff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh\nindex b5f4d6a653..cfeb8c84b0 100755\n--- a/t/t3206-range-diff.sh\n+++ b/t/t3206-range-diff.sh\n@@ -195,7 +195,7 @@ test_expect_success 'A^! and A^-<n> (unmodified)' '\n \n test_expect_success 'A^{/..} is not mistaken for a range' '\n \ttest_must_fail git range-diff topic^.. topic^{/..} -- 2>error &&\n-\ttest_i18ngrep \"not a commit range\" error\n+\ttest_grep \"not a commit range\" error\n '\n \n test_expect_success 'trivial reordering' '\n@@ -537,7 +537,7 @@ do\n \t\t\tmain..unmodified >actual &&\n \t\ttest_when_finished \"rm 000?-*\" &&\n \t\ttest_line_count = 5 actual &&\n-\t\ttest_i18ngrep \"^Range-diff:$\" 0000-* &&\n+\t\ttest_grep \"^Range-diff:$\" 0000-* &&\n \t\tgrep \"= 1: .* s/5/A\" 0000-* &&\n \t\tgrep \"= 2: .* s/4/A\" 0000-* &&\n \t\tgrep \"= 3: .* s/11/B\" 0000-* &&\n@@ -549,7 +549,7 @@ test_expect_success 'format-patch --range-diff as commentary' '\n \tgit format-patch --range-diff=HEAD~1 HEAD~1 >actual &&\n \ttest_when_finished \"rm 0001-*\" &&\n \ttest_line_count = 1 actual &&\n-\ttest_i18ngrep \"^Range-diff:$\" 0001-* &&\n+\ttest_grep \"^Range-diff:$\" 0001-* &&\n \tgrep \"> 1: .* new message\" 0001-*\n '\n \n@@ -557,7 +557,7 @@ test_expect_success 'format-patch --range-diff reroll-count with a non-integer'\n \tgit format-patch --range-diff=HEAD~1 -v2.9 HEAD~1 >actual &&\n \ttest_when_finished \"rm v2.9-0001-*\" &&\n \ttest_line_count = 1 actual &&\n-\ttest_i18ngrep \"^Range-diff:$\" v2.9-0001-* &&\n+\ttest_grep \"^Range-diff:$\" v2.9-0001-* &&\n \tgrep \"> 1: .* new message\" v2.9-0001-*\n '\n \n@@ -565,7 +565,7 @@ test_expect_success 'format-patch --range-diff reroll-count with a integer' '\n \tgit format-patch --range-diff=HEAD~1 -v2 HEAD~1 >actual &&\n \ttest_when_finished \"rm v2-0001-*\" &&\n \ttest_line_count = 1 actual &&\n-\ttest_i18ngrep \"^Range-diff ..* v1:$\" v2-0001-* &&\n+\ttest_grep \"^Range-diff ..* v1:$\" v2-0001-* &&\n \tgrep \"> 1: .* new message\" v2-0001-*\n '\n \n@@ -573,7 +573,7 @@ test_expect_success 'format-patch --range-diff with v0' '\n \tgit format-patch --range-diff=HEAD~1 -v0 HEAD~1 >actual &&\n \ttest_when_finished \"rm v0-0001-*\" &&\n \ttest_line_count = 1 actual &&\n-\ttest_i18ngrep \"^Range-diff:$\" v0-0001-* &&\n+\ttest_grep \"^Range-diff:$\" v0-0001-* &&\n \tgrep \"> 1: .* new message\" v0-0001-*\n '\n \n@@ -670,7 +670,7 @@ test_expect_success 'format-patch --range-diff does not compare notes by default\n \t\tmain..unmodified >actual &&\n \ttest_when_finished \"rm 000?-*\" &&\n \ttest_line_count = 5 actual &&\n-\ttest_i18ngrep \"^Range-diff:$\" 0000-* &&\n+\ttest_grep \"^Range-diff:$\" 0000-* &&\n \tgrep \"= 1: .* s/5/A\" 0000-* &&\n \tgrep \"= 2: .* s/4/A\" 0000-* &&\n \tgrep \"= 3: .* s/11/B\" 0000-* &&\n@@ -687,7 +687,7 @@ test_expect_success 'format-patch --range-diff with --no-notes' '\n \t\tmain..unmodified >actual &&\n \ttest_when_finished \"rm 000?-*\" &&\n \ttest_line_count = 5 actual &&\n-\ttest_i18ngrep \"^Range-diff:$\" 0000-* &&\n+\ttest_grep \"^Range-diff:$\" 0000-* &&\n \tgrep \"= 1: .* s/5/A\" 0000-* &&\n \tgrep \"= 2: .* s/4/A\" 0000-* &&\n \tgrep \"= 3: .* s/11/B\" 0000-* &&\n@@ -704,7 +704,7 @@ test_expect_success 'format-patch --range-diff with --notes' '\n \t\tmain..unmodified >actual &&\n \ttest_when_finished \"rm 000?-*\" &&\n \ttest_line_count = 5 actual &&\n-\ttest_i18ngrep \"^Range-diff:$\" 0000-* &&\n+\ttest_grep \"^Range-diff:$\" 0000-* &&\n \tgrep \"= 1: .* s/5/A\" 0000-* &&\n \tgrep \"= 2: .* s/4/A\" 0000-* &&\n \tgrep \"= 3: .* s/11/B\" 0000-* &&\n@@ -733,7 +733,7 @@ test_expect_success 'format-patch --range-diff with format.notes config' '\n \t\tmain..unmodified >actual &&\n \ttest_when_finished \"rm 000?-*\" &&\n \ttest_line_count = 5 actual &&\n-\ttest_i18ngrep \"^Range-diff:$\" 0000-* &&\n+\ttest_grep \"^Range-diff:$\" 0000-* &&\n \tgrep \"= 1: .* s/5/A\" 0000-* &&\n \tgrep \"= 2: .* s/4/A\" 0000-* &&\n \tgrep \"= 3: .* s/11/B\" 0000-* &&\n@@ -764,7 +764,7 @@ test_expect_success 'format-patch --range-diff with multiple notes' '\n \t\tmain..unmodified >actual &&\n \ttest_when_finished \"rm 000?-*\" &&\n \ttest_line_count = 5 actual &&\n-\ttest_i18ngrep \"^Range-diff:$\" 0000-* &&\n+\ttest_grep \"^Range-diff:$\" 0000-* &&\n \tgrep \"= 1: .* s/5/A\" 0000-* &&\n \tgrep \"= 2: .* s/4/A\" 0000-* &&\n \tgrep \"= 3: .* s/11/B\" 0000-* &&\ndiff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh\nindex 7326adb70f..7f4e98db7d 100755\n--- a/t/t3210-pack-refs.sh\n+++ b/t/t3210-pack-refs.sh\n@@ -227,7 +227,7 @@ test_expect_success 'notice d/f conflict with existing directory' '\n \n test_expect_success 'existing directory reports concrete ref' '\n \ttest_must_fail git branch foo 2>stderr &&\n-\ttest_i18ngrep refs/heads/foo/bar/baz stderr\n+\ttest_grep refs/heads/foo/bar/baz stderr\n '\n \n test_expect_success 'notice d/f conflict with existing ref' '\ndiff --git a/t/t3301-notes.sh b/t/t3301-notes.sh\nindex d734000d2f..cf23c06c09 100755\n--- a/t/t3301-notes.sh\n+++ b/t/t3301-notes.sh\n@@ -1469,9 +1469,9 @@ test_expect_success 'GIT_NOTES_REWRITE_REF overrides config' '\n \n test_expect_success 'git notes copy diagnoses too many or too few arguments' '\n \ttest_must_fail git notes copy 2>error &&\n-\ttest_i18ngrep \"too few arguments\" error &&\n+\ttest_grep \"too few arguments\" error &&\n \ttest_must_fail git notes copy one two three 2>error &&\n-\ttest_i18ngrep \"too many arguments\" error\n+\ttest_grep \"too many arguments\" error\n '\n \n test_expect_success 'git notes get-ref expands refs/heads/main to refs/notes/refs/heads/main' '\ndiff --git a/t/t3310-notes-merge-manual-resolve.sh b/t/t3310-notes-merge-manual-resolve.sh\nindex d3d72e25fe..60d6ed2dc8 100755\n--- a/t/t3310-notes-merge-manual-resolve.sh\n+++ b/t/t3310-notes-merge-manual-resolve.sh\n@@ -216,7 +216,7 @@ test_expect_success 'merge z into m (== y) with default (\"manual\") resolver => C\n \tgit config core.notesRef refs/notes/m &&\n \ttest_must_fail git notes merge z >output 2>&1 &&\n \t# Output should point to where to resolve conflicts\n-\ttest_i18ngrep \"\\\\.git/NOTES_MERGE_WORKTREE\" output &&\n+\ttest_grep \"\\\\.git/NOTES_MERGE_WORKTREE\" output &&\n \t# Inspect merge conflicts\n \tls .git/NOTES_MERGE_WORKTREE >output_conflicts &&\n \ttest_cmp expect_conflicts output_conflicts &&\n@@ -263,7 +263,7 @@ test_expect_success 'cannot do merge w/conflicts when previous merge is unfinish\n \ttest -d .git/NOTES_MERGE_WORKTREE &&\n \ttest_must_fail git notes merge z >output 2>&1 &&\n \t# Output should indicate what is wrong\n-\ttest_i18ngrep -q \"\\\\.git/NOTES_MERGE_\\\\* exists\" output\n+\ttest_grep -q \"\\\\.git/NOTES_MERGE_\\\\* exists\" output\n '\n \n # Setup non-conflicting merge between x and new notes ref w\n@@ -417,7 +417,7 @@ test_expect_success 'redo merge of z into m (== y) with default (\"manual\") resol\n \tgit config core.notesRef refs/notes/m &&\n \ttest_must_fail git notes merge z >output 2>&1 &&\n \t# Output should point to where to resolve conflicts\n-\ttest_i18ngrep \"\\\\.git/NOTES_MERGE_WORKTREE\" output &&\n+\ttest_grep \"\\\\.git/NOTES_MERGE_WORKTREE\" output &&\n \t# Inspect merge conflicts\n \tls .git/NOTES_MERGE_WORKTREE >output_conflicts &&\n \ttest_cmp expect_conflicts output_conflicts &&\n@@ -449,7 +449,7 @@ git rev-parse refs/notes/z > pre_merge_z\n test_expect_success 'redo merge of z into m (== y) with default (\"manual\") resolver => Conflicting 3-way merge' '\n \ttest_must_fail git notes merge z >output 2>&1 &&\n \t# Output should point to where to resolve conflicts\n-\ttest_i18ngrep \"\\\\.git/NOTES_MERGE_WORKTREE\" output &&\n+\ttest_grep \"\\\\.git/NOTES_MERGE_WORKTREE\" output &&\n \t# Inspect merge conflicts\n \tls .git/NOTES_MERGE_WORKTREE >output_conflicts &&\n \ttest_cmp expect_conflicts output_conflicts &&\n@@ -528,7 +528,7 @@ test_expect_success 'redo merge of z into m (== y) with default (\"manual\") resol\n \tgit update-ref refs/notes/m refs/notes/y &&\n \ttest_must_fail git notes merge z >output 2>&1 &&\n \t# Output should point to where to resolve conflicts\n-\ttest_i18ngrep \"\\\\.git/NOTES_MERGE_WORKTREE\" output &&\n+\ttest_grep \"\\\\.git/NOTES_MERGE_WORKTREE\" output &&\n \t# Inspect merge conflicts\n \tls .git/NOTES_MERGE_WORKTREE >output_conflicts &&\n \ttest_cmp expect_conflicts output_conflicts &&\n@@ -573,9 +573,9 @@ EOF\n \ttest \"$(git rev-parse refs/notes/y)\" = \"$(git rev-parse NOTES_MERGE_PARTIAL^1)\" &&\n \ttest \"$(git rev-parse refs/notes/m)\" != \"$(git rev-parse NOTES_MERGE_PARTIAL^1)\" &&\n \t# Mention refs/notes/m, and its current and expected value in output\n-\ttest_i18ngrep -q \"refs/notes/m\" output &&\n-\ttest_i18ngrep -q \"$(git rev-parse refs/notes/m)\" output &&\n-\ttest_i18ngrep -q \"$(git rev-parse NOTES_MERGE_PARTIAL^1)\" output &&\n+\ttest_grep -q \"refs/notes/m\" output &&\n+\ttest_grep -q \"$(git rev-parse refs/notes/m)\" output &&\n+\ttest_grep -q \"$(git rev-parse NOTES_MERGE_PARTIAL^1)\" output &&\n \t# Verify that other notes refs has not changed (w, x, y and z)\n \tverify_notes w &&\n \tverify_notes x &&\ndiff --git a/t/t3320-notes-merge-worktrees.sh b/t/t3320-notes-merge-worktrees.sh\nindex bff0aea550..0fd33280cf 100755\n--- a/t/t3320-notes-merge-worktrees.sh\n+++ b/t/t3320-notes-merge-worktrees.sh\n@@ -57,7 +57,7 @@ test_expect_success 'merge z into y while mid-merge in another workdir fails' '\n \t\tcd worktree &&\n \t\tgit config core.notesRef refs/notes/y &&\n \t\ttest_must_fail git notes merge z 2>err &&\n-\t\ttest_i18ngrep \"a notes merge into refs/notes/y is already in-progress at\" err\n+\t\ttest_grep \"a notes merge into refs/notes/y is already in-progress at\" err\n \t) &&\n \ttest_must_fail git -C worktree symbolic-ref NOTES_MERGE_REF\n '\n@@ -67,7 +67,7 @@ test_expect_success 'merge z into x while mid-merge on y succeeds' '\n \t\tcd worktree2 &&\n \t\tgit config core.notesRef refs/notes/x &&\n \t\ttest_must_fail git notes merge z >out 2>&1 &&\n-\t\ttest_i18ngrep \"Automatic notes merge failed\" out &&\n+\t\ttest_grep \"Automatic notes merge failed\" out &&\n \t\tgrep -v \"A notes merge into refs/notes/x is already in-progress in\" out\n \t) &&\n \techo \"refs/notes/x\" >expect &&\ndiff --git a/t/t3321-notes-stripspace.sh b/t/t3321-notes-stripspace.sh\nindex 028d825e8f..33c1322989 100755\n--- a/t/t3321-notes-stripspace.sh\n+++ b/t/t3321-notes-stripspace.sh\n@@ -428,7 +428,7 @@ test_expect_success 'add notes with empty messages' '\n \tgit notes add -m \"${LF}\" \\\n \t\t      -m \"${MULTI_LF}\" \\\n \t\t      -m \"${LF}\" >actual 2>&1 &&\n-\ttest_i18ngrep \"Removing note for object\" actual\n+\ttest_grep \"Removing note for object\" actual\n '\n \n test_expect_success 'add note by specifying \"-C\", \"--no-stripspace\" is the default behavior' '\ndiff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh\nindex 3ce918fdb8..621c8ef84c 100755\n--- a/t/t3400-rebase.sh\n+++ b/t/t3400-rebase.sh\n@@ -143,8 +143,8 @@ test_expect_success 'Show verbose error when HEAD could not be detached' '\n \t>B &&\n \ttest_when_finished \"rm -f B\" &&\n \ttest_must_fail git rebase topic 2>output.err >output.out &&\n-\ttest_i18ngrep \"The following untracked working tree files would be overwritten by checkout:\" output.err &&\n-\ttest_i18ngrep B output.err\n+\ttest_grep \"The following untracked working tree files would be overwritten by checkout:\" output.err &&\n+\ttest_grep B output.err\n '\n \n test_expect_success 'fail when upstream arg is missing and not on branch' '\n@@ -421,7 +421,7 @@ test_expect_success 'refuse to switch to branch checked out elsewhere' '\n \tgit checkout main &&\n \tgit worktree add wt &&\n \ttest_must_fail git -C wt rebase main main 2>err &&\n-\ttest_i18ngrep \"already checked out\" err\n+\ttest_grep \"already checked out\" err\n '\n \n test_expect_success MINGW,SYMLINKS_WINDOWS 'rebase when .git/logs is a symlink' '\ndiff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh\nindex e9e03ca4b5..5c67d07ba3 100755\n--- a/t/t3402-rebase-merge.sh\n+++ b/t/t3402-rebase-merge.sh\n@@ -171,7 +171,7 @@ test_expect_success '--reapply-cherry-picks' '\n \n \t# Regular rebase fails, because the 1-11 commit is deduplicated\n \ttest_must_fail git -C repo rebase --merge main 2> err &&\n-\ttest_i18ngrep \"error: could not apply.*add 12 in another branch\" err &&\n+\ttest_grep \"error: could not apply.*add 12 in another branch\" err &&\n \tgit -C repo rebase --abort &&\n \n \t# With --reapply-cherry-picks, it works\ndiff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh\nindex f6e4864497..a1911c4a9d 100755\n--- a/t/t3403-rebase-skip.sh\n+++ b/t/t3403-rebase-skip.sh\n@@ -108,10 +108,10 @@ test_expect_success 'correct advice upon picking empty commit' '\n \ttest_when_finished \"git rebase --abort\" &&\n \ttest_must_fail git rebase -i --onto goodbye \\\n \t\tamended-goodbye^ amended-goodbye 2>err &&\n-\ttest_i18ngrep \"previous cherry-pick is now empty\" err &&\n-\ttest_i18ngrep \"git rebase --skip\" err &&\n+\ttest_grep \"previous cherry-pick is now empty\" err &&\n+\ttest_grep \"git rebase --skip\" err &&\n \ttest_must_fail git commit &&\n-\ttest_i18ngrep \"git rebase --skip\" err\n+\ttest_grep \"git rebase --skip\" err\n '\n \n test_expect_success 'correct authorship when committing empty pick' '\n@@ -131,10 +131,10 @@ test_expect_success 'correct advice upon rewording empty commit' '\n \t\ttest_must_fail env FAKE_LINES=\"reword 1\" git rebase -i \\\n \t\t\t--onto goodbye amended-goodbye^ amended-goodbye 2>err\n \t) &&\n-\ttest_i18ngrep \"previous cherry-pick is now empty\" err &&\n-\ttest_i18ngrep \"git rebase --skip\" err &&\n+\ttest_grep \"previous cherry-pick is now empty\" err &&\n+\ttest_grep \"git rebase --skip\" err &&\n \ttest_must_fail git commit &&\n-\ttest_i18ngrep \"git rebase --skip\" err\n+\ttest_grep \"git rebase --skip\" err\n '\n \n test_expect_success 'correct advice upon editing empty commit' '\n@@ -144,10 +144,10 @@ test_expect_success 'correct advice upon editing empty commit' '\n \t\ttest_must_fail env FAKE_LINES=\"edit 1\" git rebase -i \\\n \t\t\t--onto goodbye amended-goodbye^ amended-goodbye 2>err\n \t) &&\n-\ttest_i18ngrep \"previous cherry-pick is now empty\" err &&\n-\ttest_i18ngrep \"git rebase --skip\" err &&\n+\ttest_grep \"previous cherry-pick is now empty\" err &&\n+\ttest_grep \"git rebase --skip\" err &&\n \ttest_must_fail git commit &&\n-\ttest_i18ngrep \"git rebase --skip\" err\n+\ttest_grep \"git rebase --skip\" err\n '\n \n test_expect_success 'correct advice upon cherry-picking an empty commit during a rebase' '\n@@ -157,10 +157,10 @@ test_expect_success 'correct advice upon cherry-picking an empty commit during a\n \t\ttest_must_fail env FAKE_LINES=\"1 exec_git_cherry-pick_amended-goodbye\" \\\n \t\t\tgit rebase -i goodbye^ goodbye 2>err\n \t) &&\n-\ttest_i18ngrep \"previous cherry-pick is now empty\" err &&\n-\ttest_i18ngrep \"git cherry-pick --skip\" err &&\n+\ttest_grep \"previous cherry-pick is now empty\" err &&\n+\ttest_grep \"git cherry-pick --skip\" err &&\n \ttest_must_fail git commit 2>err &&\n-\ttest_i18ngrep \"git cherry-pick --skip\" err\n+\ttest_grep \"git cherry-pick --skip\" err\n '\n \n test_expect_success 'correct advice upon multi cherry-pick picking an empty commit during a rebase' '\n@@ -170,10 +170,10 @@ test_expect_success 'correct advice upon multi cherry-pick picking an empty comm\n \t\ttest_must_fail env FAKE_LINES=\"1 exec_git_cherry-pick_goodbye_amended-goodbye\" \\\n \t\t\tgit rebase -i goodbye^^ goodbye 2>err\n \t) &&\n-\ttest_i18ngrep \"previous cherry-pick is now empty\" err &&\n-\ttest_i18ngrep \"git cherry-pick --skip\" err &&\n+\ttest_grep \"previous cherry-pick is now empty\" err &&\n+\ttest_grep \"git cherry-pick --skip\" err &&\n \ttest_must_fail git commit 2>err &&\n-\ttest_i18ngrep \"git cherry-pick --skip\" err\n+\ttest_grep \"git cherry-pick --skip\" err\n '\n \n test_expect_success 'fixup that empties commit fails' '\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex 96a56aafbe..dbd5df5aa4 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -291,9 +291,9 @@ test_expect_success 'abort with error when new base cannot be checked out' '\n \tgit rm --cached file1 &&\n \tgit commit -m \"remove file in base\" &&\n \ttest_must_fail git rebase -i primary > output 2>&1 &&\n-\ttest_i18ngrep \"The following untracked working tree files would be overwritten by checkout:\" \\\n+\ttest_grep \"The following untracked working tree files would be overwritten by checkout:\" \\\n \t\toutput &&\n-\ttest_i18ngrep \"file1\" output &&\n+\ttest_grep \"file1\" output &&\n \ttest_path_is_missing .git/rebase-merge &&\n \trm file1 &&\n \tgit reset --hard HEAD^\n@@ -604,7 +604,7 @@ test_expect_success 'clean error after failed \"exec\"' '\n \techo \"edited again\" > file7 &&\n \tgit add file7 &&\n \ttest_must_fail git rebase --continue 2>error &&\n-\ttest_i18ngrep \"you have staged changes in your working tree\" error\n+\ttest_grep \"you have staged changes in your working tree\" error\n '\n \n test_expect_success 'rebase a detached HEAD' '\n@@ -955,7 +955,7 @@ test_expect_success 'rebase --exec works without -i ' '\n \tgit reset --hard execute &&\n \trm -rf exec_output &&\n \tEDITOR=\"echo >invoked_editor\" git rebase --exec \"echo a line >>exec_output\"  HEAD~2 2>actual &&\n-\ttest_i18ngrep  \"Successfully rebased and updated\" actual &&\n+\ttest_grep  \"Successfully rebased and updated\" actual &&\n \ttest_line_count = 2 exec_output &&\n \ttest_path_is_missing invoked_editor\n '\n@@ -963,7 +963,7 @@ test_expect_success 'rebase --exec works without -i ' '\n test_expect_success 'rebase -i --exec without <CMD>' '\n \tgit reset --hard execute &&\n \ttest_must_fail git rebase -i --exec 2>actual &&\n-\ttest_i18ngrep \"requires a value\" actual &&\n+\ttest_grep \"requires a value\" actual &&\n \tgit checkout primary\n '\n \n@@ -1272,7 +1272,7 @@ test_expect_success 'todo count' '\n \t\ttest_set_editor \"$(pwd)/dump-raw.sh\" &&\n \t\tgit rebase -i HEAD~4 >actual\n \t) &&\n-\ttest_i18ngrep \"^# Rebase ..* onto ..* ([0-9]\" actual\n+\ttest_grep \"^# Rebase ..* onto ..* ([0-9]\" actual\n '\n \n test_expect_success 'rebase -i commits that overwrite untracked files (pick)' '\n@@ -1379,7 +1379,7 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = ignore' '\n \t\tFAKE_LINES=\"1 2 3 4\" git rebase -i --root 2>actual\n \t) &&\n \ttest D = $(git cat-file commit HEAD | sed -ne \\$p) &&\n-\ttest_i18ngrep \\\n+\ttest_grep \\\n \t\t\"Successfully rebased and updated refs/heads/missing-commit\" \\\n \t\tactual\n '\n@@ -1442,7 +1442,7 @@ test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = ig\n \t\tgit rebase --continue 2>actual\n \t) &&\n \ttest D = $(git cat-file commit HEAD | sed -ne \\$p) &&\n-\ttest_i18ngrep \\\n+\ttest_grep \\\n \t\t\"Successfully rebased and updated refs/heads/missing-commit\" \\\n \t\tactual\n '\n@@ -1477,7 +1477,7 @@ test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = wa\n \t\tgit rebase --continue 2>actual\n \t) &&\n \ttest D = $(git cat-file commit HEAD | sed -ne \\$p) &&\n-\ttest_i18ngrep \\\n+\ttest_grep \\\n \t\t\"Successfully rebased and updated refs/heads/missing-commit\" \\\n \t\tactual\n '\n@@ -1525,7 +1525,7 @@ test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = er\n \t\tgit rebase --continue 2>actual\n \t) &&\n \ttest D = $(git cat-file commit HEAD | sed -ne \\$p) &&\n-\ttest_i18ngrep \\\n+\ttest_grep \\\n \t\t\"Successfully rebased and updated refs/heads/missing-commit\" \\\n \t\tactual\n '\n@@ -1585,9 +1585,9 @@ test_expect_success 'static check of bad command' '\n \t\tset_fake_editor &&\n \t\ttest_must_fail env FAKE_LINES=\"1 2 3 bad 4 5\" \\\n \t\tgit rebase -i --root 2>actual &&\n-\t\ttest_i18ngrep \"pickled $(git rev-list --oneline -1 primary~1)\" \\\n+\t\ttest_grep \"pickled $(git rev-list --oneline -1 primary~1)\" \\\n \t\t\t\tactual &&\n-\t\ttest_i18ngrep \"You can fix this with .git rebase --edit-todo..\" \\\n+\t\ttest_grep \"You can fix this with .git rebase --edit-todo..\" \\\n \t\t\t\tactual &&\n \t\tFAKE_LINES=\"1 2 3 drop 4 5\" git rebase --edit-todo\n \t) &&\n@@ -1645,8 +1645,8 @@ test_expect_success 'static check of bad SHA-1' '\n \t\tset_fake_editor &&\n \t\ttest_must_fail env FAKE_LINES=\"1 2 edit fakesha 3 4 5 #\" \\\n \t\t\tgit rebase -i --root 2>actual &&\n-\t\t\ttest_i18ngrep \"edit XXXXXXX False commit\" actual &&\n-\t\t\ttest_i18ngrep \"You can fix this with .git rebase --edit-todo..\" \\\n+\t\t\ttest_grep \"edit XXXXXXX False commit\" actual &&\n+\t\t\ttest_grep \"You can fix this with .git rebase --edit-todo..\" \\\n \t\t\t\t\tactual &&\n \t\tFAKE_LINES=\"1 2 4 5 6\" git rebase --edit-todo\n \t) &&\n@@ -1673,7 +1673,7 @@ test_expect_success 'rebase -i --gpg-sign=<key-id>' '\n \t\tFAKE_LINES=\"edit 1\" git rebase -i --gpg-sign=\"\\\"S I Gner\\\"\" \\\n \t\t\tHEAD^ >out 2>err\n \t) &&\n-\ttest_i18ngrep \"$SQ-S\\\"S I Gner\\\"$SQ\" err\n+\ttest_grep \"$SQ-S\\\"S I Gner\\\"$SQ\" err\n '\n \n test_expect_success 'rebase -i --gpg-sign=<key-id> overrides commit.gpgSign' '\n@@ -1684,7 +1684,7 @@ test_expect_success 'rebase -i --gpg-sign=<key-id> overrides commit.gpgSign' '\n \t\tFAKE_LINES=\"edit 1\" git rebase -i --gpg-sign=\"\\\"S I Gner\\\"\" \\\n \t\t\tHEAD^ >out 2>err\n \t) &&\n-\ttest_i18ngrep \"$SQ-S\\\"S I Gner\\\"$SQ\" err\n+\ttest_grep \"$SQ-S\\\"S I Gner\\\"$SQ\" err\n '\n \n test_expect_success 'valid author header after --root swap' '\n@@ -1738,7 +1738,7 @@ test_expect_success 'correct error message for partial commit after empty pick'\n \t) &&\n \techo x >file1 &&\n \ttest_must_fail git commit file1 2>err &&\n-\ttest_i18ngrep \"cannot do a partial commit during a rebase.\" err\n+\ttest_grep \"cannot do a partial commit during a rebase.\" err\n '\n \n test_expect_success 'correct error message for commit --amend after empty pick' '\n@@ -1751,13 +1751,13 @@ test_expect_success 'correct error message for commit --amend after empty pick'\n \t) &&\n \techo x>file1 &&\n \ttest_must_fail git commit -a --amend 2>err &&\n-\ttest_i18ngrep \"middle of a rebase -- cannot amend.\" err\n+\ttest_grep \"middle of a rebase -- cannot amend.\" err\n '\n \n test_expect_success 'todo has correct onto hash' '\n \tGIT_SEQUENCE_EDITOR=cat git rebase -i no-conflict-branch~4 no-conflict-branch >actual &&\n \tonto=$(git rev-parse --short HEAD~4) &&\n-\ttest_i18ngrep \"^# Rebase ..* onto $onto\" actual\n+\ttest_grep \"^# Rebase ..* onto $onto\" actual\n '\n \n test_expect_success 'ORIG_HEAD is updated correctly' '\ndiff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh\nindex ceca160005..a1d7fa7f7c 100755\n--- a/t/t3406-rebase-message.sh\n+++ b/t/t3406-rebase-message.sh\n@@ -33,24 +33,24 @@ test_expect_success 'rebase -m' '\n \n test_expect_success 'rebase against main twice' '\n \tgit rebase --apply main >out &&\n-\ttest_i18ngrep \"Current branch topic is up to date\" out\n+\ttest_grep \"Current branch topic is up to date\" out\n '\n \n test_expect_success 'rebase against main twice with --force' '\n \tgit rebase --force-rebase --apply main >out &&\n-\ttest_i18ngrep \"Current branch topic is up to date, rebase forced\" out\n+\ttest_grep \"Current branch topic is up to date, rebase forced\" out\n '\n \n test_expect_success 'rebase against main twice from another branch' '\n \tgit checkout topic^ &&\n \tgit rebase --apply main topic >out &&\n-\ttest_i18ngrep \"Current branch topic is up to date\" out\n+\ttest_grep \"Current branch topic is up to date\" out\n '\n \n test_expect_success 'rebase fast-forward to main' '\n \tgit checkout topic^ &&\n \tgit rebase --apply topic >out &&\n-\ttest_i18ngrep \"Fast-forwarded HEAD to topic\" out\n+\ttest_grep \"Fast-forwarded HEAD to topic\" out\n '\n \n test_expect_success 'rebase --stat' '\n@@ -75,14 +75,14 @@ test_expect_success 'rebase -n overrides config rebase.stat config' '\n \n test_expect_success 'rebase --onto outputs the invalid ref' '\n \ttest_must_fail git rebase --onto invalid-ref HEAD HEAD 2>err &&\n-\ttest_i18ngrep \"invalid-ref\" err\n+\ttest_grep \"invalid-ref\" err\n '\n \n test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '\n \ttest_must_fail git rebase -Cnot-a-number HEAD 2>err &&\n-\ttest_i18ngrep \"numerical value\" err &&\n+\ttest_grep \"numerical value\" err &&\n \ttest_must_fail git rebase --whitespace=bad HEAD 2>err &&\n-\ttest_i18ngrep \"Invalid whitespace option\" err\n+\ttest_grep \"Invalid whitespace option\" err\n '\n \n write_reflog_expect () {\n@@ -251,8 +251,8 @@ test_expect_success 'rebase -i onto unrelated history' '\n \tgit -C unrelated remote add -f origin \"$PWD\" &&\n \tgit -C unrelated branch --set-upstream-to=origin/main &&\n \tgit -C unrelated -c core.editor=true rebase -i -v --stat >actual &&\n-\ttest_i18ngrep \"Changes to \" actual &&\n-\ttest_i18ngrep \"5 files changed\" actual\n+\ttest_grep \"Changes to \" actual &&\n+\ttest_grep \"5 files changed\" actual\n '\n \n test_done\ndiff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh\nindex fb7b68990c..108d5c28fa 100755\n--- a/t/t3418-rebase-continue.sh\n+++ b/t/t3418-rebase-continue.sh\n@@ -182,8 +182,8 @@ test_expect_success '--skip after failed fixup cleans commit message' '\n \n \t: Final squash failed, but there was still a squash &&\n \thead -n1 .git/copy.txt >first-line &&\n-\ttest_i18ngrep \"# This is a combination of 3 commits\" first-line &&\n-\ttest_i18ngrep \"# This is the commit message #3:\" .git/copy.txt\n+\ttest_grep \"# This is a combination of 3 commits\" first-line &&\n+\ttest_grep \"# This is the commit message #3:\" .git/copy.txt\n '\n \n test_expect_success 'setup rerere database' '\n@@ -276,7 +276,7 @@ test_expect_success '--reschedule-failed-exec' '\n \ttest_must_fail git -c rebase.rescheduleFailedExec=true \\\n \t\trebase -x false HEAD^ 2>err &&\n \tgrep \"^exec false\" .git/rebase-merge/git-rebase-todo &&\n-\ttest_i18ngrep \"has been rescheduled\" err\n+\ttest_grep \"has been rescheduled\" err\n '\n \n test_expect_success 'rebase.rescheduleFailedExec only affects `rebase -i`' '\ndiff --git a/t/t3431-rebase-fork-point.sh b/t/t3431-rebase-fork-point.sh\nindex 4bfc779bb8..0bb284d61d 100755\n--- a/t/t3431-rebase-fork-point.sh\n+++ b/t/t3431-rebase-fork-point.sh\n@@ -84,7 +84,7 @@ test_expect_success 'git rebase --fork-point with ambigous refname' '\n \n test_expect_success '--fork-point and --root both given' '\n \ttest_must_fail git rebase --fork-point --root 2>err &&\n-\ttest_i18ngrep \"cannot be used together\" err\n+\ttest_grep \"cannot be used together\" err\n '\n \n test_expect_success 'rebase.forkPoint set to false' '\ndiff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh\nindex e2ef619323..3eac20c098 100755\n--- a/t/t3501-revert-cherry-pick.sh\n+++ b/t/t3501-revert-cherry-pick.sh\n@@ -43,7 +43,7 @@ test_expect_success 'cherry-pick --nonsense' '\n \tgit diff --exit-code HEAD &&\n \ttest_must_fail git cherry-pick --nonsense 2>msg &&\n \tgit diff --exit-code HEAD \"$pos\" &&\n-\ttest_i18ngrep \"[Uu]sage:\" msg\n+\ttest_grep \"[Uu]sage:\" msg\n '\n \n test_expect_success 'revert --nonsense' '\n@@ -52,7 +52,7 @@ test_expect_success 'revert --nonsense' '\n \tgit diff --exit-code HEAD &&\n \ttest_must_fail git revert --nonsense 2>msg &&\n \tgit diff --exit-code HEAD \"$pos\" &&\n-\ttest_i18ngrep \"[Uu]sage:\" msg\n+\ttest_grep \"[Uu]sage:\" msg\n '\n \n # the following two test cherry-pick and revert with renames\n@@ -99,7 +99,7 @@ test_expect_success 'revert forbidden on dirty working tree' '\n \techo content >extra_file &&\n \tgit add extra_file &&\n \ttest_must_fail git revert HEAD 2>errors &&\n-\ttest_i18ngrep \"your local changes would be overwritten by \" errors\n+\ttest_grep \"your local changes would be overwritten by \" errors\n \n '\n \ndiff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh\nindex f32799e046..c88d597b12 100755\n--- a/t/t3507-cherry-pick-conflict.sh\n+++ b/t/t3507-cherry-pick-conflict.sh\n@@ -177,7 +177,7 @@ test_expect_success 'partial commit of cherry-pick fails' '\n \tgit add foo &&\n \ttest_must_fail git commit foo 2>err &&\n \n-\ttest_i18ngrep \"cannot do a partial commit during a cherry-pick.\" err\n+\ttest_grep \"cannot do a partial commit during a cherry-pick.\" err\n '\n \n test_expect_success 'commit --amend of cherry-pick fails' '\n@@ -188,7 +188,7 @@ test_expect_success 'commit --amend of cherry-pick fails' '\n \tgit add foo &&\n \ttest_must_fail git commit --amend 2>err &&\n \n-\ttest_i18ngrep \"in the middle of a cherry-pick -- cannot amend.\" err\n+\ttest_grep \"in the middle of a cherry-pick -- cannot amend.\" err\n '\n \n test_expect_success 'successful final commit clears cherry-pick state' '\n@@ -498,7 +498,7 @@ test_expect_success \\\n test_expect_success 'failed cherry-pick does not forget -s' '\n \tpristine_detach initial &&\n \ttest_must_fail git cherry-pick -s picked &&\n-\ttest_i18ngrep -e \"Signed-off-by\" .git/MERGE_MSG\n+\ttest_grep -e \"Signed-off-by\" .git/MERGE_MSG\n '\n \n test_expect_success 'commit after failed cherry-pick does not add duplicated -s' '\n@@ -563,7 +563,7 @@ test_expect_success 'cherry-pick preserves sparse-checkout' '\n \techo /unrelated >.git/info/sparse-checkout &&\n \tgit read-tree --reset -u HEAD &&\n \ttest_must_fail git cherry-pick -Xours picked>actual &&\n-\ttest_i18ngrep ! \"Changes not staged for commit:\" actual\n+\ttest_grep ! \"Changes not staged for commit:\" actual\n '\n \n test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '\ndiff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh\nindex 3b0fa66c33..72020a51c4 100755\n--- a/t/t3510-cherry-pick-sequence.sh\n+++ b/t/t3510-cherry-pick-sequence.sh\n@@ -154,7 +154,7 @@ test_expect_success 'skip \"empty\" commit' '\n \tpristine_detach picked &&\n \ttest_commit dummy foo d &&\n \ttest_must_fail git cherry-pick anotherpick 2>err &&\n-\ttest_i18ngrep \"git cherry-pick --skip\" err &&\n+\ttest_grep \"git cherry-pick --skip\" err &&\n \tgit cherry-pick --skip &&\n \ttest_cmp_rev dummy HEAD\n '\n@@ -314,7 +314,7 @@ test_expect_success '--abort does not unsafely change HEAD' '\n \tgit reset --hard base &&\n \ttest_must_fail git cherry-pick picked anotherpick &&\n \tgit cherry-pick --abort 2>actual &&\n-\ttest_i18ngrep \"You seem to have moved HEAD\" actual &&\n+\ttest_grep \"You seem to have moved HEAD\" actual &&\n \ttest_cmp_rev base HEAD\n '\n \n@@ -520,7 +520,7 @@ test_expect_success '--continue asks for help after resolving patch to nil' '\n \ttest_cmp_rev unrelatedpick CHERRY_PICK_HEAD &&\n \tgit checkout HEAD -- unrelated &&\n \ttest_must_fail git cherry-pick --continue 2>msg &&\n-\ttest_i18ngrep \"The previous cherry-pick is now empty\" msg\n+\ttest_grep \"The previous cherry-pick is now empty\" msg\n '\n \n test_expect_success 'follow advice and skip nil patch' '\ndiff --git a/t/t3600-rm.sh b/t/t3600-rm.sh\nindex 0e8afe49ed..98259e2ada 100755\n--- a/t/t3600-rm.sh\n+++ b/t/t3600-rm.sh\n@@ -276,7 +276,7 @@ test_expect_success 'Resolving by removal is not a warning-worthy event' '\n \tblob=$(echo blob | git hash-object -w --stdin) &&\n \tprintf \"100644 $blob %d\\tblob\\n\" 1 2 3 | git update-index --index-info &&\n \tgit rm blob >msg 2>&1 &&\n-\ttest_i18ngrep ! \"needs merge\" msg &&\n+\ttest_grep ! \"needs merge\" msg &&\n \ttest_must_fail git ls-files -s --error-unmatch blob\n '\n \n@@ -631,7 +631,7 @@ test_expect_success 'rm of a populated submodule with a .git directory migrates\n \ttest_path_is_missing submod/.git &&\n \tgit status -s -uno --ignore-submodules=none >actual &&\n \ttest_file_not_empty actual &&\n-\ttest_i18ngrep Migrating output.err\n+\ttest_grep Migrating output.err\n '\n \n cat >expect.deepmodified <<EOF\n@@ -722,7 +722,7 @@ test_expect_success \"rm absorbs submodule's nested .git directory\" '\n \ttest_path_is_missing submod/subsubmod/.git &&\n \tgit status -s -uno --ignore-submodules=none >actual &&\n \ttest_file_not_empty actual &&\n-\ttest_i18ngrep Migrating output.err\n+\ttest_grep Migrating output.err\n '\n \n test_expect_success 'checking out a commit after submodule removal needs manual updates' '\n@@ -731,7 +731,7 @@ test_expect_success 'checking out a commit after submodule removal needs manual\n \tgit submodule update &&\n \tgit checkout -q HEAD^ &&\n \tgit checkout -q main 2>actual &&\n-\ttest_i18ngrep \"^warning: unable to rmdir '\\''submod'\\'':\" actual &&\n+\ttest_grep \"^warning: unable to rmdir '\\''submod'\\'':\" actual &&\n \tgit status -s submod >actual &&\n \techo \"?? submod/\" >expected &&\n \ttest_cmp expected actual &&\ndiff --git a/t/t3601-rm-pathspec-file.sh b/t/t3601-rm-pathspec-file.sh\nindex a2a0c820fe..7cef12981c 100755\n--- a/t/t3601-rm-pathspec-file.sh\n+++ b/t/t3601-rm-pathspec-file.sh\n@@ -67,14 +67,14 @@ test_expect_success 'error conditions' '\n \techo fileA.t >list &&\n \n \ttest_must_fail git rm --pathspec-from-file=list -- fileA.t 2>err &&\n-\ttest_i18ngrep -e \".--pathspec-from-file. and pathspec arguments cannot be used together\" err &&\n+\ttest_grep -e \".--pathspec-from-file. and pathspec arguments cannot be used together\" err &&\n \n \ttest_must_fail git rm --pathspec-file-nul 2>err &&\n-\ttest_i18ngrep -e \"the option .--pathspec-file-nul. requires .--pathspec-from-file.\" err &&\n+\ttest_grep -e \"the option .--pathspec-file-nul. requires .--pathspec-from-file.\" err &&\n \n \t>empty_list &&\n \ttest_must_fail git rm --pathspec-from-file=empty_list 2>err &&\n-\ttest_i18ngrep -e \"No pathspec was given. Which files should I remove?\" err\n+\ttest_grep -e \"No pathspec was given. Which files should I remove?\" err\n '\n \n test_done\ndiff --git a/t/t3700-add.sh b/t/t3700-add.sh\nindex 7623689da2..f23d39f0d5 100755\n--- a/t/t3700-add.sh\n+++ b/t/t3700-add.sh\n@@ -438,7 +438,7 @@ test_expect_success 'git add --chmod fails with non regular files (but updates t\n \ttest_ln_s_add foo foo3 &&\n \ttouch foo4 &&\n \ttest_must_fail git add --chmod=+x foo3 foo4 2>stderr &&\n-\ttest_i18ngrep \"cannot chmod +x .foo3.\" stderr &&\n+\ttest_grep \"cannot chmod +x .foo3.\" stderr &&\n \ttest_mode_in_index 120000 foo3 &&\n \ttest_mode_in_index 100755 foo4\n '\n@@ -455,12 +455,12 @@ test_expect_success 'git add --chmod --dry-run reports error for non regular fil\n \tgit reset --hard &&\n \ttest_ln_s_add foo foo4 &&\n \ttest_must_fail git add --chmod=+x --dry-run foo4 2>stderr &&\n-\ttest_i18ngrep \"cannot chmod +x .foo4.\" stderr\n+\ttest_grep \"cannot chmod +x .foo4.\" stderr\n '\n \n test_expect_success 'git add --chmod --dry-run reports error for unmatched pathspec' '\n \ttest_must_fail git add --chmod=+x --dry-run nonexistent 2>stderr &&\n-\ttest_i18ngrep \"pathspec .nonexistent. did not match any files\" stderr\n+\ttest_grep \"pathspec .nonexistent. did not match any files\" stderr\n '\n \n test_expect_success 'no file status change if no pathspec is given' '\ndiff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh\nindex 34aabb7f5f..0b5339ac6c 100755\n--- a/t/t3701-add-interactive.sh\n+++ b/t/t3701-add-interactive.sh\n@@ -335,12 +335,12 @@ test_expect_success 'different prompts for mode change/deleted' '\n test_expect_success 'correct message when there is nothing to do' '\n \tgit reset --hard &&\n \tgit add -p 2>err &&\n-\ttest_i18ngrep \"No changes\" err &&\n+\ttest_grep \"No changes\" err &&\n \tprintf \"\\\\0123\" >binary &&\n \tgit add binary &&\n \tprintf \"\\\\0abc\" >binary &&\n \tgit add -p 2>err &&\n-\ttest_i18ngrep \"Only binary files changed\" err\n+\ttest_grep \"Only binary files changed\" err\n '\n \n test_expect_success 'setup again' '\n@@ -497,7 +497,7 @@ test_expect_success 'adding an empty file' '\n \n \t\techo y | git checkout -p added-file -- >actual &&\n \t\ttest_path_is_file empty &&\n-\t\ttest_i18ngrep \"Apply addition to index and worktree\" actual\n+\t\ttest_grep \"Apply addition to index and worktree\" actual\n \t)\n '\n \n@@ -838,7 +838,7 @@ test_expect_success 'diff.algorithm is passed to `git diff-files`' '\n \tgit add file &&\n \techo changed >file &&\n \ttest_must_fail git -c diff.algorithm=bogus add -p 2>err &&\n-\ttest_i18ngrep \"error: option diff-algorithm accepts \" err\n+\ttest_grep \"error: option diff-algorithm accepts \" err\n '\n \n test_expect_success 'patch-mode via -i prompts for files' '\ndiff --git a/t/t3704-add-pathspec-file.sh b/t/t3704-add-pathspec-file.sh\nindex 4e6b5177c9..3aa59f6f63 100755\n--- a/t/t3704-add-pathspec-file.sh\n+++ b/t/t3704-add-pathspec-file.sh\n@@ -138,23 +138,23 @@ test_expect_success 'error conditions' '\n \t>empty_list &&\n \n \ttest_must_fail git add --pathspec-from-file=list --interactive 2>err &&\n-\ttest_i18ngrep -e \"options .--pathspec-from-file. and .--interactive/--patch. cannot be used together\" err &&\n+\ttest_grep -e \"options .--pathspec-from-file. and .--interactive/--patch. cannot be used together\" err &&\n \n \ttest_must_fail git add --pathspec-from-file=list --patch 2>err &&\n-\ttest_i18ngrep -e \"options .--pathspec-from-file. and .--interactive/--patch. cannot be used together\" err &&\n+\ttest_grep -e \"options .--pathspec-from-file. and .--interactive/--patch. cannot be used together\" err &&\n \n \ttest_must_fail git add --pathspec-from-file=list --edit 2>err &&\n-\ttest_i18ngrep -e \"options .--pathspec-from-file. and .--edit. cannot be used together\" err &&\n+\ttest_grep -e \"options .--pathspec-from-file. and .--edit. cannot be used together\" err &&\n \n \ttest_must_fail git add --pathspec-from-file=list -- fileA.t 2>err &&\n-\ttest_i18ngrep -e \".--pathspec-from-file. and pathspec arguments cannot be used together\" err &&\n+\ttest_grep -e \".--pathspec-from-file. and pathspec arguments cannot be used together\" err &&\n \n \ttest_must_fail git add --pathspec-file-nul 2>err &&\n-\ttest_i18ngrep -e \"the option .--pathspec-file-nul. requires .--pathspec-from-file.\" err &&\n+\ttest_grep -e \"the option .--pathspec-file-nul. requires .--pathspec-from-file.\" err &&\n \n \t# This case succeeds, but still prints to stderr\n \tgit add --pathspec-from-file=empty_list 2>err &&\n-\ttest_i18ngrep -e \"Nothing specified, nothing added.\" err\n+\ttest_grep -e \"Nothing specified, nothing added.\" err\n '\n \n test_done\ndiff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh\nindex bfab245eb3..f27d09cfd9 100755\n--- a/t/t3900-i18n-commit.sh\n+++ b/t/t3900-i18n-commit.sh\n@@ -45,7 +45,7 @@ test_expect_success 'UTF-8 invalid characters refused' '\n \tprintf \"Commit message\\n\\nInvalid surrogate:\\355\\240\\200\\n\" \\\n \t\t>\"$HOME/invalid\" &&\n \tgit commit -a -F \"$HOME/invalid\" 2>\"$HOME\"/stderr &&\n-\ttest_i18ngrep \"did not conform\" \"$HOME\"/stderr\n+\ttest_grep \"did not conform\" \"$HOME\"/stderr\n '\n \n test_expect_success 'UTF-8 overlong sequences rejected' '\n@@ -55,7 +55,7 @@ test_expect_success 'UTF-8 overlong sequences rejected' '\n \tprintf \"\\340\\202\\251ommit message\\n\\nThis is not a space:\\300\\240\\n\" \\\n \t\t>\"$HOME/invalid\" &&\n \tgit commit -a -F \"$HOME/invalid\" 2>\"$HOME\"/stderr &&\n-\ttest_i18ngrep \"did not conform\" \"$HOME\"/stderr\n+\ttest_grep \"did not conform\" \"$HOME\"/stderr\n '\n \n test_expect_success 'UTF-8 non-characters refused' '\n@@ -64,7 +64,7 @@ test_expect_success 'UTF-8 non-characters refused' '\n \tprintf \"Commit message\\n\\nNon-character:\\364\\217\\277\\276\\n\" \\\n \t\t>\"$HOME/invalid\" &&\n \tgit commit -a -F \"$HOME/invalid\" 2>\"$HOME\"/stderr &&\n-\ttest_i18ngrep \"did not conform\" \"$HOME\"/stderr\n+\ttest_grep \"did not conform\" \"$HOME\"/stderr\n '\n \n test_expect_success 'UTF-8 non-characters refused' '\n@@ -73,7 +73,7 @@ test_expect_success 'UTF-8 non-characters refused' '\n \tprintf \"Commit message\\n\\nNon-character:\\357\\267\\220\\n\" \\\n \t\t>\"$HOME/invalid\" &&\n \tgit commit -a -F \"$HOME/invalid\" 2>\"$HOME\"/stderr &&\n-\ttest_i18ngrep \"did not conform\" \"$HOME\"/stderr\n+\ttest_grep \"did not conform\" \"$HOME\"/stderr\n '\n \n for H in ISO8859-1 eucJP ISO-2022-JP\ndiff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh\nindex 4f16a735d9..4b37f78829 100755\n--- a/t/t3901-i18n-patch.sh\n+++ b/t/t3901-i18n-patch.sh\n@@ -298,7 +298,7 @@ test_expect_success 'am --no-utf8 (U/L)' '\n \n \t# commit-tree will warn that the commit message does not contain valid UTF-8\n \t# as mailinfo did not convert it\n-\ttest_i18ngrep \"did not conform\" err &&\n+\ttest_grep \"did not conform\" err &&\n \n \tcheck_encoding 2\n '\ndiff --git a/t/t3903-stash.sh b/t/t3903-stash.sh\nindex 0b3dfeaea2..3bec71f056 100755\n--- a/t/t3903-stash.sh\n+++ b/t/t3903-stash.sh\n@@ -395,7 +395,7 @@ test_expect_success 'stash --staged' '\n \n test_expect_success 'dont assume push with non-option args' '\n \ttest_must_fail git stash -q drop 2>err &&\n-\ttest_i18ngrep -e \"subcommand wasn'\\''t specified; '\\''push'\\'' can'\\''t be assumed due to unexpected token '\\''drop'\\''\" err\n+\ttest_grep -e \"subcommand wasn'\\''t specified; '\\''push'\\'' can'\\''t be assumed due to unexpected token '\\''drop'\\''\" err\n '\n \n test_expect_success 'stash --invalid-option' '\n@@ -596,7 +596,7 @@ test_expect_success 'giving too many ref arguments does not modify files' '\n \tfor type in apply pop \"branch stash-branch\"\n \tdo\n \t\ttest_must_fail git stash $type stash@{0} stash@{1} 2>err &&\n-\t\ttest_i18ngrep \"Too many revisions\" err &&\n+\t\ttest_grep \"Too many revisions\" err &&\n \t\ttest 123456789 = $(test-tool chmtime -g file2) || return 1\n \tdone\n '\n@@ -604,14 +604,14 @@ test_expect_success 'giving too many ref arguments does not modify files' '\n test_expect_success 'drop: too many arguments errors out (does nothing)' '\n \tgit stash list >expect &&\n \ttest_must_fail git stash drop stash@{0} stash@{1} 2>err &&\n-\ttest_i18ngrep \"Too many revisions\" err &&\n+\ttest_grep \"Too many revisions\" err &&\n \tgit stash list >actual &&\n \ttest_cmp expect actual\n '\n \n test_expect_success 'show: too many arguments errors out (does nothing)' '\n \ttest_must_fail git stash show stash@{0} stash@{1} 2>err 1>out &&\n-\ttest_i18ngrep \"Too many revisions\" err &&\n+\ttest_grep \"Too many revisions\" err &&\n \ttest_must_be_empty out\n '\n \n@@ -654,7 +654,7 @@ test_expect_success 'stash branch - stashes on stack, stash-like argument' '\n \n test_expect_success 'stash branch complains with no arguments' '\n \ttest_must_fail git stash branch 2>err &&\n-\ttest_i18ngrep \"No branch name specified\" err\n+\ttest_grep \"No branch name specified\" err\n '\n \n test_expect_success 'stash show format defaults to --stat' '\ndiff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh\nindex 5390eec4e3..1289ae3e07 100755\n--- a/t/t3905-stash-include-untracked.sh\n+++ b/t/t3905-stash-include-untracked.sh\n@@ -404,7 +404,7 @@ test_expect_success 'stash show --include-untracked errors on duplicate files' '\n \t) &&\n \tw_commit=$(git commit-tree -p HEAD -p \"$i_commit\" -p \"$u_commit\" -m \"WIP on any-branch\" \"$tree\") &&\n \ttest_must_fail git stash show --include-untracked \"$w_commit\" 2>err &&\n-\ttest_i18ngrep \"worktree and untracked commit have duplicate entries: tracked\" err\n+\ttest_grep \"worktree and untracked commit have duplicate entries: tracked\" err\n '\n \n test_expect_success 'stash show --{include,only}-untracked on stashes without untracked entries' '\ndiff --git a/t/t3909-stash-pathspec-file.sh b/t/t3909-stash-pathspec-file.sh\nindex dead9f18d9..73f2dbdeb0 100755\n--- a/t/t3909-stash-pathspec-file.sh\n+++ b/t/t3909-stash-pathspec-file.sh\n@@ -88,13 +88,13 @@ test_expect_success 'error conditions' '\n \techo fileA.t >list &&\n \n \ttest_must_fail git stash push --pathspec-from-file=list --patch 2>err &&\n-\ttest_i18ngrep -e \"options .--pathspec-from-file. and .--patch. cannot be used together\" err &&\n+\ttest_grep -e \"options .--pathspec-from-file. and .--patch. cannot be used together\" err &&\n \n \ttest_must_fail git stash push --pathspec-from-file=list -- fileA.t 2>err &&\n-\ttest_i18ngrep -e \".--pathspec-from-file. and pathspec arguments cannot be used together\" err &&\n+\ttest_grep -e \".--pathspec-from-file. and pathspec arguments cannot be used together\" err &&\n \n \ttest_must_fail git stash push --pathspec-file-nul 2>err &&\n-\ttest_i18ngrep -e \"the option .--pathspec-file-nul. requires .--pathspec-from-file.\" err\n+\ttest_grep -e \"the option .--pathspec-file-nul. requires .--pathspec-from-file.\" err\n '\n \n test_done\ndiff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh\nindex 3dc9047044..85be1367de 100755\n--- a/t/t4001-diff-rename.sh\n+++ b/t/t4001-diff-rename.sh\n@@ -135,25 +135,25 @@ test_expect_success 'favour same basenames over different ones' '\n \tmkdir subdir &&\n \tgit mv another-path subdir/path1 &&\n \tgit status >out &&\n-\ttest_i18ngrep \"renamed: .*path1 -> subdir/path1\" out\n+\ttest_grep \"renamed: .*path1 -> subdir/path1\" out\n '\n \n test_expect_success 'test diff.renames=true for git status' '\n \tgit -c diff.renames=true status >out &&\n-\ttest_i18ngrep \"renamed: .*path1 -> subdir/path1\" out\n+\ttest_grep \"renamed: .*path1 -> subdir/path1\" out\n '\n \n test_expect_success 'test diff.renames=false for git status' '\n \tgit -c diff.renames=false status >out &&\n-\ttest_i18ngrep ! \"renamed: .*path1 -> subdir/path1\" out &&\n-\ttest_i18ngrep \"new file: .*subdir/path1\" out &&\n-\ttest_i18ngrep \"deleted: .*[^/]path1\" out\n+\ttest_grep ! \"renamed: .*path1 -> subdir/path1\" out &&\n+\ttest_grep \"new file: .*subdir/path1\" out &&\n+\ttest_grep \"deleted: .*[^/]path1\" out\n '\n \n test_expect_success 'favour same basenames even with minor differences' '\n \tgit show HEAD:path1 | sed \"s/15/16/\" > subdir/path1 &&\n \tgit status >out &&\n-\ttest_i18ngrep \"renamed: .*path1 -> subdir/path1\" out\n+\ttest_grep \"renamed: .*path1 -> subdir/path1\" out\n '\n \n test_expect_success 'two files with same basename and same content' '\n@@ -165,7 +165,7 @@ test_expect_success 'two files with same basename and same content' '\n \tgit commit -m 2 &&\n \tgit mv dir other-dir &&\n \tgit status >out &&\n-\ttest_i18ngrep \"renamed: .*dir/A/file -> other-dir/A/file\" out\n+\ttest_grep \"renamed: .*dir/A/file -> other-dir/A/file\" out\n '\n \n test_expect_success 'setup for many rename source candidates' '\n@@ -202,9 +202,9 @@ test_expect_success 'rename pretty print with nothing in common' '\n \tgit mv a/b/c c/b/a &&\n \tgit commit -m \"a/b/c -> c/b/a\" &&\n \tgit diff -M --summary HEAD^ HEAD >output &&\n-\ttest_i18ngrep \" a/b/c => c/b/a \" output &&\n+\ttest_grep \" a/b/c => c/b/a \" output &&\n \tgit diff -M --stat HEAD^ HEAD >output &&\n-\ttest_i18ngrep \" a/b/c => c/b/a \" output\n+\ttest_grep \" a/b/c => c/b/a \" output\n '\n \n test_expect_success 'rename pretty print with common prefix' '\n@@ -212,9 +212,9 @@ test_expect_success 'rename pretty print with common prefix' '\n \tgit mv c/b/a c/d/e &&\n \tgit commit -m \"c/b/a -> c/d/e\" &&\n \tgit diff -M --summary HEAD^ HEAD >output &&\n-\ttest_i18ngrep \" c/{b/a => d/e} \" output &&\n+\ttest_grep \" c/{b/a => d/e} \" output &&\n \tgit diff -M --stat HEAD^ HEAD >output &&\n-\ttest_i18ngrep \" c/{b/a => d/e} \" output\n+\ttest_grep \" c/{b/a => d/e} \" output\n '\n \n test_expect_success 'rename pretty print with common suffix' '\n@@ -222,9 +222,9 @@ test_expect_success 'rename pretty print with common suffix' '\n \tgit mv c/d/e d/e &&\n \tgit commit -m \"c/d/e -> d/e\" &&\n \tgit diff -M --summary HEAD^ HEAD >output &&\n-\ttest_i18ngrep \" {c/d => d}/e \" output &&\n+\ttest_grep \" {c/d => d}/e \" output &&\n \tgit diff -M --stat HEAD^ HEAD >output &&\n-\ttest_i18ngrep \" {c/d => d}/e \" output\n+\ttest_grep \" {c/d => d}/e \" output\n '\n \n test_expect_success 'rename pretty print with common prefix and suffix' '\n@@ -232,9 +232,9 @@ test_expect_success 'rename pretty print with common prefix and suffix' '\n \tgit mv d/e d/f/e &&\n \tgit commit -m \"d/e -> d/f/e\" &&\n \tgit diff -M --summary HEAD^ HEAD >output &&\n-\ttest_i18ngrep \" d/{ => f}/e \" output &&\n+\ttest_grep \" d/{ => f}/e \" output &&\n \tgit diff -M --stat HEAD^ HEAD >output &&\n-\ttest_i18ngrep \" d/{ => f}/e \" output\n+\ttest_grep \" d/{ => f}/e \" output\n '\n \n test_expect_success 'rename pretty print common prefix and suffix overlap' '\n@@ -242,9 +242,9 @@ test_expect_success 'rename pretty print common prefix and suffix overlap' '\n \tgit mv d/f/e d/f/f/e &&\n \tgit commit -m \"d/f/e d/f/f/e\" &&\n \tgit diff -M --summary HEAD^ HEAD >output &&\n-\ttest_i18ngrep \" d/f/{ => f}/e \" output &&\n+\ttest_grep \" d/f/{ => f}/e \" output &&\n \tgit diff -M --stat HEAD^ HEAD >output &&\n-\ttest_i18ngrep \" d/f/{ => f}/e \" output\n+\ttest_grep \" d/f/{ => f}/e \" output\n '\n \n test_expect_success 'diff-tree -l0 defaults to a big rename limit, not zero' '\ndiff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh\nindex 5de1d19075..86f3693bc0 100755\n--- a/t/t4013-diff-various.sh\n+++ b/t/t4013-diff-various.sh\n@@ -613,7 +613,7 @@ test_expect_success 'diff -I<regex> --stat' '\n \n test_expect_success 'diff -I<regex>: detect malformed regex' '\n \ttest_expect_code 129 git diff --ignore-matching-lines=\"^[124-9\" 2>error &&\n-\ttest_i18ngrep \"invalid regex given to -I: \" error\n+\ttest_grep \"invalid regex given to -I: \" error\n '\n \n # check_prefix <patch> <src> <dst>\ndiff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh\nindex 3cf2b7a7fb..7abd307c5c 100755\n--- a/t/t4014-format-patch.sh\n+++ b/t/t4014-format-patch.sh\n@@ -2369,25 +2369,25 @@ test_expect_success 'interdiff: cover-letter' '\n \t--q\n \tEOF\n \tgit format-patch --cover-letter --interdiff=boop~2 -1 boop &&\n-\ttest_i18ngrep \"^Interdiff:$\" 0000-cover-letter.patch &&\n-\ttest_i18ngrep ! \"^Interdiff:$\" 0001-fleep.patch &&\n+\ttest_grep \"^Interdiff:$\" 0000-cover-letter.patch &&\n+\ttest_grep ! \"^Interdiff:$\" 0001-fleep.patch &&\n \tsed \"1,/^@@ /d; /^-- $/q\" 0000-cover-letter.patch >actual &&\n \ttest_cmp expect actual\n '\n \n test_expect_success 'interdiff: reroll-count' '\n \tgit format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&\n-\ttest_i18ngrep \"^Interdiff ..* v1:$\" v2-0000-cover-letter.patch\n+\ttest_grep \"^Interdiff ..* v1:$\" v2-0000-cover-letter.patch\n '\n \n test_expect_success 'interdiff: reroll-count with a non-integer' '\n \tgit format-patch --cover-letter --interdiff=boop~2 -v2.2 -1 boop &&\n-\ttest_i18ngrep \"^Interdiff:$\" v2.2-0000-cover-letter.patch\n+\ttest_grep \"^Interdiff:$\" v2.2-0000-cover-letter.patch\n '\n \n test_expect_success 'interdiff: reroll-count with a integer' '\n \tgit format-patch --cover-letter --interdiff=boop~2 -v2 -1 boop &&\n-\ttest_i18ngrep \"^Interdiff ..* v1:$\" v2-0000-cover-letter.patch\n+\ttest_grep \"^Interdiff ..* v1:$\" v2-0000-cover-letter.patch\n '\n \n test_expect_success 'interdiff: solo-patch' '\n@@ -2396,7 +2396,7 @@ test_expect_success 'interdiff: solo-patch' '\n \n \tEOF\n \tgit format-patch --interdiff=boop~2 -1 boop &&\n-\ttest_i18ngrep \"^Interdiff:$\" 0001-fleep.patch &&\n+\ttest_grep \"^Interdiff:$\" 0001-fleep.patch &&\n \tsed \"1,/^  @@ /d; /^$/q\" 0001-fleep.patch >actual &&\n \ttest_cmp expect actual\n '\ndiff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh\nindex b298f220e0..730f025360 100755\n--- a/t/t4015-diff-whitespace.sh\n+++ b/t/t4015-diff-whitespace.sh\n@@ -909,7 +909,7 @@ test_expect_success 'combined diff with autocrlf conversion' '\n \tgit commit -m \"the other side\" x &&\n \tgit config core.autocrlf true &&\n \ttest_must_fail git merge one-side >actual &&\n-\ttest_i18ngrep \"Automatic merge failed\" actual &&\n+\ttest_grep \"Automatic merge failed\" actual &&\n \n \tgit diff >actual.raw &&\n \tsed -e \"1,/^@@@/d\" actual.raw >actual &&\n@@ -2187,27 +2187,27 @@ test_expect_success 'compare whitespace delta across moved blocks' '\n \n test_expect_success 'bogus settings in move detection erroring out' '\n \ttest_must_fail git diff --color-moved=bogus 2>err &&\n-\ttest_i18ngrep \"must be one of\" err &&\n-\ttest_i18ngrep bogus err &&\n+\ttest_grep \"must be one of\" err &&\n+\ttest_grep bogus err &&\n \n \ttest_must_fail git -c diff.colormoved=bogus diff 2>err &&\n-\ttest_i18ngrep \"must be one of\" err &&\n-\ttest_i18ngrep \"from command-line config\" err &&\n+\ttest_grep \"must be one of\" err &&\n+\ttest_grep \"from command-line config\" err &&\n \n \ttest_must_fail git diff --color-moved-ws=bogus 2>err &&\n-\ttest_i18ngrep \"possible values\" err &&\n-\ttest_i18ngrep bogus err &&\n+\ttest_grep \"possible values\" err &&\n+\ttest_grep bogus err &&\n \n \ttest_must_fail git -c diff.colormovedws=bogus diff 2>err &&\n-\ttest_i18ngrep \"possible values\" err &&\n-\ttest_i18ngrep \"from command-line config\" err\n+\ttest_grep \"possible values\" err &&\n+\ttest_grep \"from command-line config\" err\n '\n \n test_expect_success 'compare whitespace delta incompatible with other space options' '\n \ttest_must_fail git diff \\\n \t\t--color-moved-ws=allow-indentation-change,ignore-all-space \\\n \t\t2>err &&\n-\ttest_i18ngrep allow-indentation-change err\n+\ttest_grep allow-indentation-change err\n '\n \n EMPTY=''\ndiff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh\nindex c8d555771d..e026fac1f4 100755\n--- a/t/t4018-diff-funcname.sh\n+++ b/t/t4018-diff-funcname.sh\n@@ -53,15 +53,15 @@ do\n \t\techo \"*.java diff=$p\" >.gitattributes &&\n \t\ttest_expect_code 1 git diff --no-index \\\n \t\t\tA.java B.java 2>msg &&\n-\t\ttest_i18ngrep ! fatal msg &&\n-\t\ttest_i18ngrep ! error msg\n+\t\ttest_grep ! fatal msg &&\n+\t\ttest_grep ! error msg\n \t'\n \ttest_expect_success \"builtin $p wordRegex pattern compiles\" '\n \t\techo \"*.java diff=$p\" >.gitattributes &&\n \t\ttest_expect_code 1 git diff --no-index --word-diff \\\n \t\t\tA.java B.java 2>msg &&\n-\t\ttest_i18ngrep ! fatal msg &&\n-\t\ttest_i18ngrep ! error msg\n+\t\ttest_grep ! fatal msg &&\n+\t\ttest_grep ! error msg\n \t'\n \n \ttest_expect_success \"builtin $p pattern compiles on bare repo with --attr-source\" '\n@@ -79,8 +79,8 @@ do\n \t\tgit -C bare.git symbolic-ref HEAD refs/heads/master &&\n \t\ttest_expect_code 1 git -C bare.git --attr-source=branchA \\\n \t\t\tdiff --exit-code HEAD:A.java HEAD:B.java 2>msg &&\n-\t\ttest_i18ngrep ! fatal msg &&\n-\t\ttest_i18ngrep ! error msg\n+\t\ttest_grep ! fatal msg &&\n+\t\ttest_grep ! error msg\n \t'\n done\n \n@@ -88,7 +88,7 @@ test_expect_success 'last regexp must not be negated' '\n \techo \"*.java diff=java\" >.gitattributes &&\n \ttest_config diff.java.funcname \"!static\" &&\n \ttest_expect_code 128 git diff --no-index A.java B.java 2>msg &&\n-\ttest_i18ngrep \": Last expression must not be negated:\" msg\n+\ttest_grep \": Last expression must not be negated:\" msg\n '\n \n test_expect_success 'setup hunk header tests' '\ndiff --git a/t/t4031-diff-rewrite-binary.sh b/t/t4031-diff-rewrite-binary.sh\nindex eacc6694f7..c4394a27b5 100755\n--- a/t/t4031-diff-rewrite-binary.sh\n+++ b/t/t4031-diff-rewrite-binary.sh\n@@ -53,7 +53,7 @@ test_expect_success 'rewrite diff --numstat shows binary changes' '\n test_expect_success 'diff --stat counts binary rewrite as 0 lines' '\n \tgit diff -B --stat --summary >diff &&\n \tgrep \"Bin\" diff &&\n-\ttest_i18ngrep \"0 insertions.*0 deletions\" diff &&\n+\ttest_grep \"0 insertions.*0 deletions\" diff &&\n \tgrep \" rewrite file\" diff\n '\n \ndiff --git a/t/t4047-diff-dirstat.sh b/t/t4047-diff-dirstat.sh\nindex 70224c3da1..7b73462d53 100755\n--- a/t/t4047-diff-dirstat.sh\n+++ b/t/t4047-diff-dirstat.sh\n@@ -943,37 +943,37 @@ test_expect_success '--dirstat=future_param,lines,0 should fail loudly' '\n \ttest_must_fail git diff --dirstat=future_param,lines,0 HEAD^..HEAD >actual_diff_dirstat 2>actual_error &&\n \ttest_debug \"cat actual_error\" &&\n \ttest_must_be_empty actual_diff_dirstat &&\n-\ttest_i18ngrep -q \"future_param\" actual_error &&\n-\ttest_i18ngrep -q \"\\--dirstat\" actual_error\n+\ttest_grep -q \"future_param\" actual_error &&\n+\ttest_grep -q \"\\--dirstat\" actual_error\n '\n \n test_expect_success '--dirstat=dummy1,cumulative,2dummy should report both unrecognized parameters' '\n \ttest_must_fail git diff --dirstat=dummy1,cumulative,2dummy HEAD^..HEAD >actual_diff_dirstat 2>actual_error &&\n \ttest_debug \"cat actual_error\" &&\n \ttest_must_be_empty actual_diff_dirstat &&\n-\ttest_i18ngrep -q \"dummy1\" actual_error &&\n-\ttest_i18ngrep -q \"2dummy\" actual_error &&\n-\ttest_i18ngrep -q \"\\--dirstat\" actual_error\n+\ttest_grep -q \"dummy1\" actual_error &&\n+\ttest_grep -q \"2dummy\" actual_error &&\n+\ttest_grep -q \"\\--dirstat\" actual_error\n '\n \n test_expect_success 'diff.dirstat=future_param,0,lines should warn, but still work' '\n \tgit -c diff.dirstat=future_param,0,lines diff --dirstat HEAD^..HEAD >actual_diff_dirstat 2>actual_error &&\n \ttest_debug \"cat actual_error\" &&\n \ttest_cmp expect_diff_dirstat actual_diff_dirstat &&\n-\ttest_i18ngrep -q \"future_param\" actual_error &&\n-\ttest_i18ngrep -q \"diff\\\\.dirstat\" actual_error &&\n+\ttest_grep -q \"future_param\" actual_error &&\n+\ttest_grep -q \"diff\\\\.dirstat\" actual_error &&\n \n \tgit -c diff.dirstat=future_param,0,lines diff --dirstat -M HEAD^..HEAD >actual_diff_dirstat_M 2>actual_error &&\n \ttest_debug \"cat actual_error\" &&\n \ttest_cmp expect_diff_dirstat_M actual_diff_dirstat_M &&\n-\ttest_i18ngrep -q \"future_param\" actual_error &&\n-\ttest_i18ngrep -q \"diff\\\\.dirstat\" actual_error &&\n+\ttest_grep -q \"future_param\" actual_error &&\n+\ttest_grep -q \"diff\\\\.dirstat\" actual_error &&\n \n \tgit -c diff.dirstat=future_param,0,lines diff --dirstat -C -C HEAD^..HEAD >actual_diff_dirstat_CC 2>actual_error &&\n \ttest_debug \"cat actual_error\" &&\n \ttest_cmp expect_diff_dirstat_CC actual_diff_dirstat_CC &&\n-\ttest_i18ngrep -q \"future_param\" actual_error &&\n-\ttest_i18ngrep -q \"diff\\\\.dirstat\" actual_error\n+\ttest_grep -q \"future_param\" actual_error &&\n+\ttest_grep -q \"diff\\\\.dirstat\" actual_error\n '\n \n test_expect_success '--shortstat --dirstat should output only one dirstat' '\ndiff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh\nindex 6781cc9078..5a5d958b96 100755\n--- a/t/t4053-diff-no-index.sh\n+++ b/t/t4053-diff-no-index.sh\n@@ -56,7 +56,7 @@ test_expect_success 'git diff --no-index executed outside repo gives correct err\n \t\texport GIT_CEILING_DIRECTORIES &&\n \t\tcd non/git &&\n \t\ttest_must_fail git diff --no-index a 2>actual.err &&\n-\t\ttest_i18ngrep \"usage: git diff --no-index\" actual.err\n+\t\ttest_grep \"usage: git diff --no-index\" actual.err\n \t)\n '\n \ndiff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh\nindex 73048d0a52..3ea9ae99e0 100755\n--- a/t/t4055-diff-context.sh\n+++ b/t/t4055-diff-context.sh\n@@ -74,13 +74,13 @@ test_expect_success 'plumbing not affected' '\n test_expect_success 'non-integer config parsing' '\n \tgit config diff.context no &&\n \ttest_must_fail git diff 2>output &&\n-\ttest_i18ngrep \"bad numeric config value\" output\n+\ttest_grep \"bad numeric config value\" output\n '\n \n test_expect_success 'negative integer config parsing' '\n \tgit config diff.context -1 &&\n \ttest_must_fail git diff 2>output &&\n-\ttest_i18ngrep \"bad config variable\" output\n+\ttest_grep \"bad config variable\" output\n '\n \n test_expect_success '-U0 is valid, so is diff.context=0' '\ndiff --git a/t/t4068-diff-symmetric-merge-base.sh b/t/t4068-diff-symmetric-merge-base.sh\nindex 2d650d8f10..3356d91cd4 100755\n--- a/t/t4068-diff-symmetric-merge-base.sh\n+++ b/t/t4068-diff-symmetric-merge-base.sh\n@@ -68,27 +68,27 @@ test_expect_success 'diff with two merge bases' '\n \n test_expect_success 'diff with no merge bases' '\n \ttest_must_fail git diff br2...br3 2>err &&\n-\ttest_i18ngrep \"fatal: br2...br3: no merge base\" err\n+\ttest_grep \"fatal: br2...br3: no merge base\" err\n '\n \n test_expect_success 'diff with too many symmetric differences' '\n \ttest_must_fail git diff br1...main br2...br3 2>err &&\n-\ttest_i18ngrep \"usage\" err\n+\ttest_grep \"usage\" err\n '\n \n test_expect_success 'diff with symmetric difference and extraneous arg' '\n \ttest_must_fail git diff main br1...main 2>err &&\n-\ttest_i18ngrep \"usage\" err\n+\ttest_grep \"usage\" err\n '\n \n test_expect_success 'diff with two ranges' '\n \ttest_must_fail git diff main br1..main br2..br3 2>err &&\n-\ttest_i18ngrep \"usage\" err\n+\ttest_grep \"usage\" err\n '\n \n test_expect_success 'diff with ranges and extra arg' '\n \ttest_must_fail git diff main br1..main commit-D 2>err &&\n-\ttest_i18ngrep \"usage\" err\n+\ttest_grep \"usage\" err\n '\n \n test_expect_success 'diff --merge-base with no commits' '\n@@ -97,7 +97,7 @@ test_expect_success 'diff --merge-base with no commits' '\n \n test_expect_success 'diff --merge-base with three commits' '\n \ttest_must_fail git diff --merge-base br1 br2 main 2>err &&\n-\ttest_i18ngrep \"usage\" err\n+\ttest_grep \"usage\" err\n '\n \n for cmd in diff-index diff\n@@ -143,19 +143,19 @@ do\n \ttest_expect_success \"$cmd --merge-base with non-commit\" '\n \t\tgit checkout main &&\n \t\ttest_must_fail git $cmd --merge-base main^{tree} 2>err &&\n-\t\ttest_i18ngrep \"fatal: --merge-base only works with commits\" err\n+\t\ttest_grep \"fatal: --merge-base only works with commits\" err\n \t'\n \n \ttest_expect_success \"$cmd --merge-base with no merge bases and one commit\" '\n \t\tgit checkout main &&\n \t\ttest_must_fail git $cmd --merge-base br3 2>err &&\n-\t\ttest_i18ngrep \"fatal: no merge base found\" err\n+\t\ttest_grep \"fatal: no merge base found\" err\n \t'\n \n \ttest_expect_success \"$cmd --merge-base with multiple merge bases and one commit\" '\n \t\tgit checkout main &&\n \t\ttest_must_fail git $cmd --merge-base br1 2>err &&\n-\t\ttest_i18ngrep \"fatal: multiple merge bases found\" err\n+\t\ttest_grep \"fatal: multiple merge bases found\" err\n \t'\n done\n \n@@ -169,28 +169,28 @@ do\n \n \ttest_expect_success \"$cmd --merge-base commit and non-commit\" '\n \t\ttest_must_fail git $cmd --merge-base br2 main^{tree} 2>err &&\n-\t\ttest_i18ngrep \"fatal: --merge-base only works with commits\" err\n+\t\ttest_grep \"fatal: --merge-base only works with commits\" err\n \t'\n \n \ttest_expect_success \"$cmd --merge-base with no merge bases and two commits\" '\n \t\ttest_must_fail git $cmd --merge-base br2 br3 2>err &&\n-\t\ttest_i18ngrep \"fatal: no merge base found\" err\n+\t\ttest_grep \"fatal: no merge base found\" err\n \t'\n \n \ttest_expect_success \"$cmd --merge-base with multiple merge bases and two commits\" '\n \t\ttest_must_fail git $cmd --merge-base main br1 2>err &&\n-\t\ttest_i18ngrep \"fatal: multiple merge bases found\" err\n+\t\ttest_grep \"fatal: multiple merge bases found\" err\n \t'\n done\n \n test_expect_success 'diff-tree --merge-base with one commit' '\n \ttest_must_fail git diff-tree --merge-base main 2>err &&\n-\ttest_i18ngrep \"fatal: --merge-base only works with two commits\" err\n+\ttest_grep \"fatal: --merge-base only works with two commits\" err\n '\n \n test_expect_success 'diff --merge-base with range' '\n \ttest_must_fail git diff --merge-base br2..br3 2>err &&\n-\ttest_i18ngrep \"fatal: --merge-base does not work with ranges\" err\n+\ttest_grep \"fatal: --merge-base does not work with ranges\" err\n '\n \n test_done\ndiff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh\nindex a22a90d552..cbef0a593f 100755\n--- a/t/t4115-apply-symlink.sh\n+++ b/t/t4115-apply-symlink.sh\n@@ -136,7 +136,7 @@ test_expect_success SYMLINKS '--reject removes .rej symlink if it exists' '\n \n \tln -s foo file.t.rej &&\n \ttest_must_fail git apply patch --reject 2>err &&\n-\ttest_i18ngrep \"Rejected hunk\" err &&\n+\ttest_grep \"Rejected hunk\" err &&\n \ttest_path_is_missing foo &&\n \ttest_path_is_file file.t.rej\n '\ndiff --git a/t/t4120-apply-popt.sh b/t/t4120-apply-popt.sh\nindex 497b62868d..697e86c0ff 100755\n--- a/t/t4120-apply-popt.sh\n+++ b/t/t4120-apply-popt.sh\n@@ -31,7 +31,7 @@ test_expect_success 'apply git diff with -p2' '\n test_expect_success 'apply with too large -p' '\n \tcp file1.saved file1 &&\n \ttest_must_fail git apply --stat -p3 patch.file 2>err &&\n-\ttest_i18ngrep \"removing 3 leading\" err\n+\ttest_grep \"removing 3 leading\" err\n '\n \n test_expect_success 'apply (-p2) traditional diff with funny filenames' '\n@@ -53,7 +53,7 @@ test_expect_success 'apply (-p2) traditional diff with funny filenames' '\n test_expect_success 'apply with too large -p and fancy filename' '\n \tcp file1.saved file1 &&\n \ttest_must_fail git apply --stat -p3 patch.escaped 2>err &&\n-\ttest_i18ngrep \"removing 3 leading\" err\n+\ttest_grep \"removing 3 leading\" err\n '\n \n test_expect_success 'apply (-p2) diff, mode change only' '\ndiff --git a/t/t4122-apply-symlink-inside.sh b/t/t4122-apply-symlink-inside.sh\nindex 9696537303..2089d84f64 100755\n--- a/t/t4122-apply-symlink-inside.sh\n+++ b/t/t4122-apply-symlink-inside.sh\n@@ -95,19 +95,19 @@ test_expect_success SYMLINKS 'do not follow symbolic link (same input)' '\n \n \t# same input creates a confusing symbolic link\n \ttest_must_fail git apply patch 2>error-wt &&\n-\ttest_i18ngrep \"beyond a symbolic link\" error-wt &&\n+\ttest_grep \"beyond a symbolic link\" error-wt &&\n \ttest_path_is_missing arch/x86_64/dir &&\n \ttest_path_is_missing arch/i386/dir/file &&\n \n \ttest_must_fail git apply --index patch 2>error-ix &&\n-\ttest_i18ngrep \"beyond a symbolic link\" error-ix &&\n+\ttest_grep \"beyond a symbolic link\" error-ix &&\n \ttest_path_is_missing arch/x86_64/dir &&\n \ttest_path_is_missing arch/i386/dir/file &&\n \ttest_must_fail git ls-files --error-unmatch arch/x86_64/dir &&\n \ttest_must_fail git ls-files --error-unmatch arch/i386/dir &&\n \n \ttest_must_fail git apply --cached patch 2>error-ct &&\n-\ttest_i18ngrep \"beyond a symbolic link\" error-ct &&\n+\ttest_grep \"beyond a symbolic link\" error-ct &&\n \ttest_must_fail git ls-files --error-unmatch arch/x86_64/dir &&\n \ttest_must_fail git ls-files --error-unmatch arch/i386/dir &&\n \n@@ -135,23 +135,23 @@ test_expect_success SYMLINKS 'do not follow symbolic link (existing)' '\n \tgit add arch/x86_64/dir &&\n \n \ttest_must_fail git apply add_file.patch 2>error-wt-add &&\n-\ttest_i18ngrep \"beyond a symbolic link\" error-wt-add &&\n+\ttest_grep \"beyond a symbolic link\" error-wt-add &&\n \ttest_path_is_missing arch/i386/dir/file &&\n \n \tmkdir arch/i386/dir &&\n \t>arch/i386/dir/file &&\n \ttest_must_fail git apply del_file.patch 2>error-wt-del &&\n-\ttest_i18ngrep \"beyond a symbolic link\" error-wt-del &&\n+\ttest_grep \"beyond a symbolic link\" error-wt-del &&\n \ttest_path_is_file arch/i386/dir/file &&\n \trm arch/i386/dir/file &&\n \n \ttest_must_fail git apply --index add_file.patch 2>error-ix-add &&\n-\ttest_i18ngrep \"beyond a symbolic link\" error-ix-add &&\n+\ttest_grep \"beyond a symbolic link\" error-ix-add &&\n \ttest_path_is_missing arch/i386/dir/file &&\n \ttest_must_fail git ls-files --error-unmatch arch/i386/dir &&\n \n \ttest_must_fail git apply --cached add_file.patch 2>error-ct-file &&\n-\ttest_i18ngrep \"beyond a symbolic link\" error-ct-file &&\n+\ttest_grep \"beyond a symbolic link\" error-ct-file &&\n \ttest_must_fail git ls-files --error-unmatch arch/i386/dir\n '\n \ndiff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh\nindex a1c7686519..e7a7295f1b 100755\n--- a/t/t4129-apply-samemode.sh\n+++ b/t/t4129-apply-samemode.sh\n@@ -66,13 +66,13 @@ test_expect_success FILEMODE 'mode update (index only)' '\n test_expect_success FILEMODE 'empty mode is rejected' '\n \tgit reset --hard &&\n \ttest_must_fail git apply patch-empty-mode.txt 2>err &&\n-\ttest_i18ngrep \"invalid mode\" err\n+\ttest_grep \"invalid mode\" err\n '\n \n test_expect_success FILEMODE 'bogus mode is rejected' '\n \tgit reset --hard &&\n \ttest_must_fail git apply patch-bogus-mode.txt 2>err &&\n-\ttest_i18ngrep \"invalid mode\" err\n+\ttest_grep \"invalid mode\" err\n '\n \n test_expect_success POSIXPERM 'do not use core.sharedRepository for working tree files' '\ndiff --git a/t/t4133-apply-filenames.sh b/t/t4133-apply-filenames.sh\nindex 35f1060bc8..c21ddb2946 100755\n--- a/t/t4133-apply-filenames.sh\n+++ b/t/t4133-apply-filenames.sh\n@@ -32,9 +32,9 @@ EOF\n \n test_expect_success 'apply diff with inconsistent filenames in headers' '\n \ttest_must_fail git apply bad1.patch 2>err &&\n-\ttest_i18ngrep \"inconsistent new filename\" err &&\n+\ttest_grep \"inconsistent new filename\" err &&\n \ttest_must_fail git apply bad2.patch 2>err &&\n-\ttest_i18ngrep \"inconsistent old filename\" err\n+\ttest_grep \"inconsistent old filename\" err\n '\n \n test_expect_success 'apply diff with new filename missing from headers' '\n@@ -46,7 +46,7 @@ test_expect_success 'apply diff with new filename missing from headers' '\n \t+1\n \tEOF\n \ttest_must_fail git apply missing_new_filename.diff 2>err &&\n-\ttest_i18ngrep \"lacks filename information\" err\n+\ttest_grep \"lacks filename information\" err\n '\n \n test_expect_success 'apply diff with old filename missing from headers' '\n@@ -58,7 +58,7 @@ test_expect_success 'apply diff with old filename missing from headers' '\n \t-1\n \tEOF\n \ttest_must_fail git apply missing_old_filename.diff 2>err &&\n-\ttest_i18ngrep \"lacks filename information\" err\n+\ttest_grep \"lacks filename information\" err\n '\n \n test_done\ndiff --git a/t/t4150-am.sh b/t/t4150-am.sh\nindex 2935fe1b2d..3b12576269 100755\n--- a/t/t4150-am.sh\n+++ b/t/t4150-am.sh\n@@ -779,7 +779,7 @@ test_expect_success 'am --resolved fails if index has unmerged entries' '\n \ttest_must_fail git am --resolved >err &&\n \ttest_path_is_dir .git/rebase-apply &&\n \ttest_cmp_rev second HEAD &&\n-\ttest_i18ngrep \"still have unmerged paths\" err\n+\ttest_grep \"still have unmerged paths\" err\n '\n \n test_expect_success 'am takes patches from a Pine mailbox' '\n@@ -913,7 +913,7 @@ test_expect_success 'am newline in subject' '\n \ttest_tick &&\n \tsed -e \"s/second/second \\\\\\n foo/\" patch1 >patchnl &&\n \tgit am <patchnl >output.out 2>&1 &&\n-\ttest_i18ngrep \"^Applying: second \\\\\\n foo$\" output.out\n+\ttest_grep \"^Applying: second \\\\\\n foo$\" output.out\n '\n \n test_expect_success 'am -q is quiet' '\ndiff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh\nindex 5ed7e22827..edb38da701 100755\n--- a/t/t4151-am-abort.sh\n+++ b/t/t4151-am-abort.sh\n@@ -46,7 +46,7 @@ do\n \n \ttest_expect_success \"am$with3 --skip continue after failed am$with3\" '\n \t\ttest_must_fail git am$with3 --skip >output &&\n-\t\ttest_i18ngrep \"^Applying: 6$\" output &&\n+\t\ttest_grep \"^Applying: 6$\" output &&\n \t\ttest_cmp file-2-expect file-2 &&\n \t\ttest ! -f .git/MERGE_RR\n \t'\ndiff --git a/t/t4153-am-resume-override-opts.sh b/t/t4153-am-resume-override-opts.sh\nindex b7c3861407..4add7c7757 100755\n--- a/t/t4153-am-resume-override-opts.sh\n+++ b/t/t4153-am-resume-override-opts.sh\n@@ -53,7 +53,7 @@ test_expect_success '--no-quiet overrides --quiet' '\n \t# Applying side1 will be quiet.\n \ttest_must_fail git am --quiet side[123].eml >out &&\n \ttest_path_is_dir .git/rebase-apply &&\n-\ttest_i18ngrep ! \"^Applying: \" out &&\n+\ttest_grep ! \"^Applying: \" out &&\n \techo side1 >file &&\n \tgit add file &&\n \ndiff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh\nindex 7025cfdae5..fb53dddf79 100755\n--- a/t/t4200-rerere.sh\n+++ b/t/t4200-rerere.sh\n@@ -433,13 +433,13 @@ test_expect_success 'rerere --no-no-rerere-autoupdate' '\n \tgit update-index --index-info <failedmerge &&\n \tcp file3.conflict file3 &&\n \ttest_must_fail git rerere --no-no-rerere-autoupdate 2>err &&\n-\ttest_i18ngrep [Uu]sage err &&\n+\ttest_grep [Uu]sage err &&\n \ttest_must_fail git update-index --refresh\n '\n \n test_expect_success 'rerere -h' '\n \ttest_must_fail git rerere -h >help &&\n-\ttest_i18ngrep [Uu]sage help\n+\ttest_grep [Uu]sage help\n '\n \n concat_insert () {\ndiff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh\nindex 8e4effebdb..d7382709fc 100755\n--- a/t/t4201-shortlog.sh\n+++ b/t/t4201-shortlog.sh\n@@ -139,7 +139,7 @@ test_expect_success !MINGW 'shortlog can read --format=raw output' '\n \n test_expect_success 'shortlog from non-git directory refuses extra arguments' '\n \ttest_must_fail env GIT_DIR=non-existing git shortlog foo 2>out &&\n-\ttest_i18ngrep \"too many arguments\" out\n+\ttest_grep \"too many arguments\" out\n '\n \n test_expect_success 'shortlog should add newline when input line matches wraplen' '\ndiff --git a/t/t4202-log.sh b/t/t4202-log.sh\nindex af4a123cd2..708636671a 100755\n--- a/t/t4202-log.sh\n+++ b/t/t4202-log.sh\n@@ -1884,7 +1884,7 @@ test_expect_success '--no-graph does not unset --parents' '\n \n test_expect_success '--reverse and --graph conflict' '\n \ttest_must_fail git log --reverse --graph 2>stderr &&\n-\ttest_i18ngrep \"cannot be used together\" stderr\n+\ttest_grep \"cannot be used together\" stderr\n '\n \n test_expect_success '--reverse --graph --no-graph works' '\n@@ -1895,7 +1895,7 @@ test_expect_success '--reverse --graph --no-graph works' '\n \n test_expect_success '--show-linear-break and --graph conflict' '\n \ttest_must_fail git log --show-linear-break --graph 2>stderr &&\n-\ttest_i18ngrep \"cannot be used together\" stderr\n+\ttest_grep \"cannot be used together\" stderr\n '\n \n test_expect_success '--show-linear-break --graph --no-graph works' '\n@@ -1906,7 +1906,7 @@ test_expect_success '--show-linear-break --graph --no-graph works' '\n \n test_expect_success '--no-walk and --graph conflict' '\n \ttest_must_fail git log --no-walk --graph 2>stderr &&\n-\ttest_i18ngrep \"cannot be used together\" stderr\n+\ttest_grep \"cannot be used together\" stderr\n '\n \n test_expect_success '--no-walk --graph --no-graph works' '\n@@ -1917,8 +1917,8 @@ test_expect_success '--no-walk --graph --no-graph works' '\n \n test_expect_success '--walk-reflogs and --graph conflict' '\n \ttest_must_fail git log --walk-reflogs --graph 2>stderr &&\n-\t(test_i18ngrep \"cannot combine\" stderr ||\n-\t\ttest_i18ngrep \"cannot be used together\" stderr)\n+\t(test_grep \"cannot combine\" stderr ||\n+\t\ttest_grep \"cannot be used together\" stderr)\n '\n \n test_expect_success '--walk-reflogs --graph --no-graph works' '\n@@ -2252,7 +2252,7 @@ test_expect_success 'log on empty repo fails' '\n \tgit init empty &&\n \ttest_when_finished \"rm -rf empty\" &&\n \ttest_must_fail git -C empty log 2>stderr &&\n-\ttest_i18ngrep does.not.have.any.commits stderr\n+\ttest_grep does.not.have.any.commits stderr\n '\n \n test_expect_success REFFILES 'log diagnoses bogus HEAD hash' '\n@@ -2260,16 +2260,16 @@ test_expect_success REFFILES 'log diagnoses bogus HEAD hash' '\n \ttest_when_finished \"rm -rf empty\" &&\n \techo 1234abcd >empty/.git/refs/heads/main &&\n \ttest_must_fail git -C empty log 2>stderr &&\n-\ttest_i18ngrep broken stderr\n+\ttest_grep broken stderr\n '\n \n test_expect_success REFFILES 'log diagnoses bogus HEAD symref' '\n \tgit init empty &&\n \techo \"ref: refs/heads/invalid.lock\" > empty/.git/HEAD &&\n \ttest_must_fail git -C empty log 2>stderr &&\n-\ttest_i18ngrep broken stderr &&\n+\ttest_grep broken stderr &&\n \ttest_must_fail git -C empty log --default totally-bogus 2>stderr &&\n-\ttest_i18ngrep broken stderr\n+\ttest_grep broken stderr\n '\n \n test_expect_success 'log does not default to HEAD when rev input is given' '\ndiff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh\nindex 2016132f51..8a88dd7900 100755\n--- a/t/t4203-mailmap.sh\n+++ b/t/t4203-mailmap.sh\n@@ -360,7 +360,7 @@ test_expect_success 'mailmap.blob might be the wrong type' '\n \tcp default.map .mailmap &&\n \n \tgit -c mailmap.blob=HEAD: shortlog HEAD >actual 2>err &&\n-\ttest_i18ngrep \"mailmap is not a blob\" err &&\n+\ttest_grep \"mailmap is not a blob\" err &&\n \ttest_cmp expect actual\n '\n \ndiff --git a/t/t4208-log-magic-pathspec.sh b/t/t4208-log-magic-pathspec.sh\nindex 2e8f5ad7b8..806b2809d4 100755\n--- a/t/t4208-log-magic-pathspec.sh\n+++ b/t/t4208-log-magic-pathspec.sh\n@@ -21,7 +21,7 @@ test_expect_success '\"git log :/\" should not be ambiguous' '\n test_expect_success '\"git log :/a\" should be ambiguous (applied both rev and worktree)' '\n \t: >a &&\n \ttest_must_fail git log :/a 2>error &&\n-\ttest_i18ngrep ambiguous error\n+\ttest_grep ambiguous error\n '\n \n test_expect_success '\"git log :/a -- \" should not be ambiguous' '\n@@ -65,7 +65,7 @@ test_expect_success '\"git log :/in\" should not be ambiguous' '\n \n test_expect_success '\"git log :\" should be ambiguous' '\n \ttest_must_fail git log : 2>error &&\n-\ttest_i18ngrep ambiguous error\n+\ttest_grep ambiguous error\n '\n \n test_expect_success 'git log -- :' '\n@@ -104,7 +104,7 @@ test_expect_success '\"git log :(exclude)sub --\" must resolve as an object' '\n \n test_expect_success '\"git log :(unknown-magic) complains of bogus magic' '\n \ttest_must_fail git log \":(unknown-magic)\" 2>error &&\n-\ttest_i18ngrep pathspec.magic error\n+\ttest_grep pathspec.magic error\n '\n \n test_expect_success 'command line pathspec parsing for \"git log\"' '\ndiff --git a/t/t4209-log-pickaxe.sh b/t/t4209-log-pickaxe.sh\nindex 7f6bb27f14..64e1623733 100755\n--- a/t/t4209-log-pickaxe.sh\n+++ b/t/t4209-log-pickaxe.sh\n@@ -57,10 +57,10 @@ test_expect_success setup '\n \n test_expect_success 'usage' '\n \ttest_expect_code 129 git log -S 2>err &&\n-\ttest_i18ngrep \"switch.*requires a value\" err &&\n+\ttest_grep \"switch.*requires a value\" err &&\n \n \ttest_expect_code 129 git log -G 2>err &&\n-\ttest_i18ngrep \"switch.*requires a value\" err &&\n+\ttest_grep \"switch.*requires a value\" err &&\n \n \ttest_expect_code 128 git log -Gregex -Sstring 2>err &&\n \tgrep \"cannot be used together\" err &&\ndiff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh\nindex c6540e822f..02d76dca28 100755\n--- a/t/t4211-line-log.sh\n+++ b/t/t4211-line-log.sh\n@@ -19,7 +19,7 @@ test_expect_success 'basic command line parsing' '\n \n \t# -L requires there is no pathspec\n \ttest_must_fail git log -L1,1:b.c -- b.c 2>error &&\n-\ttest_i18ngrep \"cannot be used with pathspec\" error &&\n+\ttest_grep \"cannot be used with pathspec\" error &&\n \n \t# This would fail because --follow wants a single path, but\n \t# we may fail due to incompatibility between -L/--follow in\n@@ -50,7 +50,7 @@ canned_test_failure () {\n test_bad_opts () {\n \ttest_expect_success \"invalid args: $1\" \"\n \t\ttest_must_fail git log $1 2>errors &&\n-\t\ttest_i18ngrep '$2' errors\n+\t\ttest_grep '$2' errors\n \t\"\n }\n \ndiff --git a/t/t4212-log-corrupt.sh b/t/t4212-log-corrupt.sh\nindex 85e90acb09..e6b59123a3 100755\n--- a/t/t4212-log-corrupt.sh\n+++ b/t/t4212-log-corrupt.sh\n@@ -17,7 +17,7 @@ test_expect_success 'setup' '\n \n test_expect_success 'fsck notices broken commit' '\n \ttest_must_fail git fsck 2>actual &&\n-\ttest_i18ngrep invalid.author actual\n+\ttest_grep invalid.author actual\n '\n \n test_expect_success 'git log with broken author email' '\ndiff --git a/t/t4256-am-format-flowed.sh b/t/t4256-am-format-flowed.sh\nindex 1015273bc8..92d8c8b651 100755\n--- a/t/t4256-am-format-flowed.sh\n+++ b/t/t4256-am-format-flowed.sh\n@@ -13,7 +13,7 @@ test_expect_success 'setup' '\n \n test_expect_success 'am with format=flowed' '\n \tgit am <\"$TEST_DIRECTORY/t4256/1/patch\" 2>stderr &&\n-\ttest_i18ngrep \"warning: Patch sent with format=flowed\" stderr &&\n+\ttest_grep \"warning: Patch sent with format=flowed\" stderr &&\n \ttest_cmp \"$TEST_DIRECTORY/t4256/1/mailinfo.c\" mailinfo.c\n '\n \ndiff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh\nindex 745089479c..d402ec18b7 100755\n--- a/t/t5300-pack-object.sh\n+++ b/t/t5300-pack-object.sh\n@@ -541,7 +541,7 @@ test_expect_success 'make sure index-pack detects the SHA1 collision' '\n \t(\n \t\tcd corrupt &&\n \t\ttest_must_fail git index-pack -o ../bad.idx ../test-3.pack 2>msg &&\n-\t\ttest_i18ngrep \"SHA1 COLLISION FOUND\" msg\n+\t\ttest_grep \"SHA1 COLLISION FOUND\" msg\n \t)\n '\n \n@@ -549,7 +549,7 @@ test_expect_success 'make sure index-pack detects the SHA1 collision (large blob\n \t(\n \t\tcd corrupt &&\n \t\ttest_must_fail git -c core.bigfilethreshold=1 index-pack -o ../bad.idx ../test-3.pack 2>msg &&\n-\t\ttest_i18ngrep \"SHA1 COLLISION FOUND\" msg\n+\t\ttest_grep \"SHA1 COLLISION FOUND\" msg\n \t)\n '\n \ndiff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh\nindex f89809be53..d88e6f1691 100755\n--- a/t/t5302-pack-index.sh\n+++ b/t/t5302-pack-index.sh\n@@ -282,8 +282,8 @@ test_expect_success 'index-pack --fsck-objects also warns upon missing tagger in\n test_expect_success 'index-pack -v --stdin produces progress for both phases' '\n \tpack=$(git pack-objects --all pack </dev/null) &&\n \tGIT_PROGRESS_DELAY=0 git index-pack -v --stdin <pack-$pack.pack 2>err &&\n-\ttest_i18ngrep \"Receiving objects\" err &&\n-\ttest_i18ngrep \"Resolving deltas\" err\n+\ttest_grep \"Receiving objects\" err &&\n+\ttest_grep \"Resolving deltas\" err\n '\n \n test_expect_success 'too-large packs report the breach' '\ndiff --git a/t/t5304-prune.sh b/t/t5304-prune.sh\nindex b4df545e5a..1f1f664871 100755\n--- a/t/t5304-prune.sh\n+++ b/t/t5304-prune.sh\n@@ -318,10 +318,10 @@ test_expect_success 'prune: handle HEAD reflog in multiple worktrees' '\n \n test_expect_success 'prune: handle expire option correctly' '\n \ttest_must_fail git prune --expire 2>error &&\n-\ttest_i18ngrep \"requires a value\" error &&\n+\ttest_grep \"requires a value\" error &&\n \n \ttest_must_fail git prune --expire=nyah 2>error &&\n-\ttest_i18ngrep \"malformed expiration\" error &&\n+\ttest_grep \"malformed expiration\" error &&\n \n \tgit prune --no-expire\n '\ndiff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh\nindex 78c1c6c923..d7fd71360e 100755\n--- a/t/t5310-pack-bitmaps.sh\n+++ b/t/t5310-pack-bitmaps.sh\n@@ -271,7 +271,7 @@ test_bitmap_cases () {\n \t\tmv -f $bitmap.tmp $bitmap &&\n \t\tgit rev-list --use-bitmap-index --count --all >actual 2>stderr &&\n \t\ttest_cmp expect actual &&\n-\t\ttest_i18ngrep corrupt.ewah.bitmap stderr\n+\t\ttest_grep corrupt.ewah.bitmap stderr\n \t'\n \n \ttest_expect_success 'truncated bitmap fails gracefully (cache)' '\n@@ -284,7 +284,7 @@ test_bitmap_cases () {\n \t\tmv -f $bitmap.tmp $bitmap &&\n \t\tgit rev-list --use-bitmap-index --count --all >actual 2>stderr &&\n \t\ttest_cmp expect actual &&\n-\t\ttest_i18ngrep corrupted.bitmap.index stderr\n+\t\ttest_grep corrupted.bitmap.index stderr\n \t'\n \n \t# Create a state of history with these properties:\n@@ -471,7 +471,7 @@ sane_unset GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL\n test_expect_success 'incremental repack fails when bitmaps are requested' '\n \ttest_commit more-1 &&\n \ttest_must_fail git repack -d 2>err &&\n-\ttest_i18ngrep \"Incremental repacks are incompatible with bitmap\" err\n+\ttest_grep \"Incremental repacks are incompatible with bitmap\" err\n '\n \n test_expect_success 'incremental repack can disable bitmaps' '\n@@ -524,7 +524,7 @@ test_expect_success 'truncated bitmap fails gracefully (lookup table)' '\n \tmv -f $bitmap.tmp $bitmap &&\n \tgit rev-list --use-bitmap-index --count --all >actual 2>stderr &&\n \ttest_cmp expect actual &&\n-\ttest_i18ngrep corrupted.bitmap.index stderr\n+\ttest_grep corrupted.bitmap.index stderr\n '\n \n test_done\ndiff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh\nindex 4df76173a8..10718142b0 100755\n--- a/t/t5318-commit-graph.sh\n+++ b/t/t5318-commit-graph.sh\n@@ -47,7 +47,7 @@ test_expect_success 'exit with correct error on bad input to --stdin-packs' '\n \techo doesnotexist >in &&\n \ttest_expect_code 1 git -C full commit-graph write --stdin-packs \\\n \t\t<in 2>stderr &&\n-\ttest_i18ngrep \"error adding pack\" stderr\n+\ttest_grep \"error adding pack\" stderr\n '\n \n test_expect_success 'create commits and repack' '\n@@ -67,11 +67,11 @@ test_expect_success 'exit with correct error on bad input to --stdin-commits' '\n \t# invalid, non-hex OID\n \techo HEAD | test_expect_code 1 git -C full commit-graph write \\\n \t\t--stdin-commits 2>stderr &&\n-\ttest_i18ngrep \"unexpected non-hex object ID: HEAD\" stderr &&\n+\ttest_grep \"unexpected non-hex object ID: HEAD\" stderr &&\n \t# non-existent OID\n \techo $ZERO_OID | test_expect_code 1 git -C full commit-graph write \\\n \t\t--stdin-commits 2>stderr &&\n-\ttest_i18ngrep \"invalid object\" stderr &&\n+\ttest_grep \"invalid object\" stderr &&\n \t# valid commit and tree OID\n \tgit -C full rev-parse HEAD HEAD^{tree} >in &&\n \tgit -C full commit-graph write --stdin-commits <in &&\n@@ -143,7 +143,7 @@ test_expect_success 'commit-graph write --stdin-commits force progress on for st\n \tgit -C full rev-parse commits/5 >in &&\n \tGIT_PROGRESS_DELAY=0 git -C full commit-graph write --stdin-commits \\\n \t\t--progress <in 2>err &&\n-\ttest_i18ngrep \"Collecting commits from input\" err\n+\ttest_grep \"Collecting commits from input\" err\n '\n \n test_expect_success 'commit-graph write --stdin-commits with the --no-progress option' '\n@@ -383,13 +383,13 @@ test_expect_success 'warn on improper hash version' '\n \t\tcd sha1 &&\n \t\tmv ../cg-sha256 .git/objects/info/commit-graph &&\n \t\tgit log -1 2>err &&\n-\t\ttest_i18ngrep \"commit-graph hash version 2 does not match version 1\" err\n+\t\ttest_grep \"commit-graph hash version 2 does not match version 1\" err\n \t) &&\n \t(\n \t\tcd sha256 &&\n \t\tmv ../cg-sha1 .git/objects/info/commit-graph &&\n \t\tgit log -1 2>err &&\n-\t\ttest_i18ngrep \"commit-graph hash version 1 does not match version 2\" err\n+\t\ttest_grep \"commit-graph hash version 1 does not match version 2\" err\n \t)\n '\n \n@@ -473,7 +473,7 @@ corrupt_graph_verify() {\n \tgrepstr=$1\n \ttest_must_fail git -C full commit-graph verify 2>test_err &&\n \tgrep -v \"^+\" test_err >err &&\n-\ttest_i18ngrep \"$grepstr\" err &&\n+\ttest_grep \"$grepstr\" err &&\n \tif test \"$2\" != \"no-copy\"\n \tthen\n \t\tcp full/$objdir/info/commit-graph commit-graph-pre-write-test\n@@ -714,7 +714,7 @@ test_expect_success 'corrupt commit-graph write (broken parent)' '\n \t\tgit commit-tree -p \"$broken\" -m \"good commit\" \"$empty\" >good &&\n \t\ttest_must_fail git commit-graph write --stdin-commits \\\n \t\t\t<good 2>test_err &&\n-\t\ttest_i18ngrep \"unable to parse commit\" test_err\n+\t\ttest_grep \"unable to parse commit\" test_err\n \t)\n '\n \n@@ -735,7 +735,7 @@ test_expect_success 'corrupt commit-graph write (missing tree)' '\n \t\tgit commit-tree -p \"$broken\" -m \"good\" \"$tree\" >good &&\n \t\ttest_must_fail git commit-graph write --stdin-commits \\\n \t\t\t<good 2>test_err &&\n-\t\ttest_i18ngrep \"unable to parse commit\" test_err\n+\t\ttest_grep \"unable to parse commit\" test_err\n \t)\n '\n \ndiff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh\nindex 1bcc02004d..4b01d78ccb 100755\n--- a/t/t5319-multi-pack-index.sh\n+++ b/t/t5319-multi-pack-index.sh\n@@ -279,13 +279,13 @@ test_expect_success 'warn on improper hash version' '\n \t\tcd sha1 &&\n \t\tmv ../mpi-sha256 .git/objects/pack/multi-pack-index &&\n \t\tgit log -1 2>err &&\n-\t\ttest_i18ngrep \"multi-pack-index hash version 2 does not match version 1\" err\n+\t\ttest_grep \"multi-pack-index hash version 2 does not match version 1\" err\n \t) &&\n \t(\n \t\tcd sha256 &&\n \t\tmv ../mpi-sha1 .git/objects/pack/multi-pack-index &&\n \t\tgit log -1 2>err &&\n-\t\ttest_i18ngrep \"multi-pack-index hash version 1 does not match version 2\" err\n+\t\ttest_grep \"multi-pack-index hash version 1 does not match version 2\" err\n \t)\n '\n \n@@ -386,7 +386,7 @@ corrupt_midx_and_verify() {\n \tprintf \"$DATA\" | dd of=\"$FILE\" bs=1 seek=\"$POS\" conv=notrunc &&\n \ttest_must_fail $COMMAND 2>test_err &&\n \tgrep -v \"^+\" test_err >err &&\n-\ttest_i18ngrep \"$GREPSTR\" err\n+\ttest_grep \"$GREPSTR\" err\n }\n \n test_expect_success 'verify bad signature' '\n@@ -501,7 +501,7 @@ test_expect_success 'corrupt MIDX is not reused' '\n \tcorrupt_midx_and_verify $MIDX_BYTE_OFFSET \"\\377\" $objdir \\\n \t\t\"incorrect object offset\" &&\n \tgit multi-pack-index write 2>err &&\n-\ttest_i18ngrep checksum.mismatch err &&\n+\ttest_grep checksum.mismatch err &&\n \tgit multi-pack-index verify\n '\n \n@@ -1031,7 +1031,7 @@ test_expect_success 'load reverse index when missing .idx, .pack' '\n \n test_expect_success 'usage shown without sub-command' '\n \ttest_expect_code 129 git multi-pack-index 2>err &&\n-\t! test_i18ngrep \"unrecognized subcommand\" err\n+\t! test_grep \"unrecognized subcommand\" err\n '\n \n test_expect_success 'complains when run outside of a repository' '\ndiff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh\nindex 36c4141e67..a48c00ef50 100755\n--- a/t/t5324-split-commit-graph.sh\n+++ b/t/t5324-split-commit-graph.sh\n@@ -281,7 +281,7 @@ test_expect_success 'verify hashes along chain, even in shallow' '\n \t\tcorrupt_file \"$base_file\" $(test_oid shallow) \"\\01\" &&\n \t\ttest_must_fail git commit-graph verify --shallow 2>test_err &&\n \t\tgrep -v \"^+\" test_err >err &&\n-\t\ttest_i18ngrep \"incorrect checksum\" err\n+\t\ttest_grep \"incorrect checksum\" err\n \t)\n '\n \n@@ -295,7 +295,7 @@ test_expect_success 'verify --shallow does not check base contents' '\n \t\tgit commit-graph verify --shallow &&\n \t\ttest_must_fail git commit-graph verify 2>test_err &&\n \t\tgrep -v \"^+\" test_err >err &&\n-\t\ttest_i18ngrep \"incorrect che"},{"id":"484189","messageId":"20231031052330.3762989-1-gitster@pobox.com","threadId":"60431","inReplyTo":"881c7fea-47bb-45a9-b6e3-314f9ed9e0cd@gmail.com","subject":"[PATCH 0/2] Deprecate test_i18ngrep further","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-10-31T05:23:28Z","receivedAt":"2023-10-31T05:28:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"As an attempt to come up with a useful mechanism to ensure that\ncertain messages are left untranslated [*], we earlier wrote\nGIT_TEST_GETTEXT_POISON off as a failed experiment.\n\nBut the output from the test helper was easier to use while\ndebugging failed tests, compared to the same test writtein with the\nplain-vanilla \"grep\".  Especially when a test that expects a certain\nstring to appear in the output (e.g. \"this test must fail with this\nmessage\") fails, \"grep message output\" would just silently fail and\nin a &&-chained sequence of commands, it is hard to tell which step\nfailed.  test_i18ngrep explicitly said \"we wanted to see a line that\nmatch this pattern but did not see a hit in this file\".\n\nLet's introduce test_grep and replace existing uses of test_i18ngrep\nwith it.  The helper is still useful, but now has nothing to do with\ni18n.\n\nJunio C Hamano (2):\n  test framework: further deprecate test_i18ngrep\n  tests: teach callers of test_i18ngrep to use test_grep\n\n t/lib-httpd.sh                               |   2 +-\n t/lib-submodule-update.sh                    |   2 +-\n t/t0001-init.sh                              |  16 +--\n t/t0002-gitfile.sh                           |   4 +-\n t/t0003-attributes.sh                        |   4 +-\n t/t0008-ignores.sh                           |   4 +-\n t/t0012-help.sh                              |  16 +--\n t/t0013-sha1dc.sh                            |   2 +-\n t/t0014-alias.sh                             |   8 +-\n t/t0021-conversion.sh                        |   6 +-\n t/t0028-working-tree-encoding.sh             |  32 ++---\n t/t0040-parse-options.sh                     |   4 +-\n t/t0041-usage.sh                             |  32 ++---\n t/t0061-run-command.sh                       |   6 +-\n t/t0070-fundamental.sh                       |   4 +-\n t/t0091-bugreport.sh                         |   2 +-\n t/t0300-credentials.sh                       |   2 +-\n t/t1060-object-corruption.sh                 |   2 +-\n t/t1091-sparse-checkout-builtin.sh           |  68 ++++-----\n t/t1092-sparse-checkout-compatibility.sh     |   6 +-\n t/t1300-config.sh                            |  44 +++---\n t/t1307-config-blob.sh                       |   2 +-\n t/t1308-config-set.sh                        |  10 +-\n t/t1309-early-config.sh                      |   2 +-\n t/t1310-config-default.sh                    |   4 +-\n t/t1400-update-ref.sh                        |  22 +--\n t/t1404-update-ref-errors.sh                 |   4 +-\n t/t1410-reflog.sh                            |   6 +-\n t/t1416-ref-transaction-hooks.sh             |   2 +-\n t/t1430-bad-ref-name.sh                      |  22 +--\n t/t1450-fsck.sh                              |  80 +++++------\n t/t1506-rev-parse-diagnosis.sh               |  34 ++---\n t/t1512-rev-parse-disambiguation.sh          |   6 +-\n t/t2004-checkout-cache-temp.sh               |   2 +-\n t/t2006-checkout-index-basic.sh              |  14 +-\n t/t2010-checkout-ambiguous.sh                |   4 +-\n t/t2018-checkout-branch.sh                   |   4 +-\n t/t2019-checkout-ambiguous-ref.sh            |   8 +-\n t/t2020-checkout-detach.sh                   |   8 +-\n t/t2024-checkout-dwim.sh                     |   8 +-\n t/t2025-checkout-no-overlay.sh               |   2 +-\n t/t2026-checkout-pathspec-file.sh            |   8 +-\n t/t2027-checkout-track.sh                    |   2 +-\n t/t2030-unresolve-info.sh                    |   2 +-\n t/t2072-restore-pathspec-file.sh             |   8 +-\n t/t2106-update-index-assume-unchanged.sh     |   2 +-\n t/t2107-update-index-basic.sh                |   4 +-\n t/t2203-add-intent.sh                        |   6 +-\n t/t2204-add-ignored.sh                       |   8 +-\n t/t2401-worktree-prune.sh                    |  10 +-\n t/t2402-worktree-list.sh                     |   6 +-\n t/t2403-worktree-move.sh                     |   2 +-\n t/t2406-worktree-repair.sh                   |  24 ++--\n t/t3004-ls-files-basic.sh                    |   4 +-\n t/t3007-ls-files-recurse-submodules.sh       |   4 +-\n t/t3200-branch.sh                            |  18 +--\n t/t3202-show-branch.sh                       |   2 +-\n t/t3206-range-diff.sh                        |  22 +--\n t/t3210-pack-refs.sh                         |   2 +-\n t/t3301-notes.sh                             |   4 +-\n t/t3310-notes-merge-manual-resolve.sh        |  16 +--\n t/t3320-notes-merge-worktrees.sh             |   4 +-\n t/t3321-notes-stripspace.sh                  |   2 +-\n t/t3400-rebase.sh                            |   6 +-\n t/t3402-rebase-merge.sh                      |   2 +-\n t/t3403-rebase-skip.sh                       |  30 ++--\n t/t3404-rebase-interactive.sh                |  38 ++---\n t/t3406-rebase-message.sh                    |  18 +--\n t/t3418-rebase-continue.sh                   |   6 +-\n t/t3431-rebase-fork-point.sh                 |   2 +-\n t/t3501-revert-cherry-pick.sh                |   6 +-\n t/t3507-cherry-pick-conflict.sh              |   8 +-\n t/t3510-cherry-pick-sequence.sh              |   6 +-\n t/t3600-rm.sh                                |   8 +-\n t/t3601-rm-pathspec-file.sh                  |   6 +-\n t/t3700-add.sh                               |   6 +-\n t/t3701-add-interactive.sh                   |   8 +-\n t/t3704-add-pathspec-file.sh                 |  12 +-\n t/t3900-i18n-commit.sh                       |   8 +-\n t/t3901-i18n-patch.sh                        |   2 +-\n t/t3903-stash.sh                             |  10 +-\n t/t3905-stash-include-untracked.sh           |   2 +-\n t/t3909-stash-pathspec-file.sh               |   6 +-\n t/t4001-diff-rename.sh                       |  34 ++---\n t/t4013-diff-various.sh                      |   2 +-\n t/t4014-format-patch.sh                      |  12 +-\n t/t4015-diff-whitespace.sh                   |  20 +--\n t/t4018-diff-funcname.sh                     |  14 +-\n t/t4031-diff-rewrite-binary.sh               |   2 +-\n t/t4047-diff-dirstat.sh                      |  22 +--\n t/t4053-diff-no-index.sh                     |   2 +-\n t/t4055-diff-context.sh                      |   4 +-\n t/t4068-diff-symmetric-merge-base.sh         |  28 ++--\n t/t4115-apply-symlink.sh                     |   2 +-\n t/t4120-apply-popt.sh                        |   4 +-\n t/t4122-apply-symlink-inside.sh              |  14 +-\n t/t4129-apply-samemode.sh                    |   4 +-\n t/t4133-apply-filenames.sh                   |   8 +-\n t/t4150-am.sh                                |   4 +-\n t/t4151-am-abort.sh                          |   2 +-\n t/t4153-am-resume-override-opts.sh           |   2 +-\n t/t4200-rerere.sh                            |   4 +-\n t/t4201-shortlog.sh                          |   2 +-\n t/t4202-log.sh                               |  18 +--\n t/t4203-mailmap.sh                           |   2 +-\n t/t4208-log-magic-pathspec.sh                |   6 +-\n t/t4209-log-pickaxe.sh                       |   4 +-\n t/t4211-line-log.sh                          |   4 +-\n t/t4212-log-corrupt.sh                       |   2 +-\n t/t4256-am-format-flowed.sh                  |   2 +-\n t/t5300-pack-object.sh                       |   4 +-\n t/t5302-pack-index.sh                        |   4 +-\n t/t5304-prune.sh                             |   4 +-\n t/t5310-pack-bitmaps.sh                      |   8 +-\n t/t5318-commit-graph.sh                      |  18 +--\n t/t5319-multi-pack-index.sh                  |  10 +-\n t/t5324-split-commit-graph.sh                |  16 +--\n t/t5331-pack-objects-stdin.sh                |   4 +-\n t/t5411/test-0026-push-options.sh            |   2 +-\n t/t5411/test-0027-push-options--porcelain.sh |   2 +-\n t/t5500-fetch-pack.sh                        |  10 +-\n t/t5504-fetch-receive-strict.sh              |  26 ++--\n t/t5505-remote.sh                            |  22 +--\n t/t5510-fetch.sh                             |   8 +-\n t/t5512-ls-remote.sh                         |   2 +-\n t/t5514-fetch-multiple.sh                    |   4 +-\n t/t5516-fetch-push.sh                        |   8 +-\n t/t5520-pull.sh                              |  34 ++---\n t/t5521-pull-options.sh                      |   2 +-\n t/t5523-push-upstream.sh                     |  12 +-\n t/t5528-push-default.sh                      |   2 +-\n t/t5530-upload-pack-error.sh                 |   4 +-\n t/t5531-deep-submodule-push.sh               |   2 +-\n t/t5534-push-signed.sh                       |   6 +-\n t/t5536-fetch-conflicts.sh                   |   8 +-\n t/t5541-http-push-smart.sh                   |  20 +--\n t/t5545-push-options.sh                      |   2 +-\n t/t5550-http-fetch-dumb.sh                   |   8 +-\n t/t5551-http-fetch-smart.sh                  |   4 +-\n t/t5570-git-daemon.sh                        |  10 +-\n t/t5572-pull-submodule.sh                    |   2 +-\n t/t5573-pull-verify-signatures.sh            |  26 ++--\n t/t5574-fetch-output.sh                      |   4 +-\n t/t5580-unc-paths.sh                         |   2 +-\n t/t5601-clone.sh                             |   6 +-\n t/t5604-clone-reference.sh                   |   2 +-\n t/t5606-clone-options.sh                     |  10 +-\n t/t5607-clone-bundle.sh                      |   4 +-\n t/t5611-clone-config.sh                      |   4 +-\n t/t5616-partial-clone.sh                     |  22 +--\n t/t5701-git-serve.sh                         |   8 +-\n t/t5702-protocol-v2.sh                       |  34 ++---\n t/t5703-upload-pack-ref-in-want.sh           |   4 +-\n t/t5704-protocol-violations.sh               |   4 +-\n t/t5801-remote-helpers.sh                    |   8 +-\n t/t5812-proto-disable-http.sh                |   2 +-\n t/t6001-rev-list-graft.sh                    |   4 +-\n t/t6021-rev-list-exclude-hidden.sh           |   4 +-\n t/t6030-bisect-porcelain.sh                  |  24 ++--\n t/t6040-tracking-info.sh                     |  18 +--\n t/t6050-replace.sh                           |  14 +-\n t/t6102-rev-list-unexpected-objects.sh       |  16 +--\n t/t6112-rev-list-filters-objects.sh          |   2 +-\n t/t6120-describe.sh                          |   2 +-\n t/t6134-pathspec-in-submodule.sh             |   2 +-\n t/t6135-pathspec-with-attrs.sh               |   8 +-\n t/t6136-pathspec-in-bare.sh                  |   8 +-\n t/t6402-merge-rename.sh                      |  16 +--\n t/t6422-merge-rename-corner-cases.sh         |  16 +--\n t/t6423-merge-rename-directories.sh          | 140 +++++++++----------\n t/t6424-merge-unrelated-index-changes.sh     |   6 +-\n t/t6425-merge-rename-delete.sh               |   4 +-\n t/t6426-merge-skip-unneeded-updates.sh       |   2 +-\n t/t6430-merge-recursive.sh                   |   8 +-\n t/t6433-merge-toplevel.sh                    |   4 +-\n t/t6436-merge-overwrite.sh                   |   4 +-\n t/t6437-submodule-merge.sh                   |   2 +-\n t/t6500-gc.sh                                |  14 +-\n t/t7001-mv.sh                                |   4 +-\n t/t7105-reset-patch.sh                       |   6 +-\n t/t7106-reset-unborn-branch.sh               |   2 +-\n t/t7107-reset-pathspec-file.sh               |  10 +-\n t/t7110-reset-merge.sh                       |   6 +-\n t/t7201-co.sh                                |   4 +-\n t/t7300-clean.sh                             |   2 +-\n t/t7400-submodule-basic.sh                   |  64 ++++-----\n t/t7403-submodule-sync.sh                    |   4 +-\n t/t7406-submodule-update.sh                  |   6 +-\n t/t7411-submodule-config.sh                  |   4 +-\n t/t7414-submodule-mistakes.sh                |   8 +-\n t/t7416-submodule-dash-url.sh                |   4 +-\n t/t7417-submodule-path-url.sh                |   4 +-\n t/t7450-bad-git-dotfiles.sh                  |  12 +-\n t/t7500-commit-template-squash-signoff.sh    |   2 +-\n t/t7501-commit-basic-functionality.sh        |   6 +-\n t/t7502-commit-porcelain.sh                  |  32 ++---\n t/t7506-status-submodule.sh                  |  28 ++--\n t/t7507-commit-verbose.sh                    |   4 +-\n t/t7508-status.sh                            |  24 ++--\n t/t7509-commit-authorship.sh                 |   4 +-\n t/t7518-ident-corner-cases.sh                |  10 +-\n t/t7519-status-fsmonitor.sh                  |   6 +-\n t/t7520-ignored-hook-warning.sh              |   8 +-\n t/t7525-status-rename.sh                     |  54 +++----\n t/t7526-commit-pathspec-file.sh              |  14 +-\n t/t7600-merge.sh                             |  30 ++--\n t/t7601-merge-pull-config.sh                 |  50 +++----\n t/t7611-merge-abort.sh                       |   4 +-\n t/t7612-merge-verify-signatures.sh           |  24 ++--\n t/t7703-repack-geometric.sh                  |   4 +-\n t/t7800-difftool.sh                          |   4 +-\n t/t7810-grep.sh                              |   4 +-\n t/t7811-grep-open.sh                         |   2 +-\n t/t7814-grep-recurse-submodules.sh           |   2 +-\n t/t7816-grep-binary-pattern.sh               |   4 +-\n t/t7900-maintenance.sh                       |  24 ++--\n t/t8003-blame-corner-cases.sh                |   2 +-\n t/t8013-blame-ignore-revs.sh                 |   6 +-\n t/t9001-send-email.sh                        |   8 +-\n t/t9300-fast-import.sh                       |  26 ++--\n t/t9800-git-p4-basic.sh                      |  18 +--\n t/t9801-git-p4-branch.sh                     |   2 +-\n t/t9807-git-p4-submit.sh                     |  12 +-\n t/t9815-git-p4-submit-fail.sh                |  12 +-\n t/test-lib-functions.sh                      |  10 +-\n 225 files changed, 1196 insertions(+), 1194 deletions(-)\n\n-- \n2.42.0-530-g692be87cbb\n\n"},{"id":"484303","messageId":"876dd6fc-b57b-479f-8ffe-fbd2a6979034@gmail.com","threadId":"60431","inReplyTo":"20231031052330.3762989-3-gitster@pobox.com","subject":"Re: [PATCH 2/2] tests: teach callers of test_i18ngrep to use test_grep","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2023-11-01T14:44:11Z","receivedAt":"2023-11-01T14:44:19Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Junio\n\nOn 31/10/2023 05:23, Junio C Hamano wrote:\n> They are equivalents and the former still exists, so as long as the\n> only change this commit makes are to rewrite test_i18ngrep to\n> test_grep, there won't be any new bug, even if there still are\n> callers of test_i18ngrep remaining in the tree, or when merged to\n> other topics that add new uses of test_i18ngrep.\n> \n> This patch was produced more or less with\n> \n>      git grep -l -e 'test_i18ngrep ' 't/t[0-9][0-9][0-9][0-9]-*.sh' |\n>      xargs perl -p -i -e 's/test_i18ngrep /test_grep /'\n> \n> and a good way to sanity check the result yourself is to run the\n> above in a checkout of c4603c1c (test framework: further deprecate\n> test_i18ngrep, 2023-10-31) and compare the resulting working tree\n> contents with the result of applying this patch to the same commit.\n> You'll see that test_i18ngrep in a few t/lib-*.sh files corrected,\n> in addition to the manual reproduction.\n\nThanks for working on this. I have checked what you have in seen by \nchecking out the first parent of ce56983dd3 (Merge branch \n'jc/test-i18ngrep' into seen, 2023-11-01) and then converting \n\"test_i18ngrep\" to \"test_grep\" and diffing the result as you suggest \nabove.  The diff looks good and shows that you've corrected the \nadditional t/lib-*.sh files. Grepping ce56983dd3 for \"test_i18ngrep\" \nshows there is one instance of test_i18ngrep that has not been coverted \nin contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh.\n\nBest Wishes\n\nPhillip\n"},{"id":"484319","messageId":"xmqqr0l9oycm.fsf@gitster.g","threadId":"60431","inReplyTo":"876dd6fc-b57b-479f-8ffe-fbd2a6979034@gmail.com","subject":"Re: [PATCH 2/2] tests: teach callers of test_i18ngrep to use test_grep","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2023-11-01T23:19:53Z","receivedAt":"2023-11-01T23:20:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Phillip Wood <phillip.wood123@gmail.com> writes:\n\n> additional t/lib-*.sh files. Grepping ce56983dd3 for \"test_i18ngrep\"\n> shows there is one instance of test_i18ngrep that has not been\n> coverted in contrib/mw-to-git/t/t9363-mw-to-git-export-import.sh.\n\nThanks.  I'll tweak the patch to update that instance.  As we are\nnot removing test_i18ngrep with this series, any test_i18ngrep left\nunconverted should not break anything, but that is primarily to deal\nwith any new callsites that is added on other topics in-flight, and\nI should make sure the ones that are known in my tree are converted.\n\n\n"}]}