Git

Материал из llmdocs — справочник разработчика
Портал: Git, CI/CD, DevOps
Git
Типраспределённая система контроля версий
АвторЛинус Торвальдс
Первый выпускапрель 2005
СопровождающийДзюнио Хамано (с июля 2005)
ЯзыкиC, Shell, Perl
ЛицензияGNU GPL v2
Хеш-функция объектовSHA-1 (поддерживается SHA-256)
Сайтgit-scm.com

Git — распределённая система контроля версий: программа, которая хранит историю изменений файлов проекта, позволяет вернуться к любой прошлой версии, вести параллельные линии разработки и объединять работу многих людей. «Распределённая» означает, что у каждого участника есть полная копия репозитория со всей историей, и большинство операций выполняется локально, без сервера.

Git используют подавляющее большинство разработчиков; на нём построены платформы GitHub и GitLab, процессы code review и CI/CD. Вне программирования Git применяют для документации, конфигураций (Infrastructure as Code) и даже книг.

История

С 2002 года ядро Linux разрабатывалось в коммерческой системе BitKeeper, которую авторы предоставляли сообществу бесплатно. В 2005 году бесплатную лицензию отозвали, и Линус Торвальдс за несколько дней написал собственную систему. Требования были чёткими: скорость, простая модель, поддержка тысяч параллельных веток, полная распределённость и способность работать с проектом размера ядра.[2] Первая версия появилась 7 апреля 2005 года, а уже в июле сопровождение перешло к Дзюнио Хамано, который ведёт проект до сих пор.

Название Торвальдс объяснял шутливо: git на британском сленге — «вредный тип», а он «называет все проекты в свою честь». Популярность Git резко выросла с запуском GitHub в 2008 году; к середине 2010-х он вытеснил Subversion, Mercurial и другие системы.

Модель данных

Git хранит не разницу между версиями, а снимки проекта. Все данные — объекты четырёх типов, адресуемые по хешу содержимого:[3]

Объект Что хранит
blob содержимое файла
tree каталог: имена файлов и ссылки на blob и другие tree
commit ссылка на tree (снимок), родительские коммиты, автор, дата, сообщение
tag именованная ссылка на коммит с подписью и описанием

Одинаковые файлы хранятся один раз, а любое изменение в истории меняет хеши всех последующих коммитов — поэтому историю нельзя незаметно подделать. Исторически Git использует SHA-1; после демонстрации практической коллизии SHA-1 в 2017 году в Git добавлены защита от известных атак и поддержка SHA-256 для новых репозиториев.[4]

Ветки — это просто подвижные указатели на коммиты, поэтому создание ветки мгновенно; подробнее — в статье Ветвление в Git.

Три области

Файл в рабочем каталоге проходит через три состояния:

  1. Рабочий каталог (working tree) — файлы, которые вы редактируете.
  2. Индекс (staging area) — подготовленные к коммиту изменения; git add переносит их сюда.
  3. Репозиторий (.git) — зафиксированная история; git commit создаёт новый снимок из индекса.

Индекс позволяет собрать в один коммит только часть изменений — например, отделить исправление ошибки от попутного рефакторинга (git add -p).

Основные команды

git init                         # новый репозиторий
git clone git@github.com:user/repo.git
git status                       # что изменено
git add file.py                  # в индекс
git commit -m "Добавить проверку email"
git log --oneline --graph        # история
git diff                         # изменения, ещё не в индексе
git switch -c feature/login      # новая ветка
git merge feature/login          # слить ветку
git pull                         # забрать изменения с сервера (fetch + merge/rebase)
git push origin feature/login    # отправить ветку на сервер
git restore file.py              # отменить локальные правки файла
git revert a1b2c3d               # новый коммит, отменяющий старый

Подробное описание каждой команды есть в справочнике Git, а лучшее введение — бесплатная книга «Pro Git».[6][1]

Удалённые репозитории

Удалённый репозиторий (remote) — копия на сервере, обычно с именем origin. Git передаёт данные по SSH или HTTPS. Команда fetch скачивает новые коммиты, не трогая ваши ветки, pull дополнительно объединяет их с текущей веткой, push отправляет локальные коммиты. Поскольку у всех полные копии, потеря сервера не означает потерю истории.

Хорошие практики

  • Небольшие осмысленные коммиты с сообщением в повелительном наклонении: что и зачем изменено.
  • Файл .gitignore для сборочных артефактов, .venv, node_modules, логов.
  • Никогда не коммитить секреты: ключ, попавший в историю, остаётся в ней и после удаления файла — его нужно отзывать.
  • Не переписывать (rebase, push --force) историю веток, которыми пользуются другие; про выбор между слиянием и перебазированием — Merge и rebase.
  • Версии релизов отмечать тегами по правилам семантического версионирования, а проверки перед коммитом автоматизировать хуками.

См. также

Источники

  1. Pro Git — Scott Chacon, Ben Straub
  2. Pro Git — A Short History of Git
  3. Pro Git — Git Internals: Git Objects
  4. Git — hash-function-transition
  5. git/git — исходный код на GitHub
  6. Git Reference Manual