Git

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

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

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

Начальная разработка велась меньше чем неделю: 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[en], 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:) — открытый протокол[13], требующий наличия на сервере запущенного git-демона[14] (поставляется вместе с 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. Re: Trivia: When did git self-host?
  2. Хамано Д. [ANNOUNCE Git v2.44.0] — 2024.
  3. 1 2 3 4 5 6 Git pack format
  4. https://web.archive.org/web/20151116175401/https://github.com/git/git/commit/e83c5163316f89bfbde7d9ab23ca2e25604af290
  5. https://github.com/git/git/graphs/contributors
  6. The git Open Source Project on Open Hub: Languages Page — 2006.
  7. Copying (англ.)
  8. git. Дата обращения: 19 июня 2009. Архивировано 14 апреля 2010 года.
  9. BitKeeper and Linux: The end of the road? Дата обращения: 7 ноября 2017. Архивировано из оригинала 8 июня 2017 года.
  10. Выступление Торвальдса. Дата обращения: 28 сентября 2017. Архивировано 28 мая 2007 года.
  11. GitFaq: Why the 'Git' name. Дата обращения: 7 ноября 2017. Архивировано 23 июля 2012 года.
  12. After controversy, Torvalds begins work on 'git'. PC World. Дата обращения: 7 ноября 2017. Архивировано 1 февраля 2011 года.
  13. Git — Transfer Protocols. Дата обращения: 28 октября 2013. Архивировано 29 октября 2013 года.
  14. Git на сервере — Git-демон. Дата обращения: 9 мая 2022. Архивировано 20 апреля 2017 года.

Литература[править | править код]

  • Чакон С., Штрауб Б. Git для профессионального программиста. — Питер, 2017. — 496 с. — ISBN 978-5-496-01763-3.

Ссылки[править | править код]

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