#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 может «отслеживать отдельные фрагменты кода, перемещающиеся из одного файла в другой». Это полностью связано с умностью программ, создающих отчеты об истории, а не с чем-либо, хранящимся в самом репозитории.