Git — это распределённая система контроля версий с открытым исходным кодом, созданная Линусом Торвальдсом в 2005 году для разработки ядра Linux. В отличие от централизованных систем вроде SVN, Git хранит полную копию репозитория на каждом устройстве разработчика, что позволяет работать без постоянного подключения к серверу. По данным Git SCM, 2024, Git используется более чем в 90% всех коммерческих проектов по разработке ПО.
Главное
Git — это распределённая система контроля версий (VCS), которая отслеживает изменения в файлах и позволяет нескольким разработчикам работать над одним проектом одновременно. В отличие от централизованных систем, в Git каждый разработчик имеет полную копию репозитория, включая всю историю изменений, что делает систему устойчивой к потере данных и не требует постоянного подключения к центральному серверу.
История Git началась в 2005 году, когда Линус Торвальдс создал новую VCS после того, как компания BitKeeper отозвала бесплатную лицензию на свою систему для разработчиков ядра Linux. Целями были: скорость, простота архитектуры, поддержка нелинейной разработки через ветвление и полная распределённость. За 3 месяца Торвальдс написал ядро Git, а уже через год проект перешёл на самообслуживание под управлением Дзюн Хамано.
По данным опроса Stack Overflow (2024), Git используют 93,9% профессиональных разработчиков, что делает его доминирующей системой контроля версий в индустрии. Ближайший конкурент — Subversion (SVN) — используется лишь в 5,2% проектов, преимущественно в крупных корпоративных средах с централизованными процессами.
Репозиторий Git — это директория, в которой Git отслеживает изменения всех файлов. Внутри директории находится скрытая папка .git, где хранятся все объекты системы: коммиты, деревья, блоки и ссылки. Когда разработчик создаёт коммит, Git не копирует файлы целиком — он создаёт снимок состояния (snapshot) и сохраняет ссылку на него.
Каждый коммит содержит: уникальный SHA-1 хеш (40 символов), ссылку на предыдущий коммит (parent), автора, дату, сообщение коммита и ссылку на дерево (tree), которое описывает состояние файлов на момент коммита. Цепочка коммитов образует направленный ациклический граф, где каждый коммит указывает на одного или нескольких родителей.
# Инициализация репозитория
git init my-project
cd my-project
# Создание коммита
echo "Hello, Git" > README.md
git add README.md
git commit -m "Initial commit"
# Просмотр истории
git log --oneline --graph --all
Git использует три основные области: working directory (файлы на диске), staging area (индекс, куда попадают подготовленные файлы) и repository (история коммитов). Команда git add перемещает изменения из рабочей директории в staging, а git commit фиксирует содержимое staging в репозитории. Это разделение позволяет разработчику собирать осмысленный коммит из набора изменений, не фиксируя каждое правку отдельно.
Базовые команды Git покрывают 90% ежедневных операций разработчика. Команда git clone создаёт локальную копию удалённого репозитория, git pull забирает изменения с сервера и сливает их с текущей веткой, а git push отправляет локальные коммиты на сервер. Эти три команды формируют основной цикл работы с Git.
Для просмотра состояния используется git status — она показывает, какие файлы изменены, какие добавлены в staging и какие не отслеживаются. git diff отображает конкретные изменения в файлах до добавления в staging. Ниже приведена таблица с наиболее часто используемыми командами:
| Команда | Действие | Пример |
|---|---|---|
| git clone | Копирует удалённый репозиторий | git clone https://example.com/repo |
| git add | Добавляет файлы в staging | git add src/main.kt |
| git commit | Фиксирует изменения в истории | git commit -m "Fix login bug" |
| git push | Отправляет коммиты на сервер | git push origin main |
| git pull | Забирает изменения с сервера | git pull origin feature |
Для отмены изменений Git предоставляет несколько вариантов. git reset перемещает указатель ветки на заданный коммит и может сбросить staging или рабочую директорию. git revert создаёт новый коммит, который отменяет изменения указанного коммита — это безопасный способ отмены для общих веток, так как история не переписывается.
Ветки в Git — это лёгкие перемещаемые указатели на определённый коммит. Создание новой ветки не копирует файлы, а лишь создаёт новый указатель, что делает ветвление практически мгновенным. Ветка main (ранее master) — основная ветка проекта, которая содержит стабильный, готовый к релизу код.
Стандартная практика — использовать Git Flow или GitHub Flow. В Git Flow используются ветки: main (релизный код), develop (интеграционная ветка), feature/* (новые функции), release/* (подготовка релизов) и hotfix/* (срочные исправления). GitHub Flow проще: только main и feature-ветки, а все изменения доставляются через Pull Request.
# Создание и переключение ветки
git branch feature-auth
git checkout feature-auth
# или одной командой:
git checkout -b feature-auth
# Список веток
git branch --list
git branch -a # все ветки, включая удалённые
# Удаление ветки
git branch -d feature-auth
Важное свойство ветвления Git — возможность cherry-pick: перенос отдельного коммита из одной ветки в другую с помощью команды git cherry-pick <hash>. Это полезно, когда нужно перенести исправление бага из feature-ветки в release без слияния всей ветки. Также Git поддерживает перебазирование (rebase) и интерактивное перебазирование (git rebase -i) для склеивания, переупорядочивания и редактирования коммитов.
Merge (слияние) создаёт специальный merge-коммит, который имеет двух родителей. Этот коммит фиксирует факт объединения двух веток и сохраняет полную историю — видно, где и когда произошло слияние. Merge сохраняет историю в том виде, в котором она была создана, что упрощает аудит, но делает граф коммитов более сложным.
Rebase (перебазирование) вместо создания merge-коммита переносит коммиты текущей ветки на верхушку целевой ветки. История становится линейной — создаётся впечатление, что разработка велась последовательно. Однако rebase переписывает историю, изменяя SHA-1 хеши коммитов, что делает его опасным для общих веток, к которым имеют доступ другие разработчики.
Рекомендация по выбору: используйте merge для публичных веток, где историю видят другие разработчики (feature → develop), и rebase для локальной работы, когда нужно применить свежие изменения из main в свою feature-ветку перед созданием Pull Request. Правило простое: если коммит уже отправлен на сервер — не перебазируйте его.
Конфликт слияния возникает, когда Git не может автоматически объединить изменения в одном файле. Git помечает конфликтующие участки в файле специальными маркерами: <<<<<<< (наши изменения), ======= (разделитель), >>>>>>> (их изменения). Разработчик вручную редактирует файл, выбирая нужный вариант или комбинируя оба, и завершает слияние коммитом.
Удалённый репозиторий (remote) — это копия Git-репозитория, расположенная на сервере. GitHub, GitLab и Bitbucket — наиболее популярные платформы для хостинга удалённых репозиториев. Они предоставляют веб-интерфейс для просмотра кода, управления доступом, код-ревью и интеграции с CI/CD-системами.
В Git можно настроить несколько удалённых репозиториев для одного проекта. По умолчанию основной remote называется origin. Команда git remote add добавляет новый remote, git fetch забирает изменения без слияния, а git pull — это сокращение для git fetch + git merge. Для работы с кодом через Pull Request разработчик создаёт форк репозитория, клонирует его, работает в feature-ветке и отправляет запрос на слияние в оригинальный репозиторий.
# Добавление удалённого репозитория
git remote add origin https://github.com/user/repo.git
# Просмотр удалённых репозиториев
git remote -v
# Отправка ветки на сервер
git push -u origin feature-auth
# Забрать изменения с удалённой ветки
git pull origin main
Удалённые репозитории поддерживают тегирование для маркировки релизных версий. Теги бывают лёгкими (просто указатель на коммит) и аннотированными (содержат метаданные: автор, дата, сообщение). Аннотированные теги рекомендуется использовать для релизных версий, так как они передают полную информацию о версии и могут быть подписаны GPG-ключом для верификации авторства.
Git Worktree позволяет одновременно работать с несколькими ветками в разных директориях без переключения между ними. Команда git worktree add ../feature-auth feature-auth создаёт новую рабочую директорию feature-auth, где можно писать код, не переключая ветку в основной директории. Worktree полезен для быстрых исправлений в release-ветке, когда основная директория занята долгой разработкой.
Git Submodules — механизм включения одного Git-репозитория в другой. Submodule хранит ссылку на фиксированный коммит внешнего репозитория, что гарантирует воспроизводимость сборки. Команда git submodule add https://github.com/example/lib.git добавляет внешнюю библиотеку как подмодуль. При клонировании проекта с подмодулями требуется выполнить git submodule update --init --recursive для загрузки всех зависимостей.
Часто задаваемые вопросы
Git — распределённая VCS с локальной историей и возможностью работы офлайн. SVN — централизованная система, требующая постоянного подключения к серверу для любых операций, кроме просмотра файлов.
Используйте git revert HEAD для безопасной отмены (создаётся новый коммит). Если коммит ещё не отправлен на сервер, можно использовать git reset --soft HEAD~1.
.gitignore — файл, в котором перечислены паттерны файлов и директорий, которые Git должен игнорировать. Используется для исключения временных файлов, сборок и конфигураций IDE из репозитория.
git fetch загружает изменения с сервера, но не сливает их с текущей веткой. git pull делает fetch и сразу выполняет merge. Для контроля используйте fetch + просмотр diff, затем merge вручную.
Используйте git commit --amend — эта команда открывает редактор для изменения сообщения коммита. Если коммит уже на сервере, потребуется git push --force, что опасно для общих веток.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также