Yerel ve uzak git deposunu 1 kesinleştirme ile geri alma


188

Bu konuyla ilgili benzer yazıları okudum ve hayatım boyunca bunun nasıl düzgün bir şekilde yapılacağını anlayamıyorum.

İstemediğim yaklaşık 1000 dosyayı teslim ettim ve 1by1'den geçip hepsini depodan kaldırmak zorunda kalmam.

  • Uzak bir masterşubem var.
  • Yerel masterşubem var.

İkisi de aynı revizyonda.

Uzaktan kumandayı 1 taahhütte geri almak istiyorum.

Tarihimin açık masterolduğunu söyle A--B--C--D--E.
Yerelimi geri almak istiyorum D.
Ardından uzaktan kumandaya itin, böylece mevcut karım hem uzak hem de yerel D olacaktır.

Bunu yaparken sorunlar yaşıyorum.
Git Tower kullanıyorum ama komut satırında rahatım. Herhangi bir yardım?

GÜNCELLEME: Aşağıda harika yorumlar var. Özellikle depo diğer kullanıcılarla paylaşılıyorsa sıfırlama kullanmak kısmen önerilmez. Donanımdan sıfırlama kullanmadan önceki işlemin değişikliklerini geri almanın en iyi yolu nedir ? Bir yolu var mı?


Cevabımı "donanım sıfırlaması kullanmadan önceki işlemin değişikliklerini geri al" şeklinde güncelledim.
VonC

3
git revertSabit sıfırlamalar olmadan ve kullanıcıları rahatsız etmeden yapmak için kullanın .
user562374


Uzaktan kumandayı geri almak cesaret kırıcıdır, ancak yapmak istediğiniz şey buysa, yapın. Bunu yapmanın yüzlerce yolu var, ancak sonuç sunucu tarafında aynı olurdu.
FelipeC

Yanıtlar:


307

Henüz kimse uzaktan repo'nuzu çekmediyse, şube HEAD'inizi değiştirebilir ve söz konusu uzak repoya zorlayabilirsiniz:

git reset --hard HEAD^ 
git push -f 

(veya uzak repoya doğrudan erişiminiz varsa, çıplak bir repo olmasına rağmen HEAD referansını değiştirebilirsiniz )

Tarafından yorumladı olarak Not uzaylı teknolojisi de aşağıdaki yorum , Windows (CMD oturum) üzerinde, sen gerekir ^^:

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

2011 yılından itibaren Güncelleme:
Kullanılması git push --force-with-lease( burada mevcut olduğunu Git 1.8.5 ile 2013 yılında tanıtılan,) daha güvenlidir.

Bkz Schwern 'ın cevabını gösterim amacıyla.


Ya biri daha önce repoyu çekmişse? O zaman ne yapardım?

Sonra tarihi yeniden yazmayan bir şey öneririm:

  • git revert yerel olarak son taahhüdünüz (önceki taahhüdün yaptıklarını tersine çeviren yeni bir taahhüt oluşturmak)
  • tarafından üretilen 'geri döndür' git revert.

1
Ya biri daha önce repoyu çekmişse? O zaman ne yapardım?
Jamis Charles

1
@gwho bir şube oluşturur? Hayır, bir şubenin başını hareket ettiriyor, ama sen hala aynı şubedesin. Ancak, itme artık ileriye doğru bir ilerleme olmadığından, evet, bu itmeyi zorlamanız gerekir.
VonC

1
birisinin repoyu çekip çekmediğini bilmenin bir yolu var mı?
Pinkerton

4
Windows'ta, ^ karakteri satır devam etmek ve bir karakterden kaçmak için kullanılır ve şu komutu verir: git reset --hard HEAD ^^
Alien Technology

1
Pencereler 10, PowerShell kullanarak @AlienTechnology, sadece yazın zorunda reset --hard HEAD^değil reset --hard HEAD^^son tamamlama sıfırlamak için.
Gaspacchio

58

Yerel dalı bir düzeltme geri ayarlayın ( HEAD^bir düzeltme geri anlamına gelir):

git reset --hard HEAD^

Değişiklikleri başlangıç ​​noktasına itin:

git push --force

Zorlamak zorunda kalacaksınız, çünkü aksi takdirde git, originbir taahhütte olduğunuzu fark eder ve hiçbir şey değişmez.

Bunu yapmak git'e oradaki ilerlemelere saygı duymadan uzak repoya --forceyazılmasını söyler HEAD.


1
Bunu geri döndürme dememeyi öneririm, çünkü git'te çok farklı bir anlama sahip belirli bir terim.
Cascabel

@Jefromi: İpucu için teşekkürler. Düzenlenen.
15'te eckes

Mükemmel cevap. Özellikle depo diğer kullanıcılarla paylaşılıyorsa, sıfırlama kullanmanın kısmen önerilmez. Bunu yapmanın daha temiz bir yolu var mı, önceki taahhüdünüzün tüm değişikliklerini geri alıyor mu?
Jamis Charles

Dikkatli ol! Taahhütsüz değişikliklerinizi veya kaybettiğinizi saklayın
Nosov Pavel

Çok havalı. Peki bu, gittiğimizde git push origin masterGit'in yerel şubenin en az bir kez taahhütte olduğu için uzaktan kumandada yeni bir taahhüt oluşturabileceği anlamına mı geliyor? Ayrıca, ikincisi uzak repodaki başın gösterdiği şeyden önemli ölçüde farklı olmalıdır?
MadPhysicist

18

Son işleme geri dönmek istiyorsanız dinleyin:

Aşama 1:

Yerel taahhütlerinizi mesajlarla kontrol edin

$ git log

Adım 2:

Yerel şubedeki (veya yöneticideki) değişiklikleri sıfırlamadan son taahhüdü kaldır

$ git reset HEAD^

VEYA son işlem dosyalarını ve güncellemeleri dinlemiyorsanız

$ git reset HEAD^ --hard

Aşama 3:

Dosyaları ve kodları güncelleyebiliriz ve tekrar zorlamak zorundayız, önceki taahhüdü siler. Yeni taahhütte bulunacaktır.

$ git push origin branch -f

Bu kadar!


Bu bir taahhüdü geri döndürmez , yerine bir taahhüt koyar . Lütfen git acemileri geleneksel terimleri yanlış kullanarak karıştırmayın.
Suncat2000

7

Feryat komutunu girerek git kesin geçmişinizi görebilirsiniz -

$ git günlüğü

Diyelim ki o daldaki geçmişiniz - commit_A, commit_B, commit_C, commit_D. Burada, commit_D son taahhüttür ve HEAD burada kalır. Şimdi, son taahhüdünüzü yerel ve uzaktan kaldırmak için aşağıdakileri yapmanız gerekir:

1. Adım: Son taahhüdü yerel olarak -

$ git reset --hard HEAD ~

Bu, taahhüt HEAD'inizi commit_C olarak değiştirir

Adım 2: Uzaktan kumandayı yeni HEAD taahhüdü için değişikliğinizi itin

$ git push origin + HEAD

Bu komut son komutu uzaktan silecektir.

PS bu komut Mac OSX üzerinde test edilmiştir ve diğer işletim sistemlerinde de çalışmalıdır (yine de diğer işletim sistemleri hakkında iddia etmemek)



3

İşte daha güvenli olan prosedürün güncellenmiş bir versiyonu.

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

git push -fuzaktaki depoyu gelişigüzel kendi değişikliklerinizle değiştirecektir. Başka birisi değişiklikleri zorladıysa kaybolacak. git push --force-with-leasesadece deponuz beklediğiniz gibi ise tabanınızı zorlar. Eğer bir başkası zaten itmişse, itme başarısız olur.

Bkz . git'in - kira sözleşmesini zorlaması .

Ben bu şekilde takma öneririm repush = push --force-with-lease.

Ya biri daha önce repoyu çekmişse? O zaman ne yapardım?

Onlara söyle git pull --rebase=merges. Bir yerine git fetch originve git merge origin/masterolacak git fetch originve git rebase -r origin/master. Bu, yerel değişikliklerinden herhangi birini masteryeni temelin üzerine yeniden yazacaktır origin/master. -ryapabilecekleri birleştirmeleri koruyacaktır.

Bunu çekme için varsayılan davranış haline getirmenizi öneririm. Güvenlidir, başkalarının yeniden temellerini ele alır ve daha az gereksiz birleşmelerle sonuçlanır.

[pull]
        rebase = merges

1
Kabul edildi ve onaylandı. Savunmam için, eski 2011 cevabım seçeneğin sunulmasından iki yıl önce yazıldı --force-with-lease.
VonC

Bunu zaten yaptığımı sanıyordum (dün) stackoverflow.com/posts/4647362/revisions
VonC

1

Sizin gibi sorunu bu komutlarla çözdüm:

git reset --hard HEAD^
git push -f <remote> <local branch>:<remote branch> 


0

Sadece son taahhüdü uzak ve net taahhüt geçmişinden de kaldırmak istedim. Aşağıdaki bir cazibe gibi çalıştı

git reset --hard HEAD^ 
git push -f 

Peki "aşağıdaki" yukarıdaki cevabımdan ne kadar farklı ?
VonC

0

Kafayı sıfırlamanın ve önceki taahhüdüne geri dönmenin yolu

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

Ancak bazen uzak dalda kabul edilmeyebilir:

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.

o zaman yapmanın diğer yolu

git revert HEAD
git push <remote branch>

Bu iyi çalışıyor.

NOT: git push -f <force>başarısız olup olmadığını hatırlayın ve sonra geri almaya çalışın. Daha git pullönce yapın, böylece uzak ve yerel eşitlenir ve sonra deneyin git revert.
İle kontrol git logemin uzak hale getirmek ve yerel Aynı SHA1 ile taahhüt aynı noktadayız ..

git revert 
A --> B --> C -->D
A--> B --> C --> D --> ^D(taking out the changes and committing reverted diffs)

0

yerel ustada

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

Başkaları çekip çekmediği için endişelenmenize gerek yok.

Bitti!


0

Yalnızca yerel deponuzla uğraşmadan son depolamayı uzak depodan kaldırmak istiyorsanız, işte tek satırlık:

git push origin +origin/master~:master

Bu, aşağıdaki sözdizimini kullanır:

git push <remote> <refspec>

Burada <remote>ise origin, ve <refspec>aşağıdaki yapıya sahiptir:

+origin/master~:master

Ayrıntılar bulunabilir git-push(1). Yukarıdaki +aracı, ve "diğer parça anlamına gelir "kuvvet bu ref itmek" origin/master~için master(uzaktan arasında origin)". Daha origin/master~önceki son taahhüt olduğunu bilmek zor origin/masterdeğil mi?


0

benim için şu iki komutu çalıştırır:

git checkout commit_id
git push origin +name_of_branch

0

Bunu da yapabilirsiniz:

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

ve en son hatalı taahhütleri alan herkesin sıfırlanmasını sağlayın:

git reset --hard origin/master
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.