Как Git экономит место и работает быстро? - PullRequest
34 голосов
/ 20 мая 2010

Я только что увидел первый Git учебник на http://blip.tv/play/Aeu2CAI.

Как Git хранит все версии всех файлов и как он все же может быть более экономичным в пространстве, чем Subversion , который сохраняет только самую последнюю версию кода?

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

Итак, я думаю, что

  • Git активно сжимает данные
  • Это все еще быстрее, потому что uncompression + work все еще быстрее, чем network_fetch + work

Я прав? Даже близко?

Ответы [ 2 ]

56 голосов
/ 20 мая 2010

Я предполагаю, что вы спрашиваете, как возможно, чтобы git-клон (полный репозиторий + извлечение) был меньше извлеченных источников в Subversion. Или ты имел ввиду что-то еще?

Ответ на этот вопрос в комментариях


Размер репозитория

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

Во-вторых, git использует следующие методы, чтобы уменьшить размер хранилища:

  • каждая версия файла сохраняется только один раз; это означает, что если у вас есть только две разные версии какого-либо файла в 10 ревизиях (10 коммитов), git хранит только эти две версии, а не 10.
  • объекты (и дельты, см. Ниже) хранятся в сжатом виде; текстовые файлы, используемые в программировании, сжимаются очень хорошо (около 60% от исходного размера или 40% -ное уменьшение размера от сжатия)
  • после перепаковки объекты сохраняются в разграниченном виде, в отличие от какой-либо другой версии; кроме того, git пытается упорядочить дельта-цепочки таким образом, чтобы дельта состояла в основном из удалений (в обычном случае растущих файлов она находится в порядке недавности); Дельты IIRC также сжаты.

Производительность (скорость операций)

Во-первых, любая операция, связанная с сетью, будет намного медленнее, чем локальная операция. Поэтому, например, сравнение текущего состояния рабочей области с какой-либо другой версией или получение журнала (истории), который в Subversion включает сетевое соединение и передачу по сети, а в Git - локальная операция, конечно, будет намного медленнее в Subversion, чем в Git. КСТАТИ. в этом разница между централизованными системами контроля версий (с использованием клиент-серверного процесса) и распределенными системами контроля версий (с использованием однорангового рабочего процесса), не только между Subversion и Git.

Во-вторых, если я правильно понимаю, в настоящее время ограничением является не CPU, а IO (доступ к диску). Поэтому возможно, что выигрыш от необходимости читать меньше данных с диска из-за сжатия (и возможность отобразить его в памяти) преодолеет потери от необходимости распаковывать данные.

В-третьих, Git был разработан с учетом производительности (см., Например, GitHistory страница в Git Wiki):

  • Индекс хранит статистическую информацию для файлов, и Git использует ее, чтобы без проверки файлов решить, были ли файлы изменены или нет (см., Например, core.trustctime переменная конфигурации).
  • Максимальная дельта-глубина ограничена pack.depth, по умолчанию 50. Git имеет дельта-кеш для ускорения доступа. Существует (сгенерированный) индекс файла пакета для быстрого доступа к объектам в файле пакета.
  • Git старается не трогать файлы, которые ему не нужны. Например, при переключении веток или перемотке на другую версию Git обновляет только файлы, которые изменились. Следствием этой философии является то, что Git поддерживает только минимальное расширение ключевых слов (по крайней мере, из коробки).
  • Git использует собственную собственную версию библиотеки LibXDiff , в настоящее время также для сравнения и слияния, вместо вызова внешнего инструмента сравнения / внешнего слияния.
  • Git пытается минимизировать задержку , что означает хорошую воспринимаемую производительность. Например, он выводит первую страницу «git log» как можно быстрее, и вы видите это почти сразу, даже если генерация полной истории займет больше времени; он не ждет генерации полной истории перед ее отображением.
  • При получении новых изменений Git проверяет, какие объекты у вас общие с сервером, и отправляет только (сжатые) различия в виде тонкого файла пакета. По общему признанию Subversion может (или, возможно, по умолчанию это делает) также отправлять только различия при обновлении.

Я не хакер Git, и я, вероятно, пропустил некоторые приемы и приемы, которые Git использует для повышения производительности. Однако обратите внимание, что Git интенсивно использует POSIX (например, файлы с отображением памяти), поэтому усиление может быть не таким большим в MS Windows.

11 голосов
/ 20 мая 2010

Не полный ответ, но эти комментарии (из AlBlue ) могут помочь в аспекте управления пространством вопроса:

Здесь стоит кое-что прояснить.

Во-первых, возможно иметь Git-репозиторий большего размера, чем SVN-репозиторий ; Надеюсь, я не подразумевал, что это никогда не имело место. Однако на практике обычно бывает так, что репозиторий Git занимает меньше места на диске, чем эквивалентный репозиторий SVN.
Одна вещь, на которую вы ссылаетесь, - это единственный SVN-репозиторий Apache, который, очевидно, является массивным Однако достаточно взглянуть на git.apache.org, и вы заметите, что у каждого проекта Apache есть свой собственный Git-репозиторий. Что действительно нужно, так это сравнение «нравится за»; другими словами, извлечение проекта (abdera) SVN против клона (abdera) Git-репозитория .

Я смог проверить git://git.apache.org/abdera.git. На диске он занимал 28,8 МБ.
Затем я проверил версию SVN http://svn.apache.org/repos/asf/abdera/java/trunk/, и она потребляет 34,3 МБ.
Оба числа были взяты из отдельно смонтированного раздела в пространстве ОЗУ, а указанное число было количеством байтов, взятых с диска.
Если в качестве средства тестирования используется du -sh, проверка Git составила 11 МБ, а проверка SVN - 17 МБ.

Git-версия Apache Abdera позволит мне работать с любой версией истории вплоть до текущего выпуска; SVN будет иметь только резервную копию текущей версии. Тем не менее, он занимает меньше места на диске.

Как, спросите вы?

Ну, с одной стороны, SVN создает намного больше файлов . В кассе SVN есть 2959 файлов; соответствующий репозиторий Git содержит 845 файлов.

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

В-третьих, Git хранит свои данные в виде сжатых объектов, тогда как SVN сохраняет их в виде несжатых копий . Перейдите в любой каталог .svn/text-base, и вы найдете несжатые копии (базовых) файлов.
Git имеет механизм для сжатия всех файлов (и даже всей истории) в файлы пакета. В случае Абдеры, .git/objects/pack/ имеет один файл .pack (содержащий всю историю) в файле 4.8Mb.
Таким образом, размер репозитория (приблизительно) равен размеру текущего извлеченного кода в этом случае, хотя я не ожидаю, что это всегда будет так.

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

Обратите внимание, что Git (и Hg, и другие DVCS) страдают от проблемы, когда (большие) двоичные файлы регистрируются, а затем удаляются, так как они все равно будут отображаться в хранилище и занимать место, даже если они ' не актуально. Сжатие текста позаботится о таких вещах для текстовых файлов, но двоичные являются большей проблемой. (Существуют административные команды, которые могут обновлять содержимое репозиториев Git, но они имеют несколько более высокие накладные / административные затраты, чем CVS; git filter-branch похожа на svnadmin dump/filter/load.)


Что касается аспекта скорости, я упомянул об этом в своем ответе " Как быстро работает git по сравнению с Subversion с помощью удаленных операций? " (как Линус сказал в своей презентации Google : (перефразируя здесь) "все, что связано с сетью, просто убивает выступления")

И документ GitBenchmark , упомянутый Jakub Narębski , является хорошим дополнением, хотя он не имеет прямого отношения к Subversion.
В нем перечислены виды операций, которые необходимо отслеживать в DVCS с точки зрения производительности.

В этом SO вопросе .

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