Bagaimana membatalkan komitmen terakhir, komitmen tanpa dipaksa git tanpa kehilangan perubahan

540

Apakah ada cara untuk mengembalikan komit sehingga salinan lokal saya menyimpan perubahan yang dibuat dalam komit itu, tetapi mereka menjadi perubahan yang tidak berkomitmen pada copy pekerjaan saya? Mengembalikan komit membawa Anda ke komit sebelumnya - Saya ingin menyimpan perubahan yang dibuat tetapi saya mengikatnya ke cabang yang salah.

Ini belum didorong, hanya dilakukan.

Pak Boy
sumber
6
git reset --softdan git reset --mixedkeduanya melakukan ini (sedikit berbeda), lihat git-reset
torek

Jawaban:

932

Ada banyak cara untuk melakukannya, misalnya:

jika Anda belum mendorong komit ke publik:

git reset HEAD~1 --soft   

Itu saja, perubahan komit Anda akan berada di direktori kerja Anda, sedangkan komit TERAKHIR akan dihapus dari cabang Anda saat ini. Lihat git reset man


Dalam kasus Anda lakukan dorongan publik (pada cabang yang disebut 'master'):

git checkout -b MyCommit //save your commit in a separate branch just in case (so you don't have to dig it from reflog in case you screw up :) )

kembalikan komit secara normal dan tekan

git checkout master
git revert a8172f36 #hash of the commit you want to destroy
# this introduces a new commit (say, it's hash is 86b48ba) which removes changes, introduced in the commit in question (but those changes are still visible in the history)
git push origin master

sekarang jika Anda ingin memiliki perubahan itu saat Anda melakukan perubahan lokal di copy pekerjaan Anda ("sehingga salinan lokal Anda menyimpan perubahan yang dibuat di komit itu") - hanya mengembalikan opsi komit kembali dengan --no-commit:

git revert --no-commit 86b48ba (hash of the revert commit).

Saya telah membuat contoh kecil: https://github.com/Isantipov/git-revert/commits/master

Isantipov
sumber
5
terima kasih banyak, dalam kasus saya, saya memiliki dua komitmen yang ingin saya batalkan, dan menjalankan 'git reset HEAD ~ 1 --soft' dua kali berturut-turut membawa saya ke tempat yang saya butuhkan.
Geoff Gunter
2
untuk menambahkan sedikit kejelasan karena jika Anda tidak menggunakan CLI, resetperintah pertama yang disebutkan mengatakan "lembut" reset ke 1 rev sebelum head, yang mempertahankan semua perubahan lokal. ini tidak segera jelas bagi saya untuk digunakan dalam SourceTree. pastikan saja Anda mengatur ulang dengan lembut ke rev sebelumnya, bukan rev yang Anda coba setel ulang
Jon B
1
Saya mencoba pendekatan "sudah didorong" dan itu tidak berhasil untuk saya, dengan git 2.14.1: dikatakan "Already up to date"ketika melakukan penggabungan.
Fabio A.
1
@FabioA. , Saya telah memperbarui jawabannya dengan versi yang berfungsi. Terima kasih telah memperhatikan ini!
Isantipov
1
Ini tidak berhasil. Saya melewatkan reset dan melakukan dan hanya melakukan git mengembalikan dan mendorong keluar ... sekarang mungkin perubahan hilang belum yakin ... untungnya saya membuat cadangan dengan cara mudah semoga yang satu masih akan bekerja;) kalau tidak dapat menyalin perubahan dari yang itu .
Terbang Skybuck
13

Jika Anda mendorong perubahan, Anda bisa undodan memindahkan file kembali ke panggung tanpa menggunakan cabang lain.

git show HEAD > patch
git revert HEAD
git apply patch

Ini akan membuat file tambalan yang berisi perubahan cabang terakhir. Kemudian mengembalikan perubahan. Dan akhirnya, terapkan file tambalan ke pohon kerja.

Aminadav Glickshtein
sumber
Anda mungkin ingin rm patchjuga
Max Coplan
6

Untuk kasus ini: "Ini belum didorong, hanya dilakukan ." - jika Anda menggunakan IntelliJ (atau JetBrains IDE lainnya) dan Anda belum mendorong perubahan, Anda dapat melakukan selanjutnya.

  1. Pergi ke jendela Kontrol versi ( Alt + 9 / Command + 9 ) - tab "Log".
  2. Klik kanan pada komit sebelum yang terakhir.
  3. Setel ulang cabang saat ini ke sini
  4. pilih Soft (!!!)
  5. tekan tombolReset di bagian bawah jendela dialog.

Selesai

Ini akan "membatalkan komitmen" perubahan Anda dan mengembalikan status git Anda ke titik sebelum komit lokal terakhir Anda. Anda tidak akan kehilangan perubahan yang Anda buat.

Eduard Streltsov
sumber
2
Saya suka belajar cara JetBrains, terima kasih! Itu setara dengan git reset --soft "HEAD^"di Windows, btw. :)
payne
3

Bagi saya kebanyakan hal itu terjadi ketika saya mendorong perubahan ke cabang yang salah dan menyadarinya nanti. Dan pekerjaan berikut di sebagian besar waktu.

git revert commit-hash
git push

git checkout my-other-branch
git revert revert-commit-hash
git push
  1. kembalikan komit
  2. (buat dan) checkout cabang lain
  3. kembalikan kembalikan
Mubashar
sumber
1
Saya menguji ini. Pendekatan Anda juga berfungsi jika Anda belum mendorong ke jarak jauh. $ git revert <commit-hash> ... lalu checkout beberapa cabang lain, lalu ketik $ git revert <revert-commit-hash> (tanpa dorongan). Terima kasih telah berbagi pendekatan sederhana ini !!
Natalie Cottrill
2

2020 cara sederhana:

git reset <commit_hash>

Komit hash dari commit terakhir yang ingin Anda pertahankan.

Xys
sumber
1

Harap pastikan untuk membuat cadangan perubahan Anda sebelum menjalankan perintah ini di folder terpisah

git checkout branch_name

Checkout di cabang Anda

git merge --abort

Batalkan penggabungan

status git

Periksa status kode setelah membatalkan penggabungan

git reset --barang asli / branch_name

perintah ini akan mengatur ulang perubahan Anda dan menyelaraskan kode Anda dengan kode branch_name (branch).

Mohit Singh
sumber