Версионирование больших текстовых файлов в git - PullRequest
14 голосов
/ 30 октября 2011

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

Я тестирую это, используя текстовый файл в стиле mbox размером 550 МБ. Я сделал новый репо, чтобы сделать это. Вот мои результаты:

  • git add и git commit - общий размер репо 306mb - репо содержит один объект размером 306mb
  • добавить одно электронное письмо в файл почтового ящика и git commit - общий размер репо составляет 611 МБ - репо содержит два объекта размером 306 МБ каждый
  • добавить еще одно электронное письмо в файл почтового ящика и git commit - общий размер репо составляет 917mb - репо содержит три объекта, каждый размером 306mb

Таким образом, каждый коммит добавляет новую копию файла почтового ящика в репозиторий. Теперь я хочу попытаться уменьшить размер репо до чего-то управляемого. Вот мои результаты:

  • git repack -adf - общий размер репо составляет 877 МБ - репо содержит один файл пакета размером 876 МБ
  • git gc --aggressive - общий размер репо составляет 877 МБ - репо содержит один файл пакета размером 876 МБ

Я бы ожидал, что смогу уменьшить репо до 306 Мб, но я не могу понять, как. Все, что больше, похоже на большое количество дублирующихся данных.

Я надеюсь, что репо увеличится только по размеру нового полученного письма, а не по размеру всего почтового ящика. Здесь я не пытаюсь управлять электронной почтой с контролем версий, но мне кажется, что я сильно сдерживаюсь от использования ночного скрипта для постепенного резервного копирования домашних каталогов пользователей.

Какой-нибудь совет, как избежать увеличения размера репо при вставке небольшого количества текста в конец очень большого текстового файла?

Я смотрел на bup и git Annex, но я действительно хотел бы придерживаться простого старого git, если это возможно.

Спасибо за помощь!

Ответы [ 4 ]

3 голосов
/ 01 ноября 2011

Я не думаю, что git хорошо справится с хранением дельт в целом, и даже если вы сможете сделать это, это не будет детерминированным. Тем не менее, на основе http://metalinguist.wordpress.com/2007/12/06/the-woes-of-git-gc-aggressive-and-how-git-deltas-work/, вы можете попробовать git repack -a -d --depth=250 --window=250.

Я подозреваю, что ваш лучший вариант - обрезать вашу историю, используя git --rebase, и хранить только последние несколько резервных копий. Вы можете сделать это с помощью веток git. Сделайте ветку под названием ежегодно, ежемесячно и ежедневно. Каждый день выполняйте коммит ежедневно, а затем используйте git rebase --onto HEAD~4 HEAD~3 daily для удаления резервных копий старше 3 дней. В первый день каждой недели оформляйте заказ еженедельно и git cherry-pick daily, затем делайте то же самое git rebase для удаления еженедельных резервных копий старше 3 недель. Наконец, в первый день каждого года следуйте аналогичному процессу. Возможно, вы захотите делать git gc после этой последовательности каждый раз, чтобы освободить старое пространство.

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

2 голосов
/ 02 ноября 2014

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

Хотя Git не является подходящим инструментом (как упоминалось в других ответах), по крайней мере, проблема git diff смягчена в git 2.2.0 (4-й квартал 2014 г.).
См. commit6bf3b81 из Nguy Thn Thái Ngọc Duy (pclouds) :

diff --stat: пометить любой файл больше core.bigfilethreshold двоичный

Слишкомбольшие файлы могут привести к невозможности выделить память.
Если это произойдет здесь, это может повлиять на довольно много команд, которые включают diff.
Более того, слишком большие файлы неэффективны для сравнения в любом случае (и, скорее всего, нетекстовые), поэтому отметьте их как двоичные и пропустите, просматривая их содержимое.

2 голосов
/ 01 ноября 2011

Git не лучший инструмент для резервного копирования, но он должен уметь очень эффективно обрабатывать добавление в текстовый файл.Я с подозрением относился к вашим результатам.Я повторил ваш эксперимент с файлом 354 мегабайт и git 1.7.7 на OS X. Вот мои действия и размер .git.

  1. git init (52K)
  2. git addmbox && git commit (110M)
  3. cat mail1 >> mbox && git commit -a -m (219M)
  4. git gc (95M)
  5. cat mail2 >> mbox&& git commit -a -m (204M)
  6. git gc (95M)

Как видите, git очень эффективен.94 мегабайта это размер сжатого mbox.Это не может быть намного меньше.

Я предполагаю, что вы либо используете старую версию git, либо ваш файл mbox сжимается или шифруется вашей почтовой программой.

  • Проверьте этосодержимое вашего mbox, которое видит git, представляет собой простой текст.
  • Если вы не используете последнюю версию git, обновитесь и попробуйте снова.
1 голос
/ 01 ноября 2011

Хотя разница, которую вы видите после упаковки объектов, зависит от типа файлов и т. Д., Git не является инструментом резервного копирования и не должен использоваться в этом случае. Если вы посмотрите на всю философию git, то она основана на предположении, что дисковое пространство дешево и оптимизирует скорость операций. Кроме того, независимо от того, является ли тип файла двоичным или текстовым, git будет хранить его таким же образом, и, разумеется, как упоминалось выше, тип файла будет определять, какую разницу вы увидите после упаковки. Git делает различие между двоичными и текстовыми файлами только для сравнения и других целей, а не для хранения.

Используйте соответствующий инструмент резервного копирования, который также сэкономит ваше дисковое пространство. Стоит попробовать что-то вроде ZFS для резервного копирования: https://svn.oss.prd/repos/SHAW/BuildAndReleaseTransition/TeamCity/TeamCityConfiguration-39/TeamCityConfiguration.docx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...