2009-03-05 4 views
144

У меня есть восемь коммитов на ветке, которые я бы хотел отправить другим людям, которые еще не просвещены. До сих пор все, что я делаю, либо дает мне 8 файлов патчей, либо начинает давать мне файлы патчей для каждой фиксации в истории филиала с самого начала. Я использовал git rebase - interactive, чтобы раздавить коммиты, но теперь все, что я пробую, дает мне zillions патчей с самого начала времени. Что я делаю не так?Как вы сквош фиксируется в одном патче с git format-patch?

git format-patch master HEAD # yields zillions of patches, even though there's 
          # only one commit since master 
+0

Мне любопытно, какой метод вы в конечном итоге используете среди предложений ниже. Дайте нам знать;) – VonC

+3

Я буду использовать git diff, как это предложил Rob Di Marco. Но я не работаю в течение двух недель, только что засвидетельствовал рождение моей второй девочки вчера вечером, так что это будет некоторое время, прежде чем я его использую! :) – skiphoppy

+2

Мне бы очень хотелось увидеть git format-patch --squash master HEAD – schoetbi

ответ

168

Я бы рекомендовал сделать это на откидной ветке следующим образом. Если ваши коммиты в филиале «Newlines» и вы перешли обратно в отделение «мастер» уже, это должно сделать трюк:

[[email protected] example (master)]$ git checkout -b tmpsquash 
Switched to a new branch "tmpsquash" 

[[email protected] 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(-) 

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

[[email protected] example (tmpsquash)]$ git format-patch master 
0001-My-squashed-commits.patch 

Надеется, что это помогает!

+2

Это то, что я использую, когда хочу сохранить историю локально (в случае, если мне нужно отредактировать патч). В противном случае я просто использую rebase -i и squash коммиты. – sebnow

+1

лучшее решение! спасибо :) – kkudi

+5

для меня, он работал более надежно с 'git comit -m« Мои раздавленные коммиты », иначе он добавил бы другие невоспроизводимые файлы. – Sebastian

18

Как вы уже знаете, 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с ommits

+0

'git merge master' просто выполняет быструю перемотку вперед и не выполняет сквош в одном. Перейдите в 'git merge --squash master', чтобы получить все коммиты, раздавленные и видимые в поэтапной области. Ваш поток будет работать с этим изменением. (Я использую git версии 2.1.0.) – Stunner

+0

@Stunner хорошая точка. Я отредактировал ответ. – VonC

21

Я всегда использую Git диф так что в вашем примере, что-то вроде

git diff master > patch.txt 
+14

За исключением того, что вы потеряете все сообщения и метаданные с фиксацией. Красота git format-patch заключается в том, что можно восстановить целую ветку из набора патчей. – mcepl

+0

метод create-branch-and-squash имеет преимущество объединения всех сообщений фиксации в один, но этот метод выполняется намного быстрее, если вы хотите написать собственное сообщение фиксации – woojoo666

+0

, комбинированное сообщение может быть выполнено с помощью 'git log ', см. [мой ответ] (http://stackoverflow.com/a/32373193/1852456) для примера – woojoo666

120

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

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

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

git am < my_new_patch.diff 
+13

Мне нравится это решение. Стоит заметить, что он может иногда создавать гораздо больший патч, чем метод, описанный @Adam Alexander. Это связано с тем, что некоторые файлы могут быть отредактированы более одного раза через фиксации. Этот метод обрабатывает каждую фиксацию отдельно, даже если некоторый файл был отменен. Но большую часть времени это не проблема. – gumik

+1

Эта опция великолепна, если вы пытаетесь избежать слияния! (например, вы хотите пропустить некоторые коммиты). Вы все еще можете «git rebase -i ...» и сквоните их все до одного. –

17

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

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

[email protected]:~/example (master)$ git branch tmpsquash ba3c498878054e25afc5e22e207d62eb40ff1f38 
[email protected]:~/example (master)$ git checkout tmpsquash 
Switched to branch 'tmpsquash' 
[email protected]:~/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(-) 
[email protected]:~/example (tmpsquash)$ git commit -a -m "My squashed commits" 
[test2 6127e5c] My squashed commits 
11 files changed, 212 insertions(+), 59 deletions(-) 
[email protected]:~/example (tmpsquash)$ git format-patch master 
0001-My-squashed-commits.patch 
[email protected]:~/example (tmpsquash)$ git checkout master 
Switched to branch 'master' 
[email protected]:~/example (master)$ 
+0

Внесение изменений в мастер - это анти-шаблон, если вы не будете нажимать их на удаленный себя. И если вы это сделаете, вам, вероятно, не потребуется создавать файлы патчей для них. –

0

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

git checkout newlines 
## must be rebased to master 
git checkout -b temporary 
# squash the commits 
git rebase -i master 
git format-patch master 
4

Format-патч между двумя тегами:

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

Самым простым способом является использовать git diff, a nd добавить в 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 при работе с не текстовыми файлами, например изображения или видео.

Смежные вопросы