首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GIT预提交钩子,它在修改/添加的文件中搜索非UTF-8编码(如果找到任何文件,则拒绝提交)

GIT预提交钩子,它在修改/添加的文件中搜索非UTF-8编码(如果找到任何文件,则拒绝提交)
EN

Stack Overflow用户
提问于 2019-04-12 06:30:53
回答 2查看 1.4K关注 0票数 4

我正在使用Git (和TortoiseGit)。

我的目标是防止提交,其中至少有一个非UTF-8文件的修改/添加。

  • 枚举已修改/添加的文件:--我找到了以下代码 { git diff -名称唯一;git diff -名称唯一-阶段;} 这是最好(正确和最简洁)的方法吗?
  • 搜索非UTF-8文件:我找到了以下代码 { git diff --仅限名称;git diff -仅限名称-执行阶段;} xargs -I {} bash -c“dev -f utf-8 -t utf-16 {} &>/dev/null \\x {} }-是非utf 8!” 如果我在我的存储库根文件夹启动Git它可以工作(每个非UTF-8文件显示)。因此,我将.git/hooks/pre-commit.sample重命名为.git/hooks/pre-commit,并复制粘贴了上面的代码。提交更改后,在TortoiseGit提交gui窗口中没有特殊显示。所以看来预提交钩子不能正常工作。
  • 如果有任何非UTF-8文件,则拒绝提交:显示所有非UTP-8文件后的应被拒绝。但我不知道如何做到这一点(展示一些退出代码--但如何做?)

所以任何帮助都是非常感谢的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-12 11:51:04

因此,答案是(对phd和对torek的有用说明而言,都是非常有用的):

代码语言:javascript
复制
    git diff --name-only --staged --diff-filter d | xargs -I {} bash -c 
 "iconv -f utf-8 -t utf-16 {} &>/dev/null || { echo {} - is non-UTF8!; exit 1; }"

此代码遍历所有在提交中更改的文件(除了已删除的文件--即添加、修改、复制和重命名),并检查是否有任何非UTF8 8文件。列出所有找到的文件,并中止提交。

票数 5
EN

Stack Overflow用户

发布于 2019-04-12 15:51:38

您现有的解决方案可能已经足够了。然而,这并不是100%正确的:下面是剩下的问题,所有这些都是你可以在空闲时间(如果有的话)可以解决的小问题:

  • 您只需要git diff ... --staged (或--cached),因为Git将提交索引/暂存区域中的任何文件,git diff将其与HEAD提交中的文件进行比较,并告诉您那里的不同之处。如果索引中的文件副本与HEAD中的文件副本不同,则应检查索引副本。
  • 从技术上讲,最好在这里使用git diff-index --cached,以便不服从任何用户的git diff配置。也就是说,git diff-index是Git中的管道命令,这意味着它的目标是从其他计算机程序中使用:它只以完全可预测的方式运行,仅基于参数,而不是在任何git config设置上。但是,如果您是为自己这样做的,并且您配置了git diff,使它破坏了您自己对git diff的使用,那么这是您自己的错。:-)
  • 您还可以考虑在这里使用--diff-filter来排除已删除的文件。否则,您的检查程序在删除时总是会失败(因为iconv将无法读取已删除的文件)。
  • 最重要的是:iconv将从工作树中读取文件。正如我在第一个要点中指出的那样,Git将提交已经完成的任务,而不是工作树中的内容。

举个例子-也许可能也可能不可能在乌龟体内-考虑一下如果你这样做会发生什么:

代码语言:javascript
复制
$ git checkout master
$ printf '\300\300\300' > badfile    # put bad non-UTF-8 crud into file
$ git add badfile                    # copy file into index
$ echo 'good data' > badfile         # replace work-tree contents
$ git commit

这个提交将提交索引中的坏内容(没有换行符的\300的三个字节),但是您的预提交钩子将对好文件的内容运行iconv -f utf-8 -t utf-16,即读取good data,这当然很好。

要解决这个问题,您的预提交筛选器必须从要提交的每个文件的索引中提取数据。你怎么做取决于你自己。最简单(但可能最慢)的方法是使用git checkout-index将整个索引内容提取到临时工作区。一个更好的方法可能是将每一个索引内(in阶段-区域)路径名称转换为有效的索引说明符(即path/to/file变为:path/to/file),并使用git cat-file -p $specifier | iconv ...扫描每个路径。但所有这些都将是相当低效的,特别是在Windows上。为了提高效率,您可能需要编写一个Python脚本,该脚本使用git cat-file --batch一次提取它们,并在那里进行格式检查。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55645733

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档