Tambahkan perubahan ke komit sebelumnya dengan Magit

44

Saya memiliki 2 komitmen, A lalu B, siap untuk didorong. Saya sadar saya lupa menambahkan sesuatu dalam A.

Bagaimana saya bisa menambahkan perubahan ini ke A menggunakan Magit? Saya bahkan tidak tahu bagian mana dari dokumentasi Git yang harus saya lihat.

Mathieu Marques
sumber

Jawaban:

69

Mari kita berpura-pura sejenak bahwa Anda ingin menambahkan sesuatu ke HEADkomit, yaitu "komit kedua B" dalam contoh Anda.

Popup komit pada cfitur " aAmend " mengikat . Menekan tombol itu akan "mengubah" perubahan bertahap pada HEADkomit. Karena komit tidak dapat diubah dalam Git, ini sebenarnya akan menggantikan komit lama dengan komit baru. Buffer dengan pesan komit lama akan muncul, sehingga Anda dapat memodifikasinya seandainya perubahan yang ditambahkan juga mengharuskan Anda menyesuaikan pesan. Seperti biasa, tekan C-c C-cketika Anda selesai mengedit pesan. Ini sama dengan berjalan git commit --amenddi baris perintah.

  • a Mengubah - menambahkan perubahan bertahap ke HEADdan mengedit pesan komitnya

Karena sering terjadi bahwa Anda hanya perlu menyesuaikan perubahan atau pesan, Magit menyediakan dua varian tambahan:

  • e Extend - tambahkan perubahan bertahap HEADtanpa mengedit pesan komit
  • w Reword - ubah pesan HEADtanpa menambahkan perubahan bertahap ke dalamnya

Ketika Anda ingin mengedit komit yang tidak HEAD, maka di atas tidak akan berfungsi. Perintah-perintah ini selalu "memodifikasi" (yaitu mengganti) HEADkomit. Git tidak menyediakan perintah tunggal untuk memodifikasi komit selain HEADjadi ini sedikit lebih terlibat.

Magit memang memberikan perintah seperti itu, tetapi karena ada situasi di mana lebih disukai untuk melakukan ini dalam beberapa langkah, kita akan membahasnya terlebih dahulu.

Mengubah komit selain HEADdapat dibagi menjadi tiga langkah:

  1. Buat sementara itu komit lain ( A) HEAD.
  2. Ubah HEAD(seperti dijelaskan di atas), menghasilkan komit A'.
  3. Beri tahu Git untuk menerapkan kembali komitmen yang diikuti A, tetapi di atas A'.

Ini dapat dilakukan dengan menggunakan rebase interaktif. Ketik runtuk menampilkan munculan rebase. Kemudian ketik muntuk memohon varian rebase "edit sebuah komit". Buffer dengan komit terbaru muncul. Pindah ke komit yang ingin Anda modifikasi dan ketik C-c C-cuntuk memilihnya. Git kemudian memundurkan riwayat ke komit itu dan menunjukkan informasi tentang rebase yang sedang berlangsung di buffer status.

Ubah HEADseperti dijelaskan di atas. Lalu beri tahu Git bahwa Anda selesai dengan mengetik r r. Jika A'dan Bkonflik maka rebase akan berhenti Bdan Anda harus menyelesaikan konflik. Setelah selesai, tekan r runtuk melanjutkan.

Jika Anda tahu bahwa perubahan Anda Aakan mengakibatkan konflik dengan B, maka lanjutkan seperti yang dijelaskan di atas, jika tidak gunakan pendekatan berikut.


Git memungkinkan membuat "fixup commit" menggunakan git commit --fixup A. Ini menciptakan komit baru , yang mencatat perubahan yang "seharusnya dibuat di komit lain". Komit itu menjadi yang baru HEAD. Ada juga --squashvarian. Untuk informasi tentang perbedaan, lihat git-commithalaman manual.

Untuk benar-benar menggabungkan Akomit dan komit baru A'dan kemudian mengajukan kembali Bdi atas itu Anda harus menggunakan rebase. Magit menyediakan perintah yang mudah untuk melakukannya r f.

Perbedaan utama dengan pendekatan di atas adalah bahwa di sini kita pertama-tama membuat komit baru dan kemudian kita rebase untuk menggabungkannya dengan "target" dan mengajukan permohonan kembali B. Di atas kami mulai dengan rebasing bukannya melakukan.

Dalam Magit baik --fixupdan --squashvarian yang tersedia dari komit popup, di fdan s. Tetapi Magit juga menyediakan varian "instan" dari perintah fixup dan squash pada Fdan S. Varian ini membuat komit baru seperti varian "non-instan", tetapi kemudian mereka langsung menggabungkan komit fixup dengan komit target menggunakan rebase, tanpa Anda harus memanggil perintah lain.

"Perbaikan instan" ( c F) pada dasarnya sama dengan "memperpanjang HEAD" ( c e), kecuali itu berfungsi untuk komit apa pun, bukan hanya HEAD.


Bacaan lebih lanjut:

tarsius
sumber
Jelas! Terima kasih, paket luar biasa BTW.
Mathieu Marques
1
Yah, saya pikir ada beberapa bagian lembek di bagian kedua dari jawaban saya. Tetapi untuk menghindari itu saya harus menggandakan panjang jawaban yang sudah lama ini, jadi saya senang ini bekerja untuk Anda ;-)
tarsius
Terima kasih atas jawaban ini tarsius, ini benar-benar bekerja untuk saya.
anquegi
Kejelasan bagian pertama dari penjelasan ini membuat membaca bagian kedua, yang jauh lebih sulit untuk diikuti, cukup membuat frustrasi!
Lyn Headley
git-commithalaman manual pengalihan ke git-rebase(1)yang memiliki baris ini: Pesan komit yang disarankan untuk komit dilipat adalah gabungan dari pesan komit dari komit pertama dan orang-orang dengan perintah "squash", tetapi menghilangkan pesan komit komit dengan "fixup" perintah. IOW, menggunakan fixup jika Anda hanya ingin memperbaiki kode di komit sebelumnya, penggunaan labu jika Anda juga ingin memperbaiki pesan commit.
Yasushi Shoji
3

git commit --amend –C HEADadalah perintah Git yang ingin Anda cari, dan Anda dapat melakukan perbaikan dengan Magit C-c C-a.

Ryan
sumber
Saya menggunakan Magit terbaru, C-c C-adari versi yang lebih lama (saya pikir). Selain itu, saya tidak melihat jejak "ubah" di buffer bantuan ( ?).
Mathieu Marques
Lihat jawaban Rémi untuk setara dengan magit 2.x.
npostavs
3

Jadi satu alur kerja adalah:

  • buat perubahan Anda
  • c (komit) f (fixup - pilih komit fixing Anda)

Kemudian

  • r (rebase) -a (autosquash, dapat di-default) i (interaktif)

Autosquash secara otomatis akan memindahkan semua! Fixup melakukan ke tempat yang tepat dan mengaturnya untuk terjepit di re-base.

stsquad
sumber
Satu-satunya hal yang saya lakukan yang tidak Anda katakan adalah naik di antara peluru pertama dan kedua Anda. Memukul imenghasilkan saya Cannot rebase: Your index contains uncommitted changes. Please commit or stash them.. Kecuali saya tidak memiliki perubahan yang tidak dikomit. : /
Mathieu Marques
Mencoba lagi setelah menarik Proceed despite merge in rebase range? [c]ontinue, [s]elect other, [a]bort,. Apakah ini mencoba untuk memberi tahu saya bahwa perbaikan saya mungkin gagal pada penggabungan yang akan datang?
Mathieu Marques
@MathieuMarques: "Kecuali saya tidak memiliki perubahan yang tidak dikomit" - git berpikir Anda lakukan. Perhatikan pesan menyarankan perubahan bertahap, bukan perubahan bertahap. Re : merge in rebase, lihat BUGS di bawah git help rebase. Saya sarankan melakukan perbaikan sebelum menarik ke atas.
npostavs
1

Untuk mengubah komit terakhir, ini "c a". Fixup adalah untuk memperbaiki beberapa commit yang lebih lama.

Resi
sumber
Yang mana masalahnya, saya melakukan posting A kemudian B. Diperbarui untuk kejelasan.
Mathieu Marques