Git

Git (произносится «гит»[7]) — распределённая система управления версиями. Проект был создан Линусом Торвальдсом для управления разработкой ядра Linux, первая версия выпущена 7 апреля 2005 года. На сегодняшний день его поддерживает Джунио Хамано.

Git
Тип распределённая система управления версиями[d]
Разработчик Software Freedom Conservancy[1]
Написана на Си[2], командная оболочка UNIX, Perl, Tcl, Python и C++
Операционная система кроссплатформенность
Языки интерфейса английский
Первый выпуск 7 апреля 2005[3]
Последняя версия
Читаемые форматы файлов pack-файл git[d][5], индекс pack-файла git (версия 1)[d][5] и индекс pack-файла git (версия 2)[d][5]
Создаваемые форматы файлов pack-файл git[d][5], индекс pack-файла git (версия 1)[d][5] и индекс pack-файла git (версия 2)[d][5]
Лицензия GNU GPL 2[6]
Сайт git-scm.com (англ.)
 Медиафайлы на Викискладе

Среди проектов, использующих Git — ядро Linux, Swift, Android, Drupal, Cairo, GNU Core Utilities, Mesa, Wine, Chromium, Compiz Fusion, FlightGear, jQuery, PHP, NASM, MediaWiki, DokuWiki, Qt, ряд дистрибутивов Linux.

Программа является свободной и выпущена под лицензией GNU GPL версии 2. По умолчанию используется TCP порт 9418.

История

Разработка ядра Linux велась на проприетарной системе BitKeeper[8], которую автор — Ларри Маквой, сам разработчик Linux — предоставил проекту по бесплатной лицензии. Разработчики, высококлассные программисты, написали несколько утилит, и для одной Эндрю Триджелл произвёл реверс-инжиниринг формата передачи данных BitKeeper. В ответ Маквой обвинил разработчиков в нарушении соглашения и отозвал лицензию, и Торвальдс взялся за новую систему: ни одна из открытых систем не позволяла тысячам программистов кооперировать свои усилия (тот же конфликт привёл к написанию Mercurial). Идеология была проста: взять подход CVS и перевернуть с ног на голову[9], и заодно добавить надёжности.

Начальная разработка велась меньше, чем неделю: 3 апреля 2005 года разработка началась, и уже 7 апреля код Git управлялся неготовой системой. 16 июня Linux был переведён на Git, а 25 июля Торвальдс отказался от обязанностей ведущего разработчика.

Торвальдс так саркастически отозвался о выбранном им названии git (что на английском сленге означает «мерзавец»):

I'm an egotistical bastard, so I name all my projects after myself. First Linux, now git. Я эгоистичный ублюдок, и поэтому называю все свои проекты в честь себя. Сначала Linux, теперь git.

Возможности

Система спроектирована как набор программ, специально разработанных с учётом их использования в сценариях. Это позволяет удобно создавать специализированные системы контроля версий на базе Git или пользовательские интерфейсы. Например, Cogito является именно таким примером оболочки к репозиториям Git, а StGit использует Git для управления коллекцией исправлений (патчей).

Git поддерживает быстрое разделение и слияние версий, включает инструменты для визуализации и навигации по нелинейной истории разработки. Как и Darcs, BitKeeper, Mercurial, Bazaar и Monotone, Git предоставляет каждому разработчику локальную копию всей истории разработки, изменения копируются из одного репозитория в другой.

Удалённый доступ к репозиториям Git обеспечивается git-демоном, SSH- или HTTP-сервером. TCP-сервис git-daemon входит в дистрибутив Git и является наряду с SSH наиболее распространённым и надёжным методом доступа. Метод доступа по HTTP, несмотря на ряд ограничений, очень популярен в контролируемых сетях, потому что позволяет использовать существующие конфигурации сетевых фильтров.

Особенности реализации

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

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

По умолчанию репозиторий хранится в подкаталоге с названием «.git» в корневом каталоге рабочей копии дерева файлов, хранящегося в репозитории. Любое файловое дерево в системе можно превратить в репозиторий git, отдав команду создания репозитория из корневого каталога этого дерева (или указав корневой каталог в параметрах программы). Репозиторий может быть импортирован с другого узла, доступного по сети. При импорте нового репозитория автоматически создаётся рабочая копия, соответствующая последнему зафиксированному состоянию импортируемого репозитория (то есть не копируются изменения в рабочей копии исходного узла, для которых на том узле не была выполнена команда commit).

Архитектура

Нижний уровень git является так называемой контентно-адресуемой файловой системой. Инструмент командной строки git содержит ряд команд по непосредственной манипуляции этим репозиторием на низком уровне. Эти команды не нужны при нормальной работе с git как с системой контроля версий, но нужны для реализации сложных операций (ремонт повреждённого репозитория и так далее), а также дают возможность создать на базе репозитория git своё приложение.

Для каждого объекта в репозитории вычисляется SHA-1-хеш, и именно он становится именем файла, содержащего данный объект в каталоге .git/objects. Для оптимизации работы с файловыми системами, не использующими деревья для каталогов, первый байт хеша становится именем подкаталога, а остальные — именем файла в нём, что снижает количество файлов в одном каталоге (ограничивающий фактор производительности на таких устаревших файловых системах).

Все ссылки на объекты репозитория, включая ссылки на один объект, находящийся внутри другого объекта, являются SHA-1-хешами.

Кроме того, в репозитории существует каталог refs, который позволяет задать читаемые человеком имена для каких-то объектов Git. В командах Git оба вида ссылок — читаемые человеком из refs, и нижележащие SHA-1 — полностью взаимозаменяемы.

В классическом обычном сценарии в репозитории git есть три типа объектов — файл, дерево и «коммит» (англ. commit — фиксация). Файл есть какая-то версия какого-то пользовательского файла, дерево — совокупность файлов из разных подкаталогов, «коммит» — дерево и некая дополнительная информация (например, родительские коммиты, а также комментарий).

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

Репозиторий Git бывает локальный и удалённый. Локальный репозиторий — это подкаталог .git, создаётся (в пустом виде) командой git init и (в непустом виде с немедленным копированием содержимого родительского удалённого репозитория и простановкой ссылки на родителя) командой git clone.

Практически все обычные операции с системой контроля версий, такие, как коммит и слияние, производятся только с локальным репозиторием. Удалённый репозиторий можно только синхронизировать с локальным как «вверх» (push), так и «вниз» (pull).

Наличие полностью всего репозитория проекта локально у каждого разработчика даёт Git ряд преимуществ перед SVN. Так, например, все операции, кроме push и pull, можно осуществлять без наличия интернет-соединения.

Очень мощной возможностью git являются ветви, реализованные куда более полно, чем в SVN: по сути, ветвь git есть не более чем именованная ссылка, указывающая на некий коммит в репозитории (используется подкаталог refs). Коммит без создания новой ветви всего лишь передвигает эту ссылку на себя, а коммит с созданием ветви — оставляет старую ссылку на месте, но создаёт новую на новый коммит, и объявляет её текущей. Заменить локальные девелоперские файлы на набор файлов из иной ветви, тем самым перейдя к работе с ней — так же тривиально.

Также поддерживаются субрепозитории с синхронизацией текущих ветвей в них.

Команда push передаёт все новые данные (те, которых ещё нет в удалённом репозитории) из локального репозитория в репозиторий удалённый. Для исполнения этой команды необходимо, чтобы удалённый репозиторий не имел новых коммитов в себя от других клиентов, иначе push завершается ошибкой, и придётся делать pull и слияние.

Команда pull — обратна команде push. В случае, если одна и та же ветвь имеет независимую историю в локальной и в удалённой копии, pull немедленно переходит к слиянию.

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

Результатом всего этого является новое состояние в локальных файлах у того разработчика, что осуществил слияние. Ему нужно немедленно сделать коммит, при этом в данном объекте коммита в репозитории окажется информация о том, что коммит есть результат слияния двух ветвей и имеет два родительских коммита.

Кроме слияния, Git поддерживает ещё операцию перемещения (англ. rebase). Эта операция есть получение набора всех изменений в ветви А, с последующим их «накатом» на ветвь B. В результате ветвь B продвигается до состояния AB. В отличие от слияния, в истории ветви AB не останется никаких промежуточных коммитов ветви A (только история ветви B и запись о самом rebase, это упрощает интеграцию крупных и очень крупных проектов).

Также Git имеет временный локальный индекс файлов. Это — промежуточное хранилище между собственно файлами и очередным коммитом (коммит делается только из этого индекса). С помощью этого индекса осуществляется добавление новых файлов (git add добавляет их в индекс, они попадут в следующий коммит), а также коммит не всех изменённых файлов (коммит делается только тем файлам, которым был сделан git add). После git add можно редактировать файл далее, получатся три копии одного и того же файла — последняя, в индексе (та, что была на момент git add), и в последнем коммите.

Имя ветви по умолчанию: master. Имя удалённого репозитория по умолчанию, создаваемое git clone во время типичной операции «взять имеющийся проект с сервера себе на машину»: origin.

Таким образом, в локальном репозитории всегда есть ветвь master, которая есть последний локальный коммит, и ветвь origin/master, которая есть последнее состояние удалённого репозитория на момент завершения исполнения последней команды pull или push.

Команда fetch (частичный pull) — берёт с удалённого сервера все изменения в origin/master, и переписывает их в локальный репозиторий, продвигая метку origin/master.

Если после этого master и origin/master разошлись в стороны, то необходимо сделать слияние, установив master на результат слияния (команда pull есть fetch+merge). Далее возможно сделать push, отправив результат слияния на сервер и установив на него origin/master.

Детали реализации в Windows

В Windows-версии (официальная Windows-версия называется mSysGit) используется пакет mSys — порт POSIX-совместимой командной строки под Windows из проекта MinGW. Под mSys перенесены все необходимые для Git библиотеки и инструменты, а также сам Git. При работе с удалёнными репозиториями по протоколу SSL используется хранилище сертификатов из mSys, а не из Windows.

Существует немало графических оболочек для Git для Windows, например, TortoiseGit. Все они реализованы через вызовы mSysGit и требуют его установки на машину. Не исключение и SourceTree, решение компании Atlassian, но mSysGit оно содержит внутри себя, что имеет свои плюсы и минусы (так установка в глубокий подкаталог затрудняет добавление в mSys нужных SSL-сертификатов).

Поскольку в Windows используется отличный от большинства Unix-подобных систем символ конца строки, для работы коллективов, использующих разные операционные системы, предусматриваются параметры (как для клиентов, так и уровня репозитория), обеспечивающие унифицированное представление конца строки.

Сетевые возможности и серверные решения

Git использует сеть только для операций обмена с удалёнными репозиториями.

Возможно использование следующих протоколов:

  • git-протокол (схема URI — git:) — открытый протокол[12], требующий наличия на сервере запущенного git-демона[13] (поставляется вместе с Git), протокол не имеет средств аутентификации пользователей;
  • SSH (ssh:) — использует аутентификацию пользователей с помощью пар ключей, а также встроенный в Unix-систему «основной» SSH-сервер (sshd), со стороны сервера требуется создание учётных записей с git в качестве оболочки;
  • HTTP и HTTPS (http:, https:) — использует инструмент curl (для Windows — поставляется вместе с git), и его возможности HTTP-аутентификации, как и его поддержку SSL и сертификатов.

В последнем случае требуется работа на серверной стороне веб-приложения, исполняющего роль прослойки между командами Git на сервере и HTTP-сервером (среди таковых WebGitNet, разработанный на ASP.NET MVC 4). Кроме поддержки серверной стороны команд push и pull, такие веб-приложения могут также давать доступ только на чтение к репозиторию через веб-браузер.

Графические интерфейсы

Разработано множество графических интерфейсов для системы, среди них — GitKraken (кроссплатформенный условно бесплатный клиент Git), SmartGit (кроссплатформенный интерфейс на Java), gitk (простая и быстрая программа, написана на Tcl/Tk, распространяемая с самим Git), Giggle (вариант на Gtk+), TortoiseGit (интерфейс, реализованный как расширение для проводника Windows), SourceTree (бесплатный Git-клиент для Windows и Mac), Github-клиент и ряд других.

Кроме того, разработано множество веб-фронтендов, в числе которых - GitWebAdmin, GitLab, Gitblit, Gerrit, Gitweb, Kallithea, Gitea.

Git-хостинг

Ряд сервисов предоставляют хостинг для git-репозиториев, среди наиболее известных — GitHub, Codebase, SourceForge, SourceHut, Gitea, Bitbucket, GitLab.

Взаимодействие с другими системами контроля версий

В стандартной поставке Git поддерживается взаимодействие с CVS (импорт и экспорт, эмуляция CVS-сервера) и Subversion (частичная поддержка импорта и экспорта). Стандартный инструмент импорта и экспорта внутри экосистемы — архивы серий версионированных файлов в форматах .tar.gz и .tar.bz2.

Примечания

  1. https://github.com/git/git/graphs/contributors
  2. The git Open Source Project on Open Hub: Languages Page — 2006.
  3. Re: Trivia: When did git self-host?
  4. Git v2.35.1 Release Notes — 2022.
  5. Git pack format
  6. Copying (англ.)
  7. git
  8. BitKeeper and Linux: The end of the road? (недоступная ссылка). Дата обращения: 7 ноября 2017. Архивировано 8 июня 2017 года.
  9. Выступление Торвальдса
  10. GitFaq: Why the 'Git' name.
  11. After controversy, Torvalds begins work on 'git'. PC World.
  12. Git — Transfer Protocols
  13. Git на сервере — Git-демон

Ссылки

Учебные пособия
Официальные сайты
Интервью

Литература

  • Чакон С., Штрауб Б. Git для профессионального программиста. Питер, 2017. — 496 с. — ISBN 978-5-496-01763-3.
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.