Kembalikan rentang komit di git

128

Bagaimana cara mengembalikan rentang komit di git? Dari melihat dokumentasi gitrevision , saya tidak dapat melihat cara menentukan kisaran yang saya butuhkan. Sebagai contoh:

A -> B -> C -> D -> E -> HEAD

Saya ingin melakukan hal yang setara dengan:

git revert B-D

dimana hasilnya adalah:

A -> B -> C -> D -> E -> F -> HEAD

di mana F berisi kebalikan dari BD inklusif.

Alex Spurling
sumber
Menjelang akhir halaman gitrevision (7), ada bagian yang berjudul "SPECIFYING RANGES". Apa yang Anda inginkan berbeda dari yang dijelaskan di sana?
Gareth McCaughan
2
Halaman gitrevision menyarankan bahwa 'git revert A..D' akan melakukan apa yang saya inginkan. Namun ketika saya mencoba, saya mendapatkan kesalahan "fatal: Tidak dapat menemukan 'A..D'"
Alex Spurling

Jawaban:

173

Versi Git apa yang Anda gunakan?

Mengembalikan beberapa commit hanya didukung di Git1.7.2 +: lihat " Rollback ke commit lama menggunakan pengembalian beberapa kali. " Untuk detail selengkapnya. Halaman manual
saat ini hanya untuk versi Git saat ini (1.7.4+).git revert


Seperti yang dilaporkan OP Alex Spurling di komentar:

Mengupgrade ke 1.7.4 berfungsi dengan baik.
Untuk menjawab pertanyaan saya sendiri, inilah sintaks yang saya cari:

git revert B^..D 

B^berarti "komit orang tua pertama dari B": yang memungkinkan untuk disertakan Bdalam pengembalian.
Lihat " git rev-parseMENENTUKAN bagian REVISI " yang menyertakan sintaks <rev>^, misalnyaHEAD^ : lihat lebih lanjut di " Apa arti karakter tanda sisipan ( ^)? ")

Perhatikan bahwa setiap komit yang dikembalikan dilakukan secara terpisah.

Henrik N mengklarifikasi di komentar :

git revert OLDER_COMMIT^..NEWER_COMMIT

Seperti yang ditunjukkan di bawah ini, Anda dapat kembali tanpa langsung melakukan:

git revert -n OLDER_COMMIT^..NEWER_COMMIT
git commit -m "revert OLDER_COMMIT to NEWER_COMMIT"
VonC
sumber
1
Terima kasih, itulah jawabannya. Mengupgrade ke 1.7.4 berfungsi dengan baik. Untuk menjawab pertanyaan saya sendiri, ini adalah sintaks yang saya cari: git revert B ^ .. D
Alex Spurling
jenius. Terima kasih. Tidak terpikir oleh saya bahwa saya harus mengembalikan komitmen dalam urutan terbalik agar tambalan diterapkan, ya. Perintah ini menunjukkan jalannya.
Tim Abell
5
Saya sering merujuk kembali ke jawaban ini, dan saya selalu butuh waktu untuk mengetahui urutannya. Jadi untuk membantu diri saya di masa depan:git revert OLDER_COMMIT^..NEWER_COMMIT
Henrik N
2
apa artinya ^?
Dustin Getz
1
@DustinGetz orang tua pertama: lihat git-scm.com/docs/gitrevisions : "Sufiks ^ke parameter revisi berarti induk pertama dari objek commit itu".
VonC
15

Jika Anda ingin mengembalikan rentang komit B ke D (setidaknya dalam git versi 2) dalam satu komit, Anda dapat melakukannya

 git revert -n B^..D

Ini mengembalikan perubahan yang dilakukan oleh komit dari komit induk B (dikecualikan) ke komit D (disertakan), tetapi tidak membuat komit apa pun dengan perubahan yang dikembalikan. Kembalikan hanya mengubah pohon kerja dan indeks.

Jangan lupa untuk melakukan perubahan setelahnya

 git commit -m "revert commit range B to D"

Anda juga dapat mengembalikan beberapa komit yang tidak terkait dalam satu komit, menggunakan metode yang sama. misalnya untuk mengembalikan B dan D tetapi bukan C

 git revert -n B D
 git commit -m "Revert commits B and D"

Referensi: https://www.kernel.org/pub/software/scm/git/docs/git-revert.html

Terima kasih Honza Haering atas koreksinya

Ramast
sumber
3
git revert -n B..Dtidak mengembalikan commit B, hanya C dan D. git revert -n B^..Djuga mengembalikan B.
Honza Haering
menurut dokumentasi git yang dilakukannya. referensi di pos
Ramast
1
Jika Anda mengacu pada contoh ini (yang menurut saya agak membingungkan) di referensi git revert -n master~5..master~2:, dikatakan komit terbaru kelima disertakan. Tapi master~5sebenarnya komit terbaru ke-6. Lihat pilihan revisi di dokumen git untuk info rinci tentang ..notasi :-)
Honza Haering
6

Melakukan git revert OLDER_COMMIT^..NEWER_COMMITtidak berhasil untuk saya.

Saya menggunakan git revert -n OLDER_COMMIT^..NEWER_COMMITdan semuanya baik-baik saja. Saya menggunakan versi git 1.7.9.6.

Orlando
sumber
Saya mengalami masalah yang sama dan memperbaikinya menggunakan -n, tetapi Anda harus meninggalkan ^ dengan OLDER_COMMIT (git revert -n OLDER_COMMIT ^ .. NEWER_COMMIT).
FeelGood
@FeelGood mengapa Anda harus meninggalkan ^?
Orlando
Saya memiliki riwayat A -> B -> C dan tujuannya adalah mengembalikan B dan C. Ketika saya menjalankan 'git revert -n B..C', hanya C yang dikembalikan. Saat saya menggunakan 'git revert -n B ^ .. C', git mengembalikan kedua commit. Mungkin saya melakukan sesuatu yang salah.
FeelGood
keren, baik harus mengujinya tetapi saya pikir dalam kasus saya bekerja dengan baik (kecuali saya mengembalikan 1 rentang komit lol) saya akan mengubah jawaban untuk menyertakan ^. terima kasih
Orlando
2
The -natau --no-commitpilihan akan mengembalikan semua perubahan di kisaran di satu komit, bukan menciptakan revert komit untuk setiap komit dalam kisaran. Hasil akhirnya sama, perubahan yang sama akan dikembalikan. Tergantung bagaimana Anda ingin histori git Anda terlihat.
Dennis
0

Gunakan git rebase -iuntuk memadatkan komitmen yang relevan menjadi satu. Kemudian Anda hanya memiliki satu komitmen untuk kembali.

Graham Borland
sumber
7
Jika menggunakan git rebase, Anda cukup menghapus komit. Saya pikir ada alasan untuk tidak melakukan rebase, seperti ingin menjaga SHA1 dari commit F yang sama.
Paŭlo Ebermann
5
Cara lainnya, gabungkan komitmen pengembalian menjadi satu.
aeosynth