Yerel taahhüt edilmemiş değişikliklerimi başka bir Git dalında nasıl birleştiririm?


621

Git'te aşağıdakileri nasıl yapabilirim?

Şimdiki şubem şube1 ve bazı yerel değişiklikler yaptım. Ancak, şimdi bu değişiklikleri branş2'ye uygulamak istediğimin farkındayım. Bu değişiklikleri, branş2'de branş1'de taahhüt edilmeden yerel değişiklikler haline gelmeleri için uygulamanın / birleştirmenin bir yolu var mı?


2
Burada SO üzerinde harika bir Git Eğitimi var . Yığın taşmasıyla ilgili tüm git soruları için merkezi.
Decio Lira

Yanıtlar:


898

Dosyalarınız henüz taahhüt edilmediğinden branch1:

git stash
git checkout branch2
git stash pop

veya

git stash
git checkout branch2
git stash list       # to check the various stash made in different branch
git stash apply x    # to select the right one

Yorumladığı gibi tarafından benjohn (bkz git stashman sayfasına ):

Ayrıca etmek argüman eklemek, şu anda izlenmeyen (yeni eklenen) dosyalarını saklamak -u, böylece:

git stash -u

2
Rica ederim. En zula kullanım fazla örnek unethicalblogger.com/posts/2008/11/... .
VonC

2
Aynı soruna bir çözüm arıyorsanız, ancak TFS ile eşdeğer çözüm, değişikliklerinizi rafa kaldırmaktır, ardından / migrate anahtarını kullanarak doğru şubeye geçmek için TFS Elektrikli El Aletleri'ni kullanın.
xr280xr

1
Bu benim için çalıştı. Ancak, 'saklamak pop' çalışması için yerel bir şube oluşturmak zorunda kaldı. Size benzer bir şey olup olmadığını kontrol edin stackoverflow.com/questions/1783405/git-checkout-remote-branch .
mimoralea

21
Ayrıca, şu anda izlenmeyen (yeni eklenen) dosyalarını saklamak için argüman eklemek, -uböylece,: git stash -u.
Benjohn

2
@Benjohn İyi bir nokta. Daha fazla görünürlük için yorumunuzu cevaba ekledim.
VonC

84

Saklama, geçici taahhütler ve yeniden temellendirmenin tamamı aşırıya kaçabilir. Değiştirilen dosyaları dizine henüz eklemediyseniz, diğer dalı ödün verebilirsiniz.

git checkout branch2

Bu, düzenlemekte olduğunuz hiçbir dosya branch1 ve branch2 arasında farklı olmadığı sürece çalışır. Korunan çalışma değişiklikleri ile sizi şube2'de bırakacaktır. Farklılarsa, şubeleri -mödeme seçeneğiyle değiştirerek getirilen değişikliklerle yerel değişikliklerinizi birleştirmek istediğinizi belirtebilirsiniz .

git checkout -m branch2

Dizine değişiklikler eklediyseniz, ilk önce bir sıfırlama ile bu değişiklikleri geri almak istersiniz. (Bu, çalışma kopyanızı koruyacak, yalnızca aşamalı değişiklikleri kaldıracaktır.)

git reset

3
Ben stash bir şekilde anlamak için "daha basit" düşündüm, ama yaklaşım farklı dallarda çalışma dizini dikkate daha iyidir. +1
VonC

6
Basit bir geleneksel ödeme, eldeki soruna daha uygun görünüyordu. ödeme daha hafiftir, sadece değiştirilmesi gereken dosyaları günceller. Belki de stash yaklaşımını anlamak daha kolaydır, ya da bu kullanım durumunda kasanın 'güvenli' olduğu yeterince açık olmayabilir.
CB Bailey

Eğer checkout -mbazı durum (belki bir birleştirme çakışma neden olur) 'de "güvenli" değil, (örneğin bir zula pop unpop olabilir) herhangi bir avantaj sağlamak gizleyeceğiz?
Craig McQueen

1
@craigMcQueen Patlamış bir zulayı kaldıramazsınız, ancak zulası patlattığınızda çatışmalardan şikayet eder. Çatışmaları düzeltebilir ve sonra taahhüt edebilirsiniz, ancak orijinal stash bu durumda hala yığın üzerinde! :)
Shaun F

Birleştirme çakışması durumunda, dosyalar olarak yedeklenmez .origmi?
jocull

13

Daha önce bahsedilen saklamak yaklaşımına daha kısa bir alternatif:

Değişiklikleri geçici olarak bir zulasına taşıyın.

  1. git stash

Oluşturun ve yeni bir dala geçin ve daha sonra zulayı sadece bir adımda açın.

  1. git stash branch new_branch_name

Sonra sadece addve commitbu yeni dalda değişiklikler.


10

UYARI: Git yeni başlayanlar için değil.

Bu iş akışımda neredeyse onun için yeni bir git komutu yazmaya çalıştığım kadar geliyor. Her zamanki git stashakış gitmek için bir yol ama biraz garip. Genellikle yeni bir taahhütte bulunuyorum çünkü değişikliklere bakıyorsam, tüm bilgiler aklımda taze ve sadece git commitbulduğum şeylere başlamak daha iyidir (genellikle, özellik dalı) hemen.

Bunun gibi durumlarla çok fazla karşılaşırsanız , şu anki dizininizin yanında her zaman masterşubeyi kontrol ettiren başka bir çalışma dizininin olması da yararlıdır .

Yani bunu nasıl başaracağım şöyle:

  1. git commit değişiklikleri iyi bir taahhüt mesajı ile hemen.
  2. git reset HEAD~1 mevcut şubeden taahhüdü geri almak.
  3. (isteğe bağlı) özellik üzerinde çalışmaya devam edin.

Bazen sonradan (eşzamansız olarak) veya hemen başka bir terminal penceresinde:

  1. cd my-project-master aynı olan başka bir WD .git
  2. git reflog yaptığım bugfix'i bulmak için.
  3. git cherry-pick SHA1 taahhüt.

İsteğe bağlı olarak (yine de eşzamansız), genellikle bir PR göndermek üzereyken ve özellik dalınızı ve WD'yi zaten temizlediğinizde, hata düzeltmesini almak için özellik dalınızı yeniden adlandırabilir (veya birleştirebilirsiniz):

  1. cd my-project üzerinde çalıştığım ana WD.
  2. git rebase master hata düzeltmeleri almak için.

Bu şekilde, özellik üzerinde kesintisiz çalışmaya devam edebilirim ve bir git stashşey yapmadan veya WD'mi git checkoutdaha önce temizlemek zorunda kalmadan (ve sonra özellik dalı arkalıklarını tekrar kontrol ettirerek) endişelenmenize gerek kalmaz ve yine de tüm hata düzeltmelerim masteryerine geçer özellik dalımda gizli.

IMO git stashve git checkoutbazı büyük özellik üzerinde çalışırken ortasında gerçek bir PIA olduğunu.


Cevabım için ilginç ve geçerli bir alternatif. +1
VonC

Merkürden mi geliyorsun? my-project-masterAynı paylaşan .gitbunun gibi ses yapar. Neden olmasın git checkout -b bugfixABC; git commit -a; git reset HEAD^ --hard, daha sonra (zaman uyumsuz) sırasında master, git cherry-pick <SHA1 of the commit(s) in bugfixABC? (veya hatta, git rebase --onto master feature bugfixABCşu anda nerede olursanız olun , SHA1'i bulmaktan kaçınmak için. Bu, git resetyukarıdakilerden hemen sonra, doğrudan devam ederseniz anlamına gelir feature.)
Gauthier

Ancak OP, değişiklikleri yapmaya hazır değilmiş gibi geliyor, bu durumda checkout -mdaha iyi.
Gauthier

2

Eğer taahhüt edilen değişiklikler hakkında olsaydı, git-rebase'e bir göz atmalısınız, ancak VonC tarafından yorumda belirtildiği gibi, yerel değişikliklerden bahsederken, git-stash kesinlikle bunu yapmanın iyi bir yolu olurdu.


Bu çözümü anlamıyorum: şube2'nin şube tarihinin taahhüt tarihini şube1'den yeniden yazsın ... neden şube2'deki şube 1'in yerel olarak taahhüt edilmemiş değişikliklerini almak istediğimizde neden şube2'deki şube1'den tüm taahhütlü değişiklikleri almak? ...
VonC

@VonC: bu durumda, rebase şubeler arasındaki son birleştirmeden bu yana taahhüt edilen tüm değişiklikleri alır1. İlk başta bu sorunun "kararlı olmayan" parametresini alamadım. rebase iyi bir cevap değil.
claf

@claferri: pfew ... Başım ağrıyordu;) Cevabınızı küçümseyecektim, ama kendimi bir tane yayınladığımdan beri, "açık bir çıkar çatışması" vardı. Güncellenmiş yayınınızla, şimdi hiçbir şekilde aşağı düşürmem gerekmiyor. Teşekkürler :)
VonC

@VonC: bir dahaki sefere, cevabım bu kadar yanlış olduğu sürece aşağı oy vermekten çekinmeyin;)
claf

1

Şimdiye kadar verilen cevaplar ideal değil çünkü birleşme çatışmalarını çözmek için çok fazla gereksiz çalışmaya ihtiyaç duyuyorlar ya da sıklıkla yanlış olan çok fazla varsayım yapıyorlar. Mükemmel şekilde bu şekilde yapılır. Bağlantı kendi siteme ait.

Git'te Farklı Bir Şubeye Nasıl Taahhüt Edilir

Tüm değişiklikleri my_branchtaahhüt masteretmeden taahhüt etmek istediğiniz taahhüt edilmemiş değişiklikleriniz var my_branch.

Misal

git merge master
git stash -u
git checkout master
git stash apply
git reset
git add example.js
git commit
git checkout .
git clean -f -d
git checkout my_branch
git merge master
git stash pop

açıklama

masterNihayetinde bunu yapmanız gerekeceğinden, şubenizle birleşerek başlayın ve şimdi herhangi bir çatışmayı çözmek için en iyi zaman.

-uSeçeneği (aka --include-untrackedolarak) git stash -udaha sonra ne zaman izlenmeyen dosyaları kaybetme gelen önler sen git clean -f -diçinde master.

Sonra git checkout masterbu YAPMAK önemlidir git stash pop, çünkü daha sonra bu zulası ihtiyacınız olacak. Eğer oluşturduğunuz zulası pop ederse my_branchve sonra yapmak git stashiçinde master, size daha sonra o zulası uygulamak gereksiz birleştirme çakışmaları neden olacaktır my_branch.

git resetsonuçta ortaya çıkan herşey git stash apply. Örneğin, depoda değiştirilen ancak master"bizim tarafımızdan silindi" çatışmaları içinde hazırlanmayan dosyalar çakışıyor.

git checkout .ve git clean -f -dtaahhüt edilmeyen her şeyi atın: izlenen dosyalarda yapılan tüm değişiklikler ve izlenmeyen tüm dosya ve dizinler. Zaten saklanmış durumdadırlar ve eğer bırakılırlarsa mastergeri dönerken gereksiz birleşme çakışmalarına neden olurlar my_branch.

Sonuncusu git stash poporijinaline my_branchdayanacaktır ve bu nedenle herhangi bir birleşme çatışmasına neden olmayacaktır. Ancak, stash'ınızda master işlemi gerçekleştirdiğiniz izlenmemiş dosyalar varsa, git "Izlenmemiş dosyalar stash'tan geri yüklenemedi" şeklinde şikayet edecektir. Bu uyuşmazlığı gidermek için, çalışma ağacın ardından gelen bu dosyaları silmek git stash pop, git add .ve git reset.


2
Yanıtınız web sitenize bağlı olduğu için silinmedi, farklı bir hesaptaki diğer yanıtla aynı olduğu için silindi . Diğer hesabın sizinkiyle aynı profile sahip olduğunu görüyorum, iki hesap kullanıyor musunuz? Her iki hesabın da birleştirilmesini sağlayabilirsiniz. Ayrıca, durumu açıklamak için bir mod işaretleyin ve orijinal cevabınızı (upvote ile) geri alabilirsiniz.

1
Onların birleşti eğer bunları ayrı tutmak değil, ancak edilir sürece dolandırıcılık oylama işlemek için bunları kullanmayın olarak, birden fazla hesap açmasına izin (ya da genel olarak etkileşim birbirleri ile onlara sahip). Durumunuzu bir moda açıklayın. Ayrıca, silme dürüst bir hataydı, kimsenin iki farklı hesap kullandığınızı söylemesini nasıl bekleyebilirsiniz?

3
Sen gerek bayrak onlar silinen cevabı düzenlerken için ödeme dikkat olmaz, yazınızı ve Mod dikkatini çekmek için diğer seçeneğini kullanın. Yayınlarınızı mod dikkatleri için zaten işaretledim, ancak oldukça meşguller, bu yüzden sabırlı olun, sonunda size ulaşacaklar.

1
Özellikle farklı hesaplardan yinelenen içerik yayınlamayın. İki soru aynıysa, kopya olarak kapatmak için oy verin veya işaretleyin.
Kertenkele Bill
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.