Yanlış Git şubesine taahhüt nasıl düzeltilir?


621

Sadece yanlış dal için iyi bir taahhütte bulundum. Ana şubemdeki son taahhüdü nasıl geri alabilirim ve sonra aynı değişiklikleri alıp yükseltme şubeme nasıl alabilirim?

Yanıtlar:


975

Henüz değişikliklerinizi yapmadıysanız, yazılımdan sıfırlama da yapabilirsiniz:

git reset --soft HEAD^

Bu, taahhüdü geri alır, ancak taahhüt edilen değişiklikleri dizininize geri koyar. Şubelerin birbirine göre nispeten güncel olduğunu varsayarsak, diğer şubeye bir ödeme yapmanıza izin verir, bunun üzerine basitçe taahhüt edebilirsiniz:

git checkout branch
git commit

Dezavantajı, taahhüt mesajınızı tekrar girmeniz gerektiğidir.


10
yazılım sıfırlamasının değişikliklerinizi aşamalı ve işleme hazır hale getirdiğini unutmayın. IDE'm yumuşak sıfırlamadan sonra dosyaların değiştirilmiş duruma geri döndüğünü göstermediğinde beni biraz karıştırdı.
mtjhax

9
mükemmel bir düzeltme, aslında bir çift taahhüt vardı bu yüzden HEAD ^^ ve bam tüm sos
pablo

8
Teşekkürler. Bu beni iki kez kurtardı. Şubeler biraz farklıysa, sıfırlamadan sonra ve ödeme yapmadan önce başka bir şubeye ödeme yapmadan önce değişikliklerinizi saklamanız gerekebilir. Saklamadan sonra saklamayı tekrar uygula
Kirby

17
zsh kullanıcıları: ^ gibi kaçmak için bulabilirsiniz:git reset --soft HEAD\^
Stephen Fuhry

54
Eğer bir Daha olsun? Windows komut satırınızda, HEAD ^ ifadesini çevrelemek için tırnak işaretlerini kullanın: git reset --soft "HEAD ^"
Nate Cook

140

Konuya 4 yıl geç kaldı, ama bu birisi için yararlı olabilir.

Taahhüt etmeden önce yeni bir şube oluşturmayı unuttuysanız ve ne kadar taahhütte bulunursanız olun, master konusunda taahhütte bulunursanız, aşağıdaki yaklaşım daha kolaydır:

git stash                       # skip if all changes are committed
git branch my_feature
git reset --hard origin/master
git checkout my_feature
git stash pop                   # skip if all changes were committed

Artık ana dalınız eşittir origin/masterve tüm yeni taahhütler açıktır my_feature. my_featureUzak bir şube değil, yerel bir şube olduğunu unutmayın .


Cevap için teşekkürler. Şimdi egit kullanıyorum ve aşağıdakileri yaparak aynı şeyi yapıp yapamayacağımı merak ediyorum: 1) Mevcut 'master'ı' my_feature 'olarak yeniden adlandırın. 2) Yerel 'master'ı' orijin / master'dan yeniden oluşturun. Egit'in bu operasyonlar için kaputun altında ne yaptığını bilmiyorum ama bu uygun bir çözüm gibi görünüyor
mjj1409

neden birleşme? doğrudan üzerinde şube yaratabilecek mastersonra sıfırlama masteriçin origin/master.
caesarsol

1
Bu en ilginç kısım: bir dizi taahhüde ihtiyacınız yok, çünkü origin/masterzaten sıfırlamak istediğiniz taahhütte! Bahşiş için kredi bu sayfada: github.com/blog/…
caesarsol

4
Bu kabul edilen cevap olmalı. Basit, açık, anlaşılır, taahhüt sayısına bakılmaksızın ve yalnızca temel Git işlevini kullanarak çalışır. Bu adımları TortoiseGit ile yaptım. Teşekkürler! :)
Ian Grainger

1
Bunun en iyi cevap olduğunu düşündüm, ama bir sınırlaması var. Yalnızca son zamanlarda uzaktan kumandadan çekerseniz yardımcı olur. Ve başlamak için bir uzaktan kumandanız olduğunu varsayar. Yalnızca yerel şubelerinizde "master" varsa ve yeni özellik düzeltmeniz varsa, tek doğru yanıt master'ın belirli sayıda işlem sayısını geri sayan bir sıfırlamasıdır.
pauljohn32

111

Temiz (değiştirilmemiş) çalışan bir kopyanız varsa

Bir taahhüdü geri almak için (bir sonraki adım için taahhüdün karmasını not ettiğinizden emin olun):

git reset --hard HEAD^

Bu taahhüdü farklı bir şubeye çekmek için:

git checkout other-branch
git cherry-pick COMMIT-HASH

Değiştirilmiş veya izlenmemiş değişiklikleriniz varsa

Ayrıca dikkat git reset --hardedecek herhangi izlenmeyen ve modifiye değişiklikleri öldürmek o varsa yüzden tercih olabilir, aşağıdakiler bulunabilir:

git reset HEAD^
git checkout .

git rev-parse BRANCH_NAMESha almak için.
wilhelmtell

12
İlk önce hash'i not etmeyi unutursanız, sadece kullanın git reflog show <branch>!
Cascabel

2
@Jefromi Orada bir dakika korktum.
Ian Hunter

13
Ekstra güvenli bir his için, önce kiraz toplama işlemini doğru dalda gerçekleştirin ve ardından sadece yanlış dalı sıfırlayın.
Yaş Mooij

1
Ayrıca izlenmeyen değişiklikler durumunda git stash, sıfırlamadan önce bir kişi olabilir ve git stash popbunları geri yüklemek için daha sonra kullanabilirsiniz , bu yüzden --hardparçadan korkmanıza gerek yoktur
Clemens Klein-Robbenhaar

20

Değişikliklerinizi zaten ittiyseniz, HEAD'i sıfırladıktan sonra bir sonraki pushunuzu zorlamanız gerekir.

git reset --hard HEAD^
git merge COMMIT_SHA1
git push --force

Uyarı: Donanımdan sıfırlama, çalışma kopyanızdaki taahhüt edilmemiş değişiklikleri geri alırken, zorla itme, uzak dalın durumunun yerel dalın geçerli durumu ile tamamen üzerine yazılmasına neden olur.

Her ihtimale karşı, Windows'ta (Bash ^^^^yerine Windows komut satırını kullanarak) aslında bir yerine dörttür , bu yüzden

git reset --hard HEAD^^^^

6
Not gerektiğini değil diğer insanların kesinlikle gerekli olmadıkça kullandığınız bir dalına-itmek zorlamak - Aksi onlar rebase kadar itmek mümkün olmayacaktır. Ancak git kullanan tek geliştiriciyseniz, bu iyi.
Blair Holloway

2
Ya da bir başkası hatalı taahhütleri çekmeden önce yeterince çabuk farketmedikçe.
Michael Mior

Birden fazla işleminiz varsa, ihtiyacınız olan taahhüdü belirleyebilirsiniz:git reset --hard COMMIT_HASH git push --force
David Cramblett

17

Geçenlerde aynı şeyi yaptım, burada başka bir şubeye bağlı kalmam gerektiğinde yanlışlıkla ustalaşmak için bir değişiklik yaptım. Ama hiçbir şey itmedim.

Sadece yanlış şubeyi taahhüt ettiyseniz ve o zamandan beri bir şey değiştirmediyseniz ve repoya itmediyseniz, aşağıdakileri yapabilirsiniz:

// rewind master to point to the commit just before your most recent commit.
// this takes all changes in your most recent commit, and turns them into unstaged changes. 
git reset HEAD~1 

// temporarily save your unstaged changes as a commit that's not attached to any branch using git stash
// all temporary commits created with git stash are put into a stack of temporary commits.
git stash

// create other-branch (if the other branch doesn't already exist)
git branch other-branch

// checkout the other branch you should have committed to.
git checkout other-branch

// take the temporary commit you created, and apply all of those changes to the new branch. 
//This also deletes the temporary commit from the stack of temp commits.
git stash pop

// add the changes you want with git add...

// re-commit your changes onto other-branch
git commit -m "some message..."

NOT: yukarıdaki örnekte, git reset HEAD ~ 1 ile 1 kaydedmeyi geri sarıyordum. Ancak n işlemeyi geri sarmak istiyorsanız git reset HEAD ~ n yapabilirsiniz.

Ayrıca, yanlış şubeyi taahhüt ettiyseniz ve yanlış şubeyi taahhüt ettiğinizi fark etmeden önce biraz daha kod yazdıysanız, devam eden çalışmanızı kaydetmek için git stash'ı kullanabilirsiniz:

// save the not-ready-to-commit work you're in the middle of
git stash 

// rewind n commits
git reset HEAD~n 

// stash the committed changes as a single temp commit onto the stack. 
git stash 

// create other-branch (if it doesn't already exist)
git branch other-branch

// checkout the other branch you should have committed to.
git checkout other-branch

// apply all the committed changes to the new branch
git stash pop

// add the changes you want with git add...

// re-commit your changes onto the new branch as a single commit.
git commit -m "some message..."

// pop the changes you were in the middle of and continue coding
git stash pop

NOT: Bu web sitesini referans olarak kullandım https://www.clearvision-cm.com/blog/what-to-do-when-you-commit-to-the-wrong-git-branch/


Bana da benzer bir şey oldu, ustada birkaç değişiklik yaptım, ama yeni şubede yapmalıyım ve PR göndermeliydim, sadece git checkout -b new_branchoradan bir hak yaptım , taahhütler sağlamdı, sadece itti ve bir PR yarattı, yapmadı ' Tekrar taahhüt etmek zorunda değilim.
Nishchal Gautam

11

Dolayısıyla, senaryonuz taahhüt ettiyseniz masterancak taahhüt etmeyi amaçladıysanız another-branch(zaten var olabilir veya olmayabilir), ancak henüz itmediyseniz, bunu düzeltmek oldukça kolaydır.

// if your branch doesn't exist, then add the -b argument 
git checkout -b another-branch
git branch --force master origin/master

Şimdi tüm taahhütleriniz devam masteredecek another-branch.

Sevgiden kaynak: http://haacked.com/archive/2015/06/29/git-migrate/


en basit yaklaşım gibi görünüyor! Emin değilim neden bu kadar az sevgi ve upwotes
keligijus

4
Bu benim için işe yaramadı. another-branchzaten vardı. Bu durumda, ustalaşmak için yaptığım taahhütleri nuked etti ve koymadım another-branch.
Giselle Serate

6

Üzerinde durmak için bu size gelen örn taşımak için birden hareketin sahip durumda, cevap developiçin new_branch:

git checkout develop # You're probably there already
git reflog # Find LAST_GOOD, FIRST_NEW, LAST_NEW hashes
git checkout new_branch
git cherry-pick FIRST_NEW^..LAST_NEW # ^.. includes FIRST_NEW
git reflog # Confirm that your commits are safely home in their new branch!
git checkout develop
git reset --hard LAST_GOOD # develop is now back where it started

1
Geri dönmek için üç taahhüdüm vardı ve bu soru kıçımı ateşten çıkardı. Teşekkürler!
holdenweb

3

Bu sorunla karşılaşırsanız ve Visual Studio'nuz varsa aşağıdakileri yapabilirsiniz:

Şubenizi sağ tıklayın ve seçin View History:

resim açıklamasını buraya girin

Geri dönmek istediğiniz taahhüdü sağ tıklayın. Ve Gerektiği gibi Geri Al veya Sıfırla.

resim açıklamasını buraya girin


3

Yanlış dalda birden fazla taahhüt için

Sizin için, sadece 1 taahhüt varsa, o zaman başka birçok kolay sıfırlama çözümü var. Benim için, yanlışlıkla masterdiyelim, yanlışlıkla diyelim yaklaşık 10 taahhüdüm vardı branch_xyzve taahhüt geçmişini kaybetmek istemedim.

Yapabilecekleriniz ve beni kurtaran şey, bu yanıtı referans olarak, 4 adımlı bir işlem kullanarak kullanmaktı.

  1. Adresinden yeni bir geçici şube oluşturun master
  2. Başlangıçta taahhütler için tasarlanan şubeye, yani branch_xyz
  3. Taahhütleri geri al master
  4. Geçici dalı silin.

Aşağıda ayrıntılı olarak açıklanan adımlar verilmiştir -

  1. master(Yanlışlıkla çok fazla değişiklik yaptığım yerden) yeni bir şube oluştur

    git checkout -b temp_branch_xyz
    

    Not: -bflag yeni bir şube oluşturmak için kullanılır
    Sadece bu hakkımız olup olmadığını doğrulamak git branchiçin, temp_branch_xyzşubede olduğumuzdan emin olmak için hızlı bir şekilde yapacağım git logve taahhütlerin doğru olup olmadığını kontrol etmek için bir a yapacağım.

  2. Geçici dalı, taahhütler için başlangıçta amaçlanan şubeye birleştirin, yani branch_xyz.
    İlk olarak, orijinal şubeye geçin, örneğin branch_xyz( Yapmadıysanız yapmanız gerekebilir git fetch)

    git checkout branch_xyz
    

    Not: -bBayrağı kullanmıyor
    Şimdi, geçici şubeyi şu anda ödeme yaptığımız şubeye birleştirelimbranch_xyz

    git merge temp_branch_xyz
    

    Varsa, burada bazı çatışmalara dikkat etmeniz gerekebilir. Başarılı bir şekilde birleştirdikten sonra sonraki adımlara geçebilir veya devam ettirebilirsiniz.

  3. Yanlışlıkla bu yanıtı referans olarak masterkullanma taahhüdünü geri alın , öncemaster

    git checkout master
    

    sonra uzaktan kumandayla eşleştirmek için geri alın (veya isterseniz belirli bir işleme)

    git reset --hard origin/master
    

    Yine, git logamaçlanan değişikliklerin etkili olduğundan emin olmak için önce ve sonra yapacağım.

  4. Kanıt silindiğinde, bu geçici şubenin silinmesidir. Bunun için öncelikle geçici yani birleştirilecek olduğu şube ödeme gerekir branch_xyz(eğer kalırsan masterve komut aşağıda yürütmek, bir alabilirsiniz error: The branch 'temp_branch_xyz' is not fully merged), bu yüzden yapalım

    git checkout branch_xyz
    

    ve sonra bu yanlış anlamanın kanıtını silin

    git branch -d temp_branch_xyz
    

İşte böyle.


1

Değişikliklerinizi uygulamak istediğiniz şube zaten mevcutsa ( örneğin şube geliştirme ), aşağıdaki fotanus tarafından sağlanan talimatları izleyin , ardından:

git checkout develop
git rebase develop my_feature # applies changes to correct branch
git checkout develop # 'cuz rebasing will leave you on my_feature
git merge develop my_feature # will be a fast-forward
git branch -d my_feature

Ve açıkçası kullanabilirsiniz tempbranch yerine veya başka bir şube adını my_feature isterseniz.

Ayrıca, uygunsa, hedef dalınızda birleştirilene kadar saklı pop'u (uygula) geciktirin.


Ben ilk komut (ödeme geliştirmek) gereksiz olduğunu düşünüyorum ... Rebase sadece yaptığı ilk şey olarak "my_feature" ödeme olacaktır.
JoelFan

Ayrıca, "rebase" komutunun "my_feature" parametresini dışarıda bırakabilirsiniz ("my_feature" öğesini daha önce kontrol etmiş olduğunuzdan). "birleştirme" parametresinin "geliştirme" parametresini de bırakabilirsiniz (zaten "geliştirme" yi kullandığınızdan beri)
JoelFan

1

Benim için bu, ittiğim taahhüdü tersine çevirip, daha sonra bu şubeyi diğer şubeye çekerek çözüldü.

git checkout branch_that_had_the_commit_originally
git revert COMMIT-HASH
git checkout branch_that_was_supposed_to_have_the_commit
git cherry pick COMMIT-HASH

git logDoğru karmayı bulmak için kullanabilirsiniz ve bu değişiklikleri istediğiniz zaman itebilirsiniz!

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.