如何使用寻呼机 long git add --patch hunks?

How do I use a pager for long git add --patch hunks?

当我使用 git add --patch 交互式添加 diff 帅哥时,我有时会得到比屏幕还长的帅哥,但无法使用 less 翻阅帅哥。

这对我来说很奇怪,因为我已经设置了:

[core]
      pager = less -FRX --tabs=4

[pager]

  diff = diff-highlight | less -FRX --tabs=4
通过 less 传输的

interactive.diffFilter= 也无助于分页。

我需要做什么才能让 git add--patch 使用 less 以便我可以使用键盘导航超过一个屏幕的任何输出?

你不能。这是 the Unix pipeline model.

的本性

使用分页器的 Git 命令可以与 any 通用 stdin 分页器一起工作的原因是因为这个模型。这样的 git 命令将它们的输出写入 stdout。寻呼机从 stdin 读取它的输入。前者的 stdout 通过管道传输到后者的 stdin正是这种管道模型的简单性使得寻呼机通用并且允许git允许你选择你自己的寻呼机,因为只要它使用这个模型。

那么为什么 git add -p(或 git add -i)不能像 git diffgit log 那样做呢?

因为一次只能有一个互动应用。

git diffgit log 交互。 git add -p 和传呼机 互动的。

管道模型的性质意味着一次只能控制一个应用程序,并且需要交互式应用程序进行控制。为了使寻呼机获得终端的控制权(以便它可以显示提示并响应您的输入),git add -p 必须释放控制权。一旦发生,就无法恢复。

这样看:将有两个命令行提示 试图与您交互:一个用于 git add -p 和一个用于寻呼机。他们将如何协调?它必须像这样:

  1. git add -pstdout 写入一个大块,连同 end-of-hunk (EOH) 标记而不是通常的 end-of-file (EOF) 标记。
  2. git add -p 然后将终端的控制权交给管道另一端的任何应用程序。
  3. 寻呼机将接收到 hunk,并通过控制终端显示 hunk 的片段及其命令提示符。
  4. 寻呼机的行为与往常一样,但有很大的不同。通常它会看到一个 EOF 标记,因此当您说完成时(quit 命令),它会退出。但是 EOH 制造商告诉寻呼机,“不要退出。当用户完成后,将控制权交还给上游应用程序。不要退出。等待。”
  5. 因此,当您使用各种寻呼机命令仔细阅读 hunk 后,您可以使用它的 quit 命令告诉它您已经完成了,就像平常一样。
  6. 但现在寻呼机并没有退出,而是以某种方式将终端控制权交还给 git add
  7. git add 的终端提示将取代寻呼机的...
  8. ...现在我们回到步骤 1。继续重复直到 EOF。

如您所见,这不仅是一个 糟糕的用户体验 (使用寻呼机的 quit 命令返回到 git add 每个 hunk ), 它会完全破坏 破坏 Unix 管道模型.

的力量和美感

出于同样的原因 git add -p cannot use diff-so-fancy

git -p 拥有类似寻呼机行为的唯一方法是拥有一个 built-in,或者定义一个“Git 寻呼机 API”,然后我们等待供人们编写适用于此 API 的寻呼机。这就是插件模型,与管道模型有很大的不同。这也意味着紧密集成:git add -p 命令和寻呼机命令必须结合起来并在每个命令提示符下可用。

使用终端应用程序的分页

我发现在我的终端中向上滚动非常容易 window。我的键盘命令允许我逐行或逐页移动。

使用git add -psplit命令

你考虑过用git add -psplit命令来打散帅哥吗?无论如何,我发现较小的帅哥更容易推理!

作为解决方法,您可以设置 EDITOR=less 并在大块头上使用 e (edit) 到 运行 less。但是 as-is 该解决方法有一些缺点。这些可以通过这样的方式避免:

EDITOR="EDITOR='$EDITOR' bash -c 'set -m; less -K \"$1\"' --" git add -p
  • 在调用 less 之前重置 EDITOR 允许使用 less 中的标准 v 键来调用编辑器。

  • less-K 选项允许用 Control-C 退出 less,告诉 Git 不要上演大块头。使用 q 退出 less 将导致 hunk 上演。

  • set -m 创建一个单独的进程组,阻止 Control-C 冒泡并杀死 Git 进程。

还有Magit等工具提供a better interface for interactive staging

基于,我想到了以下别名:

ap = !"VISUAL=\"VISUAL='$VISUAL' bash -c 'set -m; less -K -+F \\"\\\"' --\" git add -p \"$@\" #"
  • e寻呼less中的帅哥
    • q 显示显示的内容
    • v编辑显示的内容
    • ^C退出并重复交互式菜单

我正在做 PR 以在 git 本身解决这个问题。