Git сравнить файлы из разных коммитов
Как вы можете показать git diff только разницу между двумя коммитами, исключая другие коммиты между ними?
«git diff» всегда показывает разницу между двумя коммитами (или коммитом, и рабочим каталогом и т. д.). @ JakubNarębski, он спрашивает, как увидеть разницу между изменениями, внесенными одной командой, и изменениями, внесенными другим коммитом. Другими словами, diff из diffs или interdiff. и если вы добавите параметр --dirstat = files к команде diff, вы получите очень хороший скриншот с точными проектами и файлами, которые были изменены, вместе с процентом изменений. Например: git diff [номер-коммита] [номер-коммита] --dirstat = filesвы можете просто передать 2 коммита в git diff:
Это сработало для меня, но теперь, как я могу обратиться my.patch в другую ветку? @ nacho4d: git checkout other-branch && git apply my.patch && git add. && git commit -am "Message" Преимущество использования git apply и patch заключается в том, что вы можете включать переименования и некоторые другие изменения, относящиеся к git. Мне нравится использовать git format-patch и git am. Этот ответ совершенно не отвечает на вопрос, поэтому я понятия не имею, почему у него так много голосов. ОП конкретно спрашивает, как НЕ получить первую команду, которую вы даете, а вторая не имеет никакого отношения к чему-либо. Этот ответ не в состоянии ничего не ответить. Работает отлично. Если вы разветвите последний из двух коммитов, о котором идет речь, то примените этот diff к этой новой ветке, вы увидите изменения между двумя коммитами без головной боли прерывистых коммитов.Запрашивать разницу / между / двумя коммитами без учета промежуточных коммитов не имеет большого смысла. Коммиты - это просто снимки содержимого хранилища; просить разницу между двумя обязательно включает их. Итак, вопрос в том, что вы действительно ищете?
Как предположил Уильям, сбор вишни может дать вам дельту одного комбита, перебазированного поверх другого. Это:
Это принимает коммит 'abcdef', сравнивает его с его непосредственным предком, затем применяет эту разницу поверх '012345'. Затем показывается это новое отличие - единственное изменение заключается в том, что контекст происходит от «012345», а не от «непосредственного предка» abcdef. Конечно, вы можете столкнуться с конфликтами и т. Д., Поэтому в большинстве случаев это не очень полезный процесс.
Если вы просто заинтересованы в самом abcdef, вы можете сделать:
Это сравнивает abcdef с его непосредственным предком, в одиночку, и обычно это то, что вы хотите.
дает вам все различия между этими двумя коммитами.
Это помогло бы получить лучшее представление о том, чего вы пытаетесь достичь - как я уже говорил, просить разницу между двумя коммитами без того, что между ними, на самом деле не имеет смысла.
Я согласен, что в общем случае не имеет смысла сравнивать два коммита. Но Git действительно не умеет говорить, как вы должны думать. Предположим, у вас есть две ветви, каждая с разными фиксациями, которые выглядят так, как будто они вносят одинаковые изменения в одни и те же наборы файлов. Я хотел бы иметь возможность использовать git, чтобы сказать мне, являются ли эти два исправления одинаковыми, не доверяя моим глазам. Я думаю, что есть полезность в этом. @ChrisCleeland, утилита interdiff может пригодиться в этом случае. Используйте git diff, чтобы получить diff каждого коммита против его непосредственного родителя, затем используйте interdiff, чтобы сравнить diff. @ChrisCleeland, git не хранит патчи. Хранит содержимое файла. У него действительно есть схема сжатия, которая использует дельты, но источники дельты не обязательно связаны с фактической историей файлов. Разница между двумя коммитами, исключая другие коммиты на их соответствующих ветвях, имеет смысл: один коммит был выбран из другого, но может иметь некоторые тонкие различия. Вы хотите увидеть, что они из себя представляют, не будучи загромождены всем другим несвязанным дерьмом, которое отличается между двумя ветвями.Для сравнения двух коммитов git 12345 и abcdef как патчей можно использовать команду 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 .
Итак, продолжаю знакомиться с системой Git и на этот раз вопрос будет касаться команды git diff . Это краткая заметка, которая ни в коей мере не претендует на полноценный обзор. Скорее всего - философское рассуждение на тему сравнения в Git.
С помощью этой команды в Git можно сравнивать между собой файлы для того, чтобы увидеть - где произошло изменение.
Когда изменение обнаружено, тогда можно решать, что с ним делать - оставить, удалить или отредактировать.
Перед использованием команды diff стоит напомнить о трех состояниях системы Git: Working Area, Staging Area, Repository. Фактически, команда diff производит сравнение между разными состояниями одного файла.
Поэтому, когда запускается команда diff , следует принимать во внимание, что и с чем будет сравниваться.
Working Area
Рассмотрим первый случай, когда имеется отслеживаемый файл index.html , в который вносятся изменения.
Но изменения в этом файле не индексируются ( git add ) и не фиксируются ( git commit ).
В этом случае, чтобы увидеть изменения, нужно запустить команду:
В этом случае производится сравнение между фиксированной версией файла index.html (в области Repository) и его измененной версией (в области Working Area).
Вывод будет примерно таким:
В этом примере все предельно ясно и понятно. Строка --- a/index.html - это фиксированная версия файла index.html . Строка +++ b/index.html - это измененная версия файла index.html .
… отображают, сколько и каких строк удалено (знак минус); сколько и каких строк добавлено (знак плюс).
Итак, с первым вариантом разобрались. Комадна git diff выполняет сравнение версии файла из области Repository и этой же версии из области Working Area.
Staging Area
Второй вариант - файл index.html отслеживается, в него внесено изменение, которое проиндексировано (внесено в область Staging Area).
Команда git diff ничего не покажет, так как изменения в файле index.html были перенесены ( git add ) из области Working Area в область Staging Area. Другими словами, область Working Area чистая и в ней нет ничего, чтобы можно было сравнить с областью Repository.
В этом случае для команды git diff необходимо добавить ключ --staged . Тогда вывод будет примерно таким:
Ключ --staged указывает, что необходимо сравнивать область Repository с областью Staging Area.
Итак, разобрались со вторым случаем. Команда git diff --staged производит сравнение области Repository с областью Staging Area.
Repository
Третий вариант - файл index.html отслеживается, в него внесены изменения, которые проиндексированы ( git add ) и зафиксированы ( git commit ).
В этом случае область Working Area и Staging Area чистые от изменений, поэтому область Repository нельзя сравнивать с ними - там нет ничего для сравнения.
Поэтому команда git diff или git diff --staged ничего не покажет - сравнивать то не с чем!
Так как все изменения зафиксированы и перенесены в область Repository, то и сравнивать их между собой нужно только там, в этой области.
В этом случае команда сравнения git diff будет выглядеть примерно таким образом:
Здесь 0644c20 - это первые семь символов hash-суммы последнего commit’а, 73a4c4c - первые семь символов hash-суммы предпоследнего commit’а.
Их можно получить командой:
Другими словами, в этом случае сравниваются между собой различные коммиты. И это могут быть совсем не обязательно соседние коммиты - можно сравнить, к примеру, первый и последний коммиты.
Итак, разобрались с третим вариантом - когда сравниваются командой git diff hash_sum_1 hash_sum_2 между собой различные коммиты, расположенные в области Repository.
TypeScript - размеченные объединения
> Пользовательское объединение типов - что это и как можно использоватьПомимо объединения **примитивных** типов данных (например):
Как в Git сравнить один и тот же файл между двумя разными коммитами (не смежными) в одной и той же ветке (например, master)?
Я ищу функцию compare , подобную той, что находится в Visual SourceSafe (VSS) или Team Foundation Server (TFS).
Возможно ли это в Git?
Из git-diff справочная страница:
Например, чтобы увидеть разницу для файла «main.c» между текущим моментом и двумя обратными фиксациями, вот три эквивалентные команды:
Вы также можете сравнить два разных файла в двух разных версиях, например:
Если вы настроили "difftool", вы можете использовать
Пример: сравнение файла из его последней фиксации с предыдущей фиксацией в той же ветке: при условии, что если вы находитесь в корневой папке проекта
У вас должны быть следующие записи в вашем
/ .gitconfig или в файле project / .git / config. Установите p4merge [это мой любимый инструмент сравнения и слияния]
Если вы хотите видеть все изменения в файле между двумя коммитами по отдельности, вы также можете сделать
git log -u $start_commit..$end_commit -- path/to/file
Вот сценарий Perl, который выводит команды Git diff для заданного файла, найденные в команде журнала Git.
Которые затем можно было вырезать и вставить в сеанс окна оболочки или передать по конвейеру в /bin/sh .
- число (в данном случае 3) указывает, сколько строк нужно напечатать
- файл (в данном случае pom.xml) должен быть согласован в обоих местах (вы можете обернуть его в функцию оболочки, чтобы предоставить один и тот же файл в обоих местах) или поместить его в двоичный каталог как сценарий оболочки
Если вы хотите провести сравнение с более чем одним файлом, с помощью метода, указанного в @mipadi:
Например. diff между HEAD и вашим master , чтобы найти все файлы .coffee :
Это будет рекурсивно искать в вашем your_search_folder/ все файлы .coffee и различать их и их версии master .
Если у вас есть несколько файлов или каталогов и вы хотите сравнить непостоянные коммиты, вы можете сделать это:
Создайте временную ветку (в этом примере "ревизия" )
Вернуться к первой цели фиксации
Черри выбирает тех, кто совершает интерес
Когда ты закончишь
Еще один способ использовать великолепие Git .
Если вам нужно простое визуальное сравнение в Windows, например, вы можете получить его в Visual SourceSafe или Team Foundation Server (TFS), попробуйте следующее:
- щелкните правой кнопкой мыши файл в проводнике
- выберите "Git History"
Примечание. После обновления до Windows 10 я потерял параметры контекстного меню Git. Однако вы можете добиться того же, используя "gitk" или "gitk filename" в командном окне.
После того, как вы вызовете Git History, запустится инструмент Git GUI с историей файла в верхней левой панели. Выберите одну из версий, которую хотите сравнить. Затем щелкните правой кнопкой мыши вторую версию и выберите либо
Отличить это -> выбрано
Выбрано различие -> это
Различия с цветовой кодировкой появятся в нижней левой панели.
Все остальные ответы более полные, так что проголосуйте за них. Это просто для того, чтобы помнить, что вы можете не знать идентификатор недавнего коммита. Обычно я устанавливаю себя в ветке, которую хочу сравнить, и запускаю инструменты сравнения, зная старый uid фиксации (вы можете использовать другие обозначения):
Кроме того, проверьте этот другой ответ здесь, чтобы установить инструмент, который вы хотите открыть с помощью git, для сравнения файла: Настройка инструмента сравнения с помощью .gitconfig А чтобы узнать больше о difftool, перейдите к документации difftool
Проверьте $ git log , скопируйте SHA-1 ID двух разных коммитов, и запустите команду git diff с этими идентификаторами. Например:
Читайте также: