Git сравнить 2 файла

Обновлено: 04.07.2024

Во время разработки программистам часто приходится останавливаться и анализировать изменения, которые они сделали с последнего коммита. Потребность смотреть изменения становится очевидной, если представить себе, что такое работа над реальным проектом. Как правило, это тысячи (десятки и сотни тысяч) строк кода, сотни и тысячи файлов и иногда несколько дней работы. Потратив даже несколько часов в таком проекте, очень сложно вспомнить что и где менялось, а что ещё осталось поменять.

Анализировать изменения важно даже в небольших проектах. Прямо сейчас во время разработки этого курса изменилось несколько файлов и git status выглядит так:

Попробуем воспроизвести подобную ситуацию в нашем проекте. Выполним следующий код в репозитории hexlet-git:

Изменились оба файла. В один мы добавили строчку, в другом заменили. Как теперь посмотреть эти изменения? Для этого в git есть команда git diff , которая показывает разницу между тем, что было и что стало:

hexlet-git $ git diff diff --git a/INFO.md b/INFO.md index d5225f8..40f51f1 100644 --- a/INFO.md +++ b/INFO.md @@ -1 +1,2 @@ git is awesome! +new line diff --git a/README.md b/README.md index ffe7ece..00fd294 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -Hello , Hexlet! +Hello, Hexlet! How are you?

Вывод команды поначалу может смутить. Здесь довольно много служебных данных, за которыми уже идут изменения. git diff выводит именно те строки, которые изменились (и иногда строки вокруг измененных для удобства анализа), а не файлы целиком. Слева от них ставится знак "-", если строка была удалена, и "+" для добавленных строк.

Сама команда не просто выводит на экран разницу между файлами, но и запускает пейджер — специальную программу, которая позволяет перемещаться по выводу и искать внутри него нужные данные. Для перемещения вниз по дифу нужно нажать f , для перемещения наверх — u Для выхода из режима просмотра нажмите q .

По умолчанию git diff показывает изменения только для тех модифицированных файлов, которые ещё не были добавлены в индекс. Подразумевается, что добавленные в индекс файлы смотреть не нужно, ведь мы их уже подготовили к коммиту. В реальности же часто хочется и, более того, нужно увидеть эти изменения. Для этого нужно запустить команду вывода дифа с флагом --staged :

git diff

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

Команда выводит изменения в файлах, которые еще не были добавлены в индекс. Сравнение происходит с последним коммитом.

Сравнение с последним коммитом, включая файлы в индексе

Если вы изменили какие-нибудь файлы в вашем рабочем каталоге и добавили один или несколько из них в индекс (с помощью git add ), то команда git diff не покажет изменения в этих файлах. Чтобы показать изменения в файлах, включая файлы, добавленные в индекс, используется ключ --cached :

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

Команда git diff позволяет сравнивать два различных коммита. Сначала нужно определить хеш (ID) коммитов, которые требуется сравнивать. Можно воспользоваться командой git log, чтобы вывести список коммитов и их идентификаторы:

Теперь сравним два коммита. Для этого в качестве первого аргумента команде git diff указывается хеш первого коммита, а вторым аргументом хеш второго коммита, например:

Сравнение двух веток

Для вывода всех изменений между концами двух веток, необходимо для git diff указать имена веток:

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

Чтобы сравнить конкретные файлы между двумя ветками используется команда:

Вместо branch1, branch2 нужно указать название веток, а вместо myfile.cpp путь до сравниваемого файла. Через пробел можно добавить еще файлы для сравнения.

Исключить некоторые файлы из сравнения

Иногда нужно выполнить git diff , но исключить один или несколько файлов, чтобы команда git diff их проигнорировала. Для этого используется запись вида ’:(exclude)имя_файла’ или короткая запись ’:!имя_файла’

Или более короткая запись:

Сравнивать только изменения в файлах (игнорировать новые и удаленные файлы)

Чтобы исключить из сравнения новые и удаленные файлы, можно воспользоваться опцией --diff-filter , которая позволяет выбирать какие именно изменения (файлы) нужно сравнивать.

Чтобы выполнить сравнение только изменений внутри файлов (игнорируя новые, удаленные, переименованные файлы) используется ключ Modified (M) — --diff-filter=M :

Сравнение — это функция, анализирующая два входных набора данных и отображающая различия между ними. git diff представляет собой многоцелевую команду Git, которая инициирует функцию сравнения источников данных Git — коммитов, веток, файлов и т. д. В этом документе описываются типичные варианты вызова git diff и схемы рабочего процесса сравнения. Зачастую вместе с командой git diff используются git status и git log для анализа текущего состояния репозитория Git.

Чтение вывода команды diff

Формат вывода необработанных данных

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

Если выполнить git diff на этом этапе, команда ничего не выведет. Это ожидаемая ситуация, поскольку в репозитории отсутствуют изменения для сравнения. После создания репозитория и добавления файла diff_test.txt можно отредактировать его содержимое и поэкспериментировать с выходными данными команды сравнения.

При выполнении этой команды содержимое файла diff_test.txt будет изменено. После этого можно просмотреть изменения и проанализировать выходные данные. Теперь при выполнении git diff мы получим следующие выходные данные:

А теперь подробно рассмотрим выходные данные сравнения.

В этой строке отображаются входные данные сравнения. Как видите, для сравнения переданы файлы a/diff_test.txt и b/diff_test.txt .

2. Метаданные

В этой строке отображаются внутренние метаданные Git. Скорее всего, они вам не понадобятся. Номера в этих выходных данных соответствуют хеш-идентификаторам версий объектов Git.

3. Маркеры изменений

Эти строки представляют собой легенду обозначений для каждого источника входных данных сравнения. В данном случае изменения из файла a/diff_test.txt помечаются символом --- , а из файла b/diff_test.txt — символом +++ .

4. Сравниваемые фрагменты

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

Первая строка — это заголовок фрагмента. К началу каждого фрагмента добавляется заголовок, ограниченный символами @@ . Заголовок кратко описывает изменения в файле. В нашем простом примере заголовок -1 +1 означает, что имеются изменения в первой строке. В реальных случаях заголовок может выглядеть так:

В данном примере заголовка было извлечено 6 строк начиная со строки 34. Кроме того, после строки 34 было добавлено 8 строк.

Остальное содержимое фрагмента сравнения — это недавние изменения. Каждой измененной строке предшествует символ + или - , указывающий на источник входных данных сравнения. Как уже упоминалось, символ - указывает на изменения в файле a/diff_test.txt , а + — на изменения в файле b/diff_test.txt .

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

1. git diff --color-words

Кроме того, команда git diff имеет специальный режим подсветки изменений с повышенной детализацией: ‐‐color-words . В этом режиме добавленные и удаленные строки отделяются пробелами, а затем выполняется их сравнение.

Теперь в выходных данных отображаются только измененные слова с цветовой подсветкой.

2. git diff-highlight

При клонировании источника Git появляется подкаталог с именем contrib. Он содержит набор связанных с Git инструментов и различные данные, которые пока еще не были включены в ядро Git. В их число входит скрипт Perl под названием diff-highlight. Diff-highlight попарно сопоставляет совпадающие строки выходных данных сравнения и подсвечивает измененные фрагменты внутри слов.

Теперь сравниваемые строки объединены в пары для определения наименьших возможных изменений.

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

Наряду с описанными возможностями обработки текстовых файлов команда git diff может работать с двоичными файлами. К сожалению, в этом случае использовать формат вывода по умолчанию не слишком продуктивно.

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

Затем необходимо связать с фильтром pdfconv один или несколько шаблонов файлов. Для этого необходимо создать файл .gitattributes в корневом каталоге репозитория.

После настройки команда git diff сначала обрабатывает двоичный файл с помощью настроенного скрипта конвертера, а затем выполняет сравнение выходных данных конвертера. Этот метод можно использовать для эффективного сравнения любых двоичных файлов, например ZIP, JAR и других архивов. Используя инструмент unzip -l (или аналогичный) вместо pdf2html, можно просмотреть, какие пути были добавлены в коммит или удалены из него по сравнению с другим коммитом. Утилиту exiv2 можно использовать для просмотра изменений метаданных, например размеров изображения. Существуют инструменты для преобразования .odf, .doc и других форматов документов в простой текст. В крайнем случае команда может работать с двоичными файлами, для которых формальных конвертеров не существует.

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

В команде git diff можно указать явный путь к файлу. Если в git diff указан путь к файлу, выполняется сравнение этого файла. Более подробно этот процесс показан на примерах ниже.

В этом примере выполняется сравнение для файла ./path/to/file . Рабочий каталог сравнивается с разделом проиндексированных файлов и выводятся изменения, которые еще не были проиндексированы. По умолчанию git diff выполняет сравнение с HEAD . Если опустить аргумент HEAD в приведенном выше примере и выполнить команду git diff ./path/to/file , это не повлияет на результат.

При вызове git diff с использованием параметра --cached сравниваются проиндексированные изменения и локальный репозиторий. Параметр --cached синонимичен параметру --staged .

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

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

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

По умолчанию команда git diff выводит все неподтвержденные изменения, внесенные после последнего коммита.

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

Команде git diff можно передать ссылки на коммиты Git для сравнения. Возможные варианты ссылок — HEAD , теги и имена веток. Каждый коммит в Git имеет идентификатор, который можно получить с помощью команды git log . Этот идентификатор коммита тоже можно передать в git diff .

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

Сравнение двух веток

Ветки сравниваются с помощью команды git diff точно так же, как любые другие входные ссылки.

В этом примере демонстрируется оператор точка. Две точки показывают, что сравниваются последние коммиты двух веток. Тот же результат можно получить, если опустить точки и поставить пробел между именами веток. Кроме того, можно использовать трехточечный оператор:

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

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

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

Резюме

На этой странице были рассмотрены процесс сравнения в Git и команда git diff . Мы объяснили, как читать вывод команды git diff и различные виды выходных данных. В примерах было показано, как изменить выходные данные git diff с помощью подсвечивания и использования цветов. Кроме того, были рассмотрены различные стратегии сравнения, например сравнение файлов в разных ветках и конкретных коммитах. Наряду с git diff также использовались команды git log и git checkout .

У меня есть script, который отлично работает в одной ветке и разбивается на другую. Я хочу посмотреть на две версии бок о бок и посмотреть, что другое. Есть ли способы сделать это?

Чтобы быть ясным Я не ищу инструмент сравнения (я использую Beyond Compare). Я ищу команду git diff, которая позволит мне сравнить главную версию с моей текущей версией ветки, чтобы увидеть, что изменилось. Я не в середине слияния или чего-то еще. Я просто хочу сказать что-то вроде

ОТВЕТЫ

Ответ 1

git diff может показать разницу между двумя коммитами:

Или, что эквивалентно:

Используя последний синтаксис, если обе стороны HEAD , его можно опустить (например, master.. сравнивает master с HEAD ).

Вы также можете быть заинтересованы в mybranch. master (от git diff docs):

Эта форма предназначена для просмотра изменений на ветке, содержащей и до второго <commit> , начиная с общего предка обоих <commit> . git diff A. B эквивалентно git diff $(git-merge-base A B) B .

Другими словами, это даст diff изменений в master , так как оно отклонилось от mybranch (но без новых изменений с тех пор в mybranch ).

Те же аргументы могут быть переданы в git difftool , если у вас есть один.

Ответ 2

Вы можете сделать это: git diff branch1:path/to/file branch2:path/to/file

Если у вас настроен difftool, вы также можете: git difftool branch1:path/to/file branch2:path/to/file

Ответ 3

Более современный синтаксис:

git diff ..master path/to/file

Префикс с двумя точками означает "от текущего рабочего каталога до". Вы также можете сказать:

  • master.. , т.е. обратное выше. Это то же самое, что и master .
  • mybranch..master , явно ссылаясь на состояние, отличное от текущего рабочего дерева.
  • v2.0.1..master , т.е. ссылаясь на тег.
  • [refspec]..[refspec] , в основном что-либо идентифицируемое как состояние кода для git.

Ответ 4

Есть много способов сравнить файлы из двух разных веток:

Вариант 1. Если вы хотите сравнить файл из n определенной ветки с другой конкретной веткой:

Пример:

В этом примере вы сравниваете файл в ветке "mybranch" с файлом в ветке "mysecondbranch".

Вариант 2: Простой способ:

Пример:

Этот пример похож на вариант 1.

Вариант 3: Если вы хотите сравнить ваш текущий рабочий каталог с какой-то веткой:

Пример:

В этом примере вы сравниваете файл из вашей фактической ветки с файлом в главной ветки.

Ответ 5

Я просто делаю git diff branch1 branch2 path/to/file

Это проверяет различия между файлами. Изменения в branch1 будут красными. Изменения в branch2 будут зелеными.

Предполагалось, что branch1 - это прошлое, а branch2 - будущее. Вы можете отменить это, изменив порядок ветвей в diff: git diff branch2 branch1

Ответ 6

Соглашаясь с ответом, предложенным @dahlbyk. Если вы хотите, чтобы diff был записан в файл diff для просмотра кода, используйте следующую команду.

Ответ 7

Если вы хотите сделать сравнение с текущей веткой, вы можете пропустить его и использовать:

git diff BRANCH -- path/to/file

таким образом, он будет отличаться от текущей ветки к указанной ветки (BRANCH).

Ответ 8

В моем случае я использую следующую команду:

Эта команда может помочь вам сравнить один и тот же файл в двух разных ветках

Ответ 9

Используйте хеши коммитов так:

где hash1 может быть любым коммитом из любой ветки, то же самое для hash2.

Ответ 10

Чтобы сравнить два файла в git bash, вам нужно использовать команду:

Эта команда покажет разницу между двумя файлами в самом bash.

Ответ 11

Лучший способ сделать это - использовать git diff следующим образом: git diff <source_branch> <target_branch> -- file_path

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

Ответ 12

Существует два сценария сравнения файлов:

Сценарий 1: Сравнение файлов в удаленных ветвях (обе ветки должны существовать в удаленном хранилище)

Сценарий 2. Сравните локальные файлы (в локальной копии рабочей области) с файлами в удаленном хранилище.

Логика проста. Если вы предоставите для diff два имени ветки, он всегда будет сравнивать удаленные ветки, а если вы предоставите только одно имя ветки, он всегда будет сравнивать вашу локальную рабочую копию с удаленным репо (который вы указали). Вы можете использовать диапазон для предоставления удаленных репозиториев.

например Оформить заказ в филиале

в этом случае, если вы укажете имя файла, оно будет сравнивать вашу локальную копию имени файла с удаленной веткой с именем "branch2".

в этом случае он будет сравнивать имя файла из удаленных веток с именем "branch1" vs "branch2"

в этом случае он также сравнивает имя файла из удаленных веток с именем "branch1" и "branch2". Итак, как и выше. Однако, если вы только что создали ветку из другой ветки, скажем "master", а ваша текущая ветвь не существует в удаленном хранилище, она будет сравнивать удаленную "master" и удаленную "branch2".

Читайте также: