Как объединить коммиты в один патч с помощью git format-patch?

StackOverflow https://stackoverflow.com/questions/616556

  •  03-07-2019
  •  | 
  •  

Вопрос

У меня есть восемь коммитов в ветке, которые я хотел бы разослать по электронной почте некоторым людям, которые еще не знакомы с git.Пока что все, что я делаю, либо дает мне 8 файлов патчей, либо начинает давать мне файлы патчей для каждого коммита в истории ветки, с начала времен.Я использовал git rebase --interactive, чтобы сжать коммиты, но теперь все, что я пытаюсь сделать, дает мне миллионы патчей с начала времен.Что я делаю не так?

git format-patch master HEAD # yields zillions of patches, even though there's 
                             # only one commit since master
Это было полезно?

Решение

Я бы порекомендовал сделать это на одноразовой ветке следующим образом. Если ваши коммиты находятся в "новых строках" ветку, и вы вернулись к своему " главному " ветвь уже, это должно сработать:

[adam@mbp2600 example (master)]$ git checkout -b tmpsquash
Switched to a new branch "tmpsquash"

[adam@mbp2600 example (tmpsquash)]$ git merge --squash newlines
Updating 4d2de39..b6768b2
Fast forward
Squash commit -- not updating HEAD
 test.txt |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

[adam@mbp2600 example (tmpsquash)]$ git commit -a -m "My squashed commits"
[tmpsquash]: created 75b0a89: "My squashed commits"
 1 files changed, 2 insertions(+), 0 deletions(-)

[adam@mbp2600 example (tmpsquash)]$ git format-patch master
0001-My-squashed-commits.patch

Надеюсь, это поможет!

Другие советы

Просто добавьте еще одно решение в банк: Если вы используете это вместо:

git format-patch master --stdout > my_new_patch.diff

Тогда все равно будет 8 патчей ... но все они будут в одном патч-файле и будут применяться как один с:

git am < my_new_patch.diff

Я всегда использую git diff, поэтому в вашем примере что-то вроде

git diff master > patch.txt

Это адаптация ответа Адама Александра, если ваши изменения находятся в основной ветке.Для этого выполните следующие действия:

  • Создает новую одноразовую ветку «tmpsquash» с нужной нам точки (найдите ключ SHA, запускающий «git --log» или с помощью gitg.Выберите коммит, который вы хотите сделать tmpsquash head, последующие коммиты в master будут сжатыми коммитами).
  • Объединяет изменения из master в tmpsquash.
  • Фиксирует сжатые изменения в tmpsquash.
  • Создает патч со сжатыми коммитами.
  • Возвращается в главную ветку

laura@rune:~/example (master)$ git branch tmpsquash ba3c498878054e25afc5e22e207d62eb40ff1f38
laura@rune:~/example (master)$ git checkout tmpsquash
Switched to branch 'tmpsquash'
laura@rune:~/example (tmpsquash)$ git merge --squash master
Updating ba3c498..40386b8
Fast-forward
Squash commit -- not updating HEAD

[snip, changed files]

11 files changed, 212 insertions(+), 59 deletions(-)
laura@rune:~/example  (tmpsquash)$ git commit -a -m "My squashed commits"
[test2 6127e5c] My squashed commits
11 files changed, 212 insertions(+), 59 deletions(-)
laura@rune:~/example  (tmpsquash)$ git format-patch master
0001-My-squashed-commits.patch
laura@rune:~/example  (tmpsquash)$ git checkout master
Switched to branch 'master'
laura@rune:~/example  (master)$

Как вы уже знаете, git format-patch -8 HEAD даст вам восемь патчей.

Если вы хотите, чтобы ваши 8 коммитов отображались как один, и вы не против переписать историю своей ветви ( o-o-X-A-B-C-D-E-F-G-H ), вы можете:

git rebase -i
// squash A, B, C, D, E ,F, G into H

или, и это было бы лучшим решением, воспроизведите все ваши 8 коммитов из X (коммит до ваших 8 коммитов) в новой ветке

git branch delivery X
git checkout delivery
git merge --squash master
git format-patch HEAD

Таким образом, у вас есть только один коммит для " доставки " ветвь, и она представляет все ваши последние 8 коммитов

Формат-патч между двумя тегами:

git checkout <source-tag>
git checkout -b <tmpsquash>
git merge --squash <target-tag>
git commit -a -m "<message>"
git format-patch <source-tag>

Самый простой способ - использовать git diff и добавить в git log , если вы хотите получить сообщение с комбинированной фиксацией, которое будет выводить метод squash. Например, чтобы создать патч между коммитом abcd и 1234 :

git diff abcd..1234 > patch.diff
git log abcd..1234 > patchmsg.txt

Тогда при применении патча:

git apply patch.diff
git add -A
git reset patch.diff patchmsg.txt
git commit -F patchmsg.txt

Не забывайте аргумент - binary для git diff при работе с нетекстовыми файлами, например, изображения или видео.

На основании ответа Адама Александра:

git checkout newlines
## must be rebased to master
git checkout -b temporary
# squash the commits
git rebase -i master
git format-patch master
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top