Membatalkan komit tertentu di Git yang telah didorong ke repo jarak jauh

789

Apa cara paling sederhana untuk membatalkan komitmen tertentu yaitu:

  • tidak di kepala atau KEPALA
  • Telah didorong ke remote.

Karena jika itu bukan komitmen terbaru,

git reset HEAD

tidak bekerja Dan karena telah didorong ke remote,

git rebase -i

dan

git rebase --onto

akan menyebabkan beberapa masalah di remote.

Terlebih lagi, saya benar-benar tidak ingin memodifikasi sejarah. Jika ada kode buruk, itu ada di sana dalam sejarah dan bisa dilihat. Saya hanya ingin itu dalam copy pekerjaan, dan saya tidak keberatan komit penggabungan terbalik.

Dengan kata lain, apa yang setara dengan Git dari perintah svn berikut:

svn merge -r 303:295 http://svn.example.com/repos/calc/trunk

yang menghapus semua perubahan dari 295 hingga 302 dengan membalikkan semua perubahan dalam revisi tersebut, sebagai komit baru.

svn merge -c -302 ^/trunk

yang membatalkan 302 commit, tentu saja dengan menambahkan commit lain yang membalikkan menggabungkan perubahan dari commit tersebut.

Saya pikir itu harus menjadi operasi yang cukup sederhana di Git dan kasus penggunaan yang cukup umum. Apa lagi maksud dari komitmen atom?

Kami memiliki staging stashing dan semuanya untuk memastikan bahwa komit adalah atomik sempurna, tidakkah Anda dapat membatalkan satu atau lebih dari komit atomik itu dengan mudah?

Lakshman Prasad
sumber

Jawaban:

1211

Identifikasi hash dari commit, gunakan git log, kemudian gunakan git revert <commit>untuk membuat komit baru yang menghapus perubahan ini. Di satu sisi, git revertadalah kebalikan dari git cherry-pick- yang terakhir menerapkan patch ke cabang yang hilang, yang pertama menghapusnya dari cabang yang memilikinya.

Andrew Aylett
sumber
237
Dan gunakan tombol -n jika Anda ingin kode itu kembali, tetapi tidak secara otomatis dilakukan lagi
jaygooby
17
Apa yang dilakukan opsi "m"? Saya mencoba git revert 8213f7d tetapi mendapatkan ini sebagai gantinya: error: Commit 8213f7dad1ed546b434a0d8a64cb783b530a5a30 merupakan penggabungan tetapi opsi -m tidak diberikan. fatal: revert gagal
Malcolm
10
Untuk mengembalikan gabungan: git revert -m 1 <hash>
brunozrk
31
Peringatan bagi siapa saja yang ingin mengembalikan gabungan: git revert akan membatalkan semua perubahan data (yaitu, perubahan file akan dikembalikan), tetapi gabungan masih tetap dalam sejarah. Karenanya, jika Anda mencoba menggabungkan cabang yang sama lagi nanti, ia tidak akan menyertakan komit apa pun dari cabang gabungan sebelum penggabungan yang dikembalikan. Ini kemungkinan besar bukan yang Anda inginkan. Untuk sepenuhnya menggabungkan cabang lagi, Anda harus terlebih dahulu mengembalikan komit tempat Anda mengembalikan gabungan asli. Pelajari lebih lanjut di sini: kernel.mirrors.pair.com/pub/software/scm/git/docs/howto/…
etreworgy
3
Tautan dalam komentar oleh @etreworgy adalah 404. Saya menduga ini adalah versi terbaru tautan: kernel.org/pub/software/scm/git/docs/howto/…
Tim Smith
368

Saya tidak suka komit otomatis yang git revertmelakukannya, jadi ini mungkin bermanfaat bagi sebagian orang.

Jika Anda hanya ingin file yang dimodifikasi bukan komitmen otomatis , Anda dapat menggunakannya--no-commit

% git revert --no-commit <commit hash>

yang sama dengan -n

% git revert -n <commit hash>
Terima kasih
sumber
9
Anda juga dapat melakukannya git reset HEAD~1 --softjika Anda sudah kembali tanpa-n
Daniel
1
Tetapi git reset HEAD~ntidak akan menyelesaikan kehancuran dari komitmen yang tidak dapat dijangkau dari kepala. Kueri adalah untuk mengembalikan komit tertentu.
sangeethkumarp
Saya menggunakan solusi ini tetapi mengalami konflik di tengah-tengah pemulihan. Setelah menyelesaikan konflik, saya melakukan git revert --continueseperti yang diperintahkan kepada saya. Itu berhasil, tetapi sayangnya hasilnya berkomitmen. Mungkin saya perlu melakukannya git revert --no-commit --continue.
mareoraft
1
@sangeethkumarp komentar oleh Daniel adalah langkah tambahan yang dapat Anda ambil setelah git revert, jika Anda lupa -n; karena pada saat itu komit terakhir adalah pengembalian, sehingga soft reset akan membatalkan komit itu tetapi tidak terkait perubahan kode revert
Oliver
@Daniel memberikan solusi dengan pekerjaan komentar untuk saya Terima kasih banyak 'git reset HEAD ~ 1 --soft' '
Md. Abu Sayed
41

Karena sudah didorong, Anda tidak boleh secara langsung memanipulasi sejarah. git revertakan mengembalikan perubahan spesifik dari komit menggunakan komit baru, sehingga tidak memanipulasi riwayat komit.

moatPylon
sumber
1

Jika komit yang ingin Anda kembalikan adalah komit gabungan (sudah digabung), maka Anda harus memilih salah satu -m 1atau -m 2seperti yang ditunjukkan di bawah ini. Ini akan memberi tahu git komit mana dari komit gabungan untuk digunakan. Rincian lebih lanjut dapat ditemukan di SINI .

  • git revert <commit> -m 1
  • git revert <commit> -m 2
Meysam Sadeghi
sumber