Git

git grep 輸出被緩衝。為什麼?

  • November 4, 2018

git grep第一次在大樹(Linux 核心)上執行。

這需要很長時間才能執行。如果我在完成之前使用 ctrl+C 取消,通常它會立即顯示它找到的一行。

為什麼沒有git grep立即顯示該行,當它找到它時?


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

git grep輸出由 緩衝less。(在大多數情況下。如果需要,可以使用各種配置選項進行更改)。

我沒有註意到這一點的原因是當輸出少於一屏時git grep不顯示分頁頁腳。less但是,輸出仍然被緩衝。(我可以看到它less正在執行,通過打開另一個終端並執行ps -ax)。

實際上,檢查原始碼時,git 輸出並不會一直被 less 緩衝。

檢查 pager.c,它顯示 git 輸出被指向 PAGER shell 變數的程序緩衝;如果沒有定義,就會省略使用less。

更有趣的是,當較少的輸出被分頁時,它將 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);
}

引用自:https://unix.stackexchange.com/questions/477212