Руководство по Git: от основ до продвинутых техник

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

В этой статье мы подробно разберём:

  • Что такое Git и зачем он нужен.
  • Установку и первоначальную настройку.
  • Основные команды для ежедневной работы.
  • Ветвление, слияние и разрешение конфликтов.
  • Работу с удалёнными репозиториями.
  • Популярные стратегии ветвления (Git-flow, GitHub Flow).
  • Интеграцию Git с CI/CD.
  • Полезные команды и трюки.
  • Частые ошибки и способы их исправления.

1. Что такое Git и основные понятия

Git — это система контроля версий, которая хранит историю изменений файлов в виде набора снимков (коммитов). В отличие от централизованных систем (например, SVN), Git является распределённым: каждый разработчик имеет полную копию репозитория со всей историей на своём компьютере.

Ключевые понятия:

  • Репозиторий — хранилище всех файлов и истории изменений.
  • Коммит (commit) — снимок состояния файлов в определённый момент времени с уникальным идентификатором (хешем) и сообщением.
  • Ветка (branch) — отдельная линия разработки, позволяющая вести работу параллельно с основной.
  • Тег (tag) — метка для конкретного коммита (обычно используется для версий релизов).
  • Индекс (staging area) — промежуточная область, куда добавляются файлы перед коммитом.
  • Удалённый репозиторий (remote) — репозиторий, расположенный на сервере (GitHub, GitLab, Bitbucket и др.), с которым синхронизируются локальные изменения.

2. Установка Git

2.1 Установка на Linux (Ubuntu/Debian)

Bash
sudo apt update
sudo apt install git
git --version   # проверка версии

2.2 Установка на CentOS / RHEL / Rocky Linux

Bash
sudo dnf install git
git --version

2.3 Установка на Windows

  1. Скачайте установщик с официального сайта Git.
  2. Запустите установку. Настройки по умолчанию подходят для большинства пользователей.
  3. После установки запустите Git Bash — это эмулятор командной строки с поддержкой Git.
  4. Проверьте: git --version.

2.4 Установка на macOS

Bash
# Через Homebrew
brew install git

# Или через Xcode Command Line Tools
xcode-select --install

2.5 Настройка Git на Windows: Git Bash vs CMD

На Windows рекомендуется использовать Git Bash, так как он эмулирует Linux-окружение, поддерживает те же команды и обеспечивает совместимость со скриптами. Командная строка (CMD) и PowerShell также работают, но могут иметь ограничения с некоторыми командами.

3. Первоначальная настройка Git

Перед началом работы укажите ваше имя и email — они будут записываться в каждый коммит.

Bash
git config --global user.name "Ваше Имя"
git config --global user.email "your.email@example.com"

Настройка редактора по умолчанию (например, nano):

Bash
git config --global core.editor nano

Просмотр всех настроек:

Bash
git config --list

Настройки хранятся в файле ~/.gitconfig. Можно редактировать его напрямую.

4. Основные команды для ежедневной работы

4.1 Создание репозитория

Bash
# Создать новый репозиторий в текущей папке
git init

# Клонировать существующий удалённый репозиторий
git clone https://github.com/user/repo.git
git clone git@github.com:user/repo.git   # через SSH

4.2 Добавление и коммит изменений

Bash
# Показать статус (изменённые, новые, удалённые файлы)
git status

# Добавить файл в индекс (staging area)
git add filename.php
git add .          # добавить все изменения в текущей папке
git add -A         # добавить все изменения во всём репозитории

# Зафиксировать изменения с сообщением
git commit -m "Добавлен функционал авторизации"

# Закоммитить все отслеживаемые файлы без явного add (только для уже отслеживаемых)
git commit -a -m "Исправлена ошибка в обработчике"

4.3 Просмотр истории

Bash
# Лог коммитов (полный)
git log

# Сокращённый лог (одна строка на коммит)
git log --oneline

# Графическое отображение веток
git log --graph --oneline --all

# Посмотреть изменения в файле между коммитами
git diff
git diff --staged   # изменения в индексе

4.4 Отмена изменений

Bash
# Отменить изменения в рабочей директории (несохранённые)
git checkout -- filename.php

# Убрать файл из индекса (но оставить изменения в рабочей директории)
git reset HEAD filename.php

# Отменить последний коммит, сохранив изменения в рабочей директории
git reset --soft HEAD~1

# Отменить последний коммит и удалить изменения (ОСТОРОЖНО!)
git reset --hard HEAD~1

# Отменить коммит, создав новый коммит с обратными изменениями
git revert HEAD   # или git revert <commit_hash>

# Современный способ отменить изменения в файле
git restore filename.php

# Современный способ убрать файл из индекса
git restore --staged filename.php

4.5 Ветки: создание, переключение, удаление

Bash
# Показать все ветки
git branch

# Создать новую ветку
git branch feature/new-login

# Переключиться на ветку
git checkout feature/new-login
# или (современная команда)
git switch feature/new-login

# Создать и сразу переключиться
git checkout -b feature/new-login
git switch -c feature/new-login

# Удалить ветку (локально)
git branch -d feature/old      # безопасное удаление (если ветка уже слита)
git branch -D feature/old      # принудительное удаление

# Переименовать ветку
git branch -m old-name new-name

4.6 Слияние веток (merge)

Bash
# Переключиться на целевую ветку (например, main)
git checkout main

# Слить изменения из ветки feature в текущую
git merge feature/new-login

Типы слияния:

  • Fast-forward — если целевая ветка не расходилась с основной, Git просто перемещает указатель.
  • Трёхстороннее слияние — если ветки разошлись, Git создаёт коммит слияния.

4.7 Перебазирование (rebase)

Rebase переносит коммиты одной ветки на вершину другой, создавая линейную историю.

Bash
# Переключиться на ветку, которую нужно перебазировать
git checkout feature/new-login

# Перебазировать на main
git rebase main

Когда использовать rebase:

  • Для поддержания чистой линейной истории.
  • Перед отправкой изменений в удалённый репозиторий, чтобы избежать лишних коммитов слияния.

Когда НЕ использовать rebase:

  • На публичных ветках, которые уже используются другими разработчиками. Это нарушит их историю.

4.8 Разрешение конфликтов

Конфликт возникает, когда в одной и той же строке файла внесены изменения в разных ветках.

Как разрешить:

  • Git пометит конфликтующие участки в файле:
  • Отредактируйте файл вручную: оставьте нужный код или объедините оба варианта.
  • Удалите маркеры конфликта (<<<<<<<=======>>>>>>>).
  • Добавьте файл в индекс:
Bash
git add filename.php

Завершите слияние:

Bash
git commit   # Git сам сгенерирует сообщение о разрешении конфликта

Визуальный инструмент для разрешения конфликтов:

  • git mergetool — запускает настроенный инструмент (например, vimdiff, kdiff3, или встроенный в IDE).

5. Работа с удалёнными репозиториями

5.1 Настройка удалённого репозитория

Bash
# Добавить удалённый репозиторий
git remote add origin https://github.com/user/repo.git

# Просмотр удалённых репозиториев
git remote -v

# Удалить удалённый репозиторий
git remote remove origin

5.2 Основные команды синхронизации

Bash
# Отправить изменения в удалённый репозиторий (push)
git push origin main

# Отправить новую ветку
git push -u origin feature/new-login   # -u устанавливает связь с удалённой веткой

# Получить изменения из удалённого репозитория, но не сливать
git fetch origin

# Получить изменения и сразу слить с текущей веткой
git pull origin main

# Удалить ветку на удалённом репозитории
git push origin --delete feature/old

5.3 Настройка SSH-ключей для безопасного подключения

Использование SSH вместо HTTPS удобнее и безопаснее — не нужно вводить пароль при каждом push/pull.

Генерация ключа:

Bash
ssh-keygen -t ed25519 -C "your.email@example.com"

Будет создана пара ключей: ~/.ssh/id_ed25519 (приватный) и ~/.ssh/id_ed25519.pub (публичный).

Добавление публичного ключа на GitHub/GitLab:

  1. Скопируйте содержимое публичного ключа: cat ~/.ssh/id_ed25519.pub.
  2. Зайдите в настройки аккаунта на GitHub/GitLab → SSH and GPG keys → Add new key.
  3. Вставьте ключ и сохраните.

Проверка подключения:

Bash
ssh -T git@github.com   # для GitHub
ssh -T git@gitlab.com   # для GitLab

6. Стратегии ветвления

6.1 Git-flow

Git-flow — одна из самых популярных стратегий, особенно в классических проектах с релизными циклами.

Основные ветки:

  • main — стабильная версия, всегда готова к релизу.
  • develop — интеграционная ветка для разработки.

Вспомогательные ветки:

  • feature/* — для новых фич, создаются от develop, сливаются обратно.
  • release/* — для подготовки релиза (исправление мелких багов, обновление версий), создаются от develop, сливаются в main и develop.
  • hotfix/* — для срочных исправлений в продакшене, создаются от main, сливаются в main и develop.

Пример:

Bash
# Начало работы над фичей
git checkout develop
git checkout -b feature/user-profile

# По завершении фичи
git checkout develop
git merge --no-ff feature/user-profile

# Подготовка релиза
git checkout develop
git checkout -b release/1.2.0
# ... исправления ...
git checkout main
git merge --no-ff release/1.2.0
git tag -a 1.2.0 -m "Release 1.2.0"
git checkout develop
git merge --no-ff release/1.2.0

Когда использовать: проекты с чёткими релизными циклами, несколько параллельных фич.

6.2 GitHub Flow

Более простая стратегия, популярная в проектах с непрерывным деплоем.

Правила:

  • Ветка main всегда стабильна и готова к деплою.
  • Для любой работы создаётся ветка с описательным именем.
  • После завершения работы создаётся Pull Request (PR).
  • PR проходит ревью, CI-проверки, затем сливается в main.
  • После слияния автоматически происходит деплой.

Пример:

Bash
git checkout -b feature/add-login
# ... работа ...
git push -u origin feature/add-login
# Затем создаётся Pull Request на GitHub
# После одобрения и всех проверок — слияние

Когда использовать: проекты с частыми деплоями (несколько раз в день), веб-приложения, стартапы.

6.3 Trunk-based Development

Все разработчики работают в одной ветке (main или trunk). Новый код интегрируется часто (несколько раз в день) через короткие ветки, которые живут не более дня.

Преимущества: минимальное количество конфликтов, быстрая интеграция.
Недостатки: требует высокого уровня дисциплины и хороших автотестов.

Какой подход выбрать?

  • Git-flow — для крупных проектов с длительными релизами.
  • GitHub Flow — для большинства веб-проектов с CI/CD.
  • Trunk-based — для команд с высокой культурой тестирования и непрерывной интеграцией.

7. Интеграция Git с CI/CD

Git — идеальный триггер для автоматизации сборки, тестирования и деплоя.

7.1 Триггеры на события

  • push в определённую ветку (например, main).
  • pull_request — создание/обновление PR.
  • release — создание релизного тега.

7.2 Пример пайплайна GitHub Actions

YAML
name: CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.1'
      - name: Install dependencies
        run: composer install --prefer-dist
      - name: Run tests
        run: vendor/bin/phpunit

  deploy:
    if: github.ref == 'refs/heads/main'
    needs: test
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to server
        uses: appleboy/ssh-action@v0.1.5
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: ${{ secrets.DEPLOY_USER }}
          key: ${{ secrets.DEPLOY_KEY }}
          script: |
            cd /var/www/myapp
            git pull origin main
            composer install --no-dev
            sudo systemctl reload nginx

ВАЖНО! Actions/checkout@v3 уже устарел, актуальная — @v4.

7.3 Автоматическое тегирование версий

Можно настроить автоматическое создание тегов на основе версии в файле или через семантическое версионирование:

Bash
# Вручную
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin --tags

# Автоматически в CI (пример для GitHub Actions)
# Используйте готовые действия, например, "softprops/action-gh-release"

8. Полезные команды и трюки

8.1 Временное сохранение изменений (stash)

Bash
git stash                    # сохранить текущие изменения в стек
git stash list               # показать все сохранения
git stash pop                # применить последнее сохранение и удалить его из стека
git stash apply              # применить сохранение, но оставить в стеке
git stash drop stash@{0}     # удалить конкретное сохранение
git stash -u                 # сохранить включая untracked файлы

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

8.2 Выборочное применение изменений (cherry-pick)

Bash
git cherry-pick <commit-hash>

Применяет изменения из указанного коммита в текущую ветку. Полезно, когда нужно перенести только одно исправление без слияния всей ветки.

8.3 Интерактивный rebase (переписывание истории)

Bash
git rebase -i HEAD~3   # последние 3 коммита

Позволяет:

  • Сжать коммиты (squash).
  • Изменить сообщение (reword).
  • Удалить коммит (drop).
  • Изменить порядок коммитов.

ВАЖНО: Никогда не переписывайте историю веток, которые уже опубликованы в общем репозитории.

8.4 Поиск автора изменений

Bash
git blame filename.php

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

8.5 Восстановление потерянных коммитов (reflog)

Bash
git reflog

Показывает историю перемещений указателя HEAD. Если вы случайно сбросили коммит (reset --hard), можно восстановить его, найдя хеш в reflog и выполнив git reset --hard <hash>.

8.6 Сравнение веток

Bash
git diff main..feature/new-login

Показывает разницу между двумя ветками.

8.7 Просмотр изменений за определённый период

Bash
git log --since="2 weeks ago" --oneline
git log --author="Имя" --oneline
git log --grep="исправление" --oneline

9. Частые ошибки и как их исправить

ОшибкаПроявлениеРешение
Случайно закоммитил не те файлыВ коммите лишние файлыgit reset --soft HEAD~1 → убрать лишнее → git commit -m "..."
Случайно сбросил локальные изменения (reset --hard)Потерял незакоммиченный кодИспользуйте git reflog, чтобы найти хеш состояния до сброса и восстановить.
Не могу выполнить push из-за расхождения ветокpush rejectedgit pull --rebase origin main → разрешить конфликты → git push
Забыл переключиться на ветку перед работойИзменения попали в main вместо featureИспользуйте git stash → переключиться на нужную ветку → git stash pop
Конфликт при mergeФайлы помечены конфликтомВручную разрешить конфликт → git add → git commit
Случайно удалил веткуВетка исчезлаЕсли ветка уже слита, можно восстановить по хешу коммита: git checkout -b restored-branch <hash>
Неправильно настроен user.emailКоммиты привязаны к чужому emailИсправить git config user.email, затем переписать историю: git rebase -i или git filter-branch (аккуратно!)
git push --force на общей веткеПерезапись чужих коммитов на remoteИспользуйте git push --force-with-lease — он отменяет push, если remote изменился

10. Git и безопасность

  • Храните приватные ключи SSH в надёжном месте, никогда не публикуйте их в репозиториях.
  • Не храните секреты (пароли, токены) в коде. Используйте .env файлы или секреты CI/CD.
  • Добавьте .gitignore для исключения ненужных файлов (логи, кеш, зависимости, конфиги с секретами).
  • Подписывайте коммиты и теги GPG-ключом для подтверждения авторства (рекомендуется для open-source проектов).

Пример базового .gitignore для PHP-проекта:

11. Заключение

Git — это фундамент современной разработки. Освоив его, вы получаете контроль над историей проекта, возможность безопасно экспериментировать, эффективно работать в команде и автоматизировать процессы развёртывания. Мы разобрали все ключевые аспекты: от первых команд до сложных стратегий ветвления и интеграции с CI/CD.

Помните главные принципы:

  • Коммитьте часто и пишите осмысленные сообщения.
  • Используйте ветки для каждой новой задачи.
  • Никогда не переписывайте историю общих веток.
  • Регулярно синхронизируйтесь с удалённым репозиторием, чтобы избежать больших конфликтов.

С Git ваш код становится надёжным, а разработка — предсказуемой и приятной.

Нашли ошибку? Напишите нам!