首页 > 解决方案 > 在推送到 git 远程之前检查提交大小

问题描述

我的编辑器中有一个错误(这很可怕),有时大文件会写入工作目录。然后我在git push没有手动检查这些大的新文件的情况下进行操作,并且 git 远程超载并最终出错。

是否有一些检查(可能是 git 钩子)可以用来检查我的 repo 是否超过特定大小(以 MB 为单位)?

标签: gitgithubgithooks

解决方案


当您运行 .git 时,Git 不会以任何方式使用工作树git push。具体来说,git push推送是提交,以及任何对象(主要是其内容在提交时被冻结到提交中的文件)都是完成这些提交所必需的。1

请注意,git commit它本身也不使用工作树:它提交索引中的任何内容(也称为暂存区域,有时也称为缓存)。这就是为什么您必须git add在提交之前提交文件。有几个选项可以git commit让它自动将工作树文件复制到索引/暂存区域中这些文件的版本之上;但原则仍然存在:git commit提交索引中的内容,而不是工作树中的内容。

因此,如githooks 文档中所述,您最好使用 Git钩子来检测此问题是一个预提交钩子:

预提交

    这个钩子由git commit(1)调用,并且可以通过 --no-verify选项绕过。它不带任何参数,并在获取建议的提交日志消息并进行提交之前被调用。从此脚本中以非零状态退出会导致git commit命令在创建提交之前中止。

(文档还有更多内容;请点击链接查看。)

编写 Git 钩子有点棘手(尤其是服务器端钩子),但这个还不错:

#! /bin/sh
# pre-commit hook: check for large files
TMP=$(mktemp)
trap "rm -f $TMP" 0 1 2 3 15
MAX_FILE_SIZE=1048576 # 1 MB
status=0
git ls-files --stage > $TMP
while read mode hash stage path; do
    objsize=$(git cat-file -s $hash)
    if [ $objsize -gt $MAX_FILE_SIZE ]; then
        echo "file too big: '$path' as staged exceeds $MAX_FILE_SIZE bytes" 1>&2
        status=1
    fi
done < $TMP
exit $status

(未经测试)。您可以改为选择 pre-push 钩子,但这比适当的要晚。


1这些 Git 对象也被压缩。只要有可能,它们就会通过使用服务器上已经存在的现有先前对象进行高度压缩。因此,如果您有一个 10 GB 的文本文件,但您对其进行了一些小的更改并提交,那么推送该提交(即使它里面有一个 10 GB 的文件)占用的空间非常小,因为Git 发送的所谓的瘦包最后说:嘿,还记得你已经拥有的 10 GB 对象吗?拿那个,从中间删除几个字节,然后用这些其他字节替换它们。


推荐阅读