Как различные системы управления версиями обрабатывают двоичные файлы?
Я слышал некоторые утверждения о том, что SVN обрабатывает двоичные файлы лучше, чем Git/Mercurial. Это правда, и если да, то почему? Насколько я могу себе представить, никакая система контроля версий (VCS) не может различать и объединять изменения между двумя версиями одних и тех же двоичных ресурсов.
Итак, не все ли VCS плохо при обработке двоичных файлов? Я не очень разбираюсь в технических деталях, стоящих за конкретными реализациями VCS, поэтому, возможно, у них есть некоторые плюсы и минусы.
Ответы
Ответ 1
Основная точка боли в "распределенном" аспекте любого DVCS: вы клонируете все (всю историю всех файлов)
Поскольку двоичные файлы не хранятся в delta для большинства из них и не сжимаются, а также текстовый файл, если вы храните быстро развивающиеся двоичные файлы, вы быстро получаете большой репозиторий, который становится намного громоздким для перемещения (тяни-Толкай).
Например, для Git см. Каковы ограничения Git?.
Бинарники не подходят для функции, которую VCS может принести (diff, branch, merge) и лучше управляться в репозитории артефактов (например, Nexus, например).
Это не обязательно для CVCS (централизованного VCS), где репозиторий может играть эту роль и быть хранилищем для двоичных файлов (даже если это не его основная роль)
Ответ 2
Одно пояснение о git и двоичных файлах.
Git сжимает двоичные файлы, а также текстовые файлы. Таким образом, git не дерьмо при обработке двоичных файлов, как кто-то предложил.
Любой файл, добавляемый git, будет сжат в свободные объекты. Неважно, являются ли они двоичными или текстовыми. Если у вас есть двоичный или текстовый файл, и вы его фиксируете, репозиторий будет расти. Если вы внесете небольшое изменение в файл и снова зафиксируете, ваш репозиторий будет расти снова примерно на том же уровне, в зависимости от степени сжатия.
Затем вы создаете git gc
. git найдет сходство в двоичных или текстовых файлах и сжимает их вместе. У вас будет хорошее сжатие, если сходство велико.
Если, с другой стороны, нет никакого сходства между файлами, вы не будете иметь большого выигрыша, сжимающего их вместе по сравнению с их сжатием по отдельности.
Вот тест с битовым отображением (двоичным), который я немного изменил:
[email protected]:~/testing123$ git init
Initialized empty Git repository in /home/martin/testing123/.git/
[email protected]:~/testing123$ ls -l
total 1252
-rw------- 1 martin martin 1279322 Jan 8 22:42 pic.bmp
[email protected]:~/testing123$ git add .
[email protected]:~/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:
[email protected]:~/testing123$ du -s .git
1244 .git
// Changed a few pixels in the picture
[email protected]:~/testing123$ git add .
[email protected]:~/testing123$ git commit -a -m second
[master da025e1] second
1 files changed, 0 insertions(+), 0 deletions(-)
// here is the size:
[email protected]:~/testing123$ du -s .git
2364 .git
// As you can see the repo is twice as large
// Now we run git gc to compress
[email protected]:~/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:
[email protected]:~/testing123$ du -s .git
1236 .git
// we are back to a smaller size than ever...
Ответ 3
Git и Mercurial обрабатывают двоичные файлы с апломбом. Они не повреждают их, и вы можете проверить их. Проблема заключается в размере.
Источник обычно занимает меньше места, чем двоичные файлы. У вас может быть 100K исходных файлов, которые строят двоичный файл 100Mb. Таким образом, сохранение одной сборки в моем репозитории может привести к ее росту в 30 раз больше.
И это еще хуже:
Системы управления версиями обычно хранят файлы через формат формы. Скажем, у меня есть файл из 100 строк, и каждая строка содержит около 40 символов. Весь файл размером 4K. Если я изменяю строку в этом файле и сохраняю это изменение, я добавляю только около 60 байт к размеру моего репозитория.
Теперь, скажем, я скомпилировал и добавил, что 100Mb файл. Я вношу изменения в свой исходный код (возможно, 10K или около того), перекомпилировать и сохранить новую двоичную сборку. Ну, двоичные файлы обычно не отличаются очень хорошо, поэтому, скорее всего, я добавлю еще 100 Мб размера в мой репозиторий. Сделайте несколько сборок, а размер моего репозитория увеличивается до нескольких гигабайт, но исходная часть моего репозитория составляет всего несколько десятков килобайт.
Проблема с Git и Mercurial заключается в том, что вы обычно проверяете весь репозиторий на свою систему. Вместо того, чтобы просто загружать несколько десятков килобайт, которые можно перенести за несколько секунд, теперь я загружаю несколько гигабайт сборок вместе с несколькими десятками килобайт данных.
Возможно, люди говорят, что Subversion лучше, так как я могу просто проверить версию, которую я хочу в Subversion, и не загружать весь репозиторий. Однако Subversion не дает вам простой способ удалить устаревшие двоичные файлы из вашего репозитория, поэтому ваш репозиторий будет расти и расти в любом случае. Я все еще не рекомендую. Черт, я даже не рекомендую его, даже если система контроля версий позволяет удалить старые версии устаревших двоичных файлов. (Perforce, ClearCase и CVS все делают). Это просто заканчивается большой головной болью обслуживания.
Теперь это не означает, что вы не должны хранить двоичные файлы. Например, если я создаю веб-страницу, у меня, вероятно, есть некоторые gif и jpeg, которые мне нужны. Нет проблем с хранением данных в Subversion или Git/Mercurial. Они относительно малы и, вероятно, меняются намного меньше, чем сам мой код.
То, что вы не должны хранить, - это построенные объекты. Они должны храниться в репозитории выпуска и извлекаться по мере необходимости. Maven и Ant w/Ivy отлично справляются с этим. Кроме того, вы можете использовать структуру репозитория Maven в проектах C, С++ и С#.
Ответ 4
В Subversion вы можете lock бинарные файлы, чтобы никто не мог их редактировать. Это в основном гарантирует, что никто другой не изменит этот двоичный файл, пока вы его заблокировали. Распределенные VCS не имеют (и не могут) блокировок - нет центрального хранилища для их регистрации.
Ответ 5
Текстовые файлы имеют естественную линейную привязку, которой не хватает двоичных файлов. Вот почему их сложнее сравнивать с помощью обычных текстовых инструментов (diff). В то время как это должно быть возможно, преимущество чтения (причина, по которой мы используем текст в качестве нашего предпочтительного формата в первую очередь) будет потеряна при применении diff к двоичным файлам.
Что касается вашего предположения, что все системы управления версиями "дерьмо при обработке двоичных файлов", я не знаю. В принципе, нет причин, по которым двоичный файл должен обрабатываться медленнее. Я бы сказал, что преимущества использования VCS (отслеживание, различие, обзор) более очевидны при обработке текстовых файлов.