Orijin / KAFA nasıl ayarlanır?


144

Bir kökeni ref izlemek için kurulmuş bir şube var. git checkout <branchname>bir şubeye geçiyor ve bir şubem, git statusşubemden ne kadar ileride veya arkasında olduğumuzu gösterecek, ama origin/HEADhala işaret ettiğine şaşırdım origin/master, değilorigin/<branchname>

Benim sorum şu: menşe / HEAD hangi şartlar altında hareket ediyor?

DÜZENLE:

Kökeni / HEAD'in nasıl taşınacağına dair cevapları takdir ediyorum , ancak "organik" olarak neyin hareket ettirdiğiyle ilgileniyorum, dışımda bunu açıkça söyledi.

Örneğin, dalları değiştirdiğimde git, kontrol ettiğim dalda HEAD noktası yapıyor, bu yüzden orijin / HEAD'in aynı şekilde hareket etmemesine şaşırdım.


Bu sorunun uzaktan kumandalardaki yerel sembolik referanslarla ilgili olduğunu unutmayın refs/origin/HEAD. Bir havuzun kendi sembolik referansının nasıl HEADayarlandığı ile ilgili değildir.
clacke

Yanıtlar:


173

Öncelikle sorunuzun biraz yanlış anlama gösterdiğini unutmayın. origin / HEAD, uzaktan kumandadaki varsayılan dalı , yani orijini çağırdığınız uzak depodaki HEAD'i temsil eder . Reponuzdaki şubeleri değiştirdiğinizde bunu etkilemezsiniz. Aynısı uzak dallar için de geçerlidir; repo'nuzda olabilir masterve origin/masterburada deponuz, uzak depodaki şubenin origin/masteryerel bir kopyasını temsil eder master.

başlangıç ​​noktası HEAD yalnızca siz veya bir başkası uzak depoda gerçekten değiştirirse değişecektir , bu temelde asla gerçekleşmemelidir - varsayılan dalın genel dalın sabit dalda (muhtemelen ana) sabit kalmasını istersiniz. origin / HEAD, uzak depodaki HEAD'ın yerel bir kopyasını temsil eden yerel bir ref. (Tam adı refs / uzaktan kumandalar / orijin / KAFA'dır.)

Yukarıdaki bilgilerin aslında bilmek istediklerinizi cevapladığını düşünüyorum, ancak devam etmek ve açıkça sorduğunuz soruyu cevaplamak için ... bir depoyu klonladığınızda orijin / HEAD otomatik olarak ayarlanır ve bu konuda. Garip, bu oluyor o değil gibi komutlar tarafından belirlenen git remote update- Ben manuel olarak değişiklik eğer değişecek tek yol olduğuna inanıyoruz. (Değişim demek istediğim farklı bir dalı işaret ediyor; açıkçası bu şube değişirse değişikliklere işaret ediyor, bu getirme / çekme / uzaktan güncellemede olabilir.)


Düzenleme : Aşağıda tartışılan sorun Git 1.8.4.3'te giderilmiştir ; bu güncellemeye bakın .


Yine de küçük bir uyarı var. HEAD sembolik bir ref'dir, doğrudan bir taahhüt yerine bir şubeye işaret eder, ancak git uzaktan aktarım protokolleri sadece ref için taahhütte bulunur. Git, HEAD ve diğer tüm referansların işaret ettiği taahhüdün SHA1'ini biliyor; daha sonra aynı taahhüde işaret eden bir şube bularak HEAD'ın değerini çıkarmalıdır. Bu, iki dalın oraya işaret etmesi durumunda belirsiz olduğu anlamına gelir. (Mümkünse efendiyi seçtiğine, ardından alfabetik olarak ilk sıraya düştüğüne inanıyorum.) Bunun çıktısında bildirildiğini göreceksiniz git remote show origin:

$ git remote show origin
* remote origin
  Fetch URL: ...
  Push  URL: ...
  HEAD branch (remote HEAD is ambiguous, may be one of the following):
    foo
    master

Tuhaf bir şekilde, HEAD kavramı bu şekilde yazdırılmış olsa da, uzaktan kumandadaki şeyler değişirse (örn. Foo kaldırılırsa), aslında güncellenmez refs/remotes/origin/HEAD. Bu gerçekten garip durumlara yol açabilir. Yukarıdaki örnekte, origin / HEAD'ın aslında foo'ya işaret ettiğini ve orijinallerin foo dalının kaldırıldığını varsayalım. Sonra bunu yapabiliriz:

$ git remote show origin
...
HEAD branch: master
$ git symbolic-ref refs/remotes/origin/HEAD
refs/remotes/origin/foo
$ git remote update --prune origin
Fetching origin
 x [deleted]         (none)     -> origin/foo
   (refs/remotes/origin/HEAD has become dangling)

Uzak gösteri HEAD'ın usta olduğunu bilmesine rağmen, hiçbir şey güncellemiyor. Eski foo dalı doğru budanır ve HEAD sarkar (var olmayan bir dalı işaret eder) ve yine de master'ı işaret edecek şekilde güncellemez. Bunu düzeltmek istiyorsanız, git remote set-head origin -abaşlangıç ​​noktasının başlığını otomatik olarak yukarıdaki gibi belirleyen ve daha sonra aslında başlangıç ​​/ BAŞLIK'ı uygun uzak dalı işaret edecek şekilde ayarlayan kullanın.


@jefromi Müthiş cevap! Sadece bir açıklama: HEAD'in doğrudan bir taahhüt yerine bir şubeye işaret eden sembolik bir referans olduğunu yazıyorsunuz [...] , ancak tamlık için "müstakil HEAD durumu" ndan bahsetmeye değer olabilir.
jub0bs

2
@Jubobs Teşekkürler! Cevabımın güncellenmesi gerekiyorsa, lütfen basitçe düzenlemekten çekinmeyin - iki yıl önce doğru olanı ve şimdi doğru olanı sıralamak yerine, insanların gerçekte nasıl çalıştığının kısa bir özetini okumak için kesinlikle zaman kazandıracak. .
Cascabel

en az 5 kez okudum ve hala biraz anlamıyorum
krb686

7
git remote set-head origin -abenim için iş yaptı
Shujito

75

Yerel repo sahibi olarak sizin ayarınızdır. Bu şekilde değiştirin:

git remote set-head origin some_branch

Ve orijin / HEAD master yerine şubenizi gösterecektir. Bu daha sonra sadece repo için geçerlidir, başkaları için geçerli değildir. Uzak depoda başka bir şey yapılandırılmadığı takdirde, varsayılan olarak master'ı gösterecektir.

Uzak set başlığı için manuel giriş , bu konuda bazı iyi bilgiler sağlar.

Düzenleme: vurgulamak için: bunu söylemeden, "hareket" tek yolu "organik" kabul olduğunu sanmıyorum ana dalı , yeniden adlandırmak gibi bir durum olacaktır . Yani, organik olarak hareket etmediğini söyleyebilirim.


1
Düzenleme vurgusu burada tam olarak doğru değil. Ana dalda olmayan yerel bir kopyadan kopyalarsanız da değişebilir.
mphair

Ben bir klon "hareketli" düşünmüyorum, ama sanırım buna katılmıyorum :)
eis

24

Kökeni / HEAD'i "organik olarak" hareket ettiren nedir?

  • git clone bir kez HEAD'ın başlangıç ​​noktasında olduğu yere ayarlar
    • ile klonlamadan sonra ödeme yapmak için varsayılan şube olarak hizmet eder git clone

Menşe üzerine HEAD neyi temsil eder?

  • çıplak depolarda (genellikle “sunucularda” depolar) varsayılan dal için bir işaretleyici görevi görür, çünkü git clonebu şekilde kullanır
  • çıplak olmayan depolarda (yerel veya uzak), deponun mevcut kasasını yansıtır

Kökeni / başlığı ne belirler?

  • git clone getirir ve ayarlar
  • git fetchbaşka bir referans gibi güncellemesi mantıklı olurdu , ancak
  • git remote set-head origin -a getirir ve ayarlar
    • uzaktan kumandanın “varsayılan şube” olarak neyi düşündüğüne ilişkin yerel bilgileri güncellemek için yararlıdır

önemsiz şeyler

  • origin/HEAD uzaktan kumandayla temas etmeden başka bir değere de ayarlanabilir: git remote set-head origin <branch>
    • Test dışında bunun için bir kullanım durumu görmüyorum
  • ne yazık ki hiçbir şey uzaktan kumandaya KAFA ayarlayamıyor
  • git'in eski sürümleri, uzaktan kumandada hangi şube HEAD'ini işaret ettiğini bilmiyordu, sadece nihayet hangi karma karmasını gösterdi: bu yüzden umarım aynı karmayı işaret eden bir şube adı seçti

Referansımı kaybettim origin/HEADve çözümünüz yardımcı oldu. Teşekkürler!
java_dude

git fetch(Yerel) bir kısayol yapılandırmaya izin verdiğinden, güncellemeye katılmıyorum . Dokümandan alıntı: "Bir uzaktan kumanda için varsayılan bir şubeye sahip olmak gerekli değildir, ancak uzaktan kumandanın adının belirli bir dal yerine belirtilmesini sağlar". Uzak bir değişikliğin yerel olarak yapılandırılmış kısayolları güncellemesi garip olurdu.
Micha Wiedenmann

@MichaWiedenmann Bu neden yerel olarak yapılandırılmış bir kısayol olsun? Yerel olarak yapılandırılmış bir kısayol origin/HEADiçin kötü bir ad. Ve bu git clone, “yerel olarak yapılandırılmış dal” için varsayılan olarak uzak bir ad kullanır. Çıplak olmayan depolarda, uzaktan kumandanın akımını kullanmak bile mantıklı değildir HEAD.
Robert Siemer

10

Feragatname : Bu, meraklıları bir süre kurtarmak için yazdığım Jefromi'nin cevabı için bir güncelleme .

Boşuna remote HEAD is ambiguousJefromi'nin cevabında bahsettiği mesajı (Git 2.0.1'de) tekrarlamaya çalıştım ; bu yüzden biraz kazma yaptım ( https://github.com/git/git klonlayarak ve günlükte arama yaparak). Eskiden böyle

Determining HEAD is ambiguous since it is done by comparing SHA1s.

In the case of multiple matches we return refs/heads/master if it
matches, else we return the first match we encounter. builtin-remote
needs all matches returned to it, so add a flag for it to request such.

( 4229f1fa325870d6b24fe2a4c7d2ed5f14c6f77127 Şubat 2009 tarihli taahhüt ile birlikte bulundu git log --reverse --grep="HEAD is ambiguous")

Bununla birlikte, söz konusu belirsizlik kaldırılmıştır :

One long-standing flaw in the pack transfer protocol used by "git
clone" was that there was no way to tell the other end which branch
"HEAD" points at, and the receiving end needed to guess.  A new
capability has been defined in the pack protocol to convey this
information so that cloning from a repository with more than one
branches pointing at the same commit where the HEAD is at now
reliably sets the initial branch in the resulting repository.

( 9196a2f8bd46d36a285bdfa03b4540ed3f01f6718 Kasım 2013 tarihli taahhüt , ile birlikte bulundu git log --grep="ambiguous" --grep="HEAD" --all-match)

Düzenleme ( torek sayesinde ):

$ git name-rev --name-only 9196a2f8bd46d36a285bdfa03b4540ed3f01f671
tags/v1.8.4.3~3

Bu, Git v1.8.4.3 veya üstünü kullanıyorsanız , belirsiz-uzak-HEAD sorunuyla karşılaşmamanız gerektiği anlamına gelir .


1
Git kaynağındaki etiketlere bağlı olarak, bu düzeltme git 1.8.4.3 ve sonraki sürümleri için geçerlidir.
torek

@RobertSiemer Emin değilim, ama öyle düşünüyorum, evet.
jub0bs

8

Bahsettiğimiz iki bağımsız git deposu olduğunu unutmayın . Kodunuzla birlikte yerel repo ve uzaktan kumanda başka bir yerde çalışıyor.

Haklısınız, bir şubeyi değiştirdiğinizde HEAD mevcut şubenizi işaret ediyor. Bütün bunlar yerel git deponuzda oluyor. Başka bir geliştiriciye ait olabilecek veya ofisinizdeki bir sunucuda, github'da veya dosya sistemindeki başka bir dizinde vb.

Bilgisayarınızın (yerel repo) uzak git repo'sundaki HEAD işaretçisini değiştiren bir işi yok. Örneğin, farklı bir geliştiriciye ait olabilir.

Bir şey daha, bilgisayarınızın orijin / XXX olarak adlandırdığı şey, bilgisayarınızın son getirme sırasında uzaktan kumandanın durumunu anlamasıdır.

Peki "organik olarak" kökeni / KAFA ne güncelleyecek? Uzak git deposunda etkinlik olurdu. Yerel deponuz değil.

İnsanlar bahsetti

git symbolic-ref HEAD referansları / head / my_other_branch

Normalde bu, geliştirme ekibi tarafından kullanılmak üzere bir sunucuda paylaşılan bir merkezi git repo olduğunda kullanılır. Uzak bilgisayarda yürütülen bir komut olurdu. Bunu uzak git deposunda etkinlik olarak görürsünüz.


1
Üzgünüm, eğer biraz tekrarlıysam. Sadece git'in dağıtılmış bir sürüm kontrol sistemi olduğu ve iki deponun bağımsız olduğu gerçeğini belirtmek istiyorum.
Pablo Maurin

3

Git CLI'den aşağıdaki komutları çalıştırın:

# move to the wanted commit
git reset --hard <commit-hash> 

# update remote
git push --force origin <branch-name> 

1
Harika, bu bana yardımcı oldu!
Shay Zambrovski
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.