使用GitHub时防止添加大文本文件以提交

时间:2018-12-09 07:35:42

标签: bash git unity3d github git-lfs

我们要防止:

  • 非常大的文本文件(每个文件大于50MB)在填充git历史记录时被提交到git而不是git-lfs
  • 问题是,其中99%是<1MB,应该提交以实现更好的差异。
  • 大小差异的原因:这些是YAML文件,它们支持通过base64编码进行二进制序列化。
  • 我们无法可靠地阻止二进制序列化的原因:这是一个Unity项目,出于各种原因需要二进制序列化。

给出:

  • GitHub托管缺乏预接收挂钩支持。
  • git-lfs缺少文件大小属性支持。

问题:

  1. 我们如何可靠地阻止添加大文件来提交?
  2. 是否可以通过回购中的配置文件来完成此操作,以便所有用户都能正常遵守此规则?
  3. 如果不是,可以通过bash命令别名来做到这一点,以便受信任的用户在意外git add大文件并且未被git-lfs处理时看到警告消息吗?

(我们的环境是macOS。我已经研究了许多解决方案,但到目前为止都还不能满足我们的需求)

2 个答案:

答案 0 :(得分:1)

  
      
  • 我们如何可靠地阻止添加大文件来提交?
  •   
  • 是否可以通过回购中的配置文件来完成此操作,以便所有用户都能正常遵守此规则?   由于GitHub不支持服务器端挂钩,因此您可以使用客户端挂钩。您可能已经知道,可以毫无问题地传递和禁用这些挂钩,但这仍然是实现此目标的好方法。
  •   

core.hooksPath

Git v2.9 添加了在远程文件夹上设置客户端挂钩的功能。在此之前,必须将钩子放置在.git文件夹中。

这将使您可以编写脚本并将其放在任何地方。我以为您知道钩子是什么,但如果不敢问的话。


怎么做?

通常,将挂钩放置在仓库(或其他任何常见文件夹)中。

# set the hooks path. for git config, the default location is --local
# so this configuration is locally per project
git config core.hooksPath .githooks

答案 1 :(得分:1)

好的,在CodeWizard和this SO answer的帮助下,我自己创建了一个很好的指南:

首先,使用以下命令设置您的仓库core.hooksPath

git config core.hooksPath .githooks

第二,在pre-commit文件夹中创建此.githooks文件,以便可以对其进行跟踪(gist link),然后记住使用chmod +x授予其执行权限。

#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments. The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

# Redirect output to stderr.
exec 1>&2

FILE_SIZE_LIMIT_KB=1024
CURRENT_DIR="$(pwd)"
COLOR='\033[01;33m'
NOCOLOR='\033[0m'
HAS_ERROR=""
COUNTER=0

# generate file extension filter from gitattributes for git-lfs tracked files
filter=$(cat .gitattributes | grep filter=lfs | awk '{printf "-e .%s$ ", $1}')

# before git commit, check non git-lfs tracked files to limit size
files=$(git diff --cached --name-only | sort | uniq | grep -v $filter)
while read -r file; do
    if [ "$file" = "" ]; then
        continue
    fi
    file_path=$CURRENT_DIR/$file
    file_size=$(ls -l "$file_path" | awk '{print $5}')
    file_size_kb=$((file_size / 1024))
    if [ "$file_size_kb" -ge "$FILE_SIZE_LIMIT_KB" ]; then
        echo "${COLOR}${file}${NOCOLOR} has size ${file_size_kb}KB, over commit limit ${FILE_SIZE_LIMIT_KB}KB."
        HAS_ERROR="YES"
        ((COUNTER++))
    fi
done <<< "$files"

# exit with error if any non-lfs tracked files are over file size limit
if [ "$HAS_ERROR" != "" ]; then
    echo "$COUNTER files are larger than permitted, please fix them before commit" >&2
    exit 1
fi

exit 0

现在,假设您正确设置了.gitattributesgit-lfs,那么当您尝试git commit并确保git-t不会跟踪所有暂存的文件时,此预提交挂钩将运行lfs(在.gitattributes中指定)将满足指定的文件大小限制。

回购的任何新用户都需要自己设置core.hooksPath,但是除此之外,一切都应该正常工作

希望这可以帮助其他Unity开发人员应对不断增长的git repo大小!