Есть ли хорошие обходные пути для ограничения размера файла GitHub 100 МБ для текстовых файлов?

У меня есть простой текстовый файл 190 МБ, который я хочу отслеживать на GitHub.

Текстовый файл является файлом лексики произношения для нашего механизма преобразования текста в речь. Мы регулярно добавляем и изменяем строки в текстовых файлах, и различия довольно малы, поэтому в этом смысле он идеально подходит для git.

Тем не менее, GitHub имеет строгое ограничение размера файла 100 МБ. Я попробовал сервис GitHub Large File Storage, но он загружает новую версию всего файла 190 МБ каждый раз, когда он изменяется, так что если я пойду по этому пути, он быстро увеличится до многих гигабайт.

Я хотел бы сохранить файл как один файл вместо того, чтобы разбивать его, потому что таков наш рабочий процесс в настоящее время, и потребуется некоторое кодирование, чтобы разрешить использование нескольких текстовых файлов для ввода / вывода в наших инструментах (и у нас не так много ресурсов для разработки),

Одна идея, которая у меня возникла, заключается в том, что, возможно, можно настроить некоторые хуки до и после фиксации для автоматического разделения и объединения большого файла? Это будет возможно?

Другие идеи?

Изменить: Мне известно об ограничении размера файла в 100 МБ, описанном в аналогичных вопросах здесь, на Stackru, но я не считаю свой вопрос дубликатом, потому что я спрашиваю о конкретном случае, когда различия небольшие и частые (я я не пытаюсь загрузить большой ZIP-файл или что-нибудь). Тем не менее, я понимаю, что git-lfs подходит только для файлов, которые редко изменяются, и что обычный git идеально подходит для файлов, которые я описываю; за исключением того, что GitHub имеет ограничение на размер файла.

Обновление: я провел вчера, экспериментируя с созданием небольшой кроссплатформенной программы, которая разбивает и объединяет файлы в более мелкие файлы с помощью перехватчиков git. Это отчасти работает, но не совсем удовлетворительно. Вам нужно исключить ваш большой текстовый файл из.gitignore, что делает git не осведомленным о том, изменился он или нет. Разделенные файлы изначально не обнаруживаются git status или же git commit и приводит к той же проблеме, которая описана в этом вопросе SO, что довольно раздражает: сценарий предварительной фиксации создает файл mysqldump, но "ничего не фиксируется (рабочий каталог очищен)"? Настройка задания cron (linux) и запланированного задания (windows) для автоматической регулярной регенерации разделенных файлов может исправить это, но автоматическая настройка не так проста, может вызвать проблемы с производительностью на компьютере пользователя и просто не очень элегантна решение. Также могут потребоваться некоторые хакерские решения, такие как динамическое изменение.gitignore, и вы ни в коем случае не получите различий между фактическими текстовыми файлами, только разделенными файлами (хотя это может быть приемлемо, поскольку они будут очень похожи).

Поэтому, поспав на нем, сегодня я думаю, что подход с использованием git hook все-таки не очень хороший вариант, поскольку в нем слишком много причуд. Как было предложено @PyRulez, я думаю, что мне придется взглянуть на другие сервисы, кроме GitHub (к сожалению, так как я люблю github). Хостинговое решение было бы предпочтительным, чтобы избежать необходимости управлять нашим собственным сервером. Я также хотел бы, чтобы это было публично доступно...

Обновление 2: я рассмотрел некоторые альтернативы GitHub, и в настоящее время я склоняюсь к использованию GitLab. Я связался со службой поддержки GitHub о возможности повышения лимита в 100 МБ, но если они этого не сделают, я просто переключусь на GitLab для этого конкретного проекта.

3 ответа

Чистый и грязный

Вы можете использовать clean и smudge для сжатия вашего файла. Обычно в этом нет необходимости, поскольку git сжимает его внутри, но поскольку gitHub ведет себя странно, это может помочь. Основные команды будут выглядеть так:

git config filter.compress.clean gzip
git config filter.compress.smudge gzip -d

GitHub увидит это как сжатый файл, но на каждом компьютере это будет текстовый файл.

См. https://git-scm.com/book/en/v2/Customizing-Git-Git-Attributes для получения более подробной информации.

В качестве альтернативы, вы можете получить чистую публикацию в онлайн-папке и распаковать ее, например, http://pastebin.com/. Многие другие комбинации возможны с чистым и смазанным.

Очень хорошим решением будет использовать:

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

Это открытый исходный код, предназначенный для работы с большими файлами.

Вы можете создать скрипт / программу на любом языке для разделения или объединения файлов.

Вот пример разделения файла, написанного на 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);
    }
}

Это будет стоить почти ничего (время / деньги).

Редактировать: Вы можете создать исполняемый файл Java и добавить его в свой репозиторий, или, что еще проще, создать скрипт Python (или любой другой язык), чтобы сделать это, и сохранить его в виде простого текста в своем репозитории.

Другие вопросы по тегам