Git - Undo mendorong komitmen


609

Saya punya proyek di repositori jarak jauh, disinkronkan dengan repositori lokal (pengembangan) dan server satu (prod). Saya telah membuat beberapa perubahan yang sudah dilakukan yang didorong ke jarak jauh dan ditarik dari server. Sekarang, saya ingin membatalkan perubahan itu. Jadi saya bisa langsung git checkoutke komit sebelum perubahan dan komit perubahan baru, tapi saya kira akan ada masalah untuk mendorong mereka lagi ke jarak jauh. Ada saran tentang bagaimana saya harus melanjutkan?


Jawaban:


735

Anda dapat mengembalikan komitmen individu dengan:

git revert <commit_hash>

Ini akan membuat komit baru yang mengembalikan perubahan komit yang Anda tentukan. Perhatikan bahwa itu hanya mengembalikan komit tertentu, dan tidak melakukan setelah itu. Jika Anda ingin mengembalikan serangkaian komitmen, Anda dapat melakukannya seperti ini:

git revert <oldest_commit_hash>..<latest_commit_hash>

Ini mengembalikan komit antara dan termasuk komit yang ditentukan.

Lihatlah halaman manual git-revert untuk informasi lebih lanjut tentang git revertperintah ini. Lihat juga jawaban ini untuk informasi lebih lanjut tentang mengembalikan komit.


22
Dengan kata lain itu kembali ke <oldest_commit_hash>;)
David

7
@mr_jigsaw Usegit log
gitaarik

2
Dalam dokumentasi git, dikatakan bahwa kembalikan perintah mengembalikan komit antara komit pertama dan terakhir (keduanya termasuk pertama dan terakhir). Lihat Dokumentasi
Onur Demir

4
@ aod benar, jawaban ini perlu diperbarui. API git saat ini untuk revert telah <oldest_commit_hash>dimasukkan dalam daftar reverts
JHixson

4
dengan git 2.17.2 kembalikan <old> .. <new> tidak termasuk yang lama tetapi termasuk <new>
chingis

353

Solusi yang tidak menyimpan jejak "undo".

CATATAN: jangan lakukan ini jika seseorang sudah menarik perubahan Anda (saya hanya akan menggunakan ini pada repo pribadi saya)

melakukan:

git reset <previous label or sha1>

ini akan memeriksa ulang semua pembaruan secara lokal (jadi status git akan mencantumkan semua file yang diperbarui)

maka Anda "melakukan pekerjaan Anda" dan komit kembali perubahan Anda (Catatan: langkah ini opsional)

git commit -am "blabla"

Pada saat ini pohon lokal Anda berbeda dari jarak jauh

git push -f <remote-name> <branch-name>

akan mendorong dan memaksa jarak jauh untuk mempertimbangkan dorongan ini dan menghapus yang sebelumnya (menentukan nama jarak jauh dan nama cabang tidak wajib tetapi disarankan untuk menghindari memperbarui semua cabang dengan bendera pembaruan).

!! hati-hati beberapa tag mungkin masih menunjukkan komit yang dihapus !! cara-menghapus-a-remote-tag


4
-sebuah file yang dilacak akan dikomit -m komit mengikuti
jo_

3
Persis apa yang saya cari. Seseorang melakukan kesalahan komit dan mendorong dan mengembalikannya lagi sesudahnya. Cabang-cabang tidak dapat digabungkan karena ini dan saya ingin mendapatkan repositori berada dalam keadaan yang benar lagi (dan menghapus komit dari sejarah karena mereka yang salah sih)
byemute

1
"Label atau sha1 sebelumnya" manakah yang harus saya gunakan ?. Haruskah saya memasukkan yang "benar" terakhir atau yang sebelumnya dan melakukan kembali semua perubahan yang dilakukan oleh yang benar terakhir?
elysch

3
yang tepat sebelum komit yang salah
jo

1
Apa yang saya butuhkan. Saya telah mendorong cabang untuk menguasai karena kesalahan. Dan sebagai hasilnya, saya memiliki banyak sampah di sepanjang sejarah yang dilakukan. Saya baru saja melakukan git push -fkomit yang benar terakhir dan riwayat jauh dibersihkan! Terima kasih!
Anton Rybalko

193

Apa yang saya lakukan dalam kasus ini adalah:

  • Di server, pindahkan kursor kembali ke komit baik terakhir yang diketahui:

    git push -f origin <last_known_good_commit>:<branch_name>
    
  • Secara lokal, lakukan hal yang sama:

    git reset --hard <last_known_good_commit>
    #         ^^^^^^
    #         optional
    



Lihat contoh lengkap tentang cabang my_new_branchyang saya buat untuk tujuan ini:

$ git branch
my_new_branch

Ini adalah sejarah terbaru setelah menambahkan beberapa hal ke myfile.py:

$ git log
commit 80143bcaaca77963a47c211a9cbe664d5448d546
Author: me
Date:   Wed Mar 23 12:48:03 2016 +0100

    Adding new stuff in myfile.py

commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date:   Tue Mar 18 12:46:59 2016 +0100

    Initial commit

Saya ingin menyingkirkan komit terakhir, yang sudah didorong, jadi saya jalankan:

$ git push -f origin b4zad078237fa48746a4feb6517fa409f6bf238e:my_new_branch
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:me/myrepo.git
 + 80143bc...b4zad07 b4zad078237fa48746a4feb6517fa409f6bf238e -> my_new_branch (forced update)

Bagus! Sekarang saya melihat file yang diubah pada komit itu ( myfile.py) menunjukkan "tidak dipentaskan untuk komit":

$ git status
On branch my_new_branch
Your branch is up-to-date with 'origin/my_new_branch'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   myfile.py

no changes added to commit (use "git add" and/or "git commit -a")

Karena saya tidak ingin perubahan ini, saya hanya memindahkan kursor kembali secara lokal juga:

$ git reset --hard b4zad078237fa48746a4feb6517fa409f6bf238e
HEAD is now at b4zad07 Initial commit

Jadi sekarang HEAD ada di komit sebelumnya, baik di lokal maupun jarak jauh:

$ git log
commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date:   Tue Mar 18 12:46:59 2016 +0100

    Initial commit

10
Ini jawaban yang benar! ini persis apa yang perlu dilakukan dalam kasus saya, terima kasih belajar sesuatu yang baru hari ini :)
Egli Becerra

2
Ini jawaban yang benar! Ini terkait dengan komitmen push (!)!
powtac

3
Jika Anda ingin benar-benar mengembalikan perubahan (seolah-olah Anda tidak pernah mendorongnya), ini adalah jawaban yang benar.
Yakub

1
Jawaban sempurna. Bekerja dengan baik seperti yang diharapkan!
RafiAlhamd

2
Seseorang membelikan bir untuk pria ini!
Jay Nebhwani

72

Anda dapat REVERT (atau Anda juga bisa menyebutnya HAPUS ) Git Commit BOTH Locally dan Remotely jika Anda mengikuti langkah-langkah seperti yang diberikan di bawah ini melalui baris perintah git.

Jalankan perintah berikut untuk melihat id komit yang ingin Anda kembalikan

git log --oneline --decorate --graph

Anda akan mendapatkan seperti tangkapan layar berikut masukkan deskripsi gambar di sini

Jika Anda juga memeriksa jarak jauh (melalui Antarmuka Web) maka Anda dapat melihat bahwa ini akan sama seperti yang ditunjukkan di bawah ini

masukkan deskripsi gambar di sini

Sesuai tangkapan layar saat ini Anda sedang berada di commit id e110322 namun Anda ingin kembali ke 030bbf6 KEDUA LOKAL dan REMOTELY .

Lakukan langkah-langkah berikut untuk HAPUS / REVERT Komit Lokal + Jarak Jauh


Pertama Secara Lokal Mengembalikan untuk melakukan id 030bbf6

git reset --hard 030bbf6

diikuti oleh

git clean -f -d

Kedua perintah clean force reset untuk melakukan stage 030bbf6 seperti yang ditunjukkan di bawah ini dalam snapshot

masukkan deskripsi gambar di sini

sekarang jika Anda menjalankan git status maka Anda akan melihat bahwa Anda DUA Komit DIBALIK dari cabang jarak jauh seperti yang ditunjukkan di bawah ini masukkan deskripsi gambar di sini

Jalankan berikut untuk memperbarui indeks Anda (jika ada pembaruan). Disarankan agar Anda meminta semua pengembang untuk tidak menerima permintaan penarikan apa pun di cabang jarak jauh utama.

git fetch --all

Setelah Anda selesai dengan itu maka Anda diminta untuk Push komit ini secara paksa dengan menggunakan simbol + di depan cabang seperti yang ditunjukkan di bawah ini. Saya telah menggunakan di sini sebagai cabang utama , Anda dapat menggantinya dengan apa saja

masukkan deskripsi gambar di sini Kode

git push -u origin +master

sekarang jika Anda melihat antarmuka web dari remote maka komit di sana harus dikembalikan juga.

masukkan deskripsi gambar di sini


61

Ini akan menghapus komit Anda yang didorong

git reset --hard 'xxxxx'

git clean -f -d

git push -f

7
Metode ini dengan benar menulis ulang sejarah untuk menghapus komit. Luar biasa
Jesse Reza Khorasanee

2
jawaban ini adalah el magnifeco!
truthadjustr

3
Senang jawabannya, terima kasih :)
Dzenis H.

1
Hanya untuk menjadi jelas (saya tidak yakin): Komit akan menjadi komit saat ini setelah operasi. Bukan yang terakhir dihapus.
Maik639

21
git revert HEAD -m 1

Pada baris kode di atas. "Argumen terakhir mewakili"

  • 1 - mengembalikan satu komit.

  • 2 - mengembalikan dua komit terakhir.

  • n - mengembalikan n terakhir yang dilakukan.

Anda perlu menekan setelah perintah ini untuk mengambil efek pada jarak jauh. Anda memiliki opsi lain seperti menentukan rentang komitmen untuk kembali. Ini adalah salah satu opsi.


Kemudian gunakan git commit -am "COMMIT_MESSAGE" itu git pushataugit push -f


8
Ini tidak benar - parameter -m menentukan jumlah induk untuk dikembalikan ke (biasanya 1 jika Anda ingin mengembalikan masuk, "milik mereka", perubahan, yang bertentangan dengan 2 untuk perubahan digabung-ke, "milik kita" - untuk menggabungkan 2 berkomitmen). Ini tidak ada hubungannya dengan jumlah komit yang dikembalikan - jika Anda ingin mengembalikan rentang komit, gunakangit revert ref1..ref2
Null Reference

1
Tidak memiliki efek yang diinginkan
Sam Tuke

4

2020 Cara sederhana:

git reset <commit_hash>

(Hash dari commit terakhir yang ingin Anda pertahankan).

Anda akan menyimpan perubahan yang sekarang tidak dikomit secara lokal.

Jika Anda ingin mendorong lagi, Anda harus melakukan:

git push -f

0

Inilah cara saya:

Katakanlah nama cabang adalah develop.

# Create a new temp branch based on one history commit
git checkout <last_known_good_commit_hash>
git checkout -b develop-temp

# Delete the original develop branch and 
# create a new branch with the same name based on the develop-temp branch
git branch -D develop
git checkout -b develop

# Force update this new branch
git push -f origin develop

# Remove the temp branch
git branch -D develop-temp

0

Anda dapat melakukan sesuatu seperti

git push origin +<short_commit_sha>^:<branch_name>
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.