Buat tambalan git dari perubahan dalam direktori kerja saat ini


880

Katakanlah saya memiliki perubahan yang tidak dikomit di direktori kerja saya. Bagaimana saya bisa membuat tambalan dari mereka tanpa harus membuat komit?


29
Jawaban yang diterima mungkin harus diubah, mengingat jawaban kedua hampir empat kali lebih populer.
Tim Ogilvy

5
@TimOgilvy setuju. OP harus melakukannya. Jawaban kedua jauh lebih populer dan memberikan lebih banyak informasi
John Demetriou

1
Saya pikir itu layak untuk menyebutkan Anda perlu menambal dari perubahan yang tidak terikat pada judul juga.
2i3r

Jawaban:


401

git diffuntuk perubahan yang tidak dipentaskan. git diff --cacheduntuk perubahan bertahap.


12
yup, git diff adalah kebalikan dari git yang berlaku
Spike Gronim

33
git format-patchjuga termasuk diff biner dan beberapa info meta. Sebenarnya itu akan menjadi taruhan terbaik untuk membuat tambalan, tetapi afaik ini hanya berfungsi untuk memeriksa sumber / perubahan, bukan?
Eric

20
Terkadang mungkin berguna untuk membuat tambalan relatif ke direktori saat ini. Untuk mencapai ini, gunakangit diff --relative
ejboy

30
git diff> a.patch untuk menulisnya ke file
qasimzee

139
Terse berbatasan dengan sarkastik, jawaban di bawah ini lebih bermanfaat.
Air

1865

Jika Anda belum melakukan perubahan, maka:

git diff > mypatch.patch

Tetapi kadang-kadang terjadi bahwa sebagian dari hal-hal yang Anda lakukan adalah file baru yang tidak terlacak dan tidak akan di git diffoutput Anda . Jadi, salah satu cara untuk melakukan patch adalah dengan mem-stage semua untuk komit baru ( git addsetiap file, atau hanya git add .) tetapi tidak melakukan komit, dan kemudian:

git diff --cached > mypatch.patch

Tambahkan opsi 'biner' jika Anda ingin menambahkan file biner ke tambalan (mis. File mp3):

git diff --cached --binary > mypatch.patch

Anda nanti dapat menerapkan tambalan:

git apply mypatch.patch

Catatan: Anda juga dapat menggunakan --stagedsinonim dari --cached.


128
Terima kasih banyak untuk contohnya. Berbeda dengan jawaban yang diterima Anda menunjukkan perintah bagaimana melakukannya dan tidak hanya berbicara. Sangat membantu dan bekerja tanpa cacat untuk saya :)
nuala

4
Saya melakukan hal itu dan mendapat "input fatal: tidak dikenal" setelah mengeksekusi git berlaku. Adakah yang tahu apa yang menyebabkan ini dan bagaimana cara memperbaikinya?
Vitaly

6
@Vitaly: apakah tambalan Anda dapat dibaca jika Anda membukanya dengan editor teks? itu harus bersih tanpa karakter aneh, misalnya jika pengaturan color.diff diatur patch Anda akan memiliki beberapa 'karakter warna' yang dapat membuat 'git apply' gagal, dalam hal ini coba git diff --no-color. Kalau tidak, sepertinya masalah penyandian.
jcarballo

3
Terkait dengan "file baru yang tidak dilacak": "git diff" dan "git diff --cached" hanya berfungsi jika "git add <file>" telah dipanggil terlebih dahulu. (Saya baru git dan bertanya-tanya mengapa saya mendapat patch kosong setiap kali)
Anonymous

5
Ini membuat saya keluar dari neraka penggabungan / rebase yang aneh dengan mudah, terima kasih :)
John Hunt

86

git diffdan git applyakan bekerja untuk file teks, tetapi tidak akan bekerja untuk file biner.

Anda dapat dengan mudah membuat tambalan biner penuh, tetapi Anda harus membuat komit sementara. Setelah Anda membuat komit sementara, Anda dapat membuat tambalan dengan:

git format-patch <options...>

Setelah Anda membuat tambalan, jalankan perintah ini:

git reset --mixed <SHA of commit *before* your working-changes commit(s)>

Ini akan mengembalikan komit sementara Anda. Hasil akhir membuat copy pekerjaan Anda (sengaja) kotor dengan perubahan yang sama seperti yang Anda alami sebelumnya.

Di sisi penerima, Anda dapat menggunakan trik yang sama untuk menerapkan perubahan pada copy pekerjaan, tanpa memiliki riwayat komit. Cukup terapkan tambalan, dan git reset --mixed <SHA of commit *before* the patches>.

Perhatikan bahwa Anda mungkin harus disinkronkan dengan baik agar seluruh opsi ini berfungsi. Saya telah melihat beberapa kesalahan ketika menerapkan tambalan ketika orang yang membuatnya tidak menarik sebanyak yang saya miliki. Mungkin ada cara untuk membuatnya bekerja, tetapi saya belum melihat jauh ke dalamnya.


Inilah cara membuat tambalan yang sama di Tortoise Git (bukan yang saya sarankan menggunakan alat itu):

  1. Komit perubahan pekerjaan Anda
  2. Klik kanan direktori root cabang dan klik Tortoise Git->Create Patch Serial
    1. Pilih rentang mana yang masuk akal ( Since: FETCH_HEADakan berfungsi jika Anda disinkronkan dengan baik)
    2. Buat tambalan
  3. Klik kanan direktori root cabang dan klik Tortise Git->Show Log
  4. Klik kanan komit sebelum komit sementara Anda, dan klikreset "<branch>" to this...
  5. Pilih Mixedopsi

Dan bagaimana cara menerapkannya:

  1. Klik kanan direktori root cabang dan klik Tortoise Git->Apply Patch Serial
  2. Pilih tambalan yang benar dan terapkan
  3. Klik kanan direktori root cabang dan klik Tortise Git->Show Log
  4. Klik kanan komit sebelum komit patch, dan klikreset "<branch>" to this...
  5. Pilih Mixedopsi

5
Secara teknis ini memang membutuhkan membuat komit yang diminta OP hindari, tapi itu temporer dan jawabannya berguna.
davenpcj

33

Untuk membuat tambalan dengan file yang dimodifikasi & baru (dipentaskan) Anda dapat menjalankan:

git diff HEAD > file_name.patch

Terima kasih, dalam kasus saya, jawaban ini berfungsi, tetapi git diff --cached > mypatch.patchtidak berfungsi.
pertambangan

Saya punya pertanyaan: dapat file_name.patchdigunakan oleh patchperintah? Apakah mereka kompatibel satu sama lain?
Rakshith Ravi

git diff + git diff --cached / staged == git diff HEAD (tampilkan semua perubahan sejak komit terakhir)
K. Symbol

20

Saya suka:

git format-patch HEAD~<N>

di mana <N>jumlah komit terakhir untuk disimpan sebagai tambalan.

Rincian cara menggunakan perintah ada di DOC

UPD
Di sini Anda dapat menemukan cara menerapkannya.

UPD Bagi mereka yang tidak mendapatkan ide format-patch
Tambah alias:

git config --global alias.make-patch '!bash -c "cd ${GIT_PREFIX};git add .;git commit -m ''uncommited''; git format-patch HEAD~1; git reset HEAD~1"'

Kemudian di direktori mana pun repositori proyek Anda berjalan:

git make-patch

Perintah ini akan dibuat 0001-uncommited.patchdi direktori Anda saat ini. Patch akan berisi semua perubahan dan file yang tidak terlacak yang terlihat oleh perintah selanjutnya:

git status .

@ jcarballo: Saya telah memperbarui jawabannya. Jangan ragu untuk mengirimi saya pemberitahuan yang Anda miliki.
Eugen Konkov

2
Ada cara yang lebih sederhana daripada membuat komit dan tidak mengikat. git diff --cached --binary
Gaurav Agarwal

9

Jika Anda ingin melakukan biner, beri --binaryopsi ketika Anda menjalankan git diff.


0

Kami juga dapat menentukan file, untuk memasukkan hanya file dengan perubahan relatif, terutama ketika mereka span beberapa direktori ex

git diff ~/path1/file1.ext ~/path2/file2.ext...fileN.ext > ~/whatever_path/whatever_name.patch

Saya menemukan ini tidak ditentukan dalam jawaban atau komentar, yang semuanya relevan dan benar, jadi pilih untuk menambahkannya. Eksplisit lebih baik daripada implisit!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.