Может ли кто-нибудь объяснить разницу между отслеживанием содержимого, используемым в Git, и отслеживанием файлов, используемым в других SCM

#svn #git

#svn #git

Вопрос:

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

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

Кто-нибудь может объяснить, почему это так? Я не заметил ничего особенного в этом отношении по сравнению с SVN. Что я упускаю?

Ответ №1:

Git хранит три части данных отдельно:

  • содержимое хранится в объектах blob
  • история хранится в объектах фиксации
  • структура хранится в древовидных объектах

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

Аналогично, если файл не изменяется от версии к версии, git должен сохранить этот файл только один раз. Несколько объектов истории указывают на одно и то же содержимое.

Некоторые из видимых пользователем преимуществ заключаются в том, что git blame очень хорошо видит перемещение кода по файлам, особенно если вы попросите его выглядеть очень жестко git blame -C . Это также отчасти объясняет, почему git такой компактный и быстрый, структура очень простая, очень дешевая в использовании и не повторяется.

Одним из недостатков является то, что git не хранит копии файлов и переименования, он просто угадывает, и иногда это неправильно.

Эта запись в блоге содержит прилично усвоенное, но все же подробное обсуждение того, что для отслеживания контента покупает git. Если вы хотите узнать больше, вы можете посмотреть выступление Лайнуса в Google Tech по Git или прочитать стенограмму.

Ответ №2:

Единственная информация, которую Git хранит от одной ревизии к следующей, — это состояние (имена и содержимое) файлов в каждой ревизии. В редакции A этот файл содержал это содержимое, а в редакции B этот файл содержал другое содержимое. Git не волнует, как файлы попали из пункта А в пункт Б, было ли это редактирование, или переименование, или разрешение конфликта, или слияние octopus.

Преимущество этого подхода заключается в концептуально простом формате репозитория. Это важно, потому что ваш репозиторий — это ваша история, а история должна сохраняться в максимально простом формате.

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

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