git basic

git diff

Показать изменения между коммитами, индексом и рабочим деревом

Описание

git diff показывает разницу между двумя состояниями в формате unified diff (строки, начинающиеся с -, — удалены; с + — добавлены). Команда может сравнивать: рабочее дерево с индексом, индекс с последним коммитом, два произвольных коммита, две ветки, файл в разных состояниях и многое другое.

Понимание «трёх деревьев» Git (рабочее дерево, индекс, HEAD) критично для правильного использования git diff. Без аргументов команда показывает изменения, которые ещё не добавлены в индекс. Флаг --cached (или --staged) показывает, что уже добавлено в индекс и войдёт в следующий коммит.

git diff также умеет показывать только статистику (--stat), список имён изменённых файлов (--name-only), игнорировать изменения пробелов (-w) и выводить diff в различных форматах для интеграции с другими инструментами.

Синтаксис

git diff [ОПЦИИ] [<коммит>] [--] [<путь>…] git diff [ОПЦИИ] <коммит> <коммит> [--] [<путь>…] git diff [ОПЦИИ] <blob> <blob>

Ключевые варианты вызова и что они показывают:

# Рабочее дерево vs индекс (unstaged изменения) git diff # Индекс vs HEAD (staged изменения — войдут в коммит) git diff --cached git diff --staged # синоним --cached # Рабочее дерево vs HEAD (все изменения) git diff HEAD # Между двумя коммитами git diff abc1234 def5678 # Между ветками git diff main feature # Изменения только в одном файле git diff -- src/auth.py # Что изменилось с тега v1.0 git diff v1.0 HEAD

Флаги и опции

ФлагОписание
--cached / --stagedСравнить индекс с HEAD (staged изменения). Показывает то, что войдёт в следующий коммит.
--statПоказать только статистику: имена файлов, количество вставок и удалений, итог. Без самого diff.
--shortstatТолько итоговая строка статистики (N files changed, M insertions, K deletions).
--name-onlyПоказать только имена изменённых файлов.
--name-statusИмена файлов с кодами изменений (A/M/D/R/C).
-w / --ignore-all-spaceИгнорировать все изменения пробелов и отступов.
-b / --ignore-space-changeИгнорировать изменения количества пробелов (не игнорировать добавление/удаление пробелов полностью).
--ignore-blank-linesИгнорировать изменения, состоящие только из пустых строк.
-U <n> / --unified=<n>Показывать N строк контекста вокруг каждого изменения (по умолчанию 3). -U0 — только изменённые строки без контекста.
--word-diffПоказать diff на уровне слов, а не строк. Режимы: color, plain, porcelain, none.
--color-wordsКороткий вариант для --word-diff=color. Удобен для документации и конфигурационных файлов.
-M / --find-renames[=<n>%]Определять переименования файлов. Порог схожести — процент совпадающего содержимого (по умолчанию 50%).
-C / --find-copiesОпределять копирования файлов (аналогично -M, но для копий).
--diff-filter=<фильтр>Показывать только файлы с определёнными статусами: A (Added), M (Modified), D (Deleted), R (Renamed) и т.д.
--binaryПоказывать diff для бинарных файлов в base85-кодировке (применим для патчей).
--output=<файл>Записать diff в файл вместо вывода в stdout.

Паттерны использования

Проверка перед коммитом

# 1. Что изменилось (ещё не в индексе)?
git diff

# 2. Что добавлено в индекс (войдёт в коммит)?
git diff --cached

# 3. Итоговая статистика
git diff --cached --stat

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

# Что изменилось в feature по сравнению с main?
git diff main..feature

# Только список изменённых файлов
git diff main..feature --name-only

# Только добавленные файлы
git diff main..feature --name-status --diff-filter=A

Diff отдельного файла

# Unstaged изменения в конкретном файле
git diff -- src/models/user.py

# Staged изменения в файле
git diff --cached -- src/models/user.py

# Файл в двух коммитах
git diff HEAD~3 HEAD -- README.md

Игнорировать форматирование

# Исправили только отступы — не показывать как изменение
git diff -w

# Слияние с игнорированием пробелов
git merge -Xignore-all-space feature

# Diff только по смыслу, не по пробелам
git diff --ignore-blank-lines --ignore-space-change

Diff на уровне слов (для текста)

# Подсветить изменённые слова (не строки)
git diff --color-words

# Для документации — читабельнее
git diff --word-diff=plain docs/README.md

# Показать diff прямо в git log
git log -p --color-words -1

Сохранить diff в файл / применить патч

# Сохранить staged изменения как патч
git diff --cached > my-changes.patch

# Применить патч к другому репозиторию
git apply my-changes.patch

# Создать набор патчей из коммитов (для email)
git format-patch main..feature

Советы и подводные камни

Совет: настройте внешний difftool
Для графического сравнения используйте git difftool. Установите предпочитаемый инструмент:
git config --global diff.tool vscode
git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE'
Запускайте: git difftool вместо git diff. Также работают: vimdiff, meld, kdiff3, Beyond Compare.
Совет: --staged — синоним --cached, оба правильны
git diff --cached и git diff --staged — абсолютно одинаковы. --staged появился позже как более читаемая альтернатива. Используйте тот, что удобнее. В скриптах предпочтительнее --cached для совместимости со старыми версиями Git.
Внимание: git diff без аргументов не показывает staged изменения
Распространённая ошибка: сделали git add, потом git diff — файл не показывается. Это потому что git diff без --cached сравнивает рабочее дерево с индексом, а не с HEAD. После git add рабочее дерево и индекс совпадают, поэтому diff пустой. Используйте git diff --cached для просмотра staged изменений.