Menggulir kembali repositori git lokal dan jauh dengan 1 commit

188

Saya sudah membaca posting serupa tentang topik ini, dan tidak bisa seumur hidup saya mencari tahu bagaimana melakukan ini dengan benar.

Saya memeriksa sekitar 1000 file yang tidak saya inginkan, dan saya lebih suka tidak harus melalui 1by1 dan menghapus semuanya dari repo.

  • Saya memiliki masterCabang terpencil .
  • Saya memiliki masterCabang setempat .

Keduanya revisi yang sama.

Saya ingin mengembalikan kendali jarak jauh saya dengan 1 commit.

Katakanlah sejarah saya di masteris A--B--C--D--E.
Saya ingin mengembalikan ke lokal saya D.
Kemudian dorong ke remote sehingga hash saya saat ini akan menjadi D baik remote dan lokal.

Saya mengalami masalah dalam melakukan ini.
Saya menggunakan Git Tower tetapi saya merasa nyaman dengan baris perintah. Ada bantuan?

UPDATE: Komentar luar biasa di bawah ini. Menggunakan reset tampaknya sebagian tidak dianjurkan terutama jika repositori dibagikan dengan pengguna lain. Apa cara terbaik untuk membatalkan perubahan komit sebelumnya tanpa menggunakan hard reset ? Apakah ada cara?

Jamis Charles
sumber
Saya telah memperbarui jawaban saya untuk "membatalkan perubahan komit sebelumnya tanpa menggunakan hard reset".
VonC
3
Gunakan git revertuntuk melakukan tanpa reset keras dan tanpa mengganggu pengguna.
user562374
2
Kemungkinan duplikat dari commit Hapus dari cabang di Git
wjandrea
Membalikkan kendali jarak jauh adalah hal yang tidak dianjurkan, tetapi jika itu yang ingin Anda lakukan, lakukanlah. Ada ratusan cara untuk melakukan itu, tetapi hasilnya akan sama di sisi server.
FelipeC

Jawaban:

307

Jika belum ada yang menarik repo jarak jauh Anda, Anda dapat mengubah KEPALA cabang Anda dan mendorongnya ke repo jarak jauh tersebut:

git reset --hard HEAD^ 
git push -f 

(atau, jika Anda memiliki akses langsung ke repo jarak jauh, Anda dapat mengubah referensi KEPALA meskipun repo telanjang )

Catatan, seperti yang dikomentari oleh alien-technology dalam komentar di bawah ini , pada Windows (sesi CMD), Anda perlu ^^:

git reset --hard HEAD^^
git push -f 

Pembaruan sejak 2011:
Menggunakan git push --force-with-lease( yang saya sajikan di sini , diperkenalkan pada 2013 dengan Git 1.8.5) lebih aman.

Lihat Schwern 's jawaban untuk ilustrasi.


Bagaimana jika seseorang sudah menarik repo? Apa yang akan saya lakukan?

Maka saya akan menyarankan sesuatu yang tidak menulis ulang sejarah:

  • git revert secara lokal komit terakhir Anda (membuat komit baru yang membalikkan apa yang dilakukan komit sebelumnya)
  • tekan 'kembalikan' yang dihasilkan oleh git revert.
VONC
sumber
1
Bagaimana jika seseorang sudah menarik repo? Apa yang akan saya lakukan?
Jamis Charles
1
@ gapa yang membuat cabang? Tidak itu memindahkan KEPALA cabang, tetapi Anda masih di cabang yang sama. Namun, karena dorongan itu tidak lagi maju cepat, ya, Anda perlu memaksakan dorongan itu.
VonC
1
apakah ada cara untuk mengetahui apakah seseorang telah menarik repo?
Pinkerton
4
Di Windows, karakter ^ digunakan untuk kelanjutan garis dan untuk keluar dari karakter, membuat perintah: git reset --hard HEAD ^^
Alien Technology
1
@AlienTechnology Menggunakan Powershell, pada windows 10, saya hanya perlu mengetik reset --hard HEAD^dan tidak reset --hard HEAD^^mengatur ulang komit terakhir.
Gaspacchio
58

Atur cabang satu revisi kembali ( HEAD^berarti satu revisi kembali):

git reset --hard HEAD^

Dorong perubahan ke asal:

git push --force

Anda harus memaksa mendorong karena jika tidak git akan mengenali bahwa Anda ketinggalan originsatu komit dan tidak ada yang akan berubah.

Melakukannya dengan --forcememberitahu git untuk menimpa HEADrepo jarak jauh tanpa menghormati kemajuan apa pun di sana.

eek
sumber
1
Saya sarankan untuk tidak menyebut ini revert, karena itu adalah istilah khusus dengan arti yang sangat berbeda di git.
Cascabel
@ Jeffromi: Terima kasih atas petunjuknya. Diedit.
eckes
Jawaban yang bagus Saya pernah membaca bahwa menggunakan reset tampaknya sebagian tidak dianjurkan terutama jika repositori dibagikan dengan pengguna lain. Apakah ada cara yang lebih bersih untuk melakukan ini, yang membatalkan semua perubahan komit Anda sebelumnya?
Jamis Charles
Hati-hati! Simpan perubahan yang tidak dikomit atau kehilangan Anda
Nosov Pavel
Itu keren. Jadi, apakah ini berarti bahwa ketika kita melakukannya git push origin master, Git dapat membuat komit baru di remote karena cabang lokal berada di depan dengan setidaknya sekali komit? Lebih jauh lagi, yang terakhir harus secara substansial berbeda dari apa yang kepala di repo jarak jauh untuk?
MadPhysicist
18

Jika Anda ingin mengembalikan komit terakhir, dengarkan:

Langkah 1:

Periksa komit lokal Anda dengan pesan

$ git log

Langkah 2:

Hapus komit terakhir tanpa mengatur ulang perubahan dari cabang lokal (atau master)

$ git reset HEAD^

ATAU jika Anda tidak ingin file komit terakhir dan pembaruan mendengarkan

$ git reset HEAD^ --hard

Langkah 3:

Kami dapat memperbarui file dan kode dan sekali lagi perlu mendorong dengan paksa itu akan menghapus komit sebelumnya. Itu akan membuat komitmen baru.

$ git push origin branch -f

Itu dia!

Kannan S
sumber
Itu bukan mengembalikan komit, itu menggantikan yang komit. Tolong jangan membingungkan kami git pemula dengan menyalahgunakan istilah konvensional.
Suncat2000
7

Dengan memasukkan perintah di bawah ini Anda dapat melihat riwayat komit git Anda -

$ git log

Katakanlah riwayat Anda pada cabang tertentu adalah seperti - commit_A, commit_B, commit_C, commit_D. Di mana, commit_D adalah komit terakhir dan ini adalah tempat HEAD tetap. Sekarang, untuk menghapus komit terakhir Anda dari lokal dan jarak jauh, Anda perlu melakukan hal berikut:

Langkah 1: Hapus komit terakhir secara lokal dengan -

reset $ git --hard HEAD ~

Ini akan mengubah komit HEAD Anda menjadi commit_C

Langkah 2: Dorong perubahan Anda untuk komit HEAD baru ke jarak jauh

$ git dorong asal + KEPALA

Perintah ini akan menghapus komit terakhir dari jarak jauh.

PS perintah ini diuji pada Mac OSX dan harus bekerja pada sistem operasi lain juga (tidak mengklaim OS lain)

sahilabrar
sumber
3

Untuk Mesin Windows, gunakan:

git reset HEAD~1  #Remove Commit Locally
Anvesh Yalamarthy
sumber
3

Ini versi terbaru dari prosedur yang lebih aman.

git reset --hard HEAD^ 
git push --force-with-lease

git push -fakan mengganti repositori jarak jauh dengan perubahan Anda sendiri. Jika orang lain telah mendorong perubahan, mereka akan hilang. git push --force-with-leasehanya akan mendorong rebase Anda jika repositori seperti yang Anda harapkan. Jika orang lain telah mendorong, push Anda akan gagal.

Lihat – memaksa dianggap berbahaya; memahami git-force-with-lease .

Saya merekomendasikan aliasing ini sebagai repush = push --force-with-lease.

Bagaimana jika seseorang sudah menarik repo? Apa yang akan saya lakukan?

Katakan pada mereka untuk git pull --rebase=merges. Alih-alih a git fetch origindan git merge origin/masteritu akan git fetch origindan git rebase -r origin/master. Ini akan menulis ulang setiap perubahan lokal mereka masterdi atas yang baru dibuat ulang origin/master. -rakan mempertahankan gabungan apa pun yang mungkin telah mereka buat.

Saya sarankan menjadikan ini perilaku default untuk menarik. Aman, akan menangani rebasing orang lain, dan menghasilkan penggabungan yang tidak perlu.

[pull]
        rebase = merges
Schwern
sumber
1
Setuju, dan terangkat. Untuk pembelaan saya , jawaban lama 2011 saya ditulis dua tahun sebelum opsi diperkenalkan --force-with-lease.
VonC
Saya pikir saya sudah melakukannya (kemarin): stackoverflow.com/posts/4647362/revisi
VonC
1

Saya memecahkan masalah seperti Anda dengan perintah ini:

git reset --hard HEAD^
git push -f <remote> <local branch>:<remote branch> 
Ibrohim Ermatov
sumber
0

Saya hanya ingin menghapus komit terakhir dari riwayat komit jauh dan menghapus juga. Berikut ini bekerja seperti pesona

git reset --hard HEAD^ 
git push -f 
minhas23
sumber
Tetapi bagaimana "berikut ini" berbeda dari jawaban saya di atas ?
VonC
0

Cara untuk mengatur ulang kepala dan melakukan pengembalian ke komit sebelumnya adalah melalui

$ git reset HEAD^ --hard
$ git push <branchname> -f

Tetapi kadang-kadang itu mungkin tidak diterima di cabang terpencil:

To ssh:<git repo>
 ! [rejected]        develop -> develop (non-fast-forward)
error: failed to push some refs to 'ssh:<git repo>'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

maka cara lain yang harus dilakukan adalah

git revert HEAD
git push <remote branch>

Ini berfungsi dengan baik.

CATATAN: ingat jika git push -f <force>gagal dan kemudian Anda mencoba untuk mengembalikan. Lakukan git pullsebelumnya, sehingga remote dan lokal dalam sinkronisasi dan kemudian coba git revert.
Periksa dengan git loguntuk memastikan remote dan lokal pada titik yang sama komit dengan SHA1 yang sama ..

git revert 
A --> B --> C -->D
A--> B --> C --> D --> ^D(taking out the changes and committing reverted diffs)
ravi.zombie
sumber
0

pada master lokal

git reflog
-- this will list all last commit
  e.g Head@{0} -- wrong push
      Head@{1} -- correct push  
git checkout Head@{1} .
  -- this will reset your last modified files

git status 
git commit -m "reverted to last best"
git push origin/master

Tidak perlu khawatir apakah orang lain sudah menarik atau belum.

Selesai!

Bhushan
sumber
0

Jika Anda hanya ingin menghapus komit terakhir dari repositori jarak jauh tanpa mengacaukan repositori lokal Anda, berikut adalah one-liner:

git push origin +origin/master~:master

Ini menggunakan sintaks berikut:

git push <remote> <refspec>

Di sini, <remote>adalah origin, dan <refspec>memiliki struktur berikut:

+origin/master~:master

Detail dapat ditemukan di git-push(1). Kata sebelumnya +berarti "tekan paksa ref ini", dan bagian lainnya berarti "dari origin/master~ke master(dari jarak jauh origin)". Tidak sulit untuk mengetahui bahwa itu origin/master~adalah komit terakhir sebelumnya origin/master, kan?

iBug
sumber
0

bagi saya bekerja dua perintah ini:

git checkout commit_id
git push origin +name_of_branch
Yahor M
sumber
0

Anda juga dapat melakukan ini:

git reset --hard <commit-hash>
git push -f origin master

dan minta semua orang yang mendapatkan ulang commit buruk terbaru:

git reset --hard origin/master
A-Sharabiani
sumber