Файл: Система управления версиями git и российский сервис хранения исходного кода gitflic.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 06.12.2023

Просмотров: 206

Скачиваний: 7

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

20
− svn switch – сделать ветку рабочей директорией;
− svn merge – объединить ветвь из репозитория с текущей ветвью на ра- бочем компьютере (объединение произойдёт только на рабочем компьютере, для сохранения изменений в файле истории нужно будет сделать коммит);
− svn log – показать историю коммитов.
1.5. Системы управления версиями третьего поколения
Системы управления версиями второго поколения обеспечили воз- можность коллективной удалённой работы. Географически распределённые команды разработчиков смогли выполнять совместные проекты. Однако, некоторые недостатки, связанные с удалённой работой, всё же остались. Эти недостатки связаны с необходимостью использовать центральный репози- торий, через который происходит обмен коммитами. Если по какой-то при- чине центральный репозиторий недоступен, то коллективная работа над проектом становится невозможной.
Проблемы, связанные с недоступностью центрального хранилища, ре- шаются путём его исключения из архитектуры сети. Архитектура, в которой все компьютеры могут общаться друг с другом напрямую, называется рас- пределённой сетью. Было логично ожидать, что появится система управле- ния версиями, основанная на распределённой сети. И она появилась. В
2005 году Линус Торвальдс создал систему управления версиями Git (Scott
Chacon, 2014). Будучи создателем операционной системы Linux, Торвальдс разрабатывал Git, прежде всего, для координации работы программистов, принимающих участие в разработке ядра Linux. Со временем Git стали ис- пользовать и программисты, не связанные с работой над Linux. Сфера при- менения Git расширилась, и в настоящее время это наиболее популярная си- стема управления версиями.
Как было сказано, Git является распределённой системой, централь- ного репозитория нет, и программисты могут обмениваться версиями раз- рабатываемых программ напрямую. По правде говоря, централизованное хранилище в Git обычно присутствует, но его функция отличается от функ-

21 ции центрального репозитория в системах управления версиями второго по- коления. В Git централизованное хранилище используется, в основном, для хранения окончательных версий продукта в целом или его подсистем. Даже если централизованное хранилище используется для обмена версиями в процессе работы, оно рассматривается как участник рабочей группы.
Ключевой особенностью систем управления версиями третьего поко- ления и Git в частности является то, что на локальном компьютере хранятся не только рабочие файлы, но и файлы истории. В результате коммиты можно выполнять локально, даже без доступа к сети. Работая с Git, програм- мист выполняет коммиты на локальном компьютере до тех пор, пока не бу- дет готов поделиться результатами своей работы со всеми членами группы разработчиков или с некоторыми её участниками, работающими над одной и той же подсистемой. Как будет производиться обмен, через центральный репозиторий или непосредственно между компьютерами членов группы, ре- шают сами программисты, участвующие в обмене.
Дельты в Git используются только для пересылки файлов в удалённые репозитории. Для создания коммитов дельты не используются, и это делает
Git очень быстрым, так как в коммитах хранятся полные версии файлов, и нет необходимости тратить время на восстановление версии, применяя одну дельту за другой. Когда файл добавляется для отслеживания в Git, он сжи- мается с использованием алгоритма zlib, и результат хэшируется с помощью хэш-функции SHA-1. Полученный уникальный хэш однозначно соответ- ствует содержимому файла. Все файлы хранятся в папке git/objects. Сово- купность хранимых файлов называется базой объектов. Именами файлов в базе объектов являются полученные хэши. Сами сжатые файлы называются блобами. Блобы создаются каждый раз, когда новый файл добавляется в Git для отслеживания или когда сохраняется изменённая версия существую- щего файла.
При подготовке коммита Git создаёт промежуточный индексный файл
(staging index). По мере добавления изменений в коммит ссылки на блобы, соответствующие этим изменениям, добавляются в индексный файл. Содер- жимое индексного файла представляет собой структуру, описывающую де- рево. Дерево является ещё одним объектом Git наряду с блобами. В узлах дерева хранится информация о реальном имени файла, правах доступа к


22 файлу, имени его автора и ссылки на предыдущие и следующие версии файла. Также узел дерева может хранить ссылку на другое дерево, реализуя инструмент ветвей. Когда все данные с историей изменений подготовлены, да-
ётся команда на создание коммита. Коммит является третьим объектом Git (пер- вые два – блоб и дерево). Коммит хранится в базе коммитов и содержит дату создания, комментарий, имя автора, адрес его электронной почты и ссылку на объект дерево. Каждый коммит, кроме того, содержит ссылку на родительский коммит, в результате чего создаётся история изменений проекта.
В целях экономии места все объекты Git (блобы, деревья и коммиты) сжимаются, дельты не используются. Они называются свободными объек- тами (loose objects). Однако есть исключение. Передача коммитов в удалён- ный репозиторий, хранение очень больших наборов объектов или выполне- ние команды сборки мусора вызывают переупаковку объектов и создание пакетных файлов. Пакетные файлы сжимаются и имеют расширение pack.
Для каждого пакетного файла создаётся индексный файл с расширением idx.
Индексный файл содержит ссылки на упакованные объекты и их располо- жение в пакетном файле.
При выполнении обмена коммитами по сети передаются пакетные файлы. После получения пакетного файла адресатом он распаковывается, и в дальнейшем для работы используются свободные объекты.
Набор команд Git более обширный и разнообразный, чем у систем первого и второго поколений. Ниже приведены некоторые из них:
− git init – текущая папка на локальном компьютере инициализиру- ется как репозиторий Git, в ней создаётся скрытый каталог git;
− git clone – на локальный компьютер загружается репозиторий, нахо- дящийся по адресу, указанному в команде. Существенное отличие от систем управления версиями предыдущих поколений заключается в том, что загру- жаются файлы истории, без преобразования в рабочие файлы;
− git add – создаёт для нового файла блоб и добавляет информацию о нём в дерево готовящегося коммита;
− git commit – создать коммит и поместить его в базу коммитов;
− git status – показать статус файлов в рабочем каталоге (добавленные в коммит, изменённые, не отслеживаемые и т.п.);
− git branch – создаёт новую ветвь;

23
− git checkout – извлечь ветвь в рабочий каталог;
− git merge – объединить ветвь с ранее извлечённой в рабочий каталог;
− git pull – получить из удалённого репозитория обновления, отсут- ствующие в рабочем каталоге;
− git push – объединить файлы коммитов для текущей ветви в пакет- ный файл и передать пакетный файл в удалённый репозиторий;
− git log – показать историю коммитов для активной ветви;
− git stash – сохранить все незафиксированные изменения в кэш, чтобы извлечь их позже.
В 2005 году появилась ещё одна система управления версиями треть- его поколения под названием Mercurial. Она была создана Мэттом Маккол- лом и, как и Git, предназначалась для управления версиями ядра Linux. В конкурентной борьбе между Mercurial и Git победил Git. В настоящее время
Mercurial является второй по распространённости системой управления вер- сиями, хотя и используется гораздо реже по сравнению с Git.
Mercurial, как и Git, является распределённой системой управления вер- сиями. Она позволяет большому количеству программистов работать с ло- кальной версией репозитория, сохраняя изменения по мере необходимости. В
Mercurial тоже используются сжатие и хэширование, но архитектура си- стемы коренным образом отличается от Git. Идеологически Mercurial ближе к CVS и Subversion.
Когда новый файл добавляется для отслеживания, в специальном скрытом каталоге hg/store/data создаётся соответствующий ему файл revlog
(журнал изменений). Этот файл можно рассматривать как модификацию файла истории системы CVS. Если Git создаёт блоб для каждой модифика- ции файла, Mercurial создаёт новую запись в журнале истории. Для эконо- мии места каждая новая запись содержит только дельту. Когда число дельт до- стигает порогового значения, новая версия файла сохраняется целиком. Это позволяет уменьшить время извлечения рабочего файла для ранних версий.
Пока всё очень похоже на то, как устроены более ранние системы управления версиями. Но есть и отличия. Имя каждого revlog совпадает с именем файла, история изменений которого в нём отслеживается. Для боль- шинства файлов создаются два файла revlog с одинаковыми именами, но с


24 разными расширениями. У одного из них расширение i, у другого d. Расши- рение d имеет revlog, содержащий дельты, а расширение i имеет индексный файл, используемый для быстрого отслеживания версий внутри файла с ин- дексом d. Для небольших файлов, содержащих малое количество дельт, дельты хранятся внутри файла с индексом i, файл с индексом d при этом не создаётся. Записи revlog сжимаются и хэшируются. Хэши являются иденти- фикаторами дельт и называются nodeid.
При каждом коммите Mercurial создаёт файл манифеста, который тоже носит название revlog, но это revlog другого типа. Манифест содержит список файлов, включённых в коммит, и список nodeid, указывающих на изменения, фиксирующиеся в данном коммите. Все записи манифеста сжимаются и хэши- руются. Хэши, идентифицирующие записи манифеста, тоже называются nodeid.
Третий тип revlog, который использует Mercurial, называется changelog (журнал изменений). В журнале изменений для каждого коммита содержатся следующие данные:
− nodeid манифеста, который содержит информацию обо всех вер- сиях файлов, доступных на момент включения записи в журнал изменений;
− один или два nodeid родительских коммитов. Если коммит не явля- ется коммитом слияния двух ветвей, то сохраняется один nodeid родителя.
В противном случае у коммита два родителя, и поэтому сохраняются два no- deid. Такая структура позволяет отслеживать изменение проекта во времени;
− имя автора коммита;
− дата коммита;
− комментарий к коммиту.
Каждая запись журнала изменений тоже хэшируется, и хэш называ- ется nodeid журнала изменений.
По смыслу команды Mercurial, приведённые ниже, во многом похожи на команды Git:
− hg init – инициализировать текущую папку как репозиторий Mercu- rial (создать скрытый каталог hg и его структуру);
− hg clone – загрузить копию сетевого репозитория Mercurial на ло- кальный компьютер;
− hg add – добавить новый файл для отслеживания изменений (созда- ются соответствующие revlog с индексами i и d);

25
− hg commit – зафиксировать изменения, создать манифест и запись в журнале истории;
− hg status – показать информацию о состоянии файлов текущего ка- талога (изменённые файлы, не отслеживаемые файлы и т.д.);
− hg update – извлечь указанную ветвь в рабочий каталог;
− hg merge – объединить указанную ветвь с ветвью, находящейся в рабочем каталоге;
− hg pull – скачать новые версии из удалённого репозитория, но не распаковывать их в рабочую директорию;
− hg push – перенести новые версии из локального каталога в удалён- ный репозиторий;
− hg log – показать историю коммитов и соответствующих им ком- ментариев для текущей ветви.
1   2   3   4   5   6   7   8   9   ...   12

1.6. Встроенные системы управления версиями
В предыдущих разделах рассмотрены системы управления версиями, представляющие собой самостоятельный, отдельно стоящий инструмент.
Эти системы используются в процессе профессиональной разработки про- граммного обеспечения. Наряду с профессиональными существуют си- стемы управления версиями, встроенные в программные инструменты, ис- пользуемые для решения офисных и даже повседневных задач. Большинство работающих с этими инструментами людей даже не подозревают, что пользу- ются системами управления версиями. Рассмотрим несколько примеров.
Сервисы синхронизации файлов между устройствами, такие как Drop- box, отслеживают версии файлов, с которыми работают пользователи. Про- цесс выглядит следующим образом. Файловая система компьютера автома- тически сохраняет информацию о времени последнего изменения файла.
Сервис синхронизации периодически сравнивает файлы, находящиеся на сервере, с файлами на локальном компьютере. Если файлы отличаются и файл, находящийся на сервере, старше файла, находящегося на локальном компьютере, то выполняется процесс синхронизации. Файл, находящийся на сервере, становится частью истории изменений, а на его место скачива-

26 ется файл с локального компьютера. Dropbox сохраняет файл в истории каж- дый раз, когда пользователь нажимает кнопку «Сохранить». Файл сохраня- ется целиком и называется снимком. Благодаря такой процедуре Dropbox в состоянии восстановить любую версию файла. Недостаток такого подхода очевиден – значительный расход дискового пространства. Возможно, с точки зрения экономии дискового пространства было бы эффективнее хра- нить дельты, как это делается во многих профессиональных системах управ- ления версиями. Но в этом случае время восстановления версий будет зна- чительным. Экономия дискового пространства или малое время восстанов- ления предыдущих версий? Эта дилемма возникает всегда при разработке систем управления версиями.
Системы управления версиями являются неотъемлемой частью тек- стовых редакторов, особенно онлайновых. Google Docs выполняет проце- дуру автосохранения приблизительно каждые 5 секунд. Если файл изме- нился, то делается снимок, который сохраняется в истории изменений.
История изменений иначе называется историей ревизий. Ревизия бо- лее общее понятие, чем снимок. Ревизия – это любое зафиксированное из- менение в файле, как правило, сохранённое в истории изменений. Ревизия может выполняться с использованием снимка или дельты. Ревизия – это контейнер для снимка или дельты, помимо самого снимка (дельты), она со- держит дополнительную информацию, например, дату сохранения, имя ав- тора и т.п. Процесс переключения между ревизиями имеет своё название в рамках систем управления версиями. Этот процесс называется checkout.
Например, в Git существует команда git checkout.
Современные текстовые редакторы являются инструментом коллек- тивной работы над документами. Любой коммерческий договор проходит несколько стадий согласования и зачастую возвращается к автору или ре- цензенту несколько раз. Разумеется, сотрудник, получивший документ с ис- правлениями (замечаниями), прежде всего, хочет узнать, какие правки в него были внесены. Для того чтобы увидеть изменения, необходимо срав- нить ревизии. Если ревизия была сохранена с использованием дельты, то достаточно извлечь нужную дельту и отобразить её. Если ревизия хранится в виде снимков, то необходимо вычислить дельту перед отображением.
Например, Microsoft Word хранит историю ревизий и позволяет сравнивать версии документа, отображая в наглядной форме, что и где изменилось. Для


27
Microsoft Word существуют два вида ревизий. Одна из них называется ре- жимом записи исправлений и сохраняет только удаления или изменения текста. В режиме записи исправлений возможно сравнивать оригинал и из- менённый документ, располагая их в двух соседних окнах. Такая история ревизий хранится непосредственно в документе в виде дельт. Другой вид истории ревизий сохраняет снимки и позволяет восстановить любую из предыдущих версий. Для того чтобы воспользоваться этим режимом, необ- ходимо подключиться к One Drive. При сохранении снимков Microsoft Word обеспечивает сравнение версий, вычисляя дельты.
Какой бы из систем управления версиями вы ни воспользовались, ра- бочий процесс будет выглядеть одинаково:
− создание репозитория;
− добавление новых файлов;
− коммит;
− внесение изменений в файлы (редактирование, добавление, удаление);
− коммит;
− и так далее до завершения работы над проектом (документом).
Термины «коммит» и «ревизия» являются синонимами. В данной ра- боте в дальнейшем будет использоваться термин «коммит».
С практической точки зрения к коммиту предъявляются два следую- щих требования.
1. Коммит должен иметь комментарий. В большинстве систем управ- ления версиями коммит невозможно сохранить, если комментарий отсут- ствует. Комментарий состоит из краткого заголовка, описывающего суть из- менений, зафиксированных в коммите. За заголовком, если требуется, сле- дуют подробные объяснения. Это правило обеспечивает самодокументиро- ванность истории версий и способствует эффективной работе с ней.
2. Коммит должен фиксировать решение одной задачи, как можно бо- лее полное. Это правило называется атомарностью коммита. Как и первое правило, оно способствует эффективной работе с историей версий, кроме того, помогает понять, какие коммиты необходимо отменить, чтобы вер- нуться к предыдущей версии, если это необходимо.
Контрольные вопросы
1. Какие задачи решает система управления версиями?

28 2. Дайте сравнительную характеристику систем управления верси- ями 1-го, 2-го и 3-го поколений.
3. Опишите принципы формирования файла истории. Что такое дельта (прямая и обратная)?
4. Раскройте понятие термина «ветка» по отношению к системе управления версиями.
5. Что такое «централизованный репозиторий»? Какова его роль в развитии систем управления версиями?
6. Что такое «коммит»? Какие проблемы, возникающие при исполь- зовании коммитов, решает «журналирование»?
7. Что такое «распределённый репозиторий»? Опишите его преиму- щества по отношению к «централизованному репозиторию».
8. Раскройте смысл термина «встроенная система управления верси- ями». Приведите пример встроенной системы управления версиями.