Bagaimana cara mengembalikan semua perubahan lokal di proyek yang dikelola Git ke keadaan sebelumnya?

1914

Saya punya proyek di mana saya berlari git init. Setelah beberapa komitmen, saya lakukan git statusyang memberi tahu saya semuanya sudah mutakhir dan tidak ada perubahan lokal.

Kemudian saya melakukan beberapa perubahan berturut-turut dan menyadari bahwa saya ingin membuang semuanya dan kembali ke keadaan semula. Apakah perintah ini akan melakukannya untuk saya?

git reset --hard HEAD
Jacques René Mesrine
sumber

Jawaban:

3390

Jika Anda ingin mengembalikan perubahan yang dibuat ke copy pekerjaan Anda, lakukan ini:

git checkout .

Jika Anda ingin mengembalikan perubahan yang dibuat ke indeks (yaitu, yang telah Anda tambahkan), lakukan ini. Peringatan ini akan mengatur ulang semua komitmen Anda yang belum dicopot untuk dikuasai! :

git reset

Jika Anda ingin mengembalikan perubahan yang telah Anda lakukan, lakukan ini:

git revert <commit 1> <commit 2>

Jika Anda ingin menghapus file yang tidak dilacak (mis. File baru, file yang dihasilkan):

git clean -f

Atau direktori yang tidak dilacak (mis. Direktori baru atau yang dibuat secara otomatis):

git clean -fd
INFORMASI 1800
sumber
133
fwiw setelah sekian lama, git checkout path/to/filehanya akan mengembalikan perubahan lokal kepath/to/file
Matijs
29
+1 pada jawaban di bawah ini juga menyebutkan git clean -f (untuk menghapus perubahan yang tidak terlacak) dan -fd (juga menghapus direktori yang tidak terlacak)
ptdev
3
dan jika Anda juga ingin membersihkan file-file Anda yang tidak terlacak, baca ini stackoverflow.com/questions/61212/…
Surasin Tancharoen
9
git checkout .dan git reset [--hard HEAD]tidak berhasil, saya harus melakukan git clean -fduntuk mengembalikan perubahan saya.
BrainSlugs83
7
git resettidak mengatur ulang perubahan Anda, git reset --hardapakah itu.
Cerin
388

Catatan: Anda mungkin juga ingin menjalankan

git clean -fd

sebagai

git reset --hard

akan tidak menghapus file tidak terlacak, dimana git-bersih akan menghapus file dari direktori root dilacak yang tidak di bawah pelacakan git. PERINGATAN - HATI-HATI DENGAN INI! Sangat membantu untuk menjalankan dry-run dengan git-clean terlebih dahulu, untuk melihat apa yang akan dihapus.

Ini juga sangat berguna ketika Anda mendapatkan pesan kesalahan

~"performing this command will cause an un-tracked file to be overwritten"

Yang dapat terjadi ketika melakukan beberapa hal, salah satunya memperbarui salinan yang berfungsi ketika Anda dan teman Anda berdua menambahkan file baru dengan nama yang sama, tetapi dia melakukan itu ke dalam kontrol sumber terlebih dahulu, dan Anda tidak peduli menghapus salinan yang tidak dilacak. .

Dalam situasi ini, melakukan dry run juga akan membantu menunjukkan kepada Anda daftar file yang akan ditimpa.

Antony Stubbs
sumber
13
Perintah clean file adalah "git clean -f". Direktori yang tidak dilacak dihapus dengan "git clean -d"
Jonathan Mitchell
35
git clean -fd (gaya diperlukan untuk -d)
electblake
14
-n atau --dry-run adalah flag untuk dry-run.
stephenbez
2
git clean -ffd jika Anda memiliki repositori git lain di repositori git Anda. Tanpa f ganda tidak akan dihapus.
Trismegistos
149

Kloning ulang

GIT=$(git rev-parse --show-toplevel)
cd $GIT/..
rm -rf $GIT
git clone ...
  • ✅ Menghapus komit lokal yang tidak didorong
  • ✅ Mengembalikan perubahan yang Anda buat ke file yang dilacak
  • ✅ Mengembalikan file terlacak yang Anda hapus
  • ✅ Menghapus file / dir yang terdaftar di .gitignore(seperti membangun file)
  • ✅ Menghapus file / direktori yang tidak dilacak dan tidak ada .gitignore
  • 😀 Anda tidak akan melupakan pendekatan ini
  • 😔 Menghabiskan bandwidth

Berikut ini adalah perintah lain yang saya lupa setiap hari.

Bersihkan dan atur ulang

git clean --force -d -x
git reset --hard
  • ❌ Menghapus komit lokal yang tidak didorong
  • ✅ Mengembalikan perubahan yang Anda buat ke file yang dilacak
  • ✅ Mengembalikan file terlacak yang Anda hapus
  • ✅ Menghapus file / dir yang terdaftar di .gitignore(seperti membangun file)
  • ✅ Menghapus file / direktori yang tidak dilacak dan tidak ada .gitignore

Bersih

git clean --force -d -x
  • ❌ Menghapus komit lokal yang tidak didorong
  • ❌ Mengembalikan perubahan yang Anda buat ke file yang dilacak
  • ❌ Mengembalikan file terlacak yang Anda hapus
  • ✅ Menghapus file / dir yang terdaftar di .gitignore(seperti membangun file)
  • ✅ Menghapus file / direktori yang tidak dilacak dan tidak ada .gitignore

Setel ulang

git reset --hard
  • ❌ Menghapus komit lokal yang tidak didorong
  • ✅ Mengembalikan perubahan yang Anda buat ke file yang dilacak
  • ✅ Mengembalikan file terlacak yang Anda hapus
  • ❌ Menghapus file / dir yang terdaftar di .gitignore(seperti membangun file)
  • ❌ Menghapus file / direktori yang tidak dilacak dan tidak ada .gitignore

Catatan

Test case untuk mengkonfirmasi semua hal di atas (gunakan bash atau sh):

mkdir project
cd project
git init
echo '*.built' > .gitignore
echo 'CODE' > a.sourceCode
mkdir b
echo 'CODE' > b/b.sourceCode
cp -r b c
git add .
git commit -m 'Initial checkin'
echo 'NEW FEATURE' >> a.sourceCode
cp a.sourceCode a.built
rm -rf c
echo 'CODE' > 'd.sourceCode'

Lihat juga

  • git revert untuk membuat komitmen baru yang membatalkan komitmen sebelumnya
  • git checkout untuk kembali ke masa sebelum komit sebelumnya (mungkin perlu menjalankan perintah di atas terlebih dahulu)
  • git stashsama seperti di git resetatas, tetapi Anda dapat membatalkannya
William Entriken
sumber
Maaf telah mencuri dari jawaban di atas. Saya menggunakan referensi ini terus-menerus, sebagian besar untuk saya.
William Entriken
1
Aku cukup yakin, bahwa opsi pertama ( Re-clone ) sebenarnya TIDAK "menghapus lokal, komit non-mendorong" :)
Marandil
1
@styfle ✅ adalah sesuatu yang dilakukannya, ❌ adalah sesuatu yang tidak dilakukannya
William Entriken
3
@FullDecent Agak membingungkan untuk dibaca. "❌ JANGAN menghapus komit lokal yang tidak didorong". Itu artinya BUKAN menghapus. Negatif ganda berarti tidak terhapus?
styfle
1
Tentang flag -x in git clean -f -d -x: jika opsi -x ditentukan, file yang diabaikan juga dihapus. Ini dapat, misalnya, berguna untuk menghapus semua produk build.- dari GIT docs
Alex
82

Jika Anda ingin mengembalikan semua perubahan DAN memperbarui dengan master jarak jauh saat ini (misalnya Anda menemukan bahwa kepala HEAD telah bergerak maju sejak Anda bercabang dan push Anda sedang 'ditolak') Anda dapat menggunakan

git fetch  # will fetch the latest changes on the remote
git reset --hard origin/master # will set your local branch to match the representation of the remote just pulled down.
Michael Durrant
sumber
Tampaknya penting untuk menentukan origindalam git reset --hard origin/master(yang berfungsi) - tanpanya (yaitu git reset --hard) tidak ada yang berubah.
Jake
Saya memiliki beberapa perubahan lokal dan tidak dapat menghilangkannya dengan perintah apa pun yang saya lakukan git reset --barang asli / master dan juga mampu menarik perubahan master
abhishek ringsia
50

Lihatlah ke git-reflog. Ini akan mencantumkan semua status yang diingatnya (standarnya adalah 30 hari), dan Anda cukup checkout yang Anda inginkan. Sebagai contoh:

$ git init > /dev/null
$ touch a
$ git add .
$ git commit -m"Add file a" > /dev/null
$ echo 'foo' >> a
$ git commit -a -m"Append foo to a" > /dev/null
$ for i in b c d e; do echo $i >>a; git commit -a -m"Append $i to a" ;done > /dev/null
$ git reset --hard HEAD^^ > /dev/null
$ cat a
foo
b
c
$ git reflog
145c322 HEAD@{0}: HEAD^^: updating HEAD
ae7c2b3 HEAD@{1}: commit: Append e to a
fdf2c5e HEAD@{2}: commit: Append d to a
145c322 HEAD@{3}: commit: Append c to a
363e22a HEAD@{4}: commit: Append b to a
fa26c43 HEAD@{5}: commit: Append foo to a
0a392a5 HEAD@{6}: commit (initial): Add file a
$ git reset --hard HEAD@{2}
HEAD is now at fdf2c5e Append d to a
$ cat a
foo
b
c
d
William Pursell
sumber
terima kasih banyak William, untuk git reflog. Saya mengatur ulang pohon saya ke versi lama dan tidak yakin bagaimana cara retrive ke baru-baru ini. git reflog Anda menyelamatkan saya. Sekali lagi terima kasih.
palaniraja
1
menyelamatkan saya juga! Dalam kasus saya petualangan saya dengan git rebase -isalah (berakhir dengan menghapus beberapa komitmen karena kesalahan pengeditan). Berkat tip ini saya kembali dalam keadaan baik!
paneer_tikka
Apa yang Anda maksud dengan default 30 hari !?
Mohe TheDreamy
@MoheTheDreamy Maksud saya ada batas waktu. Akhirnya pemulung akan menghapus referensi yang tidak terjangkau ketika usianya melebihi batas itu. Defaultnya dulu (dan mungkin masih) 30 hari. Jadi referensi yang lebih lama mungkin tidak tersedia.
William Pursell
36

BAHAYA KE DEPAN: (baca komentar. Menjalankan perintah yang diajukan dalam jawaban saya mungkin menghapus lebih dari yang Anda inginkan)

untuk sepenuhnya menghapus semua file termasuk direktori yang harus saya jalankan

git clean -f -d
Tobias Gassmann
sumber
13
Untuk menyelamatkan siapa pun dari rasa sakit yang baru saja saya alami: ini juga akan menghapus file .gitignore-d!
landons
maaf jika saya membuat Anda kesulitan. Saat itu saya hanya mencoba mengembalikan dan menghapus semua yang ada di folder itu. Saya tidak ingat keadaan tepatnya, tetapi "-d" adalah satu-satunya hal yang bekerja untuk saya. Saya harap saya tidak membuat Anda terlalu sakit :-)
Tobias Gassmann
1
tidak ada salahnya dilakukan. Saya memiliki cadangan, tetapi ini mungkin menjamin penafian;)
landons
35

Setelah membaca banyak jawaban dan mencobanya, saya telah menemukan berbagai kasus tepi yang berarti kadang-kadang mereka tidak sepenuhnya membersihkan copy pekerjaan.

Inilah skrip bash saya saat ini untuk melakukannya, yang berfungsi sepanjang waktu.

#!/bin/sh
git reset --hard
git clean -f -d
git checkout -- HEAD

Jalankan dari direktori copy root yang berfungsi.

Scott Davey
sumber
10
Perintah terakhir memberi sayaerror: pathspec 'HEAD' did not match any file(s) known to git.
0xC0000022L
1
Ini bekerja untuk saya ketika saya mengeluarkan "-". git checkout HEAD
Jester
4
git reset --hardmengembalikan file yang dilacak (dipentaskan atau tidak), git clean -f -dmenghapus file yang tidak terlacak, lalu git checkout -- HEADmengapa kita membutuhkan ini?
v.shashenko
Kami tidak membutuhkan tanda hubung ganda. Harus salah ketik.
Farax
35

cukup jalankan -

git stash

itu akan menghapus semua perubahan lokal Anda. dan Anda juga dapat menggunakannya nanti dengan menjalankan -

git stash apply 
piyushmandovra
sumber
3
gunakan git stash popakan secara otomatis menghapus paling atas perubahan simpanan untuk Anda
Arrow Cen
8
git stash dropuntuk menghapus status simpanan terbaru tanpa berlaku untuk copy pekerjaan.
deerchao
git stash berlaku tidak akan menambahkan file yang baru dibuat
Ravistm
27

Saya bertemu masalah serupa. Solusinya adalah menggunakan git loguntuk mencari versi komit lokal mana yang berbeda dari remote. (Misalnya versinya3c74a11530697214cbcc4b7b98bf7a65952a34ec ).

Kemudian gunakan git reset --hard 3c74a11530697214cbcc4b7b98bf7a65952a34ecuntuk mengembalikan perubahan.

Patrick
sumber
16

Saya mencari masalah serupa,

Ingin membuang komitmen lokal:

  1. kloning repositori (git clone)
  2. beralih ke cabang dev (git checkout dev)
  3. melakukan beberapa commit (git commit -m "commit 1")
  4. tetapi memutuskan untuk membuang komitmen lokal ini untuk kembali ke jarak jauh (asal / dev)

Begitu juga yang di bawah ini:

git reset --hard origin/dev

Memeriksa:

git status  

        On branch dev  
        Your branch is up-to-date with 'origin/dev'.  
        nothing to commit, working tree clean  

sekarang komit lokal hilang, kembali ke keadaan kloning awal, poin 1 di atas.

Manohar Reddy Poreddy
sumber
1
terima kasih, itulah satu-satunya hal yang bekerja untuk saya - "git reset - asal asli"
Nisim Naim
senang mengetahui itu membantu.
Manohar Reddy Poreddy
7

Anda mungkin tidak perlu / perlu menyimpan pekerjaan Anda / file di direktori kerja Anda, tetapi cukup singkirkan mereka sepenuhnya. Perintahgit clean akan melakukan ini untuk Anda.

Beberapa kasus penggunaan umum untuk melakukan ini adalah dengan menghapus cruft yang telah dihasilkan oleh gabungan atau alat eksternal atau menghapus file lain sehingga Anda dapat menjalankan build yang bersih.

Ingatlah bahwa Anda harus sangat berhati-hati dengan perintah ini, karena ini dirancang untuk menghapus file dari direktori kerja lokal Anda yang TIDAK DILACAK. jika Anda tiba-tiba berubah pikiran setelah menjalankan perintah ini, tidak akan kembali untuk melihat konten file yang telah dihapus. Alternatif yang lebih aman adalah mengeksekusi

git stash --all

yang akan menghapus semuanya tetapi menyimpan semuanya dalam simpanan. Simpanan ini kemudian dapat digunakan.

Namun, jika Anda benar-benar DO ingin menghapus semua file dan membersihkan direktori kerja Anda, Anda harus menjalankannya

git clean -f -d

Ini akan menghapus semua file dan juga sub-direktori yang tidak memiliki item apa pun sebagai hasil dari perintah. Hal yang cerdas untuk dilakukan sebelum menjalankan git clean -f -dperintah adalah menjalankannya

git clean -f -d -n

yang akan menunjukkan kepada Anda pratinjau apa yang AKAN dihapus setelah mengeksekusi git clean -f -d

Jadi di sini adalah ringkasan dari pilihan Anda dari yang paling agresif hingga paling tidak agresif


Opsi 1 : Hapus semua file secara lokal (Paling agresif)

git clean -f -d

Opsi 2 : Pratinjau dampak di atas (Pratinjau paling agresif)

git clean -f -d -n

Opsi 3 : Simpan semua file (Paling tidak agresif)

`git stash --all` 
jbooker
sumber
6

Coba ini untuk mengembalikan semua perubahan yang tidak dikomit di cabang lokal

$ git reset --hard HEAD

Tetapi jika Anda melihat kesalahan seperti ini:

fatal: Unable to create '/directory/for/your/project/.git/index.lock': File exists.

Anda dapat menavigasi ke folder '.git' lalu menghapus file index.lock:

$ cd /directory/for/your/project/.git/
$ rm index.lock

Akhirnya, jalankan lagi perintah:

$ git reset --hard HEAD
Janderson Silva
sumber
0

Pertanyaan ini lebih lanjut tentang reset / pengembalian repositori yang lebih luas, tetapi jika Anda tertarik untuk mengembalikan perubahan individu - Saya telah menambahkan jawaban yang sama di sini:

https://stackoverflow.com/a/60890371/2338477

Jawaban atas pertanyaan:

  • Cara mengembalikan perubahan individu dengan atau tanpa perubahan yang tersimpan dalam sejarah git

  • Cara kembali ke versi lama untuk memulai kembali dari kondisi yang sama

TarmoPikaro
sumber