【问题标题】:Make Git automatically remove trailing white space before committing让 Git 在提交之前自动删除尾随空格
【发布时间】:2021-11-22 15:00:13
【问题描述】:

我和我的团队一起使用 Git,想从我的差异、日志、合并等中删除空白更改。我假设最简单的方法是让 Git 自动删除尾随空白(和其他空白错误)来自所有提交,因为它们被应用。

我试图将以下内容添加到 ~/.gitconfig 文件中,但是当我提交时它没有做任何事情。也许它是为不同的东西而设计的。解决办法是什么?

[core]
    whitespace = trailing-space,space-before-tab
[apply]
    whitespace = fix

我正在使用 Ruby,以防有人对 Ruby 有任何特定的想法。提交前的自动代码格式化将是下一步,但这是一个难题,并不会真正造成大问题。

【问题讨论】:

  • 如果 core.whitespace 指令不能解决您的问题,您还可以更改预提交挂钩 (.git/hooks/pre-commit) 来为您查找并修复它们。有关详细说明,请参阅this 帖子。
  • 我对类似的空白错误和部分解决方案感到沮丧,并编写了一个灵活且功能相当完整的实用程序来修复或者简单地报告困扰版本控制系统的空白错误:Whitespace Total Fixer on Github(如果这太自我推销,我深表歉意)
  • 它似乎是一个独立的工具,可以持续监视文件夹中的更改文件并修改它们会更容易。

标签: git whitespace githooks


【解决方案1】:

这些设置(core.whitespaceapply.whitespace)不是用来删除尾随空格的,而是用来:

  • core.whitespace:检测它们并引发错误
  • apply.whitespace:并剥离它们,但仅在补丁期间,而不是“始终自动”

我相信git hook pre-commit会做得更好(包括删除尾随空格)


请注意,在任何给定时间您都可以选择不运行 pre-commit 挂钩:

  • 暂时:git commit --no-verify .
  • 永久:cd .git/hooks/ ; chmod -x pre-commit

警告:默认情况下,pre-commit 脚本(如this one)具有不是一个“删除尾随”功能,但一个“警告”功能,如:

if (/s$/) {
    bad_line("trailing whitespace", $_);
}

但是你可以build a better pre-commit hook,尤其是当你考虑到:

在 Git 中提交仅向暂存区添加一些更改仍然会导致“原子”修订可能永远不会作为工作副本存在并且可能无法工作.


例如,oldman 提议 in another answerpre-commit hook 检测并删除空格。
由于该挂钩获取每个文件的文件名,我建议对某些类型的文件要小心:您不想删除 .md(降价)文件中的尾随空格!


hakrethe comments 中建议的另一种方法:

通过在 之前添加“”,您可以在 markdown 的行尾有两个空格,而不是将其作为尾随空格。

然后是一个内容过滤驱动:

git config --global filter.space-removal-at-eol.clean 'sed -e "s/ +$//"'
# register in .gitattributes 
*.md filter=space-removal-at-eol

【讨论】:

  • 事实证明,可以通过apply.whitespace 说服 git 修复工作副本中的空白,方法是欺骗 git 将你的工作副本更改视为补丁。参见my answer below
  • > “你不想删除 .md (markdown) 文件中的尾随空格”——这是为什么呢?降价文件中尾随空格的目的是什么?我注意到一些 .editorconfig 文件对此有特定的规则。
  • @friederbluemle 根据降价的类型,尾随双空格表示<br>github.com/FriendsOfPHP/PHP-CS-Fixer/issues/…
  • git 2.5.0 中提交时,将 core.whitespace 设置为 trailing-spacegit config 不会引发错误。
  • 您可以在降价行尾有两个空格,而不是通过在前面添加“”将其作为尾随空格 . Mind 认为并非所有声称可以处理 Markdown 的工具都支持所有 Markdown,因此 YMMV。
【解决方案2】:

您可以通过欺骗 Git 将您的更改视为补丁来欺骗 Git 为您修复空白。与“预提交挂钩”解决方案相比,这些解决方案向 Git 添加了空白修复命令。

是的,这些都是黑客。


强大的解决方案

以下 Git 别名取自 my ~/.gitconfig

通过“健壮”我的意思是这些别名运行没有错误,做 正确的事情,不管树或索引是否脏。但是,如果交互式git rebase -i 已经在进行中,它们将不起作用;如果您关心这个极端情况,请参阅 my ~/.gitconfig 进行额外检查,最后描述的 git add -e 技巧应该起作用。

如果你想直接在 shell 中运行它们,而不创建 Git 别名,只需复制并粘贴双引号之间的所有内容 (假设你的 shell 是 Bash 之类的)。

修复索引而不是树

以下fixws Git 别名修复了索引中的所有空白错误, 如果有的话,但不要碰树:

# Logic:
#
# The 'git stash save' fails if the tree is clean (instead of
# creating an empty stash :P). So, we only 'stash' and 'pop' if
# the tree is dirty.
#
# The 'git rebase --whitespace=fix HEAD~' throws away the commit
# if it's empty, and adding '--keep-empty' prevents the whitespace
# from being fixed. So, we first check that the index is dirty.
#
# Also:
# - '(! git diff-index --quiet --cached HEAD)' is true (zero) if
#   the index is dirty
# - '(! git diff-files --quiet .)' is true if the tree is dirty
#
# The 'rebase --whitespace=fix' trick is from here:
# https://stackoverflow.com/a/19156679/470844
fixws = !"
  if (! git diff-files --quiet .) && 
     (! git diff-index --quiet --cached HEAD) ; then 
    git commit -m FIXWS_SAVE_INDEX && 
    git stash save FIXWS_SAVE_TREE && 
    git rebase --whitespace=fix HEAD~ && 
    git stash pop && 
    git reset --soft HEAD~ ; 
  elif (! git diff-index --quiet --cached HEAD) ; then 
    git commit -m FIXWS_SAVE_INDEX && 
    git rebase --whitespace=fix HEAD~ && 
    git reset --soft HEAD~ ; 
  fi"

这个想法是在git commit之前运行git fixws如果你有 索引中的空白错误。

修复索引和树

以下fixws-global-tree-and-index Git 别名修复了所有空格 索引和树中的错误(如果有):

# The different cases are:
# - dirty tree and dirty index
# - dirty tree and clean index
# - clean tree and dirty index
#
# We have to consider separate cases because the 'git rebase
# --whitespace=fix' is not compatible with empty commits (adding
# '--keep-empty' makes Git not fix the whitespace :P).
fixws-global-tree-and-index = !"
  if (! git diff-files --quiet .) && 
     (! git diff-index --quiet --cached HEAD) ; then 
    git commit -m FIXWS_SAVE_INDEX && 
    git add -u :/ && 
    git commit -m FIXWS_SAVE_TREE && 
    git rebase --whitespace=fix HEAD~2 && 
    git reset HEAD~ && 
    git reset --soft HEAD~ ; 
  elif (! git diff-files --quiet .) ; then 
    git add -u :/ && 
    git commit -m FIXWS_SAVE_TREE && 
    git rebase --whitespace=fix HEAD~ && 
    git reset HEAD~ ; 
  elif (! git diff-index --quiet --cached HEAD) ; then 
    git commit -m FIXWS_SAVE_INDEX && 
    git rebase --whitespace=fix HEAD~ && 
    git reset --soft HEAD~ ; 
  fi"

要同时修复未版本化文件中的空格,请执行

git add --intent-to-add <unversioned files> && git fixws-global-tree-and-index

简单但不可靠的解决方案

这些版本更容易复制和粘贴,但它们不 如果不满足他们的附带条件,这是正确的事情。

修复以当前目录为根的子树(但如果不为空则重置索引)

使用git add -e 以身份编辑器:“编辑”补丁:

(export GIT_EDITOR=: && git -c apply.whitespace=fix add -ue .) && git checkout . && git reset

修复并保留索引(但如果树脏或索引为空则失败)

git commit -m TEMP && git rebase --whitespace=fix HEAD~ && git reset --soft HEAD~

修复树和索引(但如果索引不为空则重置索引)

git add -u :/ && git commit -m TEMP && git rebase --whitespace=fix HEAD~ && git reset HEAD~

export GIT_EDITOR=: &amp;&amp; git -c apply.whitespace=fix add -ue .技巧的解释

在我从this answer了解git rebase --whitespace=fix技巧之前,我到处都在使用更复杂的git add技巧。

如果我们手动完成:

  1. apply.whitespace 设置为 fix(您只需执行一次):

    git config apply.whitespace fix
    

    这告诉 Git 修复空格补丁.

  2. 说服 Git 将您的更改视为修补:

    git add -up .
    

    一种+进入选择每个文件的所有更改。您会收到有关 Git 修复空格错误的警告。
    (此时 git -c color.ui=auto diff 显示您的非索引更改正是空白错误)。

  3. 从您的工作副本中删除空格错误:

    git checkout .
    
  4. 恢复您的更改(如果您还没有准备好提交它们):

    git reset
    

    GIT_EDITOR=: 表示使用 : 作为编辑器,并作为命令 : 是身份。

【讨论】:

  • 我刚刚在 Windows 中对其进行了测试:这在 DOS 命令提示符下工作得很好:set VISUAL= &amp;&amp; git add -ue . &amp;&amp; git checkout . 注意与git add 一起使用的“.”:即because of git1.8.3
  • @VonC 不会永久取消 VISUAL 设置,例如导致随后使用git commit 使用错误的编辑器?我在上面的 unix 版本中将 VISUAL= 部分包装在子 shell 中以避免这种情况,但我不知道 DOS 是否有子 shell。
  • 感谢伟大的破解!仅供参考,如果您设置了 core.editor,则导出 VISUAL 无效,因为配置设置优先于 man git-var。要覆盖它,您需要改为导出 GIT_EDITOR=:
  • 另外,我调整了我的 fixws 版本,如果你已经在一个交互式 rebase 中,它会快速失败,否则它会在 git rebase --whitespace=fix 行死掉,让你处于奇怪的状态。我从this question借来的,只是在if之前添加了一个额外的案例:fixws = !" if test -d $(git rev-parse --git-dir)/rebase-merge ; then echo 'In rebase - cannot fixws' ; elif (! git diff-files --quiet .) &amp;&amp; (! git diff-index --quiet --cached HEAD) ; then ...
  • 仅供参考:我将其改编成pre-commit hook
【解决方案3】:

我找到了一个 Git pre-commit hook that removes trailing white space

#!/bin/sh

if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then
   against=HEAD
else
   # Initial commit: diff against an empty tree object
   against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# Find files with trailing whitespace
for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | sed -r 's/:[0-9]+:.*//' | uniq` ; do
   # Fix them!
   sed -i 's/[[:space:]]*$//' "$FILE"
   git add "$FILE"
done
exit

【讨论】:

  • 第二个 sed 调用 (sed -r 's/:[0-9]+:.*//') 可以替换为 cut -f1 -d:。这在基于 Linux 和 BSD 的平台上应该是一样的。
  • @IhorKaharlichenko:实际上,使用cut 不如第二个sed 安全:在包含“:”的文件名(极不可能)的情况下,剪切将失败。您可以使用awk 'NF&gt;2{NF-=2}1' 以确保安全
  • 顺便说一句,如果你在 Windows (msysgit) 上使用core.autocrlf=true,你可能想在 sed 之后的 for 循环中添加 dos2unix -D "$FILE"。否则,它将通过仅发出 sed 将所有 CRLF 更改为 LF。
  • 在提交钩子中执行 git add 对我来说似乎很邪恶。如果您正在对文件进行部分暂存/提交怎么办?您不希望在您背后提交完整的文件,是吗?
【解决方案4】:

在 macOS(或者可能是任何 BSD)上,sed 命令参数必须略有不同。尝试这个:

#!/bin/sh

if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then
   against=HEAD
else
   # Initial commit: diff against an empty tree object
   against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

# Find files with trailing whitespace
for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | sed -E 's/:[0-9]+:.*//' | uniq` ; do
    # Fix them!
    sed -i '' -E 's/[[:space:]]*$//' "$FILE"
    git add "$FILE"
done

将此文件另存为 .git/hooks/pre-commit——或查找已经存在的文件,然后将底部块粘贴到其中的某处。并记得chmod a+x它。

或者对于全球使用(通过Applying a git post-commit hook to all current and future repos),您可以将其放入$GIT_PREFIX/git-core/templates/hooks(其中 GIT_PREFIX 是 /usr 或 /usr/local 或 /usr/share 或 /opt/local/share)并在您现有的内部运行 git init回购。

根据git help init

在现有存储库中运行 git init 是安全的。它不会覆盖已经存在的东西。重新运行git init 的主要原因是选择新添加的模板。

【讨论】:

  • 这个钩子不是在修改工作文件并用修改后的工作文件覆盖索引吗?如果你要“git add -p”来构建你的索引,这个提交钩子会把它吹走。
  • 是的,你可能是对的。有人可能不得不重写此脚本以使用 git hash-object -wgit update-index 将修改后的文件直接(重新)插入到索引中。一个非常勇敢的人。
【解决方案5】:

我宁愿把这个任务留给你最喜欢的编辑。

只需设置一个命令以在保存时删除尾随空格。

【讨论】:

  • 在 vim 中,您可以使用:autocmd BufWritePre.cpp,.c,*.h :%/s+$//e
  • 抱歉,我在测试之前对上面的评论投了赞成票。百分号后缺少一个“s”,如果找到空格,它将移动光标,并删除最后一个搜索模式。有关更好的选择,请参阅vim.wikia.com/wiki/Remove_unwanted_spaces
  • 在 emacs 中,它是 M-x delete-trailing-whitespace。
  • 更好的是,对于 emacs,通过将 (add-hook 'before-save-hook 'delete-trailing-whitespace) 添加到您的 .emacs 文件,设置一个钩子以在保存之前删除尾随空格。 Emacs whitespace tricks
  • 这是迄今为止最安全、最可靠的解决方案。我浪费了数小时来解决由看似无辜的预提交挂钩引起的意外问题。
【解决方案6】:

使用 Git 属性,并通过 Git 配置设置过滤器

好的,这是解决这个问题的新方法……我的方法是不使用任何钩子,而是使用过滤器和 Git 属性。这允许您在您开发的每台机器上设置一组过滤器,这些过滤器将在提交文件之前去除额外的尾随空格和文件末尾的额外空白行。

然后设置一个 .gitattributes 文件,说明过滤器应该应用于哪些类型的文件。过滤器有两个阶段,clean在将文件添加到索引时应用,smudge在将文件添加到工作目录时应用。

告诉你的 Git 去寻找一个全局属性文件

首先,告诉您的全局配置使用全局属性文件:

git config --global core.attributesfile ~/.gitattributes_global

创建全局过滤器

现在,创建过滤器:

git config --global filter.fix-eol-eof.clean fixup-eol-eof %f
git config --global filter.fix-eol-eof.smudge cat
git config --global filter.fix-eol-eof.required true

添加 sed 脚本魔法

最后,将 fixup-eol-eof 脚本放在路径中的某个位置,并使其可执行。该脚本使用 sed 进行一些即时编辑(删除行尾的空格和空白,以及文件末尾的无关空白行)

fixup-eol-eof 应该是这样的:

#!/bin/bash
sed -e 's/[     ]*$//' -e :a -e '/^
*$/{$d;N;ba' -e '}' $1

My gist of this

告诉 Git 将新创建的过滤器应用于哪些文件类型

最后,创建或打开文件~/.gitattributes_global在您最喜欢的文本编辑器中添加如下行:

pattern attr1 [attr2 [attr3 […]]]

因此,如果我们想解决空白问题,我们将为所有的 C 源文件添加一行,如下所示:

*.c filter=fix-eol-eof

过滤器的讨论

过滤器有两个阶段。将内容添加到索引或签入时应用的清理阶段,以及 Git 将内容放入工作目录时的涂抹阶段。

在这里,我们的污迹只是通过 cat 命令运行内容,这应该保持它们不变,但如果文件末尾没有,可能会添加一个尾随换行符。

clean 命令是我从 http://sed.sourceforge.net/sed1line.txt 的笔记中拼凑出来的空白过滤。看来得放到shell脚本里了。我无法弄清楚如何将 sed 命令(包括文件末尾无关的额外行的清理)直接注入到 git-config 文件中。 (你能够但是,无需单独的 sed 脚本即可摆脱尾随空白。只需将 filter.fix-eol-eof 设置为类似 sed 's/[ ]*$//' %f 的内容,其中 是一个实际的选项卡,按标签.)

require = true 会在出现问题时引发错误,以免您遇到麻烦。

【讨论】:

  • 有趣的方法。 +1
  • 谢谢@VonC!我还想借此机会指出 git 属性可以在 .git 文件夹中以每个存储库为基础进行配置,而不是全局配置,这可能更有意义。
【解决方案7】:

我写了这个预提交挂钩,它只从您更改/添加的行中删除尾随空格,因为如果目标文件有太多尾随空格,之前的建议往往会创建不可读的提交。

#!/bin/sh

if git rev-parse --verify HEAD >/dev/null 2>&1 ; then
   against=HEAD
else
   # Initial commit: diff against an empty tree object
   against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi

IFS='
'

files=$(git diff-index --check --cached $against -- | sed '/^[+-]/d' | perl -pe 's/:[0-9]+:.*//' | uniq)
for file in $files ; do
    diff=$(git diff --cached $file)
    if test "$(git config diff.noprefix)" = "true"; then
        prefix=0
    else
        prefix=1
    fi
    echo "$diff" | patch -R -p$prefix
    diff=$(echo "$diff" | perl -pe 's/[ 	]+$// if m{^+}')
    out=$(echo "$diff" | patch -p$prefix -f -s -t -o -)
    if [ $? -eq 0 ]; then
        echo "$diff" | patch -p$prefix -f -t -s
    fi
    git add $file
done

【讨论】:

  • 有趣的。 +1。有关计算空树的信息,请参阅my other answer
  • 好主意,这正是我想要的。但是,使用时要小心!对于我在 OSX 和 git 版本 2.3.5 上,它吹走了我已经上演的任何添加但未提交的更改。尽管如此,我仍然会对一个可行的解决方案感兴趣。
【解决方案8】:

请尝试my pre-commit hooks。它可以自动检测尾随空格和去掉它.

它可以在Git Bash (Windows)、Mac OS X 和 Linux 下运行!


快照:

$ git commit -am "test"
auto remove trailing whitespace in foobar/main.m!
auto remove trailing whitespace in foobar/AppDelegate.m!
[master 80c11fe] test
1 file changed, 2 insertions(+), 2 deletions(-)

【讨论】:

  • 有趣的。 +1。我在 my own answer 中引用了你的钩子
  • @VonC 感谢您的肯定!对于'.md',我只找到git commit -no-verify,有什么建议吗?
  • 我宁愿让钩子能够检测.md 文件而不删除空格,而不是要求最终用户在git commit 上添加--no-verify 选项。
  • 如果提交以 +- 开头的文件/目录,则会失败
【解决方案9】:

这是 Ubuntu 和 Mac OS X 兼容版本:

#!/bin/sh
#

# A Git hook script to find and fix trailing white space
# in your commits. Bypass it with the --no-verify option
# to git-commit
#

if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then
  against=HEAD
else
  # Initial commit: diff against an empty tree object
  against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# Find files with trailing whitespace
for FILE in `exec git diff-index --check --cached $against -- | sed '/^[+-]/d' | (sed -r 's/:[0-9]+:.*//' > /dev/null 2>&1 || sed -E 's/:[0-9]+:.*//') | uniq` ; do
  # Fix them!
  (sed -i 's/[[:space:]]*$//' "$FILE" > /dev/null 2>&1 || sed -i '' -E 's/[[:space:]]*$//' "$FILE")
  git add "$FILE"
done

# Now we can commit
exit

【讨论】:

  • 看起来你和我的唯一区别是你检查 sed 是否会在重写文件之前实际替换某些东西......我不确定这是否重要,因为 git 不会提交实际上不会改变任何东西的更改。我想它稍微安全一些,但也稍微慢一些,而且我更喜欢不在一行上重复两次正则表达式的清晰度。 De gustibus non disputandum est!
  • 没有区别是版本首先使用 ubuntu 语法,然后(如果失败)使用 osx 语法。
  • 我编辑了利奥波德的帖子,它现在应该也可以允许文件名中有空格了。
  • 我想我们可以使用这个 git rev-list --max-parents=0 HEAD 来获取初始化提交
【解决方案10】:

我今天在想这个。这就是我最终为 Java 项目所做的一切:

egrep -rl ' $' --include *.java *  | xargs sed -i 's/s+$//g'

【讨论】:

    【解决方案11】:

    对于Sublime Text 用户。

    在您的设置-用户配置。

    "trim_trailing_white_space_on_save": true
    

    【讨论】:

    • 这是一种按文件类型设置的方法吗?我有 *.md(markdown)文件依赖于“”(尾随双空格)来标记一个简单的 &lt;br /&gt;,并且该设置似乎适用于全部文件,包括那些我想要删除尾随空格。
    • @VonC 这里有关于如何应用配置的层次结构,stackoverflow.com/questions/16983328/…希望它有所帮助
    • 这与 git 无关
    【解决方案12】:

    for 文件循环使用 $IFS shell 变量。 在给定的脚本中,文件名中包含一个也在 $IFS 变量中的字符将被视为 for 循环中的两个不同文件。

    这个脚本修复了它:sed 手册中给出的多行模式修饰符默认情况下似乎在我的 Ubuntu 机器上不起作用,所以我寻求不同的实现并发现它带有迭代标签,基本上它只会开始如果我理解正确的话,替换文件的最后一行。

    #!/bin/sh
    #
    
    # A Git hook script to find and fix trailing white space
    # in your commits. Bypass it with the --no-verify option
    # to git-commit
    #
    
    if git rev-parse --verify HEAD >/dev/null 2>&1
    then
        against=HEAD
    else
        # Initial commit: diff against an empty tree object
        against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
    fi
    
    SAVEIFS="$IFS"
    # only use new-line character as separator, introduces EOL-bug?
    IFS='
    '
    # Find files with trailing white space
    for FILE in $(
        git diff-index --check --cached $against -- 
        | sed '/^[+-]/d' 
        | ( sed -r 's/:[0-9]+:.*//' || sed -E 's/:[0-9]+:.*//' ) 
        | uniq 
    )
    do
    # replace whitespace-characters with nothing
    # if first execution of sed-command fails, try second one (Mac OS X version)
        (
            sed -i ':a;N;$!ba;s/
    +$//' "$FILE" > /dev/null 2>&1 
            || 
            sed -i '' -E ':a;N;$!ba;s/
    +$//' "$FILE" 
        ) 
        && 
    # (re-)add files that have been altered to Git commit-tree
    #   when change was a [:space:]-character @EOL|EOF git-history becomes weird...
        git add "$FILE"
    done
    # restore $IFS
    IFS="$SAVEIFS"
    
    # Exit script with the exit-code of git's check for white space characters
    exec git diff-index --check --cached $against --
    

    1sed 替换模式:How can I replace a newline ( ) using sed?

    【讨论】:

    • 脚注似乎没有被引用。意图是什么?
    【解决方案13】:

    这不会删除空格自动地在提交之前,但它很容易生效。我将以下 Perl 脚本放在 $PATH 目录中名为 git-wsf(Git 空白修复)的文件中,这样我就可以:

    git wsf | sh
    

    它删除了所有的空白只要来自 Git 报告为差异的文件行。

    #! /bin/sh
    git diff --check | perl -x $0
    exit
    
    #! /usr/bin/perl
    
    use strict;
    
    my %stuff;
    while (<>) {
        if (/trailing whitespace./) {
            my ($file,$line) = split(/:/);
            push @{$stuff{$file}},$line;
        }
    }
    
    while (my ($file, $line) = each %stuff) {
        printf "ex %s <<EOT
    ", $file;
        for (@$line) {
            printf '%ds/ *$//'."
    ", $_;
        }
        print "wq
    EOT
    ";
    }
    

    【讨论】:

      【解决方案14】:

      相同结果的 Python 脚本。

      import subprocess                                                                 
                                                                                    
      def get_trailing_lines():                                                         
                                                                                    
          result = subprocess.run([                                                     
                                  'git',                                            
                                  'diff',                                           
                                  '--check'                                         
                              ], capture_output=True)                               
                                                                                    
          return result.stdout.decode().split('
      ')                                     
                                                                                    
                                                                                    
      def modify_line(file_path, l_num):                                                
                                                                                    
          f_lines = open(file_path).readlines()                                         
          f_lines[l_num] = f_lines[l_num].rstrip()+'
      '                                
                           if '
      ' in f_lines[l_num] else f_lines[l_num].rstrip()    
                                                                                    
          with open(file_path, "w") as w_fp:                                            
              w_fp.writelines(f_lines)                                                  
                                                                                    
                                                                                    
      if __name__ == '__main__':                                                        
                                                                                    
          l = get_trailing_lines()                                                      
          for m, d in zip(l[::2], l[1::2]):                                             
              f_path, l_no, *_ = m.split(":")                                           
              modify_line(f_path, int(l_no)-1)                                          
      

      【讨论】:

        【解决方案15】:

        这可能不会直接解决您的问题,但您可能希望在您的实际项目空间中通过 git-config 设置这些,编辑文件./.git/配置而不是文件~/.gitconfig.最好让所有项目成员的设置保持一致。

        git config core.whitespace "trailing-space,space-before-tab"
        git config apply.whitespace "trailing-space,space-before-tab"
        

        【讨论】:

        • afaik,.git 中的设置是不是与其他人分享;它们特定于您当地的回购
        【解决方案16】:

        要可移植地删除文件行尾的尾随空格,请使用ed

        test -s file &&
           printf '%s
        ' H ',g/[[:space:]]*$/s///' 'wq' | ed -s file
        

        【讨论】:

          【解决方案17】:

          在 Vim 中打开文件。要用空格替换制表符,请在 Vim 命令行中键入以下命令:

          :%s#	#    #gc
          

          摆脱其他尾随空格

          :%s#s##gc
          

          这几乎为我做了。如果您有很多文件要编辑,那会很乏味。但我发现它比预提交挂钩和使用多个文本编辑器更容易。

          【讨论】:

          • 如果它变得乏味 - 如果您有要编辑的内容的备份 - 那么我通常只使用 sed 将制表符更改为空格:sed -i 's| | |g' filenames(替换位置中的空格)。请注意,您可以使用 find 来获取文件名。如果您还没有想过如何获得该备份,我通常只是提交所有内容,然后通过软重置“撤消”提交回到我所在的位置;有时我将所有内容都添加到树中但不提交,有时我使用隐藏/应用(不是弹出!)。如果我感到焦虑,我会在干预之前将我的整棵树同步到一个安全的位置......
          猜你喜欢
          • 2010-10-10
          • 2013-10-09
          • 2016-09-10
          • 2015-12-01
          • 2010-11-05
          • 2015-04-27
          • 1970-01-01
          • 2014-12-08
          相关资源
          最近更新 更多