Сейчас сложно представить мир разработки программного обеспечения без git – распределенной системы контроля версий. Хотя еще 10 лет назад во многих компаниях использовались другие инструменты: CVS или SVN. Бывали даже такие команды, в которых и вовсе не велось версионирование кода. А 20 лет назад git только-только был создан Линусом Торвальдсом и начал распространяться в среде самых продвинутых разработчиков того времени — участниках опенсорс комьюнити вокруг ядра линукса.

В этой статье мы рассмотрим предпосылки появления git и его современное использование.

Первый коммит в гите был сделан 7 апреля 2005 года с описанием: Initial revision of "git", the information manager from hell. В английском языке слово гит означает «неприятный человек», и хотя история благодушно умалчивает, почему Линус назвал свой инструмент именно так, мы можем быть уверены, что в этом названии отражена та сложная обстановка, в которой оказались создатели ядра линукса в начале 21 века. Дело в том, что в начале разработки ядра Linux использовался проприетарный (то есть принадлежащий конкретной компании и не являющийся свободным) инструмент управления версиями под названием BitKeeper. Однако в 2005 году возник конфликт между разработчиками Linux и компанией-разработчиком BitKeeper, в результате которого была отозвана бесплатная лицензия разработчиков ядра.

> Licence >> /dev/null
> Git!

Тогда-то и стал востребованным новый инструмент. Git был создан как свободное и открытое программное обеспечение, что позволило разработчикам Linux продолжить работу над ядром, перестав зависеть от коммерческой системы.

В требованиях к git’у отразились потребности разработчиков опен-сорса:

  1. Распределенность: каждый разработчик имеет полную версию локально;

  2. Скорость: операции выполняются за секунды даже для очень больших проектов;

  3. Надежность: гарантированная целостность данных (хеши SHA-1).

Получившийся в результате инструмент оказался востребован в среде разработчиков, благодаря своим особенностям, совпадающими с другими трендами в IT. Во-первых, он хорошо подходит для распределенных команд, и позволяет работать с разных устройств. Всё это отлично наложилось на процессы глобализации и развитие интернета. Во-вторых, он изначально проектировался с поддержкой параллельных операций, что позволяет эффективно использовать вычислительные мощности многоядерных процессоров. И как итог, git работает в десятки раз быстрее своих прямых конкурентов: Mercurial, Bazaar. А когда в 2008 появился проект GitHub, предлагающий инфраструктуру для опен-сорс репозиториев, git получил еще больше распространения и стал стандартом де-факто.

Зачем был создан гит и чем пользовались раньше

Хотя разработчики ядра линукс уже тогда пользовались распределенной системой версионирования BitKeeper, большинство команд использовали более простые, дешевые и старые инструменты, такие как CVS и Subversion.

CVS (Concurrent Versions System) — одна из первых успешных систем контроля версий, заложившая основы для современных инструментов. Она была разработана как надстройка над локальной системой версионирования RCS (Revision Control System, 1982), которая работала только с одним файлом. Этого не хватало для работы над проектами из нескольких файлов и для возможности работать в команде. Отсюда появилось требование Concurrent (одновременная работа). И кроме того, CVS первая добавила возможность работать с общим репозиторием по сети передачи данных.

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

Subversion выступила как система, решающая проблемы CVS: в ней появились атомарные коммиты, гарантирующие, что на сервере хранится стабильный код. Проблемой стало именно то, что первоначальная цель была слишком слаба: CollabNet хотел создать систему, сохраняющую привычный workflow CVS, но без его недостатков. Однако, они не осознавали, как много недостатков сохраняют. Только представьте, что сейчас вы не могли бы сохранить изменения локально! То есть коммиты могли существовать только как результат взаимодействия с единственным центральным сервером. Для создания веток создавалась полная копия всех файлов, опять же на сервере.

В общем, когда появился гит, и оказалось, что локальная рабочая директория может быть репозиторием в полном смысле слова, процесс разработки стал более гибким и стабильным. Как сказал создатель SVN Карл Фогг: «Мы не пытались сделать революцию. Мы хотели починить CVS. Git стал революцией, которую мы не предвидели».

На основе чего Торвальдс придумал свой гит?

Одним из главных требований к системе была её распределенность. Т.к. в результате конфликта с BitKeeper разработчики ядра были в опасности оказаться без доступа к центральному репозиторию своего собственного кода, им требовалась система, в которой каждый разработчик хранит полную копию репозитория (включая всю историю). При этом не должно быть центрального сервера как единой точки отказа. Не зависимо от проблем с лицензией или связью каждый разработчик может продолжать вносить изменения в соответствии со своими целями. А после появления связи они могут обмениваться этими изменениями как независимыми ветками, или сливать их в общую ветку, включая центральную ветку master. Вообще, раньше в IT часто использовалось слово master (мастер, хозяин), теперь вместо него используется слово main (главный, основной).

Что значит распределенная система контроля версий?

Обычно мы пользуемся гитом, создавая репозиторий в GitHub или GitLab, а затем клонируя его на свой локальный компьютер. При этом по умолчанию кажется, что рабочая директория на вашей машине отличается от репозитория на гит-сервере. Но это не так. Вы можете создать гит-репозиторий в любой локальной директории с помощью команды git init и работать в ней, создавая коммиты, ветки и тэги. Если в вашей локальной сети есть другие машины и с них можно подключиться к вашей, то локальная папка на вашей машине может использоваться как репозиторий GitLab’а. Если вы сначала создали проект локально, а затем захотели сделать его доступным, выложив код на GitHub, вы создаете пустой репозиторий на гитхаб и добавляете его к своему локальному репозиторию через команду git remote add “origin” [url]. Так образом можно добавлять любое количество remote-репозиториев, давая им разные имена. Главное в этом, что на каждом указанном url должен быть действительно git-репозиторий, доступный по указанному протоколу (обычно в URL подразумевается ssh или явно прописан https).

Итак, распределенность git означает, что:

  1. У каждого разработчика на компьютере — автономный репозиторий со всей историей.

  2. Нет «главного» репозитория (хотя часто используют условный «origin» для синхронизации).

  3. Можно работать без интернета: коммиты, ветвление, просмотр истории — локально.

  4. Репозитории обмениваются изменениями выборочно через push/pull, а не через централизованные команды вроде svn commit.

Как сейчас используется гит?

Поскольку гит — это очень гибкий инструмент, он позволяет не только вести нелинейную разработку за счет легковесных ветвлений, но и эмулировать SVN-подобные репозитории. Поэтому сейчас каждая команда выбирает себе максимально подходящие практики для ведения проекта. Перечислим варианты:

  • Классический GitFlow (develop, release, hotfix) — хорош для продуктов с долгими циклами.

  • Trunk-Based Development — популярен в DevOps-практиках (частые мелкие коммиты в main).

Рассмотрим GitFlow:

ramas.png
Пример веток в практике GitFlow

Основная ветка разработки называется develop (сокращение от development), из нее создаются ветки для разработки новых фич — feature-, обычно к их имени добавляют номер задачи с описанием User Story или Feature. После окончания работы над фичей, (и тестирования) её код сливается в develop. Для соединения веток можно использовать один из двух инструментов:

  • Merge — сохраняет историю, но может её "замусорить". Лучше использовать для публичных веток (например, main). Мерж создаёт дополнительный коммит, перенося все новые изменения из сливаемой ветки.

  • Rebase — делает историю линейной, но требует осторожности. Лучше использовать для локальных веток перед пул-реквестом или мержем в develop. Эта команда переносит коммиты ветки на новую основу, указанную как база ребейза.

При мерже ветки сливаются, сохраняется история ветвления:

git-merge-graphic.png
git-merge-graphic.png

При ребейзе коммиты из фиче-ветки выстраиваются после коммитов основной ветки. Получается линия без ветвлений. При этом история изменений и все коммит месседжи сохраняются.

git-rebase-graphic.png
git-rebase-graphic.png

В гите предусмотрена возможность расширения системы за счет extension point’ов, называемых хуками (hook). Хуки могут быть добавлены для всех операций, перед выполнением операции и после нее, например:

  • Pre-commit хук: автоматические проверки кода (линтеры, тесты).

  • Post-commit хук для CI/CD запуск тестов, запуск и публикация сборки.

  • Pre-merge хук для прогона тяжеловесных тестов перед мержем в develop.

Для добавления хука нужно создать файл в .git/hooks, его имя соответствует имени команды с указанием префикса pre или post, например, .git/hooks/pre-merge. Файл должен быть исполняемым, в юникс системах это делается с помощью команды chmod +x. Внутри файла пишется исполняемый код на каком-либо скриптовом языке (к примеру, bash, python).

Если в директории проекта хранятся вспомогательные файлы, которые не нужно добавлять в репозиторий, их указывают в списке в файле .gitignore. Для многих IDE и языков программирования есть базовые шаблоны файлов .gitignore, опубликованные на сайте gitignore.io. Вкратце добавим, что отдельные библиотеки можно хранить в поддиректориях проекта с помощью инструментов git submodules или git subtrees, а потерянные коммиты можно искать с помощью команды git reflog. Если остались вопросы — пишите в комментариях, а здесь мы расскажем о том, как применяется git в современной веб-разработке.

Как используется гит в веб-разработке?

В веб-разработке git это не просто хранилище кода. В нем можно хранить данные, его же использовать для синхронизации между отдельными серверами. На пост-хуках можно построить систему деплоя и так далее. Давайте рассмотрим подробнее, как используется гит в разных задачах жизненного цикла веб-приложений.

CI/CD: тестирование и деплой на разные окружения

Современные практики CI/CD сделали автоматическую сборку после push-событий стандартом разработки. Интеграция с git-хуками позволяет гибко настраивать пайплайны:

  • Пуш в feature/* → запуск юнит-тестов через GitHub Actions,

  • Мерж в develop → деплой на staging-окружение,

  • Пуш в main или тег v1.2.3 → сборка Docker-образа и релиз в продакшен.

Иногда для этого даже не обязательно использовать сборщиков. Просто представьте, что происходит когда вся кодовая база приложения — это и есть приложение? Многие сайты созданы на основе технологий, не требующих даже компиляции, нужно просто разместить файлы в соответствующей директории. Что может помешать сделать эту директорию еще одним git-репозиторием вашего проекта? Тогда для публикации обновления вам нужно только выполнить команду git push site-origin master.

В облачных средах Git-репозитории становятся основой для сложных стратегий развёртывания:

  • Канареечные деплои (постепенный rollout на 5% → 25% → 100% серверов),

  • A/B-тестирование через параллельный деплой разных веток,

  • Изолированные среды (dev/staging/prod на отдельных поддоменах).

Инструменты вроде Docker и Kubernetes используют Git как источник данных, синхронизируя состояние кластера с конфигурацией в репозитории.

Помимо собственно разработки и версионирования кода в репозитории гита можно хранить бэкапы кодовой базы веб-приложения. Это особенно удобно, если приложение получает ресурсы из разных источников, часть из которых, что называется, сложилась исторически. Гит может быть установлен на сервере и использован по крону для создания коммита из текущего состояния и отправки данных в удалённый репозиторий.

Git: не только код, но и конфиги, схемы, данные

Git давно перестал быть просто системой контроля версий для исходного кода. Сегодня он стал полноценным хранилищем всех критически важных элементов проекта. Помимо скриптов и программного кода, в репозиториях мы храним:

  1. Схемы баз данных в различных форматах (SQL, YAML, JSON), описывающие структуру хранимой информации. В процессе разработки к ним добавляются файлы миграций, отражающие эволюцию базы данных.

  2. Наборы данных для переноса между системами. При миграции проекта экспортированная информация может быть помещена в репозиторий для последующего использования.

  3. Конфигурационные файлы, которые в современной разработке определяют не только параметры приложения, но и всю инфраструктуру окружения. Это ключевой элемент DevOps-практик.

Преимущество Git заключается в эффективной работе с текстовыми форматами. Система прекрасно справляется с:

  • Отслеживанием изменений в конфигурациях,

  • Управлением версиями схем баз данных,

  • Контролем модификаций миграционных скриптов.

На этапе развертывания Git становится центральным источником данных. Из репозитория извлекаются:

  • Конфигурации для создания и настройки серверов,

  • Скрипты для подготовки окружения,

  • Схемы и данные для инициализации баз данных.

Такой подход обеспечивает прозрачность, воспроизводимость и контроль на всех этапах жизненного цикла проекта.

Git: фундамент современной разработки

Git трансформировал веб-разработку, став не просто инструментом контроля версий, а основой всего производственного цикла. Его распределённая архитектура решила ключевые проблемы централизованных систем, взамен дав скорость и гибкость.

Благодаря GitHub он стал стандартом отрасли, а сегодня git интегрирован во все этапы разработки от создания веток в кодовой базе, до управления инфраструктурой облачных приложений. Сложно представить большой веб-проект без гита. Он продолжает эволюционировать, оставаясь центральным узлом в экосистеме современной разработки.

Комментарии (0)