git diff
Показать изменения между коммитами, индексом и рабочим деревом
Описание
git diff показывает разницу между двумя состояниями в формате unified diff (строки, начинающиеся с -, — удалены; с + — добавлены). Команда может сравнивать: рабочее дерево с индексом, индекс с последним коммитом, два произвольных коммита, две ветки, файл в разных состояниях и многое другое.
Понимание «трёх деревьев» Git (рабочее дерево, индекс, HEAD) критично для правильного использования git diff. Без аргументов команда показывает изменения, которые ещё не добавлены в индекс. Флаг --cached (или --staged) показывает, что уже добавлено в индекс и войдёт в следующий коммит.
git diff также умеет показывать только статистику (--stat), список имён изменённых файлов (--name-only), игнорировать изменения пробелов (-w) и выводить diff в различных форматах для интеграции с другими инструментами.
Синтаксис
Ключевые варианты вызова и что они показывают:
Флаги и опции
| Флаг | Описание |
|---|---|
--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
Советы и подводные камни
Для графического сравнения используйте
git difftool. Установите предпочитаемый инструмент:git config --global diff.tool vscodegit config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE'Запускайте:
git difftool вместо git diff. Также работают: vimdiff, meld, kdiff3, Beyond Compare.
git diff --cached и git diff --staged — абсолютно одинаковы. --staged появился позже как более читаемая альтернатива. Используйте тот, что удобнее. В скриптах предпочтительнее --cached для совместимости со старыми версиями Git.
Распространённая ошибка: сделали
git add, потом git diff — файл не показывается. Это потому что git diff без --cached сравнивает рабочее дерево с индексом, а не с HEAD. После git add рабочее дерево и индекс совпадают, поэтому diff пустой. Используйте git diff --cached для просмотра staged изменений.