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.

Çözüm

Ö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 yield 17a02998078923f2d62811326d130de991d1a95a Bu işlem, ana dalın geçerli ucu veya "başı "dır.
  • git rev-parse HEAD ayrıca 17a02998078923f2d62811326d130de991d1a95a 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).

HEADrefs/heads/master17a02998078923f2d62811326d130de991d1a95a` var

HEAD 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 oluyor
  • git rev-parse HEAD çıktısı 17a02998078923f2d62811326d130de991d1a95a Sembolik bir ref olmadığından, doğrudan commit'in kendisine işaret etmelidir.

HEAD17a02998078923f2d62811326d130de991d1a95a` var

Ayrı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:

git branch temp
git checkout temp

(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:

git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
git diff master temp
git diff origin/master temp

(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:

git branch -f master temp
git checkout master

(bu iki komut git checkout -B master temp olarak kısaltılabilir)

Daha sonra geçici dalı silebilirsiniz:

git branch -d temp

Son olarak, muhtemelen yeniden oluşturulmuş geçmişi zorlamak isteyeceksiniz:

git push origin master

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). Genellikle git 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).

Yorumlar (22)

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ı:

git branch

veya

git branch -a

aşağıdaki gibi bir çıktı alacaksınız:

* (no branch)
master
branch1
  • (dal yok)` ifadesi kafanızın kopuk olduğunu gösterir.

Bu duruma bir git checkout somecommit vb. yaparak da gelebilirdiniz ve sizi aşağıdaki şekilde uyarırdı:

'KAFA'nız 'ayrılmış' durumdasınız. Sen etrafa bakabilir, deneysel çalışmalar yapabilir değişiklikleri yapın ve bunları işleyin ve bu işlemde yaptığınız tüm taahhütleri atın herhangi bir şubeyi etkilemeden durum başka bir ödeme gerçekleştirerek.

Eğer yeni bir şube oluşturmak istiyorsanız oluşturduğunuz taahhütleri koruyun, şunları yapabilirsiniz bu nedenle (şimdi veya daha sonra) -b ile checkout komutunu tekrar verin. Örnek:

git checkout -b new_branch_name

Şimdi, onları ustaya götürmek için:

Bir git reflog veya hatta sadece git log yapın ve taahhütlerinizi not edin. Şimdi git checkout master ve taahhütleri git merge yapın.

git merge HEAD@{1}

Düzenle:

Eklemek gerekirse, git rebase -iyi 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 bir git rebase --continue yayınlayabilirsiniz. Bu, hiçbir zaman ayrılmış bir HEAD'e gelmemenizi sağlayacaktır.

Yorumlar (2)

Ayrılmış işleminizi kendi dalına alın

Basitçe git checkout -b mynewbranch komutunu çalıştırın.

Sonra git logu çalıştırın ve commitin artık bu yeni daldaHEAD` olduğunu göreceksiniz.

Yorumlar (2)