Müstakil KAFA'yı master/origin ile nasıl uzlaştırabilirim?
Git'in dallanma karmaşıklığı konusunda yeniyim. Her zaman tek bir dal üzerinde çalışıyorum ve değişiklikleri işliyorum ve ardından periyodik olarak uzak kaynağıma itiyorum.
Geçenlerde bir yerde, bazı dosyaları commit hazırlama aşamasından çıkarmak için sıfırladım ve daha sonra birkaç yeni yerel commit'ten kurtulmak için bir `rebase -i' yaptım. Şimdi tam olarak anlayamadığım bir durumdayım.
Çalışma alanımda, `git günlüğü' tam olarak beklediğim şeyi gösteriyor - gitmesini istemediğim taahhütlerle doğru trendeyim ve orada yenileri var, vb.
Ama az önce uzaktaki depoya gönderdim ve oradakiler farklı-- yeniden düzenlemede öldürdüğüm birkaç değişiklik gönderildi ve yerel olarak işlenen yenileri orada değil.
Sanırım "master/origin" HEAD'den ayrılmış, ancak bunun ne anlama geldiği, komut satırı araçlarıyla nasıl görselleştirileceği ve nasıl düzeltileceği konusunda %100 net değilim.
Öncelikle, HEAD'in ne olduğunu ve ayrıldığında ne anlama geldiğini açıklığa kavuşturalım.
HEAD, o anda kontrol edilen commit'in sembolik adıdır. HEAD ayrılmadığında ("normal"1 durum: kontrol edilmiş bir dalınız var), HEAD aslında bir dalın "ref "sine işaret eder ve dal da commit'e işaret eder. HEAD böylece bir dala "eklenir". Yeni bir commit yaptığınızda, HEAD'in işaret ettiği dal yeni commit'i işaret edecek şekilde güncellenir. HEAD sadece dalı işaret ettiği için otomatik olarak onu takip eder.
git symbolic-ref HEAD
,refs/heads/master
sonucunu verir "master" adlı dal kontrol edilir.git rev-parse refs/heads/master
yield17a02998078923f2d62811326d130de991d1a95a
Bu işlem, ana dalın geçerli ucu veya "başı "dır.git rev-parse HEAD
ayrıca17a02998078923f2d62811326d130de991d1a95a
sonucunu verir "Sembolik hakem" olmanın anlamı budur. Başka bir referans aracılığıyla bir nesneye işaret eder.(Sembolik referanslar başlangıçta sembolik bağlantılar olarak uygulanmış, ancak daha sonra sembolik bağlantıları olmayan platformlarda kullanılabilmeleri için ekstra yorumlama ile düz dosyalara dönüştürülmüştür).
HEAD
→
refs/heads/master→
17a02998078923f2d62811326d130de991d1a95a` varHEAD ayrıldığında, bir dal aracılığıyla dolaylı olarak bir işleme işaret etmek yerine doğrudan bir işleme işaret eder. Ayrılmış bir HEAD'i isimsiz bir dal üzerindeymiş gibi düşünebilirsiniz.
git symbolic-ref HEAD
,fatal: ref HEAD is not a symbolic ref
ile başarısız oluyorgit rev-parse HEAD
çıktısı17a02998078923f2d62811326d130de991d1a95a
Sembolik bir ref olmadığından, doğrudan commit'in kendisine işaret etmelidir.HEAD
→
17a02998078923f2d62811326d130de991d1a95a` varAyrılmış bir HEAD ile hatırlanması gereken önemli şey, işaret ettiği commit başka bir şekilde referanslanmamışsa (başka hiçbir ref ona ulaşamaz), başka bir commit'i kontrol ettiğinizde "sarkık" hale gelecektir. Sonunda, bu tür sarkan commitler çöp toplama işlemi ile budanacaktır (varsayılan olarak, en az 2 hafta tutulurlar ve HEAD'in reflog'u tarafından referans alınarak daha uzun süre tutulabilirler).
1 Ayrılmış bir HEAD ile "normal" işler yapmakta bir sakınca yoktur, sadece reflog'dan düşen geçmişi bulmak zorunda kalmamak için ne yaptığınızı takip etmeniz gerekir.
Etkileşimli bir yeniden düzenlemenin ara adımları ayrılmış bir HEAD ile yapılır (kısmen aktif dalın reflogunu kirletmekten kaçınmak için). Tam yeniden düzenleme işlemini bitirirseniz, orijinal dalınızı yeniden düzenleme işleminin kümülatif sonucu ile günceller ve HEAD'i orijinal dala yeniden ekler. Tahminimce, rebase işlemini hiçbir zaman tam olarak tamamlamadınız; bu da sizi rebase işlemi tarafından en son işlenen commit'e işaret eden ayrılmış bir HEAD ile baş başa bırakacaktır.
Durumunuzu kurtarmak için, ayrılmış HEAD'inizin şu anda işaret ettiği commit'i işaret eden bir dal oluşturmalısınız:
(bu iki komut
git checkout -b temp
olarak kısaltılabilir)Bu, HEAD'inizi yeni
temp
dalına yeniden ekleyecektir.Ardından, mevcut işlemeyi (ve geçmişini) üzerinde çalışmayı beklediğiniz normal dal ile karşılaştırmalısınız:
(Muhtemelen günlük seçeneklerini denemek isteyeceksiniz:
-p
ekleyin, tüm günlük mesajını görmek için--pretty=...
seçeneğini devre dışı bırakın, vb.)Yeni
temp
dalınız iyi görünüyorsa,master
dalını ona işaret edecek şekilde güncellemek (örneğin) isteyebilirsiniz:(bu iki komut
git checkout -B master temp
olarak kısaltılabilir)Daha sonra geçici dalı silebilirsiniz:
Son olarak, muhtemelen yeniden oluşturulmuş geçmişi zorlamak isteyeceksiniz:
Uzak dal yeni commit'e "hızlı ileri" alınamıyorsa (yani mevcut bir commit'i düşürdüyseniz veya yeniden yazdıysanız ya da başka bir şekilde geçmişin bir kısmını yeniden yazdıysanız) push etmek için bu komutun sonuna `--force' eklemeniz gerekebilir.
Bir yeniden yerleştirme işleminin ortasında olsaydınız muhtemelen temizlemeniz gerekirdi. Rebase işleminin yapılıp yapılmadığını
.git/rebase-merge/
dizinine bakarak kontrol edebilirsiniz. Sadece bu dizini silerek devam eden yeniden düzenlemeyi manuel olarak temizleyebilirsiniz (örneğin, aktif yeniden düzenleme işleminin amacını ve bağlamını artık hatırlamıyorsanız). Genelliklegit rebase --abort
kullanırsınız, ancak bu muhtemelen kaçınmak isteyeceğiniz bazı ekstra sıfırlamalar yapar (HEAD'i orijinal dala geri taşır ve orijinal commit'e geri sıfırlar, bu da yukarıda yaptığımız işin bir kısmını geri alır).Ayrılmış başın temel açıklaması için buraya bakın:
http://git-scm.com/docs/git-checkout
Görselleştirmek için komut satırı:
veya
aşağıdaki gibi bir çıktı alacaksınız:
Bu duruma bir
git checkout somecommit
vb. yaparak da gelebilirdiniz ve sizi aşağıdaki şekilde uyarırdı:Şimdi, onları ustaya götürmek için:
Bir
git reflog
veya hatta sadecegit log
yapın ve taahhütlerinizi not edin. Şimdigit checkout master
ve taahhütlerigit merge
yapın.Düzenle:
Eklemek gerekirse,
git rebase -i
yi yalnızca ihtiyacınız olmayan taahhütleri silmek / öldürmek için değil, aynı zamanda bunları düzenlemek için de kullanın. Komite listesinde "edit" yazmanız yeterlidir ve komitenizi değiştirebilir ve ardından devam etmek için birgit rebase --continue
yayınlayabilirsiniz. Bu, hiçbir zaman ayrılmış bir HEAD'e gelmemenizi sağlayacaktır.Ayrılmış işleminizi kendi dalına alın
Basitçe
git checkout -b mynewbranch
komutunu çalıştırın.Sonra
git log
u çalıştırın ve commitin artık bu yeni dalda
HEAD` olduğunu göreceksiniz.