Soru Git rebase geri alma


Herkes kolayca bir git rebase geri almak biliyor mu?

Akla gelen tek yol, ona elle gitmek:

  • git her iki şubeye de taahhüt ebeveyn
  • oradan bir geçici şube yaratın
  • tüm işleri elden almak
  • Elle oluşturulmuş şube tarafından yeniden çizildiğim dalı değiştir

Şu anki durumumda bu işe yarayacak çünkü her iki şubeden gelen işleri kolayca tespit edebilirim (biri benim eşyalarımdı, diğeri meslektaşımın eşyalarıydı).

Ancak benim yaklaşımım bana yetersiz ve hataya eğilimli olarak geliyor (diyelim ki kendi şubelerimden sadece 2'sini geri aldım).

Herhangi bir fikir?

Açıklama: Bir dizi komisyonun yeniden oynatıldığı bir rebase'den bahsediyorum. Sadece bir tane değil.


2434
2017-09-25 17:59


Menşei


Bir rebase sırasında, işleri hariç tutabileceğinizi ya da bunları ezeceğinizi not edin; Bu değişiklikler ya orijinal düğümlere bir işaretçi ya da reflog ile eleme olmadan revertable değildir, böylece vişne işe yaramazdı. - ANeves
stackoverflow.com/a/692763/2458438 Bu ideal kabul edilen cevap olmalıdır. - DDM


Cevaplar:


En kolay yol, şubenin baş taahütünü, reşit olmaya başlamadan hemen önce olduğu gibi bulmaktır. reflog...

git reflog

ve geçerli şubeyi ona sıfırlamak için (her zamanki uyarılar ile --hard seçenek).

Eski taahhüdün olduğunu varsay HEAD@{5} ref logda:

git reset --hard HEAD@{5}

Windows'da referansı belirtmeniz gerekebilir:

git reset --hard "HEAD@{5}"

Aday eski kafanın geçmişini sadece bir git log HEAD@{5} (pencereler:  git log "HEAD@{5}").

Şube refleksleri başına devre dışı kalmadıysanız yapmanız yeterlidir. git reflog branchname@{1} Bir rebase olarak son kafasına yeniden takmadan önce şube kafasını ayırır. Bunu yakın zamanda doğrulamamış olsam da, bunu tekrar kontrol ederim.

Varsayılan olarak, tüm reflog'lar çıplak olmayan depolar için etkinleştirilir:

[core]
    logAllRefUpdates = true

3371
2017-09-25 19:56



Git reflog harika, sadece daha iyi formatlanmış çıktı alabilirsiniz git log -g (Scott Chacon'un ipucu progit.org/book). - karmi
@Zach: git rebase --abort (-i hiç mantıklı değil --abort) tamamlanmamış bir rebase'den vazgeçmek içindir - ya çatışmalar olduğu ya da etkileşimli ya da her ikisi olduğu için; Bu, sorunun ne olduğuyla ilgili başarılı bir rebase'i geri almakla ilgili değil. Ya kullanırsın rebase --abort veya reset --hard hangi durumda olduğunuzu bağlı olarak. Her ikisini de yapmanıza gerek yok. - CB Bailey
Teşekkürler! Git yüklememde çalışması için "HEAD {22}" yazısını tırnak içine koymam gerekiyordu. - SidJ
Bu hayatımı kurtardı ... maalesef, benim haste yaptım git reset --hard HEAD@{5} - Yapmak istediğim şeyin üstünde iki taahhüt vardı. Söylemeye gerek yok, Git için Tanrı'ya şükür ki bu sadece devam etmeme ve düzeltmeyi yapmamı sağladı. git reflog Gitmek istediğim taahhüdün hayata geçirilmesi sadece 1'e yükseldi, bunu hemen düzeltdim ve her şey iyi. =) - marcamillion
Sadece durumda, önce bir yedek yapın: git tag BACKUP. Bir şeyler ters giderse ona geri dönebilirsiniz: git reset --hard BACKUP - kolypto


Aslında, rebase başlangıç ​​noktanızı kaydeder. ORIG_HEAD Bu genellikle aşağıdaki gibi basit:

git reset --hard ORIG_HEAD

Ancak reset, rebase ve merge tüm orijinalini koru HEAD işaretçi ORIG_HEAD Bu nedenle, geri almayı denediğiniz rebase'den bu komutlardan herhangi birini yaptıysanız, reflog'u kullanmanız gerekecektir.


1169
2018-03-28 13:24



Teşekkürler. Bu bana bir squash geri yardımcı oldu! - kakyo
Bu durumda ORIG_HEAD artık kullanışlı değil, aynı zamanda branchName@{n} sözdizimi, nerede n Şube işaretçisinin nth önceki pozisyonudur. Örneğin, eğer yeniden isimlendirirseniz featureA üstüne dal masterşube, ama rebase sonucu sevmiyorum, o zaman sadece yapabilirsin git reset --hard featureA@{1} Şubeyi, rebase yapmadan önce olduğu yere geri sıfırlamak için. Şube @ {n} sözdizimi hakkında daha fazla bilgi edinebilirsiniz. revizyonlar için resmi Git belgeleri.
Bu en kolay olanı. Bunu takip et git rebase --abort gerçi. - Seph
Bu kabul edilen cevap IMO olmalı. - Tomáš Fejfar
ORIG_HEAD Eğer bir rebase yaptı ve aklı başında ve huzurlu bir şekilde geri dönmek istiyorsanız ÇOK ÇOK ÇOK faydalıdır. TOP OYNAN cevabı (veya aynı zamanda kabul edilen cevap) olmalıdır. Bir yumruya ihtiyacı var. En çok oylanan cevap, git reset --hard HEAD@{5} Yanlış gitme olasılığı daha fazla olan gereksiz kafa sayımını içerir. - DDM


Charles'ın cevabı işe yarıyor ama bunu yapmak isteyebilirsiniz:

git rebase --abort

sonra temizlemek reset.

Aksi halde, “Interactive rebase already started”.


320
2017-07-27 18:21



Bu, istemimin "| REBASE" bölümünü kaldırdı. +1 - Wouter Thielen
Olması gerektiğini düşünüyorum git rebase --abort içinde (belki senin sürümüne bağlı olarak). - Seph
Bu soru değildi. Soru, bitmiş bir rebase nasıl geri alınacağını sorar. - Arunav Sanyal
@ArunavSanyal başarısız olursanız bu son umuttur .. - aswzen


Şube, eski ucunun sarkan taahhüt nesnesine sıfırlanması elbette ki en iyi çözümdür, çünkü herhangi bir çaba harcamadan önceki durumu geri yükler. Ancak bu taahhütleri kaybetmiş olursanız (f.ex., deponuzu bu arada çöp topladığınız için, ya da bu yeni bir klon), tekrar şubeyi yeniden oluşturabilirsiniz. Bunun anahtarı şudur --onto geçin.

Hayal edeceğiniz bir konu dalının olduğunu varsayalım topic, sen dallanmış master ne zaman master oldu 0deadbeef taahhüt. Bir noktada iken topic şube yaptın git rebase master. Şimdi bunu geri almak istiyorsun. İşte nasıl:

git rebase --onto 0deadbeef master topic

Bu, tüm taahhütleri alacaktır topic değil master ve onları üstüne tekrar oynat 0deadbeef.

İle --onto, tarihini hemen hemen yeniden düzenleyebilirsin herhangi bir şekil.

İyi eğlenceler. :-)


75
2017-09-26 02:08



Esnekliği nedeniyle bunun en iyi seçenek olduğunu düşünüyorum. Ben b1'i ustadan daldırdım, sonra b1'i yeni bir dalın b2'sine dönüştürdüm, sonra b1'i tekrar ustaya dayandırmak istedim. Ben sadece git seviyorum - teşekkürler! - ripper234
Buradaki en iyi seçenek budur! Mevcut şubemde sahip olduğum tüm değişiklikleri sakladı ve tüm istenmeyenleri sildi! - Alicia Tang
Bunu bir arada --onto ve -i Tarihinizi herhangi bir şekle yeniden düzenleyebilirsiniz. Yaptığınız şekilleri görmek için gitk (veya mac üzerinde gitx) kullanın. - rjmunro


Önemsiz bir işlem yapmadan önce aslında bir yedekleme etiketi koydum (çoğu rebas önemsiz, fakat karmaşık bir yere benziyorsa bunu yaparım).

Ardından geri yükleme kadar kolay git reset --hard BACKUP.


62
2018-05-12 20:57



Ben de bunu yapıyorum. Ayrıca ne demek istediğinizi değiştirdiğinizden emin olmak için diff backback komutunu kullanmak yararlıdır. - Paul Bone
Bunu ben de yapardım, ama refleksle daha rahat olduğum için artık gerekli hissetmiyorum. Reflog, HEAD'i her değiştirdiğinizde bunu sizin adınıza yapıyor. - Pete Hodgson
Şey, anlamlı isimleri tercih ederim, çünkü refloda doğru öğeyi aramak bazen eğlenceli değildir. - Alex Gontmakher
Aslında bir yedek şube yapmanıza bile gerek yok, sadece branchName@{n} sözdizimi, burada n Şube işaretçisinin nth önceki pozisyonudur. Örneğin, eğer yeniden isimlendirirseniz featureA üstüne dal masterşube, ama rebase sonucu sevmiyorum, o zaman sadece yapabilirsin git reset --hard featureA@{1} Şubeyi, rebase yapmadan önce olduğu yere geri sıfırlamak için. Hakkında daha fazla bilgi edinebilirsiniz branch@{n} sözdizimi revizyonlar için resmi Git belgeleri.
Aslında, yukarıdaki sözdizimini kullanmanız bile gerekmiyor. Pat Notz'un cevabı, orijinal HEAD Şube geçici olarak saklanır ORIG_HEAD. Ancak bir yedek şube etiketi kullanma tekniği de işe yarıyor, sadece daha fazla adım.


Bu durumda şubenizi uzak depoya ittiniz (genellikle orijinli) ve sonra başarılı bir rebase (birleştirmeden) yaptınız (git rebase --abort "Artık bir rebase devam ediyor" verir) kolayca yapabilirsiniz şube sıfırla kullanma komut:

git sıfırlama --hard origin / {branchName}

Örnek:

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is ahead of 'origin/{branchName}' by 135 commits.
  (use "git push" to publish your local commits)

nothing to commit, working directory clean

$ ~/work/projects/{ProjectName} $ git reset --hard origin/{branchName}
HEAD is now at 6df5719 "Commit message".

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is up-to-date with 'origin/{branchName}.

nothing to commit, working directory clean

53
2017-09-28 12:43



Bu benim için doğru cevap. Yeniden düzenleme öncesinde yeniden düzenleme ve taahhütte aynı kimlik kimliği vardı ve HEAD {1} 'e geri dönülecek olursa geri dönüş yapılmayacaktı! - Bill Kotsias


Hakemizi tamamlamadıysanız ve bunun ortasında, aşağıdaki işler işe yarar:

git rebase --abort

49
2017-10-15 20:20



Bu benim için çalıştı. Çatışmaları birleştirdim, böylece 'ortasında' olarak nitelendirildi. - Fakeer


Birden fazla taahhüt için, herhangi bir işlemin bu işleme kadar uzanan tüm geçmişe referans verdiğini unutmayın. Bu yüzden Charles'ın cevabında, “eski taahhütleri” “eski işlemlerin en yenisi” olarak okuyun. Bu işleme sıfırlarsanız, o işleme giden tüm tarihler tekrar görünür. Bu istediğini yapmalı.


14
2017-09-25 21:36



Doğru, hatırlatma için teşekkürler ;-) - webmat


kullanma reflog benim için çalışmadı.

Benim için çalışılan şey açıklandığı gibi oldu İşte. Dosyayı, rebased olan ve ismini "rebase finsihed" içeren satırdan alan .git / logs / refs dosyasında açın.

5fce6b51 88552c8f Kris Leech <me@example.com> 1329744625 +0000  rebase finished: refs/heads/integrate onto 9e460878

Satırda listelenen ikinci işlemi kontrol edin.

git checkout 88552c8f

Bir kez teyit edildim, bu kayıplarımı içeriyordu, ben dallanıp rahat bir nefes aldım.

git log
git checkout -b lost_changes

14
2018-02-20 13:59



veya bu: stackoverflow.com/questions/1108853/... - cregox
Whoa - bu bağlantıdan, "Bir uyarı var: Şubenin tarihini kaybettim ama bu durumda gerçekten önemli değildi. Değişikliklerimi aldığım için mutlu oldum." ? - ruffin