Git diff в тематической ветке, исключая коммиты слияния, которые произошли за это время?

Допустим, у меня следующая ситуация:

    B---D---F---G topic
   /       /
--A---C---E master

Для целей проверки кода я хотел бы извлечь diff из коммита A в коммит G, но не включая коммиты E и C, которые произошли в основной ветке, а также не включая коммит F, который является фиксацией слияния.

Другими словами, я хотел бы создать diff, содержащий изменения от F до G, и объединить эти изменения с изменениями от A до D.

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

Это возможно? Если git не может обрабатывать такие «агрегации различий», я был бы очень благодарен, если бы кто-нибудь мог предоставить некоторые указатели относительно того, как это может сделать какая-то внешняя команда (чтобы я мог попробовать написать сценарий bash, который сделает трюк).


person Vladimir Mitrovic    schedule 20.09.2011    source источник
comment
Как насчет извлечения файла в A и G по отдельности и создания vim diff ???   -  person Kit Ho    schedule 20.09.2011
comment
Мне нужен diff для всех файлов, а не для одного файла. Кроме того, я думаю, что то, что вы предлагаете, также будет включать изменения, внесенные фиксацией слияния.   -  person Vladimir Mitrovic    schedule 20.09.2011
comment
Кажется, тройная точка помогла мне в этом. stackoverflow.com/a/17618008/4200039   -  person Ben Creasy    schedule 11.02.2019


Ответы (3)


Если вам все равно, что находится в «контекстной» части различий, то git diff master..topic даст вам то, что вы хотите. Любые изменения, внесенные в C и E, считаются частью «базы» diff, поэтому изменения из master будут присутствовать в контексте, но только фактические изменения, сделанные в вашей тематической ветке, будут отмечены + или - как изменения. . Обычно это то, что люди хотят для проверки кода.

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

git rebase --onto A master
person Karl Bielefeldt    schedule 20.09.2011
comment
Спасибо, Карл, git diff master..topic сделал свое дело. Оказывается, перед запуском скрипта diff мне пришлось объединить master в тему. - person Vladimir Mitrovic; 21.09.2011

Ответ Карла вводит в заблуждение:

git diff никогда не работает в правильных диапазонах (т. е. множественных коммитах), только между двумя коммитами!

Синтаксис диапазона имеет особое значение для git diff.

git diff E..G всегда равно git diff E G
git diff E...G равно git diff E G в данном случае, потому что E является базой слияния между ними).

git diff master...topic - это то, что вам нужно в этом и в общем случае: он показывает вам все изменения ветки темы, сравнивая ее с последней базой слияния (т. е. сравнивая ее с master, когда она была слита последним время, игнорируя все более поздние изменения в мастере, которых нет в вашей тематической ветке).

Примечание: к сожалению (по совпадению?) эффект x..y в git log и т. д. лучше всего представлен x...y в git diff и наоборот!

person Robert Siemer    schedule 19.02.2015
comment
Да, это правильный ответ. Из руководства: git diff A...B эквивалентен git diff $(git-merge-base A B) B. - person jmiserez; 27.05.2016

Что о:

  1. тема проверки git

  2. git checkout -b временная

  3. git вернуть F

  4. git разница А

После этого вы можете с радостью удалить временную ветку.

person topek    schedule 20.09.2011