Как разные системы контроля версий обрабатывают двоичные файлы? - PullRequest
31 голосов
/ 06 июля 2011

Я слышал некоторые утверждения, что SVN обрабатывает двоичные файлы лучше, чем Git / Mercurial. Это правда и если да, то почему? Насколько я могу себе представить, ни одна система контроля версий (VCS) не может различать и объединять изменения между двумя ревизиями одних и тех же двоичных ресурсов.

Итак, разве все VCS плохо справляются с бинарными файлами? Я не очень осведомлен о технических деталях конкретных реализаций VCS, поэтому, возможно, у них есть свои плюсы и минусы.

Ответы [ 5 ]

21 голосов
/ 06 июля 2011

Основная проблема заключается в «распределенном» аспекте любой DVCS: вы клонируете все (всю историю всех файлов)

Поскольку двоичные файлы не хранятся в дельтедля большинства из них, и они не сжимаются так же, как текстовые файлы, если вы храните быстро развивающиеся двоичные файлы, вы быстро получаете репозиторий large , который становится очень громоздким для перемещения (push / pull),

Например, для Git см. Каковы пределы git? .

Двоичные файлы не подходят для функции, которую может принести VCS (diff, branch,слиянием) и лучше управляются в хранилище артефактов (например, Nexus ).
Это не обязательно в случае CVCS (централизованного VCS), где хранилище может играть эту роль ихранилище для двоичных файлов (даже если это не его основная роль)

13 голосов
/ 08 января 2012

Одно разъяснение о git и двоичных файлах.

Git сжимает двоичные файлы, а также текстовые файлы.Так что git не дерьмо обрабатывает бинарные файлы, как кто-то предложил.

Любой файл, который добавляет Git, будет сжат в свободные объекты.Неважно, являются ли они двоичными или текстовыми.Если у вас есть бинарный или текстовый файл, и вы фиксируете его, репозиторий будет расти.Если вы внесете небольшое изменение в файл и подтвердите его, ваш репозиторий снова вырастет примерно на ту же величину, в зависимости от степени сжатия.

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

Вот тест с растровым изображением (двоичный)что я немного изменил:

martin@martin-laptop:~/testing123$ git init  
Initialized empty Git repository in /home/martin/testing123/.git/  
martin@martin-laptop:~/testing123$ ls -l   
total 1252  
-rw------- 1 martin martin 1279322 Jan  8 22:42 pic.bmp  
martin@martin-laptop:~/testing123$ git add .  
martin@martin-laptop:~/testing123$ git commit -a -m first  
[master (root-commit) 53886cf] first  
 1 files changed, 0 insertions(+), 0 deletions(-)  
 create mode 100644 pic.bmp  

// here is the size:  
martin@martin-laptop:~/testing123$ du -s .git  
1244    .git  

// Changed a few pixels in the picture  

martin@martin-laptop:~/testing123$ git add .  
martin@martin-laptop:~/testing123$ git commit -a -m second  
[master da025e1] second  
 1 files changed, 0 insertions(+), 0 deletions(-)  

// here is the size:  
martin@martin-laptop:~/testing123$ du -s .git  
2364    .git  

// As you can see the repo is twice as large  
// Now we run git gc to compress  

martin@martin-laptop:~/testing123$ git gc  
Counting objects: 6, done.  
Delta compression using up to 2 threads.  
Compressing objects: 100% (4/4), done.  
Writing objects: 100% (6/6), done.  
Total 6 (delta 1), reused 0 (delta 0)  

// here is the size after compression:  
martin@martin-laptop:~/testing123$ du -s .git  
1236    .git  

// we are back to a smaller size than ever...  
9 голосов
/ 06 июля 2011

Git и Mercurial обрабатывают двоичные файлы с помощью aplomb.Они не портят их, и вы можете проверить их и выйти.Проблема заключается в размере.

Источник обычно занимает меньше места, чем двоичные файлы.У вас может быть 100 КБ исходных файлов, которые создают бинарный файл размером 100 МБ.Таким образом, хранение одной сборки в моем репозитории может привести к увеличению его размера в 30 раз.

И это еще хуже:

Системы контроля версий обычно хранят файлы в какой-либо форме diff-формата.Допустим, у меня есть файл из 100 строк, и каждая строка в среднем содержит около 40 символов.Весь этот файл имеет размер 4 КБ.Если я изменю строку в этом файле и сохраню это изменение, я добавлю только около 60 байт к размеру моего хранилища.

Теперь, скажем, я скомпилировал и добавил этот файл размером 100 МБ.Я делаю изменения в моем источнике (может быть, 10K или около того в изменениях), перекомпилирую и сохраняю новую двоичную сборку.Ну, бинарные файлы обычно не очень хорошо различаются, так что вполне вероятно, что я добавляю еще 100Мб в мой репозиторий.Выполните несколько сборок, и размер моего хранилища увеличится до нескольких гигабайт, но исходная часть моего хранилища составляет всего несколько десятков килобайт.

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

Может быть, люди говорят, что Subversion лучше, так как я могу простоОформите нужную мне версию в Subversion, а не загружайте весь репозиторий.Однако Subversion не дает вам простого способа удалить устаревшие двоичные файлы из вашего репозитория, поэтому ваш репозиторий будет расти и расти в любом случае.Я все еще не рекомендую это.Черт возьми, я даже не рекомендую это делать, даже если система контроля версий позволяет вам удалять старые версии устаревших двоичных файлов.(Perforce, ClearCase и CVS все делают).Это просто приводит к большой головной боли при обслуживании.

Это не значит, что вы не должны хранить любые двоичные файлы.Например, если я делаю веб-страницу, у меня, вероятно, есть несколько GIF-файлов и JPEG, которые мне нужны.Не проблема хранить их в Subversion или Git / Mercurial.Они относительно малы и, вероятно, меняются намного меньше, чем сам мой код.

То, что вы не должны хранить, это встроенные объекты.Они должны храниться в репозитории релизов и извлекаться по мере необходимости.Maven и Ant w / Ivy отлично справляются с этой задачей.И вы также можете использовать структуру репозитория Maven в проектах C, C ++ и C #.

2 голосов
/ 06 июля 2011

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

0 голосов
/ 06 июля 2011

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

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

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