我在我的编辑器中发现一个错误(很糟糕),偶尔会将大文件写入工作目录。然后我执行git push
时,没有手动检查这些大文件是否存在,导致git远程出现过载并最终报错。
有没有办法检查我存储库的大小是否超过了某个以MB为单位的阈值(也许可以使用git hook)?
git push
时不会以任何方式使用工作树。具体来说,git push
推送的是提交,以及使这些提交完整所需的任何对象,这些对象通常是在提交时冻结到提交中的文件。1
请注意,git commit
本身也不会使用工作树:它会提交索引(也称为暂存区,有时称为缓存)中的所有内容。这就是为什么您必须在提交之前添加您的文件git add
。虽然git commit
有几个选项可以使其自动将工作树文件复制到暂存区中那些文件的版本上;但原理仍然是相同的:git commit
提交的是索引中的内容,而不是工作树中的内容。(文档还有更多内容,请跟随链接查看。)pre-commit
该挂钩由git commit(1)调用,并且可以使用
--no-verify
选项绕过。它不需要任何参数,并且在获取建议的提交日志消息并进行提交之前调用。从此脚本中退出并具有非零状态会导致git commit
命令在创建提交之前中止。
#! /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
(未经测试)。您可以选择使用预推挂钩,但那比较晚。
1这些 Git 对象也是压缩的。尽可能地,它们会使用服务器上已存在的先前对象进行非常压缩。因此,如果您有一个十 GB 的文本文件,但只对其进行了一点更改并提交,即使该提交包含了一个十 GB 的文件,由于 Git 发送的所谓的thin pack 将告诉服务器: 嘿,记得你已经有那个十 GB 的对象吗?取出那个对象,从中间删除几个字节,并替换为这些其他字节。
由于这是一个持续进行的问题,您应该养成在执行git commit
之前运行git status
的习惯。您可以查看将被提交的文件列表,以查找不应该存在的文件。
如果您想要多个提交的大小,可以采用另一种方法:
使用 Git 2.29(2020年第四季度), "git for-each-ref --format= <>
(man)" 学会了 %(contents:size)
。
请查看 commit b6839fd(2020年7月16日),以及 commit 6e2ef8e,commit 9fcc9ca(2020年7月10日),作者为 Christian Couder (chriscool
)。
(由 Junio C Hamano -- gitster
-- 在 commit be53706 中合并,2020年7月30日)
ref-filter
:添加对%(contents:size)
的支持签名:Christian Couder
It's useful and efficient to be able to get the size of the contents directly without having to pipe through
wc -c
.Also the result of the following:
git for-each-ref --format='%(contents)' refs/heads/my-branch | wc -c
is off by one as
git for-each-ref
(man) appends a newline character after the contents, which can be seen by comparing its output with the output fromgit cat-file
(man).As with
%(contents)
,%(contents:size)
is silently ignored, if a ref points to something other than a commit or a tag:
$ git update-ref refs/mytrees/first HEAD^{tree} $ git for-each-ref --format='%(contents)' refs/mytrees/first $ git for-each-ref --format='%(contents:size)' refs/mytrees/first
git for-each-ref
现在在其手册页面中包含:
contents:size
提交或标签消息的字节数大小。
git push
不会处理未提交的文件。你必须在本地进行提交。你是盲目使用git add .
或类似命令吗?那是一个不好的反模式。 - Chris