Kembalikan ke Git lama yang melakukan repo publik

802

Bagaimana saya bisa kembali ke komit tertentu git ?

Jawaban terbaik yang bisa diberikan seseorang kepada saya adalah menggunakan git revert X kali sampai saya mencapai komit yang diinginkan.

Jadi katakanlah saya ingin kembali ke komit yang berumur 20 komit, saya harus menjalankannya 20 kali.

Adakah cara yang lebih mudah untuk melakukan ini?

Saya tidak dapat menggunakan reset karena repositori ini bersifat publik.

David
sumber
1
git revert <commit> tidak berfungsi?
miku
8
Seperti yang dinyatakan dalam pertanyaan saya, ini benar-benar tidak membantu saya jika saya ingin kembali ke sesuatu yang dilakukan 20 yang lalu.
David
7
Pertanyaan ini telah dijawab dengan baik di sini stackoverflow.com/questions/4114095/…
user7610
4
Tidak jelas apa yang Anda maksud dengan "memutar kembali". Apakah itu berarti Anda ingin untuk sementara waktu memindahkan copy pekerjaan Anda ke revisi tertentu? Atau Anda ingin mengembalikan riwayat repositori Anda secara permanen ke revisi tertentu?
1
Anda harus menerima jawaban, dan mungkin memilih jawaban lain yang Anda suka.
Nabil Kadimi

Jawaban:

1194

Coba ini:

git checkout [revision] .

di mana [revision]hash komit (misalnya 12345678901234567890123456789012345678ab:).

Jangan lupa .pada akhirnya, sangat penting. Ini akan menerapkan perubahan pada keseluruhan pohon. Anda harus menjalankan perintah ini di root proyek git. Jika Anda berada di sub direktori, maka perintah ini hanya mengubah file dalam direktori saat ini. Kalau begitu komit dan Anda harus baik.

Anda dapat membatalkan ini dengan

git reset --hard 

yang akan menghapus semua modifikasi dari direktori kerja dan area pementasan.

Alex Reisner
sumber
7
@AlexReisner Periode itu pada titik akhir di direktori Anda saat ini, yang belum tentu seluruh proyek git, benar? Jika Anda ingin menerapkan perubahan pada keseluruhan proyek, apakah Anda akan menggunakan ': /' like in 'git add: /', jika Anda saat ini tidak berada di root proyek git?
MSpreij
10
Catatan: jika Anda telah menambahkan file baru ke proyek Anda sejak itu, ini tidak akan menghapusnya. Jadi, ketika Anda pergi untuk membangun (tergantung pada platform Anda), Anda mungkin masih mendapatkan kesalahan. Hapus file baru dan Anda siap melakukannya.
TheWestIsThe ...
6
@ MSpreij Anda harus menjalankan perintah ini di root proyek git. Jika Anda berada di sub direktori, maka perintah ini hanya mengubah file dalam direktori saat ini.
volatilevar
3
Sangat bagus ketika Anda dapat mengkloning proyek di direktori lain dan menggunakan git checkout [revisi]. untuk kembali ke revisi tertentu dan kemudian membandingkannya dengan proyek yang sama di direktori lain. Menghemat banyak waktu.
Donato
4
Sial, aku lupa "." kerusakan apa yang telah saya lakukan pada repositori saya?
Burung hantu
196

Untuk mengembalikan ke komit tertentu:

git reset --hard commit_sha

Untuk mengembalikan 10 komit kembali:

git reset --hard HEAD~10

Anda dapat menggunakan "git revert" seperti pada posting berikut jika Anda tidak ingin menulis ulang sejarah

Bagaimana cara mengembalikan repositori Git ke komit sebelumnya?

Naga Kiran
sumber
4
hanya perbedaan antara pendekatan ini dan "git checkout [revisi]." adalah bahwa yang terakhir mempertahankan revisi.
deeshank
53
Jawaban ini SALAH karena OP secara khusus menyatakan "Saya tidak bisa menggunakan reset karena repo ini publik"
Yarin
4
Jika repo bersifat publik, saya pikir tidak ada cara untuk mengembalikan komit pada repositori publik tanpa menggunakan paksa (git push -f) karena akan mempengaruhi orang-orang yang telah menarik perubahan sebelum rollback. Jadi, reset dapat digunakan di kotak pasir lokal dari repo publik juga.
Naga Kiran
4
Sangat bagus bahwa ini menghindari KEPALA yang terpisah! Apa yang saya cari.
cyber-monk
1
Dalam kasus saya ini berhasil, kemudian gunakan 'git pull' untuk maju cepat kembali ke kepala setelah Anda menguji regresi, dll.
Peter Quiring
86

Yah, saya kira pertanyaannya adalah, apa yang Anda maksud dengan 'mundur'? Jika Anda tidak bisa resetkarena itu bersifat publik dan Anda ingin menjaga riwayat komit tetap utuh, maksud Anda hanya ingin copy pekerjaan Anda mencerminkan komit tertentu? Gunakan git checkoutdan hash komit.

Sunting: Seperti yang ditunjukkan dalam komentar, menggunakan git checkouttanpa menentukan cabang akan membuat Anda dalam keadaan "tidak ada cabang". Gunakan git checkout <commit> -b <branchname>untuk checkout ke cabang, atau git checkout <commit> .untuk checkout ke cabang saat ini.

Ben
sumber
Tidakkah ini menempatkan Anda dalam kondisi 'Tidak ada cabang' yang aneh saat ini? Bagaimana Anda melakukan perubahan untuk menyelesaikan rollback?
Alex Reisner
Yah, saya hanya menyarankan penggunaan git checkout- dia bebas untuk memeriksa cabang apa saja (saat ini atau baru) yang dia inginkan. Saya akan memperbarui jawaban saya sehingga tidak ambigu.
Ben
2
Saya mencoba ini tetapi saya tidak berpikir ini adalah cara yang tepat untuk melakukannya karena ia meninggalkan file stagnan. Ini tidak menghapus file yang tidak ada dalam komit terakhir.
David
3
Jika Anda berada di direktori yang berfungsi dan Anda tetap di master, Anda perlu git resetmenghapus file-file itu, yang Anda katakan tidak ingin Anda lakukan. Coba lakukan ke cabang terpisah:, git checkout <commit> -b <branchname>Anda tidak akan memiliki file stagnan di cabang itu .
Ben
2
Masalah dengan menggunakan checkoutadalah bahwa itu tidak akan menghapus file yang ditambahkan dalam komit sebelumnya.
42

Poster asli menyatakan:

Jawaban terbaik yang bisa diberikan seseorang kepada saya adalah menggunakan git revertX kali sampai saya mencapai komit yang diinginkan.

Jadi katakanlah saya ingin kembali ke komit yang berumur 20 komit, saya harus menjalankannya 20 kali.

Adakah cara yang lebih mudah untuk melakukan ini?

Saya tidak dapat menggunakan reset karena repo ini bersifat publik.

Tidak perlu menggunakan git revertX kali. git revertdapat menerima rentang komit sebagai argumen, jadi Anda hanya perlu menggunakannya sekali untuk mengembalikan rentang komit. Misalnya, jika Anda ingin mengembalikan 20 komit terakhir:

git revert --no-edit HEAD~20..

Rentang komit HEAD~20..adalah kependekan dari HEAD~20..HEAD, dan berarti "mulai dari induk ke- 20 dari komit HEAD, dan kembalikan semua komit setelah hingga HEAD".

Itu akan mengembalikan 20 komit terakhir, dengan asumsi bahwa tidak ada dari mereka yang menggabungkan komit. Jika ada gabungan komit, maka Anda tidak bisa mengembalikan semuanya dalam satu perintah, Anda harus mengembalikannya secara individual

git revert -m 1 <merge-commit>

Perhatikan juga bahwa saya telah menguji menggunakan rentang dengan git revertmenggunakan git versi 1.9.0. Jika Anda menggunakan versi git yang lebih lama, menggunakan rentang dengan git revertmungkin atau mungkin tidak berfungsi.

Dalam hal ini, git revertlebih disukai daripada git checkout.

Perhatikan bahwa tidak seperti jawaban ini yang mengatakan untuk digunakangit checkout , git revert sebenarnya akan menghapus file apa pun yang ditambahkan di salah satu komit yang Anda kembalikan, yang menjadikan ini cara yang benar untuk mengembalikan serangkaian revisi.

Dokumentasi

railgun
sumber
Catatan : ini membuat komit baru dengan perubahan yang dikembalikan. Sempurna untuk pertanyaan OP. Tetapi pastikan itu yang Anda inginkan. (Contoh-contoh dalam dokumen git-revert yang ditautkan di atas sangat bagus.) Jika Anda ingin menyelidiki komitmen sebelumnya (yaitu sebelum memilih apa yang berkomitmen untuk dikembalikan ke) gunakan opsi checkout yang disebutkan dalam jawaban lain, dengan mengingat komentar yang dimiliki orang lain dibuat tentang file yang dihapus.
SherylHohman
@ SherylHohman Mengembalikan ke komit sebelumnya tidak membuat komit baru. Saya tidak bisa membayangkan apa yang Anda maksud di sini.
27

Langkah 1: ambil daftar komitmen:

git log

Anda akan mendapatkan daftar seperti dalam contoh ini:

[Comp:Folder User$ git log
commit 54b11d42e12dc6e9f070a8b5095a4492216d5320
Author: author <[email protected]>
Date:   Fri Jul 8 23:42:22 2016 +0300

This is last commit message

commit fd6cb176297acca4dbc69d15d6b7f78a2463482f
Author: author <[email protected]>
Date:   Fri Jun 24 20:20:24 2016 +0300

This is previous commit message

commit ab0de062136da650ffc27cfb57febac8efb84b8d
Author: author <[email protected]>
Date:   Thu Jun 23 00:41:55 2016 +0300

This is previous previous commit message
...

Langkah 2: salin hash komit yang diperlukan dan tempel untuk checkout:

git checkout fd6cb176297acca4dbc69d15d6b7f78a2463482f

Itu saja.

Igor
sumber
11
git read-tree -um @ $commit_to_revert_to

akan melakukannya. Ini "checkout git" tetapi tanpa memperbarui KEPALA.

Anda dapat mencapai efek yang sama dengannya

git checkout $commit_to_revert_to
git reset --soft @{1}

jika Anda lebih suka merangkai perintah kenyamanan bersama.

Ini meninggalkan Anda dengan pohon kerja Anda dan indeks dalam keadaan yang diinginkan, Anda bisa git commitmenyelesaikannya.

jthill
sumber
Ini adalah satu-satunya pendekatan langsung yang bekerja seperti pesona! Saya memeriksa dari kepala, menjalankan perintah ini, dan berhasil menghapus file yang telah kami perkenalkan dan mengembalikan semua perubahan. Luar biasa.
kamranicus
6

Ingin mode HEAD terlepas?

Jika Anda ingin mengembalikan X kali ke komit tertentu dengan HEAD DETACHED (berarti Anda tidak dapat mengacaukan apa pun), maka dengan segala cara, gunakan yang berikut:

(ganti X dengan berapa banyak komit yang ingin Anda kembalikan)

git checkout HEAD~X

IE untuk kembali satu komit:

git checkout HEAD~1
Karl Morrison
sumber
1
Saya akan menghapus bagian dengan ... sulit dipercaya ... Tampaknya pribadi, dan juga seseorang menyebutkannya di komentar di atas, dan di @ken juga dalam jawabannya.
meJustAndrew
@ MeJustAndrew Ya, begitu banyak jawaban di SO yang hanya membingungkan orang, itu cukup menjengkelkan.
Karl Morrison
Benar-benar jawaban yang sederhana dan mudah.
Ammad
2

Katakanlah Anda mengerjakan sebuah proyek dan setelah sekitar satu hari atau lebih. Anda perhatikan satu fitur masih memberi Anda kesalahan. Tapi Anda tidak tahu perubahan apa yang Anda lakukan yang menyebabkan kesalahan. Jadi, Anda harus memancing komitmen kerja sebelumnya. Untuk kembali ke komitmen tertentu:

git checkout 8a0fe5191b7dfc6a81833bfb61220d7204e6b0a9 .

Oke, jadi commit itu berfungsi untuk Anda. Tidak ada lagi kesalahan. Anda menunjukkan masalah dengan tepat. Sekarang Anda dapat kembali ke komit terbaru:

git checkout 792d9294f652d753514dc2033a04d742decb82a5 .

Dan checkout file tertentu sebelum menyebabkan kesalahan (dalam kasus saya, saya menggunakan contoh Gemfile.lock):

git checkout 8a0fe5191b7dfc6a81833bfb61220d7204e6b0a9 -- /projects/myproject/Gemfile.lock

Dan ini adalah salah satu cara untuk menangani kesalahan yang Anda buat di komit tanpa menyadari kesalahan sampai nanti.

Donato
sumber
2

Anda dapat menemukan id komit yang terkait dengan setiap komit di bagian komit di GitHub / BitBucket / Gitlab. Ini sangat sederhana, misalkan komit id Anda adalah 5889575 maka jika Anda ingin kembali ke bagian ini dalam kode Anda, maka Anda hanya perlu mengetik

git checkout 5889575 .

Ini akan membawa Anda ke titik waktu dalam kode Anda.

Naved Ahmad
sumber
1

Saya tidak yakin apa yang berubah, tetapi saya tidak dapat checkout komit tertentu tanpa opsi --detach. Perintah lengkap yang bekerja untuk saya adalah: git checkout --detach [commit hash]

Untuk kembali dari keadaan terpisah saya harus checkout cabang lokal saya: git checkout master

ken
sumber
Memeriksa mastermenyelesaikan masalah tetap terpisah, saat melakukan git reset --hardatau git checkout -- .memang bekerja tetapi tetap terpisah
DarkCygnus
0

Ini adalah contoh untuk melakukan itu

    cd /yourprojects/project-acme 


    git checkout efc11170c78 .
mcvkr
sumber