Bagaimana cara "membatalkan pengembalian" komit Git yang dikembalikan?
486
Mengingat perubahan yang telah dilakukan menggunakan commit, dan kemudian menggunakan kembali revert, apa cara terbaik untuk membatalkan pemulihan itu?
Idealnya, ini harus dilakukan dengan komit baru, agar tidak menulis ulang sejarah.
Perhatikan bahwa jika Anda ingin membatalkan kembalikan tanpa segera menerapkan perubahan asli ke cabang master, Anda dapat (1) mengembalikan cabang asli jika dihapus, (2) klik "kembalikan" pada cabang kembalikan seperti dicatat oleh Adam, lalu ( 3) klik "edit" di header PR yang dihasilkan dan ubah cabang target menjadi cabang asli alih-alih master. Sekarang cabang asli Anda dapat digabung kembali untuk mempengaruhi perubahan yang sebelumnya dikembalikan.
pauljm
1
Harap dicatat ini akan menghapus semua perubahan pada pohon dan indeks kerja. Gunakan simpanan git untuk menyimpan perubahan yang tidak akan hilang.
zpon
3
Apa kelebihan metode checkout && commit? Tampaknya dalam kasus umum git cherry-pickatau sebagai alternatif git revertadalah cara yang paling mudah untuk mengembalikan sebuah pemulihan.
Robert Jack Will
5
Saya pikir akan sangat membantu untuk menunjukkan caranya:, Otherwise, reverting the revert is perfectly fine.dan kemudian juga menjelaskan apa yang git checkout HEAD^^ -- .sedang dilakukan.
Todd
3
Tuan yang baik, jangan gunakan git add -A... kecuali jika Anda ingin menambahkan setiap file ke kontrol versi, yang kemungkinan besar tidak apa yang Anda inginkan.
Kaitain
474
git cherry-pick <original commit sha>
Akan membuat salinan komit asli, pada dasarnya menerapkan ulang komit
Mengembalikan revert akan melakukan hal yang sama, dengan pesan komit yang berantakan: git revert <commit sha of the revert>
Salah satu dari cara-cara ini akan memungkinkan Anda untuk git pushtanpa menimpa riwayat, karena itu menciptakan komit baru setelah pengembalian.
Saat mengetik komit sha, Anda biasanya hanya membutuhkan 5 atau 6 karakter pertama: git cherry-pick 6bfabc
Ini adalah solusi paling mudah dan elegan untuk pertanyaan OPs. Jauh lebih baik daripada jawaban yang diterima dengan asumsi tentang komit revert berada di KEPALA pohon komit. Op juga secara khusus meminta solusi yang tidak menulis ulang sejarah sehingga solusi keras yang ditawarkan dalam jawaban yang diterima benar-benar salah.
Timo
6
@Timo Untuk memperjelas, jawaban yang diterima berisi solusi yang saya gunakan ("reverting the revert"), dan diposting dalam beberapa jam setelah pertanyaan saya - jelas 3 tahun lebih awal dari jawaban ini. Karenanya, tanda centang.
JimmidyJoo
6
@JimmidyJoo Saya tahu saya terlambat 3 tahun, saya hanya ingin orang datang ke sini dari pencarian google untuk melihat jawaban yang lebih baik
Stephan
2
@Stephan Yep, tapi sekali lagi, untuk memperjelas - ini adalah jawaban yang lebih baik, bukan yang saya gunakan untuk menyelesaikan masalah saya. Saya hanya mengomentari mengapa tanda centang ada di mana. Pertanyaan untuk semua: apakah konvensi SO mendikte bahwa saya harus "mempertahankan" pertanyaan saya sebelumnya dan menetapkan kembali tanda centang sebagai jawaban baru masuk?
JimmidyJoo
3
@JimmidyJoo Saya tidak tahu tentang konvensi SO. Tetapi sebagai pencari google, saya benar-benar lebih suka melihat jawaban yang lebih baik diperiksa. Dan akan menghargai upaya siapa pun untuk mempertahankan pertanyaan masa lalu mereka.
Paiman Roointan
30
Revert commit sama seperti commit lainnya di git. Artinya, Anda dapat mengembalikannya, seperti pada:
Itu jelas hanya masuk akal setelah perubahan didorong, dan terutama ketika Anda tidak bisa memaksa mendorong ke cabang tujuan (yang merupakan ide bagus untuk cabang master Anda ). Jika perubahan belum didorong, lakukan saja cherry-pick, kembalikan, atau cukup hapus komit pengembalian sesuai kiriman lainnya.
Di tim kami, kami memiliki aturan untuk menggunakan revert on Revert commit yang dilakukan di cabang utama, terutama untuk menjaga sejarah tetap bersih, sehingga Anda dapat melihat commit mana yang mengembalikan apa:
Dengan cara ini, Anda dapat melacak sejarah dan mencari tahu keseluruhan cerita, dan bahkan mereka yang tidak memiliki pengetahuan tentang warisan dapat mengatasinya sendiri. Sedangkan, jika Anda memilih atau mengganti barang, informasi berharga ini hilang (kecuali Anda memasukkannya dalam komentar).
Jelas, jika suatu komit dikembalikan dan dipulihkan kembali lebih dari sekali, itu menjadi sangat berantakan.
Ini terlihat bodoh bagi saya. Tetapi saya telah berada dalam situasi yang sama dan saya kembali untuk komitmen yang dikembalikan. Saya melakukan number reverts jadi saya harus melakukan revert untuk setiap 'reit commit'.
Sekarang sejarah komit saya terlihat sedikit aneh.
Ini adalah proyek kesayangan jadi tidak masalah. Tetapi untuk proyek kehidupan nyata saya akan memberikan preferensi untuk pergi ke komit terakhir sebelum mengembalikan semua kode yang dikembalikan bersama dalam satu komit dan komentar yang lebih masuk akal.
Anda dapat menghindari komit otomatis dan memilih komit yang Anda gunakan menggunakan --no-commit flag ketika kembali dan kemudian berkomitmen dengan pesan yang relevan
David Barda
Anda juga dapat menentukan beberapa id komit saat menggunakan git revert (menurut saya harus berada dalam urutan yang benar).
Aalex Gabi
Bisakah saya melakukannya dari desktop github?
Guillaume F.
4
Begini cara saya melakukannya:
Jika cabang my_branchnamedimasukkan dalam gabungan yang bisa dipulihkan. Dan saya ingin membatalkan my_branchname:
Saya pertama kali melakukan git checkout -b my_new_branchnamedari my_branchname.
Lalu saya melakukan di git reset --soft $COMMIT_HASHmana $COMMIT_HASHhash komit dari komit tepat sebelum komit pertama my_branchname(lihat git log)
Kemudian saya membuat komit baru git commit -m "Add back reverted changes"
Kemudian saya mendorong cabang baru git push origin new_branchname
Lalu saya membuat permintaan tarik untuk cabang baru.
Cara untuk pergi ketika ada terlalu banyak "cherry-pick" untuk dilakukan. Saya tidak mengerti mengapa jawaban ini memiliki sedikit
upvote
2
Atau Anda bisa git checkout -b <new-branch>dan git cherry-pick <commit>sebelum ke dan git rebaseuntuk menjatuhkan revertkomit. kirim permintaan tarik seperti sebelumnya.
Jika Anda tidak menyukai gagasan "reverting a revert" (terutama ketika itu berarti kehilangan informasi riwayat untuk banyak komit), Anda selalu dapat menuju ke dokumentasi git tentang "Reverting a faulty merger" .
Ide bagus dan terima kasih atas tautan dokumen. Kami biasanya rebase dengan master sebelum bergabung kembali, tetapi git kemudian tampaknya menyadari bahwa A ', B', C 'sama dengan yang sebelumnya, dan saya sekarang memiliki D, E setelah W ( pastebin ). Saran tentang cara mengatasi ini?
Kristoffer Bakkejord
0
Untuk mendapatkan kembali perubahan yang tidak dipentaskan dan dipentaskan yang dikembalikan setelah komit:
git reset HEAD@{1}
Untuk memulihkan semua penghapusan yang tidak bertahap:
Jawaban:
Jika Anda belum mendorong perubahan itu,
git reset --hard HEAD^
Kalau tidak, mengembalikan reverting baik-baik saja.
Cara lain adalah dengan
git checkout HEAD^^ -- .
dan kemudiangit add -A && git commit
.sumber
git cherry-pick
atau sebagai alternatifgit revert
adalah cara yang paling mudah untuk mengembalikan sebuah pemulihan.Otherwise, reverting the revert is perfectly fine.
dan kemudian juga menjelaskan apa yanggit checkout HEAD^^ -- .
sedang dilakukan.git add -A
... kecuali jika Anda ingin menambahkan setiap file ke kontrol versi, yang kemungkinan besar tidak apa yang Anda inginkan.git cherry-pick <original commit sha>
Akan membuat salinan komit asli, pada dasarnya menerapkan ulang komit
Mengembalikan revert akan melakukan hal yang sama, dengan pesan komit yang berantakan:
git revert <commit sha of the revert>
Salah satu dari cara-cara ini akan memungkinkan Anda untuk
git push
tanpa menimpa riwayat, karena itu menciptakan komit baru setelah pengembalian.Saat mengetik komit sha, Anda biasanya hanya membutuhkan 5 atau 6 karakter pertama:
git cherry-pick 6bfabc
sumber
Revert commit sama seperti commit lainnya di git. Artinya, Anda dapat mengembalikannya, seperti pada:
Itu jelas hanya masuk akal setelah perubahan didorong, dan terutama ketika Anda tidak bisa memaksa mendorong ke cabang tujuan (yang merupakan ide bagus untuk cabang master Anda ). Jika perubahan belum didorong, lakukan saja cherry-pick, kembalikan, atau cukup hapus komit pengembalian sesuai kiriman lainnya.
Di tim kami, kami memiliki aturan untuk menggunakan revert on Revert commit yang dilakukan di cabang utama, terutama untuk menjaga sejarah tetap bersih, sehingga Anda dapat melihat commit mana yang mengembalikan apa:
Dengan cara ini, Anda dapat melacak sejarah dan mencari tahu keseluruhan cerita, dan bahkan mereka yang tidak memiliki pengetahuan tentang warisan dapat mengatasinya sendiri. Sedangkan, jika Anda memilih atau mengganti barang, informasi berharga ini hilang (kecuali Anda memasukkannya dalam komentar).
Jelas, jika suatu komit dikembalikan dan dipulihkan kembali lebih dari sekali, itu menjadi sangat berantakan.
sumber
Mengembalikan revert akan melakukan trik
Sebagai contoh,
Jika
abcdef
adalah komit danghijkl
komit yang Anda miliki saat mengembalikan komitabcdef
, jalankan:Ini akan mengembalikan revert
sumber
Ini terlihat bodoh bagi saya. Tetapi saya telah berada dalam situasi yang sama dan saya kembali untuk komitmen yang dikembalikan. Saya melakukan number reverts jadi saya harus melakukan revert untuk setiap 'reit commit'.
Sekarang sejarah komit saya terlihat sedikit aneh.
Ini adalah proyek kesayangan jadi tidak masalah. Tetapi untuk proyek kehidupan nyata saya akan memberikan preferensi untuk pergi ke komit terakhir sebelum mengembalikan semua kode yang dikembalikan bersama dalam satu komit dan komentar yang lebih masuk akal.
sumber
Begini cara saya melakukannya:
Jika cabang
my_branchname
dimasukkan dalam gabungan yang bisa dipulihkan. Dan saya ingin membatalkanmy_branchname
:Saya pertama kali melakukan
git checkout -b my_new_branchname
darimy_branchname
.Lalu saya melakukan di
git reset --soft $COMMIT_HASH
mana$COMMIT_HASH
hash komit dari komit tepat sebelum komit pertamamy_branchname
(lihatgit log
)Kemudian saya membuat komit baru
git commit -m "Add back reverted changes"
Kemudian saya mendorong cabang baru
git push origin new_branchname
Lalu saya membuat permintaan tarik untuk cabang baru.
sumber
Atau Anda bisa
git checkout -b <new-branch>
dangit cherry-pick <commit>
sebelum ke dangit rebase
untuk menjatuhkanrevert
komit. kirim permintaan tarik seperti sebelumnya.sumber
Jika Anda tidak menyukai gagasan "reverting a revert" (terutama ketika itu berarti kehilangan informasi riwayat untuk banyak komit), Anda selalu dapat menuju ke dokumentasi git tentang "Reverting a faulty merger" .
Diberikan situasi awal sebagai berikut
(W adalah pengembalian awal Anda dari gabungan M; D dan E adalah perbaikan untuk cabang fitur yang awalnya rusak / komit)
Anda sekarang dapat memutar ulang komit ke A, sehingga tidak satupun dari mereka "milik" gabungan yang dikembalikan:
Salinan baru dari cabang Anda sekarang dapat digabungkan
master
lagi:sumber
Untuk mendapatkan kembali perubahan yang tidak dipentaskan dan dipentaskan yang dikembalikan setelah komit:
Untuk memulihkan semua penghapusan yang tidak bertahap:
sumber