Membatalkan 'git push'


592

Inilah yang saya lakukan di cabang yang seharusnya stabil ...

% git rebase master
First, rewinding head to replay your work on top of it...
Fast-forwarded alpha-0.3.0 to master.
% git status
# On branch alpha-0.3.0
# Your branch is ahead of 'origin/alpha-0.3.0' by 53 commits.
#
nothing to commit (working directory clean)
% git push
Fetching remote heads...
  refs/
  refs/heads/
  refs/tags/
  refs/remotes/
'refs/heads/master': up-to-date
updating 'refs/heads/alpha-0.3.0'
  from cc4b63bebb6e6dd04407f8788938244b78c50285
  to   83c9191dea88d146400853af5eb7555f252001b0
    done
'refs/heads/unstable': up-to-date
Updating remote server info

Itu semua salah seperti yang saya sadari kemudian. Saya ingin membatalkan seluruh proses ini, dan mengembalikan cabang alpha-0.3.0 kembali seperti semula.

Apa yang harus saya lakukan?



4
Ini sebenarnya bukan situasi yang sama, membatalkan rebase adalah skenario repositori lokal, membatalkan git push melibatkan repositori jarak jauh dan bisa lebih rumit tergantung pada akses yang Anda miliki.
CB Bailey

Steen - Anda benar - mungkin saya seharusnya. Saya pikir repositori yang diberkahi dari semua yang menarik lebih dari tugas admin dan jadi milik di sini, di mana git sisi klien umum adalah pertanyaan stackoverflow.
Cyrus

Klarifikasi cepat - Saya menduga jika Anda merujuk ke git komit dengan nilai hash parsial , git akan menganggap Anda berbicara tentang komit yang hashnya dimulai dengan string itu?
Gershom

Jawaban:


944

Anda perlu memastikan bahwa tidak ada pengguna lain dari repositori ini yang mengambil perubahan yang salah atau mencoba membangun di atas komit yang ingin Anda hapus karena Anda akan memundurkan riwayat.

Maka Anda perlu 'memaksa' mendorong referensi lama.

git push -f origin last_known_good_commit:branch_name

atau dalam kasus Anda

git push -f origin cc4b63bebb6:alpha-0.3.0

Anda mungkin telah receive.denyNonFastForwardsmengatur repositori jarak jauh. Jika ini masalahnya, maka Anda akan mendapatkan kesalahan yang menyertakan frasa [remote rejected].

Dalam skenario ini, Anda harus menghapus dan membuat ulang cabang.

git push origin :alpha-0.3.0
git push origin cc4b63bebb6:refs/heads/alpha-0.3.0

Jika ini tidak berhasil - mungkin karena Anda telah receive.denyDeletesmenetapkan, maka Anda harus memiliki akses langsung ke repositori. Di repositori jarak jauh, Anda harus melakukan sesuatu seperti perintah plumbing berikut.

git update-ref refs/heads/alpha-0.3.0 cc4b63bebb6 83c9191dea8

16
Respons yang sempurna dan dijelaskan dengan baik - terima kasih banyak. Bagi siapa pun yang tersandung dalam hal ini, karena alasan akademis saya mencoba kedua pendekatan pertama, dan keduanya bekerja - jelas jika yang pertama berhasil, itu adalah pendekatan terbersih. Jika aku menjemputmu 10 kali Charles, aku akan melakukannya. :)
Cyrus

139
Untuk referensi cepat, baris pertama di sini adalahgit push -f origin last_known_good_commit:branch_name
philfreo

5
git push -f origin cc4b63bebb6: alpha-0.3.0 => yang ini membantu saya, Note alpha-0.3.0 adalah nama cabang dan cc4b63bebb6 adalah id komit yang ingin kami kembalikan ke. jadi, setelah melakukan perintah ini kita akan berada di cc4b63bebb6 melakukan id.
kumar

22
Solusi ini sangat berbahaya jika Anda bekerja di repo bersama. Sebagai praktik terbaik, semua komitmen yang didorong ke repo jarak jauh yang dibagikan harus dianggap 'tidak berubah'. Gunakan 'git
revert

1
jww - dibandingkan dengan yang lainnya, git adalah alat kendali sumber yang paling kaya fitur dan efisien. Setiap tim menggunakannya secara berbeda. Layak menghabiskan akhir pekan bermain-main dengan repositori baru dan melalui semua skenario umum. Setelah Anda menghabiskan waktu bekerja dengannya, pengembangan menjadi jauh lebih tidak stres.
user1491819

165

Saya percaya Anda juga bisa melakukan ini:

git checkout alpha-0.3.0
git reset --hard cc4b63bebb6
git push origin +alpha-0.3.0

Ini sangat mirip dengan metode terakhir, kecuali Anda tidak perlu muck sekitar di repo jarak jauh.


9
Ini bekerja untuk saya juga, tetapi perlu dicatat bahwa ini akan "menulis ulang" sejarah pada remote. Ini mungkin yang Anda inginkan, tetapi mungkin tidak!
Tom

3
+1 untuk jawaban ini yang sangat membantu saya. Saya juga ingin menambahkan (dan memperjelas) bahwa komit ID (yang muncul setelah --hardparameter " " harus menjadi ID dari komit apa pun yang Anda ingin atur ulang cabang Anda.
Michael Dautermann

1
Tulis ulang sejarah dengan baik ... siapa pun yang bisa menarik perubahan, saya hanya memastikan mereka melakukan git reset --hard [commit_id]sehingga kami tidak mengacaukan kontinum ruang-waktu.
Alien Life Form

9
Untuk apa + dalam "git push origin + alpha-0.3.0"?
jpierson

1
@jpierson +memaksa push untuk dilakukan, mirip dengan -f(tetapi sedikit berbeda: stackoverflow.com/a/25937833/1757149 ). Tanpa itu, jika Anda mencoba git push origin alpha-0.3.0push akan gagal: Updates were rejected because the tip of your current branch is behind.
A__

106

git revert kurang berbahaya daripada beberapa pendekatan yang disarankan di sini:

prompt> git revert 35f6af6f77f116ef922e3d75bc80a4a466f92650
[master 71738a9] Revert "Issue #482 - Fixed bug."
 4 files changed, 30 insertions(+), 42 deletions(-)
prompt> git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
prompt>

Ganti 35f6af6f77f116ef922e3d75bc80a4a466f92650 dengan komit Anda sendiri.


2
Bagaimana cara membuat ID 35f6af6f77f116ef922e3d75bc80a4a466f92650? Jawaban ini akan lebih baik jika Anda bisa menjelaskannya.
Volomike

2
@Vomomike (dan pengembang Googling di masa depan), pertanyaan ini menjelaskan banyak cara untuk mendapatkannya: kontrol versi dan pertanyaan hash di SO
Jaime

Ini adalah jawaban yang tepat, karena dengan "git reset" Anda seharusnya tidak dapat mendorong (Pembaruan ditolak karena ujung cabang Anda saat ini berada di belakang mitra jarak jauhnya) atau Anda perlu memaksa tarikan yang tidak benar-benar bersih.
Thomas Decaux

Ini bekerja untuk saya. Namun, hati-hati karena mengembalikan akan mengembalikan semua perubahan di file lokal Anda.
user1941537

Saya memilih pendekatan ini beberapa kali, tetapi saya juga menggunakan git rebase -i <id-before-last-good-commit> untuk melakukan rebase interaktif dan membersihkan riwayat seperti yang disarankan di sini, stackoverflow.com/questions/5189560/… .
Ernesto Allely

35

Solusi yang diterima (dari @charles bailey) sangat berbahaya jika Anda bekerja dalam repo bersama.

Sebagai praktik terbaik, semua komitmen yang didorong ke repo jarak jauh yang dibagikan harus dianggap 'tidak berubah'. Gunakan 'git revert' sebagai gantinya: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#fixing-mistakes

https://git-scm.com/book/be/v2/Git-Basics-Undoing-Things


Apa, tepatnya, instruksi yang Anda resepkan? Tampaknya Anda hanya memiliki tautan lama.
jww

32

Cara untuk melakukannya tanpa kehilangan perubahan yang Anda inginkan:

git reset cc4b63b 
git stash
git push -f origin alpha-0.3.0
git stash pop

Kemudian Anda dapat memilih file yang ingin Anda dorong


19

Cara lain untuk melakukan ini:

  1. buat cabang lain
  2. checkout komit sebelumnya pada cabang itu menggunakan "git checkout"
  3. dorong cabang baru.
  4. hapus cabang lama & dorong hapus (gunakan git push origin --delete <branch_name>)
  5. ganti nama cabang baru menjadi cabang lama
  6. dorong lagi.

2
Yang ini terlihat seperti solusi nyata ketika Anda sudah salah melakukan dalam repo
Illarion Kovalchuk


11

Undo multiple commit git reset --hard 0ad5a7a6 (Hanya berikan komit hash SHA1)

Batalkan komit terakhir

git reset --hard HEAD ~ 1 (perubahan komit terakhir akan dihapus) git reset --soft HEAD ~ 1 (perubahan komit terakhir akan tersedia sebagai modifikasi lokal tanpa komitmen)


9

Skenario 1 : Jika Anda ingin membatalkan komit terakhir katakan 8123b7e04b3, di bawah ini adalah perintah (ini bekerja untuk saya):

git push origin +8123b7e04b3^:<branch_name>

Output terlihat seperti di bawah ini:

Total 0 (delta 0), reused 0 (delta 0)
To https://testlocation/code.git
 + 8123b7e...92bc500 8123b7e04b3^ -> master (forced update)

Info tambahan: Skenario 2 : Dalam beberapa situasi, Anda mungkin ingin mengembalikan apa yang baru saja Anda undo'ed (pada dasarnya membatalkan undo) melalui perintah sebelumnya, lalu gunakan perintah di bawah ini:

git reset --hard 8123b7e04b3

Keluaran:

HEAD is now at cc6206c Comment_that_was_entered_for_commit

Info lebih lanjut di sini: https://github.com/blog/2019-how-to-undo-almost-anything-with-git


Skenario 1 harus jawaban yang diterima karena pertanyaan tidak menentukan yang berkomitmen untuk dihapus. Jawaban yang diterima hanya menghapus komit terakhir . Jawaban ini menghapus komit apa pun .
Dominic Cerisano

0

Jawaban yang ada baik dan benar, namun bagaimana jika Anda harus membatalkan pushtetapi:

  1. Anda ingin menyimpan komit secara lokal atau ingin menyimpan perubahan yang tidak dikomit
  2. Anda tidak tahu berapa banyak komit yang baru saja Anda dorong

Gunakan perintah ini untuk mengembalikan perubahan ke ref:

git push -f origin refs/remotes/origin/<branch>@{1}:<branch>

-2

Jika Anda ingin mengabaikan komit terakhir yang baru saja Anda tekan di cabang jarak jauh: ini tidak akan menghapus komit tetapi mengabaikannya dengan menggerakkan pointer git ke komit sebelumnya, dirujuk oleh HEAD ^ atau HEAD ^ 1

git push origin +HEAD^:branch

Tetapi jika Anda sudah mendorong komit ini, dan yang lain telah menarik cabang. Dalam hal ini, menulis ulang riwayat cabang Anda tidak diinginkan dan Anda sebaiknya mengembalikan komit ini:

git revert <SHA-1>
git push origin branch

1
Iya! ini bekerja seperti pesona ketika bekerja dengan github. Terima kasih.
cukabeka

Pertanyaannya adalah tentang "push" maka itu menyangkut cabang Remote. Tidak untuk memindahkan HEAD tentang satu komit yang berarti mengabaikan komit terakhir yang terdorong lakukan saja ini: git push origin + HEAD ^: your_branch
mkebri
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.