git очень-очень медленный при отслеживании больших двоичных файлов

84

Моему проекту шесть месяцев, а git работает очень-очень медленно. Мы отслеживаем около 30 файлов размером от 5 до 50 МБ. Это двоичные файлы, и мы храним их в git. Я считаю, что эти файлы замедляют работу git.

Есть ли способ убить все файлы размером> 5 МБ из репозитория. Я знаю, что потеряю все эти файлы, и это меня устраивает.

В идеале мне нужна команда, которая перечисляла бы все большие файлы (> 5 МБ). Я вижу список и говорю, ладно, удалите эти файлы и сделайте git быстрее.

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

Таким образом, исправление должно затрагивать сервер, а не только пользователей репозитория.

Ник Вандербильт
источник
4
Вы можете попробовать использовать git из git-bigfilesпроекта
Якуб Наребски
1
вы можете попробовать использовать что-то вроде git-application для управления двоичными файлами. git-annex.branchable.com
Джед Шнайдер
Если это кому-то будет полезно, позвольте мне добавить, что моя версия git для Cygwin зависала на ребазах. Когда я использовал Git-Bash, в том же репозитории не было проблем.
Шридхар Сарнобат
Интересно, так ли это до сих пор. Я надеюсь, что они отключат сжатие для всего, где эффект сжатия ниже 50% (или любого другого выбираемого X%). В какой-то момент скорость явно перевешивает аппаратное пространство!
Триларион

Ответы:

125

Вы собираете мусор?

git gc

Это дает значительную разницу в скорости даже для небольших репозиториев.

Куби
источник
8
Это делается автоматически, когда становится слишком много беспорядка. Я сомневаюсь, что это действительно поможет ОП.
Cascabel
@ Джефроми, это новенькое? Я только что обновился до 1.7.1 вчера, но до этого версия, которую я использовал, определенно не запускалась автоматически gc.
Куби
@kubi: Ну, он не был всегда, но он не совсем новый - он вызывается из commit, merge, am и rebase с caf9de2 (14 сентября 2007 г.) или в стабильной версии v1.5.4 (1 февраля 2008 г. ).
Cascabel
1
Если подумать, git gcне может быть вызван commitи mergeиначе git fsck --unreachableникогда бы ничего не вернул.
Куби
4
Нашел. По умолчанию количество незакрепленных объектов перед автоматическим gcзапуском составляет 6700, что объясняет, почему я никогда не видел, чтобы он запускался.
Куби
79

Объяснение

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

Это обычная проблема среди DVCS, которая усугубляется тем фактом, что вы загружаете каждую версию каждого файла («весь репозиторий») каждый раз при клонировании. Ребята из Kiln работают над плагином, который будет обрабатывать эти большие файлы больше как Subversion, который загружает только исторические версии по запросу.

Решение

Эта команда выведет список всех файлов в текущем каталоге размером> = 5 МБ.

find . -size +5000000c 2>/dev/null -exec ls -l {} \;

Если вы хотите удалить файлы из всей истории репозитория, вы можете использовать эту идею, git filter-branchчтобы просмотреть историю и избавиться от всех следов больших файлов. После этого все новые клоны репозитория будут более компактными. Если вы хотите расширить репозиторий без клонирования, вы найдете инструкции на странице руководства (см. «Контрольный список для сжатия репозитория»).

git filter-branch --index-filter \
    'find . -size +5000000c 2>/dev/null -exec git rm --cached --ignore-unmatch {} \;'

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

Андрес Яан Так
источник
4
Примечание: это версия find для Unix / Linux, а не find.exe для Windows.
Craig Trader
1
+1. Возможно, вы захотите findсначала отправить вывод в файл, проверить список, а затем использовать git rm, на случай ложных совпадений. В качестве альтернативы, проверьте git statusпосле удаления больших файлов и используйте git checkout HEAD <file>для возврата ошибочно удаленных файлов.
Cascabel
2
Я думаю, что ваш комментарий о том, что git «по умолчанию хранит отдельные копии», является обратным. Согласно цепочке писем, с которой вы связались ( thread.gmane.org/gmane.comp.version-control.git/146957/… ), по умолчанию git пытается различать двоичные файлы - и это то, что вызывает проблему; не хранилище.
Александр Берд
16

Вот цензурированная ревизия, призванная быть менее негативной и подстрекательской:

Git имеет хорошо известную слабость, когда речь идет о файлах, которые не являются построчными текстовыми файлами. В настоящее время нет решения, и основная команда git не объявила о планах по решению этой проблемы. Есть обходные пути, если ваш проект небольшой, скажем, 100 МБ или около того. Существуют ветки проекта git для решения этой проблемы масштабируемости, но в настоящее время эти ветки не являются зрелыми. Некоторые другие системы контроля версий не имеют этой конкретной проблемы. Вы должны рассматривать эту проблему как лишь один из многих факторов при принятии решения о выборе git в качестве системы контроля версий.

Джон
источник
8
«У Git есть известная слабость ...» - необходима цитата
Nav
6
Я знаю это. Кому нужны цитаты, когда его актуально общеизвестно. просто не используйте git для двоичных файлов. использовать принудительное или специализированное управление активами.
v.oddou
1
@ v.oddou Ну, есть разница между «я знаю это» и «это общеизвестно». Дело в том, что не все это знают и, вероятно, это даже не совсем так. Так что любое цитирование улучшает этот ответ. Это нормально, но определенно не выдающееся и не подтвержденное.
Триларион
2
Ну, не для того, чтобы подлить масла в огонь, но если вы выполните поиск в Google по запросу «git and binary files slow», будет найдено множество ссылок, которые сообщают о проблемах пользователей с управлением двоичными файлами в git. Кроме того, разработчики, использующие тот или иной SCM, знают сильные и слабые стороны каждой системы ... так что git заработал репутацию очень медленного, когда двоичные файлы помещаются в репозиторий.
AhiyaHiya
во всех вводных ресурсах, которые я использовал, git плохо работает с двоичными файлами. git-application существует, чтобы исправить это. git хорош, но не для двоичных данных. Было бы хорошо сделать ссылку на форки, добавляющие бинарные функции, чтобы люди могли поддержать работу.
fuzzyTew
15

Нет ничего особенного в двоичных файлах и способах их обработки в git. Когда вы добавляете файл в репозиторий git, добавляется заголовок, файл сжимается с помощью zlib и переименовывается после хэша SHA1. Это точно так же, независимо от типа файла. В сжатии zlib нет ничего, что делало бы его проблемным для двоичных файлов.

Но в какой-то момент (нажатие, gc) Git начинает рассматривать возможность дельта-сжатия содержимого. Если git находит похожие файлы (имя файла и т. Д.), Он помещает их в ОЗУ и начинает сжимать их вместе. Если у вас есть 100 файлов и каждый из них, скажем, 50 МБ, он попытается разместить в памяти 5 ГБ одновременно. К этому вам нужно добавить еще немного, чтобы все заработало. На вашем компьютере может не быть этого объема ОЗУ, и он начинает подкачку. Процесс требует времени.

Вы можете ограничить глубину дельта-сжатия, чтобы процесс не использовал столько памяти, но в результате получилось менее эффективное сжатие. (core.bigFileThreshold, атрибут delta, pack.window, pack.depth, pack.windowMemory и т. д.)

Итак, есть много способов заставить git работать с большими файлами.

Мартин
источник
4
См. Здесь объяснение того, как отключить эти «дельта-попытки».
Александр Берд
6

Один из способов ускорить процесс - использовать --depth 1флаг. См. Подробности на странице руководства. Я не великий git-гуру, но я считаю, что это говорит делать эквивалент a p4 getили an svn get, то есть давать вам только самые последние файлы вместо того, чтобы «дать мне все версии всех файлов за все время», что является что git cloneделает.

Дэвид
источник
1
Это не позволяет вам отправлять сообщения из репозитория, поэтому его полезность ограничена.
Мартин К. Мартин
4

вы сказали git, что эти файлы бинарные?

например, добавлен *.ext binaryв ваш репозиторий.gitattributes

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

Я использую Git с 2008 года как на Windows, так и на GNU / linux, и большинство файлов, которые я отслеживаю, являются двоичными. Некоторые из моих репозиториев занимают несколько ГБ и содержат Jpeg и другие носители. У меня дома и на работе много компьютеров с Git.

У меня никогда не было симптомов, описанных в оригинальном посте. Но всего пару недель назад я установил MsysGit на старый ноутбук с Win-XP, и почти все, что я сделал, это остановило git. Даже тест с двумя или тремя небольшими текстовыми файлами был до смешного медленным. Мы говорим о 10 минутах, чтобы добавить файл размером менее 1 КБ ... похоже, что процессы git остались живы навсегда. Все остальное на этом компьютере работало как положено.
Я понизился с последней версии до 1.6 что-то и проблемы исчезли ...
меня есть другие ноутбуки той же марки, также с Win-XP, установленными тем же ИТ-отделом, образуют один и тот же образ, где Git отлично работает независимо от версии. .. Значит, с этим компьютером должно быть что-то странное.

Я также провел несколько тестов с двоичными файлами и сжатием. Если у вас есть изображение BMP, и вы вносите в него небольшие изменения и фиксируете их, git gc сжимается очень хорошо. Итак, я пришел к выводу, что сжатие не зависит от того, являются ли файлы двоичными или нет.

Мартин
источник
-2

Просто установите файлы, которые будут игнорироваться. См. Ссылку ниже:

http://help.github.com/git-ignore/

joshlrogers
источник
@Jefromi на самом деле, если вы посмотрите ссылку, которую я опубликовал, вы увидите, что во втором абзаце есть инструкции, которые точно говорят ему, что делать в этом случае.
joshlrogers
14
Правда. Но прямое содержание вашего ответа - «игнорировать файлы», а не «удалить файлы из отслеживания, а затем игнорировать их». Обычно лучше написать здесь, чем ссылаться на другой сайт.
Cascabel
-24

Это потому, что git не масштабируется.

Это серьезное ограничение в git, которое игнорируется защитой git. Поищите в списках рассылки git, и вы найдете сотни пользователей, которые задаются вопросом, почему всего лишь скудные 100 МБ изображений (скажем, для веб-сайта или приложения) ставят git на колени. Проблема заключается в том, что почти весь git полагается на оптимизацию, которую они называют «упаковкой». К сожалению, упаковка неэффективна для всех текстовых файлов, кроме самых маленьких (т.е. исходного кода). Хуже того, он становится все менее и менее эффективным по мере увеличения истории.

Это действительно досадный недостаток в git, который рекламируется как «быстрый» (несмотря на отсутствие доказательств), и разработчики git хорошо об этом знают. Почему не починили? В списке рассылки git вы найдете ответы от разработчиков git, которые не распознают проблему, потому что документы Photoshop (* .psd) являются проприетарным форматом. Да, это действительно так плохо.

Вот результат:

Используйте git для крошечных проектов только с исходным кодом, для которых вам не хочется создавать отдельное репо. Или для небольших проектов только с исходным кодом, где вы хотите воспользоваться моделью децентрализованной разработки git copy-the-all-repo. Или когда вы просто хотите изучить новый инструмент. Все это веские причины использовать git, и всегда интересно изучать новые инструменты.

Не используйте git, если у вас большая база кода, двоичные файлы, огромная история и т. Д. Только один из наших репозиториев - TB. Git не может с этим справиться. VSS, CVS и SVN прекрасно справляются с этим. (Однако SVN раздувается.)

Также дайте git время созреть. Он еще незрелый, но набирает обороты. Я думаю, что со временем практическая природа Линуса превзойдет пуристов OSS, и git, в конечном итоге, можно будет использовать в более широкой области.

Джон
источник
15
Этот ответ действительно чрезмерно отрицательный и подстрекательский. Да, у git есть проблемы с масштабируемостью двоичных файлов . Он довольно масштабируемый и быстрый для кода. Существует множество свидетельств скорости (несмотря на то, что вы утверждаете обратное), даже если не учитывать тот факт, что CVS / SVN требует доступа к сети вместо доступа к диску для многих операций. Есть много крупных проектов с огромной историей, которые вполне успешно используют git.
Cascabel
8
И ... твое мнение о фотошопе? Я не собираюсь тратить свое время на подробный ответ, но если прочитать всю ветку thread.gmane.org/gmane.comp.version-control.git/146957/… (возможно, вас раздражает то, что Джон в это вы?), я вижу много разумных ответов о том, как лучше всего справиться с этим с помощью текущего git, как это может быть решено в будущем и почему это не их главный приоритет.
Cascabel
14
Да, я не думаю, что ты здесь прав. Git работает так же хорошо для ядра Linux , чтобы заслужить пренебрежительно, «не является масштабируемым.»
Andres Jaan Tack
1
Этот комментарий был бы более правдоподобным, если бы в нем были ссылки или данные для его резервного копирования. Кстати, что вы думаете о ртути?
vy32
3
Может быть, он не выражает общепринятого мнения, но я думаю, что отрицательное голосование было более чрезмерным в своей «негативности», чем ответ ОП. Мы должны поощрять инакомыслие, а не наваливаться только потому, что кому-то не нравится стиль года, связанный с контролем версий. GIT действительно не подходит для отслеживания двоичных файлов. Но он отлично работает с исходным кодом, это основное предназначение, поэтому он отлично работает с ядром Linux.
dyasta