Git
Git — распределённая система управления версиями, предназначенная для отслеживания изменений в исходном коде и данных. Git широко используется программистами в процессе совместной разработки программного обеспечения.
Основными целями при создании Git были высокая скорость работы, целостность данных и поддержка распределённых и нелинейных сценариев разработки с большим количеством параллельных веток. Как и большинство систем распределённого управления версиями, Git хранит полную локальную копию всего репозитория, включая историю изменений, что позволяет работать с проектом и отслеживать его историю без постоянного доступа к сети или центральному серверу. Git предоставляет средства для синхронизации изменений между репозиториями, в том числе на удалённых машинах. Для организации интеграции изменений часто пользуются центральным сервером, однако все репозитории равноправны.
Git распространяется как свободное и открытое программное обеспечение на условиях лицензии GPL-2.0-only.
Git был создан Линусом Торвальдсом для управления версиями в процессе разработки ядра Linux. Торговая марка «Git» зарегистрирована организацией Software Freedom Conservancy.
Сегодня Git является фактическим стандартом управления версиями: по данным за 2022 год, им пользуются почти 95 % профессиональных разработчиков, а сервисы для размещения Git-репозиториев, такие как GitHub, SourceForge, Bitbucket и GitLab, стали индустриальным стандартом.
Что важно знать
| Git | |||
|---|---|---|---|
| Тип | Система управления версиями | ||
| Автор | Линус Торвальдс | ||
| Разработчики | Хамино Джунио и др. | ||
| Написана на | преимущественно C, а также сценарии на Shell, Perl, Tcl, Python | ||
| Операционные системы | POSIX (включая Linux, macOS, Solaris, AIX), Windows | ||
| Языки интерфейса | английский | ||
| Первый выпуск | 7 апреля 2005 | ||
| Последняя версия |
|
||
| Репозиторий | github.com/git/git | ||
| |||
| |||
| Лицензия | GPL-2.0-only | ||
| Сайт | git-scm.com | ||
История
Разработка Git началась Линусом Торвальдсом в апреле 2005 года после того, как свободная лицензия на проприетарную систему управления версиями BitKeeper, использовавшуюся для работы над ядром Linux с 2002 года, была отозвана. Это решение побудило также создание альтернатив — в частности, Mercurial. Торвальдс хотел получить распределённую систему с функционалом BitKeeper, однако существовавшие на тот момент свободные аналоги не удовлетворяли его требованиям по производительности и безопасности. Критериями стали: производительность — применение патча и обновление метаданных не более чем за 3 секунды (в отличие от 30 секунд у альтернатив), поддержка распределённой работы и устойчивость к повреждениям данных.
Разработка Git стартовала 3 апреля 2005 года; уже 6 апреля проект был анонсирован, а начиная с 7 апреля для поддержки ядра Linux стала применяться самособирающаяся версия системы. Первая слияние веток реализовано 18 апреля, а к 16 июня на Git уже осуществлялись полноценные релизы ядра Linux.
26 июля 2005 года Линус Торвальдс передал поддержку и развитие Git Джунио Хамино, одному из ключевых участников проекта, который выпустил версию 1.0 21 декабря 2005 года.
Линус Торвальдс иронично прокомментировал выбор названия «git» (в британском английском сленге — «недотёпа», «придурок»): «Я эгоистичный ублюдок, называю все свои проекты в честь себя. Сначала — „Linux“, теперь — „git“». В man-странице система определяется как «тупой трекер содержимого». В файле README исходного кода отмечается:
"git" может значить всё что угодно, в зависимости от вашего настроения:
- Случайная трёхбуквенная комбинация, не совпадающая с командами UNIX; возможная неправильная транслитерация «get».
- Глупый, презренный, простой. Выберите любое значение из сленгового словаря.
- «Global information tracker»: когда всё работает — ангелы поют, свет наполняет комнату.
- «Goddamn idiotic truckload of sh*t»: когда всё ломается.
В исходных файлах Git система называется «the information manager from hell» (информационный менеджер из ада).
Характеристики
Дизайн Git основан на опыте Торвальдса по поддержке масштабных распределённых проектов (ядро Linux) и знании быстродействия файловых систем. Было реализовано:
- Поддержка нелинейной разработки
- Git облегчает быстрое ветвление и объединение, включает средства визуализации истории, а сами ветки представляют собой просто ссылки на коммиты.
- Распределённая модель
- каждый пользователь хранит локальную копию полной истории разработки; изменения между репозиториями импортируются в виде веток и могут объединяться.
- Совместимость
- поддерживается публикация репозиториев по HTTPS, HTTP, FTP и собственному протоколу Git, а также эмуляция сервера CVS для поддержки соответствующих клиентов и плагинов IDE. Конвертация репозиториев Subversion реализуема через git-svn.
- Высокая производительность
- Git оптимизирован для работы с большими проектами и может на порядки превосходить другие системы по скорости операций.
- Криптографическая целостность
- идентификатор версии-коммита зависит от истории изменений и реализован на основе SHA-1, так что искажение истории можно легко выявить.
- Модульная структура
- большинство команд реализовано как отдельные программы на C, обёрнутые в shell-скрипты; компоненты можно объединять в цепочки.
- Расширяемость слияния
- поддерживаются плагины стратегий слияния, а в случае невозможности автослияния пользователь получает требование разрешить конфликт вручную.
- Сборка «мусора»
- ненужные объекты, создаваемые при завершении операций, автоматически удаляются сборщиком мусора (git gc); также возможна ручная сборка.
- Упаковка объектов
- для экономии пространства объекты периодически сохраняются в pack-файлы с delta-компрессией и индексами, поддерживается контроль целостности через SHA-1, анализ целостности — командой git fsck.
Git оперирует снимками состояний (snapshot) каталогов, не отслеживая индивидуальных историй отдельных файлов.
- Для просмотра истории изменений отдельного файла требуется обход истории всего проекта.
- Переименования обнаруживаются по эвристике при просмотре истории, а не фиксируются явно, и требуют больше вычислений.
Git реализует ряд стратегий слияния веток<ref name="merge">:
- resolve — классический трёхсторонний алгоритм;
- recursive — вариант resolve по умолчанию при слиянии одной ветки (уменьшает количество конфликтов, поддерживает обнаружение переименований);
- octopus — применяется при слиянии более двух веток.
Основные структуры данных в Git — изменяемый индекс (stage/cache), кэширующий информацию о рабочем каталоге и будущем коммите, и неизменяемая база объектов.
В базе хранятся пять типов объектов:
- blob — содержимое файла;
- tree — эквивалент директории со списками файлов и ссылками на объекты;
- commit — связывает tree-объекты в историю;
- tag — контейнер метаданных, часто для подписи релизов;
- packfile — сжатый пакет объектов для компактного хранения.
Каждый объект идентифицируется хешем SHA-1; имена и организация каталогов строятся на основе хеша. Объекты можно группировать в пакеты для экономии дискового пространства (используется delta-компрессия).
Для навигации по истории используются ссылки (refs): ветки (heads), HEAD (текущая активная ветка), теги (tags).
Основные команды Git для работы из командной строки:
git init— создать новый репозиторий;git clone [URL]— клонировать внешний репозиторий;git add [файл]— добавить файл в индекс (для фиксации изменений);git commit -m "[комментарий]"— зафиксировать изменения в репозитории.
Для игнорирования некоторых файлов можно создать текстовый файл .gitignore, где указываются файлы и шаблоны, которые не должны отслеживаться.
Git поддерживает различные типы ссылок (references); для их просмотра используется команда git show-ref. Например:
- heads — локальные ветки,
- remotes — ветки в удалённых репозиториях,
- stash — временные сохранения,
- meta — метаданные (например, в Gerrit),
- tags — теги.
Реализации
Основная реализация Git (на C) изначально создавалась и поддерживалась под Linux, однако существует поддержка большинства популярных ОС (BSD-семейство, Solaris, macOS, Windows).
Первая портированная версия для Windows включала эмулирующую среду Linux, а текущие официальные сборки распространяются как 32- и 64-разрядные установщики на базе MSYS2.
Существуют альтернативные реализации:
- JGit — чистый Java-библиотека для встраивания Git в Java-приложения (используется в Gerrit, EGit);
- go-git — реализация Git на Go, используется, в том числе, для SQL-интерфейса и шифрования;
- Dulwich — на Python, поддерживает CPython 3.6+ и PyPy;
- libgit2 — библиотека на ANSI C без сторонних зависимостей, поддерживает различные платформы и языки (Ruby, Python, Haskell);
- JS-Git — реализация части Git на JavaScript;
- Game of Trees — open source-реализация Git для OpenBSD.
Git-сервер
Как распределённая система, Git может быть сервером «из коробки» благодаря встроенной команде git daemon, запускающей простой TCP-сервер по протоколу Git; репозитории можно клонировать и использовать как центральное хранилище. Для управления доступом/публикации можно использовать отдельные HTTP-серверы, оболочку ssh, интегрированные web-интерфейсы.
- Gerrit — сервер Git с поддержкой кода-ревью, доступа через ssh/OpenSSH/Jetty и интеграцией авторизации;
- Phabricator — поддержка Git наряду с Mercurial и Subversion;
- RhodeCode Community Edition — поддержка Git, Mercurial и Subversion;
- Kallithea — сервер на Python с поддержкой Git/Mercurial;
- gitolite, Gogs, Gitea, Forgejo — самописные или форки, реализованные на Go, с открытым кодом и MIT-лицензией.
Сервисов хостинга Git-репозиториев множество; наиболее популярны GitHub, SourceForge, Bitbucket и GitLab.
Графические интерфейсы
Графические клиенты Git предоставляют пользовательский интерфейс для упрощения работы с репозиториями. Они визуализируют историю, ветки, коммиты, различия файлов, позволяют выполнять типовые действия (стадирование, коммиты, управление ветками/объединением, разрешение конфликтов).
Официальный GUI реализован на Tcl/Tk, поддерживает создание и изменение коммитов, управление ветками и взаимодействие с удалёнными хранилищами. Существуют и сторонние решения с расширенным функционалом.
Использование GUI снижает порог вхождения и повышает эффективность работы с системой контроля версий.
Применение
По данным отчёта Eclipse Foundation за май 2014 года, Git стал самым широко используемым инструментом управления версиями исходных текстов (42,9 % опрошенных разработчиков — против 36,3 % в 2013, 32 % в 2012). Похожие показатели приведены в open source-аналитике Open Hub.
В ежегодных опросах Stack Overflow Git уверенно лидирует с долей до 93,9 % опрошенных (2022); аналогичные значения подтверждаются по опиcаниям вакансий IT-работы в Великобритании.
Применяемость различных систем управления версиями среди разработчиков (по Stack Overflow):
| Название | 2015 | 2017 | 2018 | 2022 |
|---|---|---|---|---|
| Git | 69,3 % | 69,2 % | 87,2 % | 93,9 % |
| Subversion | 36,9 % | 9,1 % | 16,1 % | 5,2 % |
| TFVC | 12,2 % | 7,3 % | 10,9 % | |
| Mercurial | 7,9 % | 1,9 % | 3,6 % | 1,1 % |
| CVS | 4,2 % | — | — | — |
| Perforce | 3,3 % | — | — | — |
| VSS | — | 0,6 % | — | — |
| IBM DevOps Code ClearCase | — | 0,4 % | — | — |
| Zip file backups | — | 2,0 % | 7,9 % | — |
| Raw network sharing | — | 1,7 % | 7,9 % | — |
| Другое | 5,8 % | 3,0 % | — | — |
| Не используют | 9,3 % | 4,8 % | 4,8 % | 4,3 % |
Расширения
К Git доступно множество расширений, в частности, Git LFS для работы с большими файлами, git-annex (распределённая синхронизация медиафайлов), git-flow (автоматизация ветвлений), git-machete (органайзер веток).
Корпорация Microsoft разработала Virtual File System for Git (VFS for Git) — расширение для поддержки масштабных репозиториев на Windows, позволяющее скачивать содержимое файлов только при обращении.
Конвенции
- По умолчанию
git initсоздаёт ветку master (во многих современных инструментах вместо неё применяется main). - Коммиты в общих репозиториях обычно не перезаписывают, а отменяют дополнительным коммитом с обратимыми изменениями.
- Популярна модель работы git-flow с отдельными ветками: feature/* (разработка), develop (нестабильная), main (стабильная), hotfix (экстренные исправления).
- Pull request/merge request — не встроенная функция Git, а возможность облачных сервисов; по сути это тикет на сервере для объединения веток с ручной модерацией.
Безопасность
Git не реализует механизмов контроля доступа, полагаясь на внешние инструменты.
В декабре 2014 года была выявлена уязвимость, позволяющая злоумышленнику выполнять произвольный код на Windows и macOS при загрузке и раскрытии особых директорий .git, что было исправлено в версии 2.2.1.
В сентябре 2015 года устранена критическая уязвимость (CVE-2015-7545), также связанная с возможностью удалённого исполнения кода при особых условиях клонирования.
Хотя SHA-1 использовался в первую очередь для контроля целостности, после атаки SHAttered в 2017 году Git внедрил модифицированный SHA-1 и разрабатывает переход на другие хеши.
Торговая марка
Слово «Git» зарегистрировано в качестве товарного знака организацией Software Freedom Conservancy в США (с 3 февраля 2015 года).


