W3docs

git diff

On this page you will find useful information about git diff command and its outputs, as well as learn to highlight changes and compare files.

Описание

Команда git diff используется для сравнения изменений между коммитами, рабочей директорией и областью индексации (staging area). Она принимает два набора входных данных и выводит различия между ними. Обычно она используется в сочетании с командами git status и git log для анализа состояния git-репозитория.

gitdiff

Вывод diff

Результаты сравнения могут иметь несколько форматов, которые будут рассмотрены ниже.

Формат сырого вывода

Посмотрите на команды ниже для создания простого репозитория:

git diff

mkdir test_repo
cd test_repo
touch test.txt
echo "this is a git diff test example" > test.txt
git init .
#Initialized empty Git repository in /Users/kev/code/test/.git/
git add test.txt
git commit -am "add diff test file"
#[master (root-commit) 9e2dcac] add diff test file
#1 file changed, 1 insertion(+)
#create mode 100644 test.txt

Чтобы git diff вывел результат, необходимо изменить содержимое файла test.txt после добавления его в созданный репозиторий. Это можно сделать, выполнив следующую команду:

git diff

echo "this is a diff example" > test.txt

Только теперь мы можем просмотреть diff и обсудить вывод. Выполнение git diff даст следующий результат:

git diff

diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

Источники ввода для diff

Ниже показано входное сравнение для diff. В результате a/test.txt и b/test.txt будут переданы в diff.

git diff

diff --git a/test.txt b/test.txt

Метаданные

Эта строка показывает некоторые внутренние метаданные Git. Числа в этом выводе соответствуют идентификаторам хешей версий объектов Git.

git diff

index 6b0c6cf..b37e70a 100644

Символы изменений

Эти строки показывают символы, назначенные каждому источнику ввода diff. Изменения из a/test.txt отмечены знаком ---, а изменения из b/test.txt отмечены знаком +++.

git diff

--- a/test.txt
+++ b/test.txt

Чанки diff

Diff не показывает весь файл целиком. Он отображает только изменённые строки. Эта изменённая часть называется «чанком» (chunk). Преимущество чанков в том, что они показывают строки до и после изменений, что позволяет лучше понять контекст модификаций.

git diff

@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

Первая строка — это заголовок чанка. Каждый чанк начинается с заголовка, заключённого в символы @@. Изменения, внесённые в файл, суммируются в этом заголовке.

Распространённые флаги

Git предоставляет несколько полезных флагов для различных рабочих процессов:

  • --staged (или --cached): Сравнивает изменения в индексе с коммитом HEAD.
  • --stat: Показывает сжатое сводное представление изменённых файлов вместо полного diff.
  • --name-only: Выводит только имена изменённых файлов.

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

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

git diff --color-words

Первый способ подсветки изменений — это специальный режим, предлагаемый git diff: --color-words. Он разбивает добавленные и удалённые строки на токены по пробельным символам, а затем сравнивает их.

git diff

git diff --color-words
diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

(Примечание: --color-words подсвечивает встроенные изменения с помощью цветов терминала. В обычном текстовом формате вывод соответствует стандартному diff.)

git diff-highlight

При клонировании исходного кода Git будет найдена поддиректория с именем contrib. Эта поддиректория содержит инструменты, связанные с Git. Один из этих инструментов называется diff-highlight. Он подсвечивает изменённые части слов. Обратите внимание, что этот инструмент фильтрует стандартный ввод и требует включения цветов в терминале для отображения.

git diff

git diff | git diff-highlight
diff --git a/test.txt b/test.txt
index 6b0c6cf..b37e70a 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example

Сравнение бинарных файлов

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

git diff

git diff
Binary files a/script.pdf and b/script.pdf differ

В Git есть функция, позволяющая указать команду оболочки для преобразования содержимого бинарных файлов в текст перед выполнением diff. Однако может потребоваться небольшая настройка. Прежде всего, вам следует определить фильтр textconv с описанием способа преобразования определённого типа бинарных файлов в текст. Например, вы можете использовать простую утилиту pdftohtml (доступную через Homebrew) для преобразования PDF в HTML. Есть два способа настройки: путём редактирования файла .git/config или глобально, путём редактирования .gitconfig.

git diff

[diff "pdfconv"]
textconv=pdftohtml -stdout

Затем вам нужно связать один или несколько шаблонов файлов с фильтром pdfconv, что можно сделать, создав файл .gitattributes в корне репозитория.

git diff

*.pdf diff=pdfconv

После настройки git diff сначала запустит бинарный файл через настроенный скрипт конвертера и выполнит diff вывода конвертера. Используя тот же подход, вы также можете получать полезные diff для всех типов бинарных файлов (zip, jar и других архивов).

Сравнение файлов: git diff file

Команда git diff также имеет явную опцию указания пути к файлу. Операция git diff обработает конкретный файл, как только ему будет передан путь к файлу. В примере ниже аргумент ./path/to/file сравнит изменения в рабочей директории с коммитом HEAD.

git diff

git diff HEAD ./path/to/file

Сравнение всех изменений

Чтобы сравнить изменения во всём репозитории, следует запустить git diff без указания пути к файлу. Таким образом, вы можете вызвать примеры выше без аргумента ./path/to/file и получить одинаковые результаты для всех файлов в локальном репозитории.

Изменения с последнего коммита

По умолчанию git diff сравнивает рабочую директорию с областью индексации (индексом). Чтобы увидеть все неизменённые изменения с момента последнего коммита:

git diff

git diff

Сравнение файлов между двумя коммитами

Команде git diff можно передать ссылки Git (refs), такие как имена хвостов (heads), тегов и веток. Каждый коммит в Git имеет уникальный идентификатор, который можно найти, выполнив git log. Вы также можете передать два идентификатора коммитов для их прямого сравнения:

git diff

git diff <commit-hash-1> <commit-hash-2>

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

Сравнение веток выполняется аналогично другим ссылкам (refs), передаваемым в git diff. Давайте рассмотрим примеры с оператором точек:

git diff

git diff branch1..branch2

Две точки в примере выше показывают, что входными данными для diff являются концы (tips) обеих веток. Вы получите тот же результат, если опустить точки и использовать пробел между ветками. Кроме того, существует оператор с тремя точками:

git diff

git diff branch1...branch2

Оператор с тремя точками изменяет первый входной параметр branch1, инициирующий diff. Он преобразует branch1 в ссылку на общий коммит-предок для двух входных данных diff. Последний входной параметр остаётся таким же, как конец ветки branch2.

Сравнение файлов из двух веток

Чтобы сравнить конкретный файл в ветках, следует передать путь к файлу в качестве третьего аргумента для git diff:

git diff

git diff master new_branch ./test.txt

Практика

Практика

Какие функциональные возможности и опции есть у команды 'git diff'?