我的编辑器有一个bug(很可怕),有时会有大文件被写入工作目录。然后我在没有手动检查这些新的大文件的情况下执行git push,git remote就会过载,最终出错。是否有一些检查(也许是一个git挂钩),我可以用来检查我的回购是否超过一定的大小在MB?
git push
u4vypkhs1#
当你运行git push时,Git不会以任何方式使用工作树。具体来说,git push推送的是 commits,沿着任何对象(大多数是在提交时被冻结在提交中的文件),这些对象是完成这些提交所必需的。1注意,git commit本身 * 也 * 不使用工作树:它会提交 index(也称为 staging-area,有时也称为 cache)中的所有文件。这就是为什么你必须在提交前对文件进行git add。git commit有几个选项可以让它自动将工作树文件复制到index / staging-area中的文件版本之上;但原则仍然是:git commit提交索引中的内容,而不是工作树中的内容。因此,使用Git * 钩子 * 检测此问题的最佳方法是使用预提交钩子,如the githooks documentation中所述:预先提交此挂接由git commit(1)调用,可以使用--no-verify选项绕过。它不带参数,在获取建议的提交日志消息并进行提交之前调用。以非零状态退出此脚本将导致git commit命令在创建提交之前中止。(文档还有一些内容;点击链接查看。)编写Git钩子有点棘手(尤其是服务器端钩子),但这一个还不错:
git commit
git add
--no-verify
#! /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对象也是压缩的。只要有可能,它们都是通过使用服务器上已经存在的先前对象进行高度压缩的。因此,如果你有一个10 G的文本文件,但你对它做了一个小的修改并提交,推送该提交-即使它里面有一个10 G的文件-占用的空间非常小,因为Git发送的所谓的“精简包”最终会说:* 嘿,还记得你已经拥有的10 GB对象吗?拿那个对象,从中间删除几个字节,然后用其他字节替换它们。*
hjqgdpho2#
如果您知道大文件名或模式(例如后缀),则可以将其添加到.gitignore,直到您解决编辑器的问题。您可以选中this answer,它描述了服务器端更新挂接。
.gitignore
mkshixfv3#
由于这是一个持续的问题,您应该养成在执行git commit之前运行git status的习惯。您可以查看将提交的文件列表,以查找不属于该文件的文件。
git status
zfycwa2u4#
另一种方法是,如果你想要多个提交的大小:在Git 2.29(2020年第四季度)中,“git for-each-ref --format= <>(人)”学习了%(contents:size)。参见commit b6839fd(2020年7月16日)和commit 6e2ef8e、commit 9fcc9ca(2020年7月10日),作者为Christian Couder ( chriscool )。(2020年7月30日由Junio C Hamano -- gitster --合并至commit be53706)第1001章:添加对%(contents:size)的支持签署人:克里斯蒂安·库德能够直接获得内容的大小,而不必通过wc -c管道,这是非常有用和高效的。也是以下的结果:
git for-each-ref --format= <>
%(contents:size)
chriscool
gitster
wc -c
git for-each-ref --format='%(contents)' refs/heads/my-branch | wc -c
git for-each-ref(man)会在内容之后附加新行字符,因此会相差1,比较其输出与git cat-file(man)的输出即可看出这一点。与%(contents)一样,如果ref指向的不是commit或tag,%(contents:size)也会被忽略:
git for-each-ref
git cat-file
%(contents)
$ 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
提交或标记消息的大小(以字节为单位)。
4条答案
按热度按时间u4vypkhs1#
当你运行
git push
时,Git不会以任何方式使用工作树。具体来说,git push
推送的是 commits,沿着任何对象(大多数是在提交时被冻结在提交中的文件),这些对象是完成这些提交所必需的。1注意,
git commit
本身 * 也 * 不使用工作树:它会提交 index(也称为 staging-area,有时也称为 cache)中的所有文件。这就是为什么你必须在提交前对文件进行git add
。git commit
有几个选项可以让它自动将工作树文件复制到index / staging-area中的文件版本之上;但原则仍然是:git commit
提交索引中的内容,而不是工作树中的内容。因此,使用Git * 钩子 * 检测此问题的最佳方法是使用预提交钩子,如the githooks documentation中所述:
预先提交
此挂接由git commit(1)调用,可以使用
--no-verify
选项绕过。它不带参数,在获取建议的提交日志消息并进行提交之前调用。以非零状态退出此脚本将导致git commit
命令在创建提交之前中止。(文档还有一些内容;点击链接查看。)
编写Git钩子有点棘手(尤其是服务器端钩子),但这一个还不错:
(未测试)。你可以选择一个预推钩子,但这是晚于适当的。
1这些Git对象也是压缩的。只要有可能,它们都是通过使用服务器上已经存在的先前对象进行高度压缩的。因此,如果你有一个10 G的文本文件,但你对它做了一个小的修改并提交,推送该提交-即使它里面有一个10 G的文件-占用的空间非常小,因为Git发送的所谓的“精简包”最终会说:* 嘿,还记得你已经拥有的10 GB对象吗?拿那个对象,从中间删除几个字节,然后用其他字节替换它们。*
hjqgdpho2#
如果您知道大文件名或模式(例如后缀),则可以将其添加到
.gitignore
,直到您解决编辑器的问题。您可以选中this answer,它描述了服务器端更新挂接。
mkshixfv3#
由于这是一个持续的问题,您应该养成在执行
git commit
之前运行git status
的习惯。您可以查看将提交的文件列表,以查找不属于该文件的文件。zfycwa2u4#
另一种方法是,如果你想要多个提交的大小:
在Git 2.29(2020年第四季度)中,“
git for-each-ref --format= <>
(人)”学习了%(contents:size)
。参见commit b6839fd(2020年7月16日)和commit 6e2ef8e、commit 9fcc9ca(2020年7月10日),作者为Christian Couder (
chriscool
)。(2020年7月30日由Junio C Hamano --
gitster
--合并至commit be53706)第1001章:添加对
%(contents:size)
的支持签署人:克里斯蒂安·库德
能够直接获得内容的大小,而不必通过
wc -c
管道,这是非常有用和高效的。也是以下的结果:
git for-each-ref
(man)会在内容之后附加新行字符,因此会相差1,比较其输出与git cat-file
(man)的输出即可看出这一点。与
%(contents)
一样,如果ref指向的不是commit或tag,%(contents:size)
也会被忽略:git for-each-ref
现在在其手册页中包括:contents:size
提交或标记消息的大小(以字节为单位)。