Di git, bagaimana cara membuat satu patch untuk 2+ revisi terakhir?

Saya ingin membuat tambalan untuk 2 revisi terakhir.

git format-patch -2

memberi saya 2 file patch, satu untuk setiap revisi

git format-patch HEAD~2..HEAD

memberikan hal yang sama.

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

memberikan satu file, tetapi hanya berisi perubahan untuk revisi terakhir.

Apakah ada cara untuk melakukan ini di git?


person Matthew    schedule 07.02.2010    source sumber
comment
Bisakah Anda memberi tahu kami lebih banyak tentang konteks apa yang ingin Anda lakukan? Apakah Anda mengetahui kemampuan untuk menghentikan komitmen bersama dengan rebase interaktif? Jika ya, mengapa Anda ingin menghentikan patch yang Anda kirim ke orang lain tetapi tidak melakukan commit terkait di riwayat Anda?   -  person Greg Bacon    schedule 08.02.2010
comment
@gbacon: Saya sebenarnya belajar tentang rebase segera setelah memposting pertanyaan ini. Anda benar bahwa ini adalah solusi yang lebih baik untuk masalah saya. Namun, tidak ada salahnya mengetahui cara melakukan ini.   -  person Matthew    schedule 08.02.2010
comment
@GregBacon: Satu hal yang sekarang sering saya lakukan adalah: Bekerja di cabang fitur, dengan banyak komitmen kecil. Ketika tiba waktunya untuk mendorong cabang ke master, hancurkan terlebih dahulu. Namun sementara itu, saya menggunakan git diff master mybranch untuk mengirimkan patch untuk ditinjau, sambil tetap menyimpan riwayat penerapan kecil saya (untuk saya gunakan sendiri).   -  person Matthew    schedule 21.08.2012
comment
kemungkinan duplikat Bagaimana cara Anda menekan komitmen menjadi satu patch dengan git format-patch?   -  person Damien    schedule 20.08.2013


Jawaban (4)


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

Namun, ia tidak akan memiliki metadata per-komit format-patch.

person Tobu    schedule 07.02.2010
comment
Jelas sekali. Penulis apa yang harus dimiliki jika kedua komitmen tersebut memiliki penulis berbeda? Bagaimana seharusnya tampilan pesan komit untuk perubahan 2 komit? Dll. - person Jakub Narębski; 08.02.2010
comment
Perhatikan bahwa jika Anda menggunakan cabang fitur, Anda cukup melakukan git diff master mybranch > my-patch.diff untuk membuat tambalan untuk cabang tersebut. - person Matthew; 21.08.2012

Gunakan opsi --stdout lalu masukkan ke file.

Seperti:

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

Ini akan menjaga metadata per komitmen.

person JC Brand    schedule 17.08.2012
comment
Apa yang Anda dapatkan adalah file mbox (file email gabungan), bukan file patch. Anda dapat menerapkannya dengan git am. Anda tidak akan dapat menggunakan alat standar untuk file patch. - person Tobu; 30.08.2012
comment
@Tobu: tetapi sering kali Anda ingin menerapkan komit dengan git am, karena komit tetap dipertahankan sebagaimana adanya, alih-alih satu gumpalan besar kode... - person Smar; 01.06.2016
comment
apakah ada cara untuk mereferensikan HEAD asal sebagai awal dari refspec?! Itu akan menjadi sesuatu yang luar biasa seperti git format-patch origin/HEAD..HEAD --stdout > changes.patch... OMG ITU BERFUNGSI - person Ray Foss; 12.06.2020
comment
Solusi ini lebih baik daripada solusi di atas - jika ada file biner (misalnya file rahasia) maka tidak akan disertakan dalam solusi di atas. Solusi ini juga akan menghasilkan daftar lengkap komit menjadi satu file patch besar yang luar biasa - jika Anda perlu melakukan squash, mungkin saja menggunakan git rebase -i nanti. - person John Basila; 19.10.2020

Dengan Git 2.20 (Q4 2018) dan lebih banyak lagi, Anda kini memiliki:

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

Keduanya membantu menjelaskan perbedaan antara versi ini dan upaya sebelumnya dalam surat lamaran (atau setelah tanda hubung pohon sebagai komentar).

format-patch: izinkan --interdiff / --rangediff untuk diterapkan ke patch tunggal

Saat mengirimkan versi revisi dari sebuah patch atau seri, akan sangat membantu (bagi pengulas) untuk menyertakan ringkasan perubahan sejak upaya sebelumnya dalam bentuk interdiff, biasanya dalam surat lamaran.
Namun, hal ini memang benar. kadang-kadang berguna, meskipun membuat pembacaan menjadi berisik, untuk memasukkan interdiff atau rangediff ke bagian komentar dari patch tunggal dari seri 1-patch.

Lihat melakukan ee6cbf7, komit 3fcc7a2, komit 3b02641, melakukan 5ac290f, melakukan 126facf, commit fa5b7ea (22 Juli 2018) oleh Eric Sunshine (sunshineco).
(Digabung oleh Junio ​​C Hamano -- gitster -- di melakukan 688cb1c, 17 Sep 2018)

Oleh karena itu, perluas git format-patch --interdiff=<prev> untuk menyisipkan interdiff ke dalam bagian komentar dari patch tersendiri daripada memerlukan surat lamaran.
Interdiff dibuat menjorok ke dalam untuk menghindari kebingungan git-am dan pembaca manusia agar menganggapnya sebagai bagian dari patch yang sebenarnya.

Lihat melakukan 40ce416, komit 8631bf1, komit 4ee9968, komit 2e6fd71, komit 31e2617, komit 73a834e, komit 2566865, commit 87f1b2d (22 Juli 2018) oleh Eric Sunshine (sunshineco).
(Digabung oleh Junio ​​C Hamano -- gitster -- di commit 881c019, 17 Sep 2018)

Oleh karena itu, perluas git format-patch --range-diff=<refspec> untuk memasukkan range-diff ke bagian komentar dari satu tambalan daripada memerlukan surat lamaran.

person VonC    schedule 22.09.2018
comment
Jadi, git format-patch --range-diff=<commit hash> menghasilkan tambalan hanya dengan komit yang diperlukan, dan tidak ada surat PATCH dengan setiap file diubah? - person ZeroPhase; 08.05.2019
comment
@ZeroPhase tidak ada surat tempelan, sejauh yang saya tahu. (git-scm .com/docs/git-format-patch#Dokumentasi/) - person VonC; 08.05.2019

Anda dapat melakukan sesuatu seperti:

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

Komit ke cabang tmp akan sama dengan 2 komit individu.

person William Pursell    schedule 07.02.2010
comment
atau git rebase -i HEAD~2, dan labu. - person Tobu; 07.02.2010
comment
Huh, suara tidak setuju pada jawaban yang berusia lebih dari 6 tahun! Itu adalah arkeologi yang serius. Sebuah komentar akan bagus untuk menjelaskan nekrofilia. - person William Pursell; 31.05.2016
comment
Saya bukan orang yang tidak setuju, tapi menurut saya itu karena ada cara yang lebih mudah dan aman untuk melakukannya; git reset dapat menghilangkan sesuatu yang ekstra. Rebase yang diberikan dalam komentar akan sedikit lebih aman karena setidaknya akan mengetahui apakah pohon kerja kotor. Meskipun demikian, menurut saya jawaban ini memiliki nilai. - person Smar; 01.06.2016
comment
Jawaban ini membantu saya karena saya harus menangani lebih dari 20 komitmen... - person Dror Cohen; 25.05.2017
comment
Ini adalah cara yang berbahaya untuk melakukan sesuatu jika Anda telah menambahkan file baru/mengganti namanya. - person sdevikar; 10.02.2018