让git在差异中突出显示制表符?

22

我正在努力确保自己不会提交使用制表符进行缩进的代码。这是一种我对自己的提交应用的软性约束(目前我们没有关于缩进字符的标准,但我想使用空格,因为对于空格的宽度没有争议,但有些人使用宽度为4的制表符而另一些人使用宽度为8的制表符)。

检查此类约束条件最简单的方法通常是每次要提交时查看git diff的实际输出,并查看是否存在任何问题。例如,对于我来说,默认情况下会突出显示尾随空格并在差异中也可见Windows换行符,因此如果我即将意外提交带有尾随空格的代码,则会收到警告。有没有办法使制表符也在git diff中显示出来呢?

4个回答

26
Git在1.7.2版本(2010年7月21日)中学习了tab-in-indent空格类别。引自Documentation/RelNotes/1.7.2.txt
  • "git apply --whitespace"和 "git diff"中使用的空格规则扩展了新成员(tab-in-indent),以帮助只使用空格缩进的项目。

它的控制和使用方式与其他空格检查选项相同。
git diff中的突出显示与其他空格错误相同。
可以使用git diff --check进行检查,等等。

tab-in-indent添加到core.whitespace配置变量的值中可启用它(可能在一个或多个特定存储库或者在您的“全局”(每次使用)配置中)。

set-show-tabs() {
    global=
    test "$1" = -g || test "$1" = --global && global=--global
    cws=$(git config $global core.whitespace)
    case "$cws" in
        tab-in-indent,*|*,tab-in-indent|*,tab-in-indent,*) ;;
        *) git config $global core.whitespace "$cws"${cws:+,}tab-in-indent ;;
    esac
}
set-show-tabs           # only in local repository
set-show-tabs --global  # for all your Git activities
# or just edit it manually with "git config [--global] --edit"

或者,您可以为单个命令设置它(git -c也是从1.7.2开始的):

git -c core.whitespace=tab-in-indent diff --check

您可以在 pre-commit 钩子中使用这样的方法来检查制表符,而无需将其添加到任何实际的存储库配置文件中。


由于某种原因,所有的制表符都以红色呈现。有没有办法让它们像color.diff.newcolor.diff.old一样行为? - rr-
1
@rr-:这是在core.whitespace中设置tab-in-indent的一个效果之一。如果您不想要特殊突出显示制表符,请从配置中删除它(默认情况下未启用,因此它将在其中一个配置文件中可见;例如git config --editgit config --edit --global)。如果您想更改突出显示,请参阅color.diff.whitespace(尽管像红色突出显示一样,它将在“旧”和“新”部分中具有相同的颜色)。 - Chris Johnsen
我希望在差异比较中,像前导空格一样突出显示前导制表符;目前我只能给它们一个特定的颜色(与“旧”和“新”的不兼容),就像你说的那样。我想知道为什么会这样?我的意思是,为什么制表符被特别对待(否则它们将像任何其他文本一样被突出显示),甚至与普通空格不同? - rr-
请注意,如果没有启用 tab-in-indent,则制表符将不会被突出显示,也不会使用 color.diff.new/old(我正在尝试将其分别设置为 红色反转绿色反转)。 - rr-
2
@rr-:在空格错误高亮方面使用单一颜色可能是为了保持简单的设计决策。关于从不突出显示制表符(即使使用-tab-in-indent;以及制表符前的空格使用-space-before-tab)可能是一个错误或只是实现细节。Git 2.5.0将具有--ws-error-highlight=none,它将完全禁用空格错误高亮,使这些制表符(和制表符前的空格)与“新”和“旧”行的其余部分颜色相同。 - Chris Johnsen
显示剩余2条评论

12

查找包含制表符的行:

git grep -n --cached 'LITERAL TAB HERE'
在bash或zsh中,您可以使用Ctrl-VCtrl-I输入文字制表符。该命令将显示所有包含制表符的文件和行。
如果您想通过防止使用制表符提交来强制执行您的策略,请将以下内容放入.git/hooks/pre-commit并标记为可执行(chmod +x):
#!/bin/sh
allowtabs=$(git config hooks.allowtabs)
if [ "$allowtabs" != "true" ] &&
   git diff --cached | egrep '^\+.* '>/dev/null
then
   cat<<END;
Error: This commit would contain a tab, which is against this repo's policy.

If you know what you are doing you can force this commit with:

  git commit --no-verify

Or change the repo policy like so:

  git config hooks.allowtabs true
END
  exit 1
fi

git diff --cached | egrep行中*'之间有一个实际的制表符。在Vim中,可以使用Ctrl-V Ctrl-I来获取它,在Emacs中可以使用C-q C-i

它的作用是查找差异中(以“+”开头)包含制表符的新行。如果想要显示钩子中的有问题的制表符,则可以将git grep行放入错误消息中。

我已经将这个钩子放在了Github上(链接地址)


由于某些原因,当我包含行首字符串'^'时,egrep无法匹配任何行,但如果我删除'^',它会找到相关的行。您知道这可能是为什么吗? - jonderry
1
最终,为了获得完整的效果,我执行了以下操作:git diff --cached | sed -e "s/^\(^[\[32m+\)[^\t]*\(\t\+\)/\\1${red_bg}\\2${norm_bg}/g",其中 ^[ 是一个原始转义字符(在emacs中是C-q ESC),而 norm_bg=$(tput sgr0)red_bg=$(tput setab 1) 参考自 https://dev59.com/ElXTa4cB1Zd3GeqP6vke#5575161。 - jonderry
@jonderry 很棒!颜色将你的注意力吸引到了恰当的位置。 - Matt Curtis
这里有很多有用的信息,但由于它是一种更内置的解决方案,所以我将检查切换到Chris Johnsen。尽管如此,我仍然给予+1,因为我学到了很多并且有很多有用的信息。 - jonderry
@jonderry 没问题 - 我也觉得Chris的回答很有用! - Matt Curtis
显示剩余2条评论

0

让制表符可见的一种方法是将它们替换为一些显眼的东西,例如.       (这是一个点后面跟着七个空格)。这可以通过在您的配置中替换分页器以添加对sed的调用来实现。像这样:

[core]
    pager = sed 's/\t/.       /g' | less -R

例子

没有自定义分页器:

         for (int i = 0; i < 3; ++i) {
-        for (int h = 0; h < 4; ++h) {
+                for (int h = 0; h < 4; ++h) {
                         for (int k = 0; k < 4; ++k) {

使用自定义分页器:

 .       for (int i = 0; i < 3; ++i) {
-        for (int h = 0; h < 4; ++h) {
+.       .       for (int h = 0; h < 4; ++h) {
 .       .       .       for (int k = 0; k < 4; ++k) {

0

我已经制作了一个预提交钩子,可以阻止您提交使用制表符缩进的代码https://github.com/martinjoiner/portable-code-pre-commit-hook,它看起来像这样...

enter image description here

我现在在所有项目中都经常使用它。请随意使用。

我所在的团队在Mac、Windows和Linux环境中编写代码,还通过Github网站在浏览器上进行代码审核。团队非常高兴有帮助他们检查代码的援手,因为这样可以确保代码在所有场合下看起来一致。

如果您发现任何问题,请告诉我,我希望有机会改善任何缺点。谢谢。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接