База знаний

Git: полное руководство по командам и терминологии (с акцентами на информационную безопасность)

Git: полное руководство по командам и терминологии

Git: больше не только для разработчиков!

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

Что такое Git?

Git — это система управления версиями. Она записывает изменения файлов и позволяет при необходимости вернуться к любой предыдущей точке. Проще говоря, это цифровое рабочее пространство, где все изменения безопасно «сохраняются» и «публикуются».

Например, если вы пишете роман и хотите откатиться к версии недельной давности — Git сделает это возможным.

Сегодня Git также активно используется в связке с Obsidian, Logseq для личного управления знаниями (PKM).

Новичкам рекомендуется начинать с графических инструментов: Sourcetree, GitKraken, GitHub Desktop, VS Code.

—

Основы Git (концепции)

Git Workflow

[Рабочий каталог (Working Directory)]  🖥️
        |
        |  работа с файлами (изменение, добавление, удаление)
        |    |
        |    |  git add <файл>  (индексация изменений)
        |    ↓
        ↓
[Область индексирования (Staging Area)]  📦
        |
        |  git commit -m "сообщение"  (сохранить изменения в локальном репозитории)
        ↓
[Локальный репозиторий (Local Repository)]  🏠
        |
        |  git push origin <ветка>  (отправить изменения в удалённый репозиторий)
        ↓
[Удалённый репозиторий (Remote Repository)] 🌍
        |
        |  git pull origin <ветка>  (git fetch + git merge)
        ↓
[Локальный репозиторий коллеги]  🏠
        |
        |  возникает слияние (merge)
        |    |
        |    |  разрешение конфликтов (при необходимости)
        |    ↓
        ↓
[Рабочий каталог коллеги]  🖥️

—

Глоссарий терминов Git

| Термин | Описание | Пример использования |
|——–|———-|———————-|
| Working Directory | Каталог, где вы сейчас работаете; Git отслеживает файлы в нём. | git status — просмотр состояния рабочего каталога |
| Staging Area | Промежуточная область для подготовки коммита. | git add <file> — добавить файл в Staging Area |
| Index | То же, что и Staging Area; внутренняя структура данных Git. | git ls-files --stage |
| Worktree | Позволяет работать с несколькими рабочими каталогами в одном репозитории. | git worktree add <path> <branch> |
| HEAD | Указатель на последний коммит текущей ветки. | git checkout main — HEAD указывает на main |
| Detached HEAD | HEAD указывает непосредственно на коммит (не на ветку). | git checkout <хэш-коммита> |
| Repository | Хранилище проекта (локальное или удалённое). | git init, git clone <URL> |
| Commit | Сохранение изменений с уникальным хэшем. | git commit -m "сообщение" |
| Branch | Отдельная линия разработки. | git branch feature-branch |
| Checkout | Переключение между ветками или коммитами. | git checkout feature-branch |
| Merge | Слияние изменений из двух веток. | git merge feature-branch |
| Pull | Забрать изменения из удалённого репозитория и слить с текущей веткой. | git pull origin main |
| Push | Отправить локальные изменения в удалённый репозиторий. | git push origin feature-branch |
| Fetch | Забрать изменения из удалённого репозитория без слияния. | git fetch origin |
| Clone | Клонировать удалённый репозиторий локально. | git clone https://github.com/user/repo.git |
| Fork | Создать копию чужого репозитория в своём аккаунте (GitHub). | Кнопка "Fork" на GitHub |
| Pull Request (PR) | Запрос на вливание изменений в оригинальный репозиторий. | Кнопка "New Pull Request" |
| Stash | Временно отложить текущие изменения, очистить рабочий каталог. | git stash, git stash pop |
| Rebase | Перестроить историю коммитов на основе другой ветки. | git rebase main |
| Tag | Присвоить имя коммиту (обычно для версий). | git tag v1.0.0 |
| Remote | Ссылка на удалённый репозиторий (обычно origin). | git remote add origin <URL> |
| Conflict | Конфликт при слиянии из-за изменений в одних и тех же строках. | Разрешается вручную |
| Cherry-pick | Применить конкретный коммит из другой ветки. | git cherry-pick <хэш> |
| Reset | Переместить HEAD и (опционально) сбросить индексацию/рабочий каталог. | git reset --hard HEAD~1 |
| Revert | Отменить коммит, создав новый коммит с обратными изменениями. | git revert <хэш> |
| Blame | Показать, кто и когда изменил каждую строку файла. | git blame <file> |
| Log | Показать историю коммитов. | git log |
| Diff | Показать различия между состояниями. | git diff |
| Stage | Добавить изменения в индекс. | git add <file> |
| Unstage | Убрать изменения из индекса. | git reset <file> |
| Ignore | Игнорировать файлы/каталоги (через .gitignore). | node_modules/ в .gitignore |
| Submodule | Включить другой Git-репозиторий в текущий. | git submodule add <URL> |
| Bisect | Бинарный поиск коммита, внёсшего баг. | git bisect start, git bisect bad, git bisect good |
| Hooks | Скрипты, срабатывающие на события Git. | .git/hooks/pre-commit |
| Reflog | Журнал всех перемещений HEAD и ссылок. | git reflog |
| Upstream | Ветка в удалённом репозитории, связанная с локальной. | git push --set-upstream origin feature-branch |

> 🔒 БЕЗОПАСНОСТЬ (MITRE T1552.001):
> Избегайте хранения паролей, токенов и ключей в любых файлах, которые могут попасть в репозиторий. Используйте .gitignore для секретных файлов и pre-commit хуки с инструментами типа gitleaks, чтобы автоматически блокировать коммиты с чувствительными данными.

—

Важность указателей (pointers) в Git

Git основан на указателях: коммиты, ветки, HEAD, теги — всё это ссылки на объекты.

1. Указатель HEAD

  • Указывает на последний коммит текущей ветки.
  • Хранится в .git/HEAD.
  • При переключении на конкретный коммит переходит в состояние Detached HEAD.
  • Синтаксис для навигации:
    HEAD^ — родительский коммит (первый родитель).
    HEAD^^ — два поколения назад.
    HEAD^2 — второй родитель (для merge-коммитов).
    HEAD~2 — два шага назад по первому родителю.

    2. Указатели веток (branch pointers)

  • Каждая ветка — это файл в .git/refs/heads/, содержащий хэш последнего коммита.
  • При создании нового коммита указатель ветки автоматически перемещается.
  • 3. Указатели тегов

  • Файлы в .git/refs/tags/ содержат хэш коммита.
  • Обычно не изменяются после создания (легковесные теги — только имя, аннотированные — включают метаданные).
  • 4. Указатели удалённых веток

  • Хранятся в .git/refs/remotes/.
  • Обновляются командой git fetch.
  • > 🔒 БЕЗОПАСНОСТЬ (целостность истории):
    > Указатели являются критически важными для аудита. Регулярно проверяйте журнал reflog (git reflog), чтобы обнаружить несанкционированные reset, rebase или amend. Согласно 187-ФЗ (о КИИ), любое переписывание истории должно быть задокументировано.

    —

    Команды Git

    1. Настройка репозитория

    git config

    Управляет настройками Git: имя пользователя, email, редактор, алиасы. Уровни: system, global, local.

    | Команда | Описание |
    |———|———-|
    | git config --list | Показать все действующие настройки |
    | git config --global user.name "Имя" | Задать глобальное имя |
    | git config --global user.email "email@example.com" | Задать глобальный email |
    | git config --get <key> | Показать значение ключа |
    | git config --global --edit | Редактировать глобальный конфиг |
    | git config --show-origin user.name | Показать, откуда взято значение |

    Примеры:

    git config --global user.name "Иван Иванов"
    git config --global user.email "i.ivanov@company.ru"
    

    > 🔒 БЕЗОПАСНОСТЬ:
    > Никогда не используйте личный email в корпоративных репозиториях — это может привести к утечке информации о сотрудниках (152-ФЗ, персональные данные). Для подписи коммитов используйте корпоративные сертификаты или GPG-ключи, привязанные к служебному адресу.

    git alias

    Создание сокращений для часто используемых команд.

    git config --global alias.co checkout
    git config --global alias.st status
    git config --global alias.last 'log -1 HEAD'
    

    2. Инициализация и клонирование

    git init

    Создаёт новый локальный репозиторий (папку .git).

    git init                     # в текущем каталоге
    git init my-project          # в указанном каталоге
    git init --bare              # голый репозиторий (без рабочего каталога)
    git init --initial-branch main
    

    git clone

    Клонирует удалённый репозиторий.

    git clone https://github.com/user/repo.git
    git clone --branch develop --single-branch <URL>
    git clone --depth 1 <URL>           # shallow clone (только последний коммит)
    git clone --recurse-submodules <URL>
    

    > 🔒 БЕЗОПАСНОСТЬ (MITRE T1195):
    > При клонировании чужих репозиториев проверяйте их на наличие вредоносных хуков или подмодулей. Используйте git clone --depth 1, если полная история не нужна — это снижает риск извлечения старых секретов из коммитов.

    3. Отслеживание изменений и управление

    git status

    Показывает состояние рабочего каталога и индекса.

    | Статус | Описание |
    |——–|———-|
    | Untracked | Новый файл, не отслеживаемый Git |
    | Modified | Изменённый отслеживаемый файл (не в индексе) |
    | Staged | Изменения добавлены в индекс |
    | Unmerged | Конфликт после слияния |

    git status
    git status -s   # короткий формат
    

    git add

    Добавляет изменения в индекс.

    git add file.txt
    git add .                     # все изменения в текущем каталоге
    git add -A                    # все изменения во всём репозитории
    git add -u                    # только изменённые/удалённые отслеживаемые файлы
    git add --patch               # интерактивное добавление частями
    

    > 🔒 БЕЗОПАСНОСТЬ:
    > Будьте осторожны с git add -f (force) — он может добавить игнорируемые файлы (например, .env с секретами). Всегда проверяйте git status перед добавлением.

    git diff

    Показывает различия.

    git diff                      # рабочий каталог vs индекс
    git diff --cached             # индекс vs последний коммит
    git diff HEAD                 # рабочий каталог vs последний коммит
    git diff HEAD~1..HEAD         # между двумя коммитами
    git diff --stat               # статистика изменений
    git diff --name-only          # только имена файлов
    

    git stash

    Временно прячет незакоммиченные изменения.

    git stash
    git stash save "WIP: feature X"
    git stash list
    git stash apply stash@{1}
    git stash pop
    git stash drop
    git stash clear
    git stash --include-untracked
    

    > 🔒 БЕЗОПАСНОСТЬ:
    > В стэше могут остаться пароли или токены, если вы их случайно добавили. Периодически очищайте стэш (git stash clear) на общих рабочих станциях. Согласно приказу ФСТЭК № 21, временные данные должны удаляться после использования.

    git commit

    Создаёт коммит из изменений в индексе.

    Структура коммита: хэш, дерево, родитель(и), автор, коммитер, дата, сообщение, опционально GPG-подпись.

    git commit -m "Add new feature"
    git commit -a -m "Auto-add tracked files"
    git commit --amend            # изменить последний коммит
    git commit --amend --no-edit
    git commit --signoff          # добавить Signed-off-by
    git commit --no-verify        # пропустить pre-commit хуки
    

    > 🔒 БЕЗОПАСНОСТЬ (MITRE T1565.001):
    > Всегда подписывайте коммиты (-S), если ваша политика безопасности требует подтверждения авторства. В российских государственных системах допускается использование только сертифицированных средств ЭП (ГОСТ 34.10-2012).
    > --no-verify отключает проверки безопасности — используйте только по согласованию с ИБ.

    git log

    Просмотр истории.

    git log
    git log --oneline -n 10
    git log --graph --all --decorate
    git log --author="Иван"
    git log --grep="security"
    git log --since="2025-01-01"
    git log -- path/to/file
    

    git show

    Показать информацию об объекте.

    git show abc1234
    git show v1.0.0
    git show --stat abc1234
    

    4. Управление ветками

    git branch

    git branch                 # список локальных веток
    git branch feature-branch  # создать ветку
    git branch -d feature-branch   # удалить (слитую)
    git branch -D feature-branch   # принудительно удалить
    git branch -m old new       # переименовать
    git branch -a               # все ветки (включая удалённые)
    git branch --merged         # ветки, которые уже слиты
    

    git checkout / git switch

    Переключение между ветками.

    git checkout main
    git checkout -b new-feature
    git checkout -- file.txt   # откатить файл до последнего коммита
    

    > 🔒 БЕЗОПАСНОСТЬ:
    > git checkout -- . откатит все незакоммиченные изменения без возможности восстановления. Убедитесь, что вы не потеряли важные правки. Используйте git stash перед опасными операциями.

    git switch (новый синтаксис):

    git switch main
    git switch -c new-branch
    git switch --detach abc1234
    

    git merge

    Слияние веток.

    git merge feature-branch
    git merge --no-ff feature-branch   # всегда создавать merge-коммит
    git merge --ff-only                # только fast-forward
    git merge --squash feature-branch  # "сквош" всех коммитов в один
    git merge --abort                  # отменить слияние при конфликтах
    

    > 🔒 БЕЗОПАСНОСТЬ:
    > Запретите git merge --squash на критических ветках без ревью — это скрывает детальную историю изменений, что затрудняет аудит (нарушает ГОСТ Р 57580.1). Всегда используйте --no-ff для веток, связанных с КИИ.

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

    git remote

    git remote -v
    git remote add origin https://github.com/user/repo.git
    git remote remove origin
    git remote set-url origin git@github.com:user/repo.git  # переключение на SSH
    git remote show origin
    

    > 🔒 БЕЗОПАСНОСТЬ (187-ФЗ, приказ ФСТЭК № 239):
    > Используйте SSH вместо HTTPS для аутентификации на корпоративных Git-серверах. SSH-ключи должны быть длиной не менее 3072 бит и храниться на токенах (HSM). Доступ по паролю должен быть отключён.

    git pull

    git pull origin main
    git pull --rebase          # перебазирование вместо слияния
    git pull --ff-only         # только fast-forward (безопаснее)
    git pull --autostash       # автоматически применить stash
    

    git push

    git push origin main
    git push --force           # ОПАСНО! перезаписывает историю
    git push --force-with-lease # более безопасный force push (проверяет состояние)
    git push --delete origin old-branch
    git push --tags
    git push --set-upstream origin feature
    

    > 🔒 БЕЗОПАСНОСТЬ (MITRE T1565, Defense Evasion):
    > git push --force уничтожает историю и может быть использован злоумышленником для сокрытия следов. Запретите force push на защищённых ветках (main, release) через политику сервера.
    > В системах КИИ каждый push должен логироваться и проходить контроль целостности.

    git fetch

    git fetch origin
    git fetch --prune         # удалить локальные ссылки на удалённые ветки, которых больше нет
    git fetch --tags
    

    6. Теги

    git tag

    git tag                     # список тегов
    git tag v1.0.0              # легковесный тег
    git tag -a v1.0.0 -m "Release v1.0.0"   # аннотированный
    git tag -d v1.0.0
    git push origin v1.0.0
    git push --tags
    

    > 🔒 БЕЗОПАСНОСТЬ (целостность поставки):
    > Подписывайте теги релизов git tag -s v1.0.0 (GPG). Это позволяет верифицировать, что релиз создан авторизованным лицом. Соответствует требованию 187-ФЗ о защите КИИ от подмены артефактов.

    7. Логи и история изменений

    git blame

    git blame main.py
    git blame -L 10,20 main.py
    git blame -C                  # искать копирования внутри файла
    

    Используется для выяснения, кто внёс уязвимый код.

    git reflog

    Журнал ссылок — показывает все перемещения HEAD, веток, тегов.

    git reflog
    git reflog main
    git reflog --since=2.weeks.ago
    

    > 🔒 БЕЗОПАСНОСТЬ (расследование инцидентов):
    > git reflog — ключевой инструмент для обнаружения несанкционированного переписывания истории. При подозрении на взлом выполните git reflog | grep -E "reset|rebase|amend". В соответствии с приказом ФСТЭК № 21 (п. 15), reflog должен храниться не менее 1 года.

    8. Восстановление и отмена изменений

    git reset

    git reset --soft HEAD~1    # откатить коммит, но оставить изменения в индексе
    git reset --mixed HEAD~1   # откатить коммит и снять с индекса (по умолчанию)
    git reset --hard HEAD~1    # ПОЛНОСТЬЮ УДАЛИТЬ коммит и изменения (необратимо)
    

    > 🔒 БЕЗОПАСНОСТЬ:
    > git reset --hard уничтожает незакоммиченные данные. Никогда не используйте его без предварительного git stash. В случае срабатывания политики ИБ — оповестите администратора.

    git restore (новый синтаксис)

    git restore file.txt            # откатить рабочий каталог
    git restore --staged file.txt   # убрать из индекса
    git restore --source=HEAD~2 file.txt
    

    9. Rebase (перебазирование)

    git rebase main
    git rebase -i HEAD~3            # интерактивный rebase (изменение истории)
    git rebase --continue
    git rebase --abort
    

    > 🔒 БЕЗОПАСНОСТЬ (MITRE T1565):
    > Rebase переписывает историю коммитов — это может быть использовано для удаления записей о вредоносных изменениях. Запретите rebase для уже опубликованных веток (main, develop). В корпоративной политике должно быть указано, что rebase разрешён только в локальных ветках.

    10. Submodules

    git submodule add https://github.com/user/lib.git lib/
    git submodule update --init --recursive
    git submodule foreach 'git checkout main'
    

    > 🔒 БЕЗОПАСНОСТЬ (MITRE T1195.001):
    > Подмодули — это риск цепочки поставок. Всегда проверяйте хэши коммитов, на которые ссылаются подмодули. Настройте git submodule absorbgitdirs для безопасного перемещения.

    11. Другие полезные команды

    git cherry-pick

    git cherry-pick abc1234
    git cherry-pick abc1234..def5678
    git cherry-pick --continue
    

    git bisect

    git bisect start
    git bisect bad HEAD
    git bisect good v1.0.0
    # Git переключает коммиты, вы помечаете good/bad
    git bisect reset
    

    > 🔒 БЕЗОПАСНОСТЬ (анализ уязвимостей):
    > git bisect помогает быстро найти коммит, который внёс уязвимость. Это соответствует ГОСТ Р 57580.1 в части управления инцидентами.

    —

    Дополнительный раздел: Безопасность Git в российском правовом поле

    В дополнение к оригинальной статье, ниже приведены обязательные меры для организаций, работающих с персональными данными (152-ФЗ), критической инфраструктурой (187-ФЗ) или государственными информационными системами.

    | Требование | Реализация в Git | Нормативный акт |
    |————|——————|—————–|
    | Контроль целостности | Подписанные коммиты (GPG, ГОСТ) | Приказ ФСТЭК № 21 (СОВ) |
    | Защита от утечек | Pre-commit хуки с поиском секретов (gitleaks) | 152-ФЗ, ст. 19 |
    | Аудит действий | Логирование всех push, force push, branch delete на сервере | 187-ФЗ, ст. 13 |
    | Разграничение доступа | Роли: читатель, автор, мейнтейнер. Запрет прямого push в main | ГОСТ Р 57580.1 |
    | Резервное копирование | Ежедневное копирование репозиториев на изолированный носитель | 187-ФЗ, п. 7 |

    Рекомендуемые инструменты для аудита:

  • gitleaks, trufflehog — поиск секретов.
  • git log --grep — поиск подозрительных паттернов.
  • git fsck — проверка целостности объектов.
  • Серверные решения: GitLab Audit Events, Bitbucket Server Logs.

—

Что пропущено? Дальнейшие темы по безопасности

Данная статья (перевод с дополнениями) охватывает основы Git и базовые меры безопасности. Однако полноценная защита Git-инфраструктуры требует изучения следующих тем:

1. Безопасная настройка Git-сервера (GitLab/Gitea/Bitbucket) с аттестацией ФСТЭК.
2. Использование ГОСТ-алгоритмов для подписи коммитов (замена GPG на КриптоПро).
3. Интеграция Git с SIEM-системами (MaxPatrol, ArcSight) для централизованного сбора событий.
4. Продвинутые техники очистки истории (git filter-repo, BFG) при утечках секретов.
5. Политика безопасности для Git Hooks (запуск статического анализа, SAST).
6. MITRE ATT&CK для Git: детальное картирование тактик (Exfiltration, Persistence, Command and Control).