В git, как мне создать один патч для последних 2+ ревизий?

Я хотел бы создать патч для последних 2 ревизий.

git format-patch -2

дает мне 2 файла патча, по одному для каждой версии

git format-patch HEAD~2..HEAD

дает то же самое.

git format-patch -1 HEAD~2..HEAD

дает один файл, но содержит только изменения для последней версии.

Есть ли способ сделать это в git?


person Matthew    schedule 07.02.2010    source источник
comment
Можете ли вы рассказать нам больше о контексте того, что вы хотите сделать? Знаете ли вы о возможности сквоша коммитов вместе с интерактивной перебазировкой? Если да, то почему вы хотите уничтожить патч, который вы отправляете другим, но не соответствующие коммиты в своей истории?   -  person Greg Bacon    schedule 08.02.2010
comment
@gbacon: я действительно узнал о перебазировании вскоре после публикации этого вопроса. Вы правы, это лучшее решение моей проблемы. Тем не менее, знать, как это сделать, не помешает.   -  person Matthew    schedule 08.02.2010
comment
@GregBacon: Теперь я часто делаю одну вещь: работаю в функциональной ветке с множеством небольших коммитов. Когда пришло время отправить ветку на master, сначала раздавите ее. Но тем временем я использую git diff master mybranch для отправки патча на проверку, сохраняя при этом свою небольшую историю коммитов (для собственного использования).   -  person Matthew    schedule 21.08.2012
comment
возможный дубликат Как вы сжимаете коммиты в один патч с git format-patch?   -  person Damien    schedule 20.08.2013


Ответы (4)


git diff HEAD~2..HEAD > my-patch.diff

Однако у него не будет метаданных format-patch для каждого коммита.

person Tobu    schedule 07.02.2010
comment
Очевидно. Какой у него должен быть автор, если у этих двух коммитов разные авторы? Как должно выглядеть сообщение коммита для изменения 2-commit? И т.п. - person Jakub Narębski; 08.02.2010
comment
Обратите внимание, что если вы используете ветки функций, вы можете просто сделать git diff master mybranch > my-patch.diff, чтобы создать патч для этой ветки. - person Matthew; 21.08.2012

Используйте параметр --stdout, а затем запишите его в файл.

Вот так:

git format-patch HEAD~2..HEAD --stdout > changes.patch

Это сохранит метаданные для каждого коммита.

person JC Brand    schedule 17.08.2012
comment
Вы получаете файл mbox (объединенные почтовые файлы), а не файл исправления. Вы можете применить его с помощью git am. Вы не сможете использовать стандартные инструменты для патч-файлов. - person Tobu; 30.08.2012
comment
@Tobu: но часто вы хотите применить коммиты с git am, так как это сохраняет коммиты как они есть, а не один большой кусок кода ... - person Smar; 01.06.2016
comment
есть ли способ сослаться на HEAD источника как на начало refspec?! Было бы здорово что-то вроде git format-patch origin/HEAD..HEAD --stdout > changes.patch... ОМГ ЭТО РАБОТАЕТ - person Ray Foss; 12.06.2020
comment
Это решение лучше, чем приведенное выше - если есть двоичные файлы (например, секретные файлы), то они не будут включены в приведенное выше решение. Это решение также создаст полный список коммитов в одном большом файле патча, что замечательно — если вам нужно сжать, это возможно с помощью git rebase -i позже. - person John Basila; 19.10.2020

С Git 2.20 (четвертый квартал 2018 г.) и другими версиями у вас теперь есть:

  • git format-patch --interdiff.
  • git format-patch --rangediff.

Оба помогают объяснить разницу между этой версией и предыдущей попыткой в ​​сопроводительном письме (или после тире в качестве комментария).

format-patch: разрешить --interdiff / --rangediff применять к одиночному патчу

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

См. коммит ee6cbf7, коммит 3fcc7a2, , коммит 5ac290f, коммит 126facf, commit fa5b7ea (22 июля 2018 г.), автор Эрик Саншайн (sunshineco).
(Объединено Junio ​​C Hamano -- gitster -- в commit 688cb1c, 17 сентября 2018 г.)

Таким образом, расширьте git format-patch --interdiff=<prev>, чтобы вставить промежуточные различия в раздел комментариев к отдельному патчу, а не требовать сопроводительного письма.
Взаимные различия сделаны с отступом, чтобы не сбить с толку git-am и читателей-людей, считая их частью собственно патча.

См. коммит 40ce416, зафиксировать 8631bf1, , коммит 2e6fd71, коммит 31e2617, фиксация 73a834e, фиксация 2566865, коммит 87f1b2d (22 июля 2018 г.), автор Эрик Саншайн (sunshineco).
(Объединено
Junio ​​C Hamano -- gitster -- в commit 881c019, 17 сентября 2018 г.)

Поэтому расширьте git format-patch --range-diff=<refspec>, чтобы вставить range-diff в раздел комментариев одиночного патча, вместо того, чтобы требовать сопроводительного письма.

person VonC    schedule 22.09.2018
comment
Итак, git format-patch --range-diff=<commit hash> создает патч только с необходимыми фиксациями, и нет буквы PATCH с каждым измененным файлом? - person ZeroPhase; 08.05.2019
comment
@ZeroPhase, насколько я знаю, нет письма с патчем. (git-scm .com/docs/git-format-patch#Documentation/) - person VonC; 08.05.2019

Вы можете сделать что-то вроде:

$ git checkout -b tmp
$ git reset HEAD~2
$ git commit -a

Фиксация для ветки tmp будет такой же, как и для двух отдельных коммитов.

person William Pursell    schedule 07.02.2010
comment
или git rebase -i HEAD~2, и сквош. - person Tobu; 07.02.2010
comment
Ха, отрицательный голос за ответ, которому уже более 6 лет! Это серьезная археология. Комментарий был бы хорош, чтобы объяснить некрофилию. - person William Pursell; 31.05.2016
comment
Я не против, но полагаю, это потому, что есть более простые и безопасные способы сделать это; git reset можно искоренить что-то лишнее. Перебазирование, указанное в комментарии, было бы немного безопаснее, поскольку оно, по крайней мере, сообщало бы, загрязнено ли рабочее дерево. Тем не менее, я думаю, что этот ответ имеет ценность. - person Smar; 01.06.2016
comment
Этот ответ помог мне, так как мне нужно было иметь дело с более чем 20 коммитами... - person Dror Cohen; 25.05.2017
comment
Это опасный способ сделать что-то, если вы добавили новые файлы/переименовали их. - person sdevikar; 10.02.2018