git дуже повільно під час відстеження великих двійкових файлів


83

Моєму проекту шість місяців, а git дуже повільний. Ми відстежуємо близько 30 файлів розміром від 5 МБ до 50 МБ. Це двійкові файли, і ми зберігаємо їх у git. Я вважаю, що ці файли роблять git повільним.

Чи є спосіб убити всі файли розміром> 5 Мб із сховища. Я знаю, що втрачу всі ці файли, і це нормально зі мною.

В ідеалі я хотів би отримати команду, яка б перераховувала всі великі файли (> 5 МБ). Я бачу список, а потім кажу, що добре, видаліть ці файли та зробіть git швидшим.

Слід зазначити, що git працює повільно не тільки на моїй машині, але розгортання програми в проміжному середовищі зараз займає близько 3 годин.

Отже, виправлення повинно мати вплив на сервер, а не лише на користувачів сховища.


4
Ви можете спробувати використовувати git з git-bigfilesпроекту
Якуб Нарембський

1
ви можете спробувати використовувати щось на зразок git-annex для управління двійковими файлами. git-annex.branchable.com
Джед Шнайдер

Якщо він комусь корисний, дозвольте мені додати, що моя версія Cygwin git висіла на базах даних. Коли я використовував Git-Bash, у того самого сховища не було проблем.
Шрідхар Сарнобат

Цікаво, чи все ще так. Я сподіваюся, що вони вимикають стиснення для всього, де ефект стиснення нижче 50% (або будь-який інший вибір X%). У якийсь момент швидкість явно перевершує апаратний простір!
Триларіон

Відповіді:


125

Ви збираєте сміття?

git gc

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


8
Це робиться автоматично, коли стає занадто багато безладу. Сумніваюся, це дійсно допоможе ОП.
Cascabel

@Jefromi, це нове? Я щойно перейшов до 1.7.1 вчора, але до цієї версії, яку я використовував, точно не запускався автоматично gc.
kubi

@kubi: Ну, це не існувало назавжди, але це не зовсім нове - його викликали з комітів, злиття, перезапису та перебазування з часів caf9de2 (14 вересня 2007 р.) або в стабільній версії v1.5.4 (1 лютого 2008 р.) ).
Cascabel

1
Задумавшись, git gcне можна закликати commitі merge, інакше git fsck --unreachableніколи б нічого не повернув.
kubi

4
Знайшов це. Кількість вільних об'єктів за замовчуванням до автоматичного gcзапуску - 6700, що пояснює, чому я ніколи не бачив, як він запускався.
kubi

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
Примітка: це версія пошуку Unix / Linux, а не Windows find.exe.
Крейг Трейдер,

1
+1. Можливо, потрібно спочатку надіслати вихідні дані у findфайл, перевірити список, а потім використовувати git rm, на випадок, якщо є якісь помилкові звернення. Також можна перевірити git statusпісля видалення великих файлів і використовувати git checkout HEAD <file>для повернення помилково видалених файлів.
Cascabel

2
Я думаю, що ваш коментар про те, що git "зберігає окремі копії за замовчуванням", є зворотним. Відповідно до ланцюжка електронної пошти, до якого ви пов’язали ( thread.gmane.org/gmane.comp.version-control.git/146957/… ) за замовчуванням, git намагається розрізнити двійкові файли - і саме в цьому причина ; не сховище.
Alexander Bird

16

Ось цензурована редакція, яка має бути менш негативною та запальною:

Git має добре відому слабкість, коли мова йде про файли, які не є рядковими текстовими файлами. В даний час рішення не існує, і жодні плани, оголошені основною командою git щодо вирішення цього питання. Існують обхідні шляхи, якщо ваш проект невеликий, скажімо, 100 МБ або близько того. Існують гілки проекту git для вирішення цієї проблеми масштабованості, але на даний момент ці гілки не є зрілими. Деякі інші системи контролю перегляду не мають цієї конкретної проблеми. Ви повинні розглядати це питання як лише один із багатьох факторів, коли приймаєте рішення, чи вибрати git як свою систему контролю версій.


8
"Git має добре відому слабкість ..." - потрібне цитування
Nav

6
Я це знаю. кому потрібні лапки, коли це фактично загальновідомо. просто не використовуйте git для двійкового файлу. використовувати ефективне або спеціалізоване управління активами.
v.oddou

1
@ v.oddou Ну, є різниця між "я це знаю" і "його фактичним загальним знанням". Справа в тому, що це знають не всі, і, мабуть, це навіть не зовсім так. Тож будь-яке цитування покращує цю відповідь. Це нормально, але, безсумнівно, не видатне та резервне.
Триларіон

2
Ну, не для того, щоб підливати масла у вогонь, але якщо ви шукаєте в Google "git і двійкові файли повільні", знайдеться багато посилань, які повідомляють, що користувачі мають проблеми з управлінням бінарними файлами в git. Крім того, розробники, які використовують ту чи іншу SCM, знають сильні та слабкі сторони кожної системи ... отже, git створив репутацію того, що стає дуже повільним, коли двійкові файли перекидаються в репо.
AhiyaHiya

саме у всіх вступних ресурсах, якими я користувався, git поганий з бінарними файлами. Для виправлення цього існує git-annex. 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
Дивіться тут пояснення щодо того, як відключити ці "дельта" спроби.
Alexander Bird

6

Одним із способів пришвидшити ситуацію є використання --depth 1прапора. Докладнішу інформацію див. На сторінці користувача. Я не великий git-гуру, але я вважаю, що це говорить робити еквівалент a p4 getабо an svn get, тобто це дає вам лише найновіші файли, замість "дати мені всі ревізії всіх файлів за весь час", що є що git cloneробить.


1
Це не дозволяє вам натискати зі сховища, тому корисність обмежена.
Martin C. Martin

4

ви сказали git, що ці файли двійкові?

наприклад, доданий *.ext binaryдо вашого сховища.gitattributes


Я припускаю, що сказання 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/


@Jefromi насправді, якщо ви подивитеся на посилання, яке я розмістив, ви побачите, що у другому абзаці є інструкції, що точно говорять, що робити в такому випадку.
joshlrogers

14
Правда. Але прямий зміст вашої відповіді - "ігнорувати файли", а не "вилучати файли з відстеження, а потім ігнорувати їх". Як правило, краще писати його тут, ніж посилатись на інший сайт.
Cascabel

-24

Це тому, що git не є масштабованим.

Це серйозне обмеження в git, яке заглушується пропагандою git. Шукайте в списках розсилки git, і ви знайдете сотні користувачів, які задаються питанням, чому лише мізерні 100 МБ зображень (скажімо, для веб-сайту чи програми) ставлять git на коліна. Проблема полягає в тому, що майже весь git покладається на оптимізацію, яку вони називають "упаковкою". На жаль, упаковка неефективна для всіх текстових файлів, окрім найменших (тобто вихідний код). Гірше того, він зростає все менше та менш ефективним із збільшенням історії.

Це справді незручний недолік git, який рекламується як "швидкий" (незважаючи на відсутність доказів), і розробники git це добре знають. Чому вони не виправили? Ви знайдете відповіді у списку розсилки git від розробників git, які не розпізнають проблему, оскільки документи Photoshop (* .psd) є власним форматом. Так, це справді так погано.

Ось результат:

Використовуйте git для крихітних проектів лише з вихідним кодом, для яких вам не хочеться створювати окреме репо. Або для невеликих проектів лише з вихідним кодом, де ви хочете скористатися перевагами децентралізованої розробки git's copy-the-whole-repo. Або коли ви просто хочете вивчити новий інструмент. Все це вагомі причини використовувати git, і завжди цікаво вивчати нові інструменти.

Не використовуйте git, якщо у вас велика база кодів, двійкові файли, величезна історія тощо. Просто одне з наших репозиторіїв - це ТБ. Git не впорається. VSS, CVS та SVN чудово справляються з цим. (Однак SVN роздувається.)

Крім того, дайте часу git дозріти. Це ще незріле, але воно має великий імпульс. З часом, я думаю, що практичний характер Лінуса подолає пуристів OSS, і git з часом стане придатним для використання в більшій галузі.


15
Ця відповідь насправді надмірно негативна та запальна. Так, git має проблеми з масштабованістю двійкових файлів . Це досить масштабовано і швидко для коду. Існує безліч доказів швидкості (незважаючи на ваше твердження про протилежне), навіть не враховуючи той факт, що CVS / SVN вимагає доступу до мережі замість доступу до диска для багатьох операцій. Є багато великих проектів з величезною історією, які цілком щасливо використовують git.
Cascabel

8
І ... ваша натякання на справу з Photoshop? Я не збираюся витрачати свій час на написання детальної відповіді, але якщо прочитати весь потік thread.gmane.org/gmane.comp.version-control.git/146957/… (можливо, вас це дратує, бо Джон у нитка - це ти?), я бачу багато розумних відповідей про те, як найкраще впоратись із цим за допомогою поточного git, як це може бути вирішено в майбутньому і чому це не є їх першочерговим завданням.
Cascabel

14
Так, я не думаю, що ти маєш рацію, тут. Git працює так само добре для ядра Linux , щоб заслужити зневажливо, «не є масштабованим.»
Andres Jaan Tack,

1
Цей коментар був би більш правдоподібним, якби він мав посилання або дані для його резервного копіювання. До речі, що ви думаєте про ртутний?
vy32

3
Можливо, він не висловлює загальноприйнятої думки, але я думаю, що його голосування проти було більш надмірним у своєму "негативі", ніж відповідь ОП. Ми повинні заохочувати інакомислення, а не нагромаджувати лише тому, що комусь не подобається аромат контролю версій року. GIT насправді погано підходить для відстеження двійкових файлів. Але він чудово працює для вихідного коду, це основний намір, саме тому він чудово працює в ядрі Linux.
діаста
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.