git diff
Сравнение — это функция, анализирующая два входных набора данных и отображающая различия между ними. git diff
представляет собой многоцелевую команду Git, которая инициирует функцию сравнения источников данных Git — коммитов, веток, файлов и т. д. В этом документе описываются типичные варианты вызова git diff
и схемы рабочего процесса сравнения. Зачастую вместе с командой git diff
используются git status
и git log
для анализа текущего состояния репозитория Git.
Чтение вывода команды diff
Формат вывода необработанных данных
Следующие примеры будут выполнены в простом репозитории. Репозиторий создается с помощью перечисленных ниже команд:
$:> mkdir diff_test_repo
$:> cd diff_test_repo
$:> touch diff_test.txt
$:> echo "this is a git diff test example" > diff_test.txt
$:> git init .
Initialized empty Git repository in /Users/kev/code/test/.git/
$:> git add diff_test.txt
$:> git commit -am"add diff test file"
[main (root-commit) 6f77fc3] add diff test file
1 file changed, 1 insertion(+)
create mode 100644 diff_test.txt
Если выполнить git diff
на этом этапе, команда ничего не выведет. Это ожидаемая ситуация, поскольку в репозитории отсутствуют изменения для сравнения. После создания репозитория и добавления файла diff_test.txt
можно отредактировать его содержимое и поэкспериментировать с выходными данными команды сравнения.
Связанные материалы
git branch
СМ. РЕШЕНИЕ
Изучите Git с помощью Bitbucket Cloud
$:> echo "this is a diff example" > diff_test.txt
При выполнении этой команды содержимое файла diff_test.txt
будет изменено. После этого можно просмотреть изменения и проанализировать выходные данные. Теперь при выполнении git diff
мы получим следующие выходные данные:
diff --git a/diff_test.txt b/diff_test.txt
index 6b0c6cf..b37e70a 100644
--- a/diff_test.txt
+++ b/diff_test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example
А теперь подробно рассмотрим выходные данные сравнения.
1. Входные данные сравнения
diff --git a/diff_test.txt b/diff_test.txt
В этой строке отображаются входные данные сравнения. Как видите, для сравнения переданы файлы a/diff_test.txt
и b/diff_test.txt
.
2. Метаданные
index 6b0c6cf..b37e70a 100644
В этой строке отображаются внутренние метаданные Git. Скорее всего, они вам не понадобятся. Номера в этих выходных данных соответствуют хеш-идентификаторам версий объектов Git.
3. Маркеры изменений
--- a/diff_test.txt
+++ b/diff_test.txt
Эти строки представляют собой легенду обозначений для каждого источника входных данных сравнения. В данном случае изменения из файла a/diff_test.txt
помечаются символом ---
, а из файла b/diff_test.txt
— символом +++
.
4. Сравниваемые фрагменты
Остальные выходные данные сравнения — это список сравниваемых фрагментов. При сравнении отображаются только разделы файла, в которых есть изменения. В данном примере имеется только один такой фрагмент, поскольку обрабатывается простой сценарий. Фрагменты имеют собственную ограниченную семантику вывода.
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example
Первая строка — это заголовок фрагмента. К началу каждого фрагмента добавляется заголовок, окруженный символами @@
. Заголовок кратко описывает изменения в файле. В нашем простом примере заголовок -1 +1 означает, что имеются изменения в первой строке. В реальных случаях заголовок может выглядеть так:
@@ -34,6 +34,8 @@
В данном примере заголовка было извлечено 6 строк начиная со строки 34. Кроме того, после строки 34 было добавлено 8 строк.
Остальное содержимое фрагмента сравнения — это недавние изменения. Каждой измененной строке предшествует символ +
или -
, указывающий на источник входных данных сравнения. Как уже упоминалось, символ -
указывает на изменения в файле a/diff_test.txt
, а + — на изменения в файле b/diff_test.txt
.
Подсветка изменений
1. git diff --color-words
Кроме того, команда git diff
имеет специальный режим подсветки изменений с повышенной детализацией: ‐‐color-words
. В этом режиме добавленные и удаленные строки отделяются пробелами, а затем выполняется их сравнение.
$:> git diff --color-words
diff --git a/diff_test.txt b/diff_test.txt
index 6b0c6cf..b37e70a 100644
--- a/diff_test.txt
+++ b/diff_test.txt
@@ -1 +1 @@
this is agit difftest example
Теперь в выходных данных отображаются только измененные слова с цветовой подсветкой.
2. git diff-highlight
При клонировании источника Git появляется подкаталог с именем contrib. Он содержит набор связанных с Git инструментов и различные данные, которые пока еще не были включены в ядро Git. В их число входит скрипт Perl под названием diff-highlight. Diff-highlight попарно сопоставляет совпадающие строки выходных данных сравнения и подсвечивает измененные фрагменты внутри слов.
$:> git diff | /your/local/path/to/git-core/contrib/diff-highlight/diff-highlight
diff --git a/diff_test.txt b/diff_test.txt
index 6b0c6cf..b37e70a 100644
--- a/diff_test.txt
+++ b/diff_test.txt
@@ -1 +1 @@
-this is a git diff test example
+this is a diff example
Теперь сравниваемые строки объединены в пары для определения наименьших возможных изменений.
Сравнение двоичных файлов
Наряду с описанными возможностями обработки текстовых файлов команда git diff
может работать с двоичными файлами. К сожалению, в этом случае использовать формат вывода по умолчанию не слишком продуктивно.
$:> git diff
Binary files a/script.pdf and b/script.pdf differ
В Git есть функция, с помощью которой можно указать команду оболочки для преобразования содержимого двоичных файлов в текст до начала сравнения. Для этого потребуется выполнить небольшую настройку. Для начала необходимо указать фильтр textconv, описывающий процесс преобразования определенного типа двоичного файла в текст. В данном случае используется простой инструмент pdftohtml (доступный в Homebrew), который позволяет преобразовывать файлы PDF в удобный для восприятия формат HTML. Его можно назначить отдельному репозиторию в файле .git/config
или глобально в файле ~ /.gitconfig
[diff "pdfconv"]
textconv=pdftohtml -stdout
Затем необходимо связать с фильтром pdfconv один или несколько шаблонов файлов. Для этого необходимо создать файл .gitattributes
в корневом каталоге репозитория.
*.pdf diff=pdfconv
После настройки команда git diff
сначала обрабатывает двоичный файл с помощью настроенного скрипта конвертера, а затем выполняет сравнение выходных данных конвертера. Этот метод можно использовать для эффективного сравнения любых двоичных файлов, например ZIP, JAR и других архивов. Используя инструмент unzip -l
(или аналогичный) вместо pdf2html, можно просмотреть, какие пути были добавлены в коммит или удалены из него по сравнению с другим коммитом. Утилиту exiv2 можно использовать для просмотра изменений метаданных, например размеров изображения. Существуют инструменты для преобразования .odf, .doc и других форматов документов в простой текст. В крайнем случае команда может работать с двоичными файлами, для которых формальных конвертеров не существует.
Сравнение файлов: файл git diff
В команде git diff
можно указать явный путь к файлу. Если в git diff
указан путь к файлу, выполняется сравнение этого файла. Более подробно этот процесс показан на примерах ниже.
git diff HEAD ./path/to/file
В этом примере выполняется сравнение для файла ./path/to/file
. Рабочий каталог сравнивается с разделом проиндексированных файлов и выводятся изменения, которые еще не были проиндексированы. По умолчанию git diff
выполняет сравнение с HEAD
. Если опустить аргумент HEAD
в приведенном выше примере и выполнить команду git diff ./path/to/file
, это не повлияет на результат.
git diff --cached ./path/to/file
При вызове git diff
с использованием параметра --cached
сравниваются проиндексированные изменения и локальный репозиторий. Параметр --cached
синонимичен параметру --staged
.
Сравнение всех изменений
При вызове git diff
без указания пути к файлу выполняется сравнение всех изменений в репозитории. Команды из приведенных выше примеров можно вызвать без аргумента ./path/to/file
и получить аналогичные результаты для всех файлов в локальном репозитории.
Изменения после последнего коммита
По умолчанию команда git diff
выводит все неподтвержденные изменения, внесенные после последнего коммита.
git diff
Сравнение файлов в двух коммитах
Команде git diff
можно передать ссылки на коммиты Git для сравнения. Возможные варианты ссылок — HEAD
, теги и имена веток. Каждый коммит в Git имеет идентификатор, который можно получить с помощью команды git log
. Этот идентификатор коммита тоже можно передать в git diff
.
git log --pretty=oneline
957fbc92b123030c389bf8b4b874522bdf2db72c add feature
ce489262a1ee34340440e55a0b99ea6918e19e7a rename some classes
6b539f280d8b0ec4874671bae9c6bed80b788006 refactor some code for feature
646e7863348a427e1ed9163a9a96fa759112f102 add some copy to body
$:> git diff 957fbc92b123030c389bf8b4b874522bdf2db72c ce489262a1ee34340440e55a0b99ea6918e19e7a
Сравнение веток
Сравнение двух веток
Ветки сравниваются с помощью команды git diff
точно так же, как любые другие входные ссылки.
git diff branch1..other-feature-branch
В этом примере демонстрируется оператор точка. Две точки показывают, что сравниваются последние коммиты двух веток. Тот же результат можно получить, если опустить точки и поставить пробел между именами веток. Кроме того, можно использовать трехточечный оператор:
git diff branch1...other-feature-branch
Оператор «три точки» инициирует сравнение путем изменения первого параметра ввода branch1
. Параметр branch1
преобразуется в ссылку на родительский коммит, общий для двух входных объектов сравнения. Это общий предок ветки branch1
и другой функциональной ветки. Последний параметр ввода остается без изменений — это последний коммит другой функциональной ветки.
Сравнение файлов из двух веток
Чтобы сравнить конкретный файл в разных ветках, передайте команде git diff
путь к файлу в качестве третьего аргумента.
git diff main new_branch ./diff_test.txt
Резюме
На этой странице были рассмотрены процесс сравнения в Git и команда git diff
. Мы объяснили, как читать вывод команды git diff
и различные виды выходных данных. В примерах было показано, как изменить выходные данные git diff
с помощью подсвечивания и использования цветов. Кроме того, были рассмотрены различные стратегии сравнения, например сравнение файлов в разных ветках и конкретных коммитах. Наряду с git diff
также использовались команды git log
и git checkout
.
Поделитесь этой статьей
Следующая тема
Рекомендуемые статьи
Добавьте эти ресурсы в закладки, чтобы изучить типы команд DevOps или получать регулярные обновления по DevOps в Atlassian.