对文本文件的GitHub 100MB文件大小限制有什么好的解决方法吗?

jos*_*naj 22 git github large-files pre-commit-hook post-commit-hook

我有一个190 MB纯文本文件,我想在github上跟踪.

文本文件是我们的文本到语音引擎的代词词典文件.我们经常在文本文件中添加和修改行,并且差异相当小,因此在这个意义上它非常适合git.

但是,GitHub具有严格的100 MB文件大小限制.我已经尝试过GitHub大文件存储服务,但每次更改时都会上传整个190 MB文件的新版本 - 因此,如果我沿着这条路走下去,那么它将迅速增长到几千兆字节.

我想将文件保存为一个文件而不是拆分它,因为这是我们的工作流程当前的方式,并且需要一些编码才能允许多个文本文件作为我们工具中的输入/输出(并且我们没有太多的开发资源) .

我有一个想法是,也许可以设置一些预提交和提交后挂钩来自动拆分和连接大文件?这可能吗?

其他想法?

编辑:我知道StackOverflow上类似问题中描述的100 MB文件大小限制,但我不认为我的问题是重复的,因为我要求的是差异很小且频繁的特定情况(我'我没有尝试上传大型ZIP文件或任何东西).但是,我的理解是git-lfs仅适用于很少更改的文件,而普通的git非常适合我所描述的那种文件; 除了GitHub有文件大小限制.

更新:我昨天花了一些时间尝试创建一个小型跨平台程序,该程序使用git hooks将文件拆分并连接成较小的文件.它有点工作但不太令人满意.您需要将.gitignore排除大文本文件,这使得git不知道它是否已更改.拆分文件最初没有检测到git statusgit commit导致与此SO问题中描述的相同问题,这非常烦人:预提交脚本创建mysqldump文件,但"没有提交(工作目录清理)"? 设置一个cron作业(linux)和计划任务(windows)以定期自动重新生成拆分文件可能会解决这个问题,但是自动设置并不容易,可能会导致用户计算机出现性能问题,而且不是很优雅解.可能还需要一些像动态修改.gitignore这样的hacky解决方案,并且绝不会得到实际文本文件的差异,只有分割文件(尽管这可能是可接受的,因为它们非常相似).

所以,睡着了,今天我觉得git hook方法毕竟不是一个好选择,因为它有太多的怪癖.正如@PyRulez所建议的那样,我想我不得不看看除GitHub之外的其他服务(不幸的是,因为我喜欢github).托管解决方案更可取,以避免必须管理我们自己的服务器.我也希望它能公开上市......

更新2:我已经看了一些GitHub的替代品,目前我倾向于使用GitLab.我已经联系了GitHub关于提高100MB限制的可能性的支持,但如果他们不这样做,我将只为这个特定项目切换到GitLab.

PyR*_*lez 11

清洁和涂抹

您可以使用干净和涂抹来压缩文件.通常,这不是必需的,因为git会在内部压缩它,但由于gitHub表现得很奇怪,它可能有所帮助.主要命令如下:

git config filter.compress.clean gzip
git config filter.compress.smudge gzip -d
Run Code Online (Sandbox Code Playgroud)

GitHub会将其视为压缩文件,但在每台计算机上,它看起来都是一个文本文件.

有关详细信息,请参阅https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes.

或者,您可以将干净的帖子发送到在线pastebin,并从pastebin中获取污迹,例如http://pastebin.com/.许多其他组合可能具有清洁和涂抹.

  • @josteinaj请参阅https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes#Binary-Files以了解如何正确区分它们. (3认同)
  • @josteinaj https://git-scm.com/docs/gitattributes为此答案提供了更深入的资料. (2认同)
  • +1这绝对是个绝妙的答案!我只有一个文件,时钟为116MB。我添加了两个过滤器,然后将我需要压缩的单个文件命名为.gitattributes。优雅! (2认同)
  • @pyrulez 你能提供更多关于你添加到 .gitattributes 文件的信息吗? (2认同)

Cod*_*ard 7

一个非常好的解决方案是使用:

https://git-lfs.github.com/

它是一个开源,旨在与大文件一起使用.

  • 是的,我已经尝试过了,但是我经常对文本文件进行更改,因此它会经常在LFS中创建一个新的190MB文件.据我所知LFS,它最适合很少改变的文件. (2认同)

May*_*uso 4

您可以使用任何语言创建脚本/程序来分割或合并文件。

这里是一个用 Java 编写的分割文件的例子(我使用 Java 是因为我觉得 Java 比其他任何语言都更舒服,但任何其他语言都可以工作,有些也比 Java 更好)。

public static void main(String[] args) throws Exception
{
    RandomAccessFile raf = new RandomAccessFile("test.csv", "r");
    long numSplits = 10; //from user input, extract it from args
    long sourceSize = raf.length();
    long bytesPerSplit = sourceSize/numSplits ;
    long remainingBytes = sourceSize % numSplits;

    int maxReadBufferSize = 8 * 1024; //8KB
    for(int destIx=1; destIx <= numSplits; destIx++) {
        BufferedOutputStream bw = new BufferedOutputStream(new FileOutputStream("split."+destIx));
        if(bytesPerSplit > maxReadBufferSize) {
            long numReads = bytesPerSplit/maxReadBufferSize;
            long numRemainingRead = bytesPerSplit % maxReadBufferSize;
            for(int i=0; i<numReads; i++) {
                readWrite(raf, bw, maxReadBufferSize);
            }
            if(numRemainingRead > 0) {
                readWrite(raf, bw, numRemainingRead);
            }
        }else {
            readWrite(raf, bw, bytesPerSplit);
        }
        bw.close();
    }
    if(remainingBytes > 0) {
        BufferedOutputStream bw = new BufferedOutputStream(new FileOutputStream("split."+(numSplits+1)));
        readWrite(raf, bw, remainingBytes);
        bw.close();
    }
        raf.close();
}

static void readWrite(RandomAccessFile raf, BufferedOutputStream bw, long numBytes) throws IOException {
    byte[] buf = new byte[(int) numBytes];
    int val = raf.read(buf);
    if(val != -1) {
        bw.write(buf);
    }
}
Run Code Online (Sandbox Code Playgroud)

这几乎不需要花费任何成本(时间/金钱)。

编辑:您可以创建一个 Java 可执行文件并将其添加到您的存储库中,或者更简单,创建一个 Python(或任何其他语言)脚本来执行此操作,并将其以纯文本形式保存在您的存储库中。

  • 查看 Unix/Linux `split` 和 `cat` 命令。`split -b 100M 大文件 大文件-` ... `cat 大文件-* &gt; 大文件` (5认同)