git grep 输出被缓冲。为什么?

git grep 输出被缓冲。为什么?

git grep第一次在一棵大树(Linux 内核)上运行。

这需要很长时间才能运行。如果我在完成之前使用 ctrl+C 取消,通常它会立即显示找到的一行。

git grep当它找到该线时,为什么不立即显示该线?


$ rpm -q git
git-2.17.2-1.fc28.x86_64

答案1

git grep输出由 缓冲less。 (在大多数情况下。如果需要,可以使用各种配置选项进行更改)。

我没有注意到这一点的原因是,当输出少于一屏时,git grep不会显示寻呼机页脚。less然而,输出仍然被缓冲。 (我可以less通过打开另一个终端并运行来看到它正在运行ps -ax)。

答案2

事实上,检查源代码,git 输出并不总是被 less 缓冲。

检查 pager.c,它显示 git 输出由指向 PAGER shell 变量的程序缓冲;如果没有定义,则省略。

更有趣的是,当较少的输出被分页时,它将 shell GIT_PAGER_IN_USE 变量设置为 true。当调用寻呼机时,它会检查该变量。

奇怪的是,它似乎不喜欢cat作为寻呼机,如果它检测到它,它就会将其清空。

#ifndef DEFAULT_PAGER
#define DEFAULT_PAGER "less"
#endif
....

void setup_pager(void)
{
    const char *pager = git_pager(isatty(1));

    if (!pager)
        return;

    /*
     * After we redirect standard output, we won't be able to use an ioctl
     * to get the terminal size. Let's grab it now, and then set $COLUMNS
     * to communicate it to any sub-processes.
     */
    {
        char buf[64];
        xsnprintf(buf, sizeof(buf), "%d", term_columns());
        setenv("COLUMNS", buf, 0);
    }

    setenv("GIT_PAGER_IN_USE", "true", 1);

    /* spawn the pager */
    prepare_pager_args(&pager_process, pager);
    pager_process.in = -1;
    argv_array_push(&pager_process.env_array, "GIT_PAGER_IN_USE");
    if (start_command(&pager_process))
        return;

    /* original process continues, but writes to the pipe */
    dup2(pager_process.in, 1);
    if (isatty(2))
        dup2(pager_process.in, 2);
    close(pager_process.in);

    /* this makes sure that the parent terminates after the pager */
    sigchain_push_common(wait_for_pager_signal);
    atexit(wait_for_pager_atexit);
}

相关内容