Git'te HEAD, çalışma ağacı ve dizin arasındaki fark nedir?


488

Birisi Git'te HEAD, çalışma ağacı ve dizin arasındaki farkı söyleyebilir mi?

Anladığım kadarıyla, hepsi farklı dalların isimleri. Varsayım doğru mu?


Düzenle

Bunu buldum

Tek bir git deposu rasgele sayıda dalı izleyebilir, ancak çalışma ağacınız bunlardan yalnızca biri ("geçerli" veya "kullanıma alınmış" dalı) ile ilişkilendirilir ve HEAD bu dalı işaret eder.

Bu KAFA ve çalışan ağacın her zaman aynı olduğu anlamına mı geliyor?


26
Düzenlemenizle ilgili olarak: kesinlikle hayır. HEADmevcut dalın ucundaki taahhüttür. Şubeyi yeni kontrol ettiyseniz, yani değiştirilmiş dosyanız yoksa, içeriği çalışma ağacıyla eşleşir. Bir şeyi değiştirir değiştirmez, artık eşleşmez.
Cascabel

6
Bence bunu okumak zorundasın: think-like-a-git.net
Andrzej Duś

5
Ayrıca Staging Areabu listeye bir eklerdim. Nedir HEAD, Working Tree, IndexveStaging Area
Yeşil

2
@ Jefromi'nin son cümlesi şu şekilde daha açık olur:> Herhangi bir şeyi değiştirir değiştirmez, çalışma ağacı artık HEAD taahhüdüyle eşleşmiyor
starscream_disco_party

3
Gelecekte bunu okumak için, bu cevaplardan bazılarını gerçekten anlamanın en iyi yolu, neler olduğunu görmek ve hissetmek ve görsel olarak kavramsallaştırmaktır: bu git'i
BKSpurgeon

Yanıtlar:


578

Bu konular hakkında birkaç iyi referans:

alternatif metin

İndeksi bir kontrol noktası olarak kullanıyorum .

Yanlış gidebilecek bir değişiklik yapmak üzereyken - takip edebileceğimden emin olmadığım bir yönü araştırmak istediğimde veya bunun kavramsal olarak talepkar bir yeniden düzenleme veya değiştirme gibi iyi bir fikir olup olmadığından emin olmak istediğimde temsil türü - Çalışmamı indekste kontrol ederim. Bu son işlemimden bu yana yaptığım ilk değişiklikse, yerel veri havuzunu bir kontrol noktası olarak kullanabilirim, ancak çoğu zaman küçük adımlar kümesi olarak uyguladığım kavramsal bir değişikliğim var. Her adımdan sonra kontrol etmek istiyorum, ancak çalışmaya, test edilen koda geri dönene kadar taahhüdü kaydedin.

Notlar:

  1. Çalışma alanı (kaynak) dizin ağacı görmek ve düzenlemek olduğunu dosyaları.

  2. İndeks tek, büyük, ikili dosyadır <baseOfRepo>/.git/indextüm güncel dalında dosyaları, onların listeler, sha1 toplamlarını, zaman damgaları ve dosya adını - o dosyaların bir kopyasını başka bir dizin değil.

  3. Yerel havuz gizli dizin (olan .gitbir dahil) objectssıkıştırılmış "blob" dosyası olarak repo her dosyanın tüm sürümlerini (yerel şubeleri ve uzak şube kopya) içeren dizinin.

Yukarıdaki resimde gösterilen dört 'diski' repo dosyalarının ayrı kopyaları olarak düşünmeyin.

alternatif metin

Temel olarak Git taahhütleri için referanslar olarak adlandırılırlar. İki temel refs türü vardır: etiketler ve kafalar.

  • Etiketler, tarihte belirli bir noktayı işaret eden sabit referanslardır, örneğin v2.6.29.
  • Aksine, başlıklar daima proje geliştirmenin mevcut konumunu yansıtacak şekilde hareket ettirilir.

alternatif metin

(not: olarak yorumladı tarafından Timo Huovinen , bu oklar değil kaydedilmesini işaret nelerdir, bu kadar iş akışı düzeni temelde olarak okları göstererek, 1 -> 2 -> 3 -> 4nerede 1ilk taahhüt ve 4sonuncusu)

Şimdi projede neler olduğunu biliyoruz.
Ancak burada neler olduğunu bilmek için şu anda HEAD adı verilen özel bir referans var. İki ana amaca hizmet eder:

  • Git'e, ödeme yaptığınızda hangi dosyaları almayı taahhüt ettiğini bildirir ve
  • Git'e taahhüt ettiğinizde nereye yeni taahhütler koyacağınızı söyler.

Eğer çalıştırdığınızda git checkout refo işaret HEADtanımlamış ve ondan ekstreler dosyaları ettik ref. Çalıştırdığınızda git commit, geçerli bir alt öğe olan yeni bir taahhüt nesnesi oluşturur HEAD. Normalde HEADkafalardan birine işaret eder, bu yüzden her şey yolunda gider.

alternatif metin


20
Git lot hakkında birçok kez okuduktan sonra hiç tam olarak anlayamadım, gerçekten hayal kırıklığına uğradım n f kelimesini kullanmak istiyorum; Ama topluluktayım! Kafalardan bahsetmiştim ama yukarıdaki resimlerde her zaman tek bir HEAD var mı? "Normalde HEAD kafalardan birine işaret ediyor, bu yüzden her şey yolunda gidiyor." Bunu açıklamaya yalvarıyorum, Ur ifadesi.
Necktwi

12
@neckTwi BAŞ olduğunu taahhüt akım sen (çalışıyorsanız stackoverflow.com/a/964927/6309 ). Genellikle "şube başkanlarından" ( söz konusu şubelerin ucunu temsil eden şubeler tarafından referans verilen taahhütlerden biridir ). Ancak herhangi bir taahhüdü kontrol edebilir (ve üzerinde çalışabilirsiniz). (Şube) kafalarından biri olmayan bir taahhüdü kontrol ederseniz, "müstakil KAFA" modundasınız: stackoverflow.com/a/3965714/6309
VonC

1
@ Kabul ediyorum, ancak bu resimleri 5 yıl önce bu şekilde buldum ( hades.name/blog/2010/01/28/… )
VonC

11
Dizinle ilgili olarak, söyleyebileceğim en yararlı şey, "İndeks evreleme alanı için başka bir isimdir", @ ashraf-alam gibi. Çoğu zaman tartışma alanı olarak adlandırılıyor gibi hissediyorum , bu yüzden otomatik olarak dizin ile aynı şey olduğunu bağlantı yapmadım.
Pete

1
@Pete katılıyorum. Önbellek ve dizin arasındaki fark hakkında daha fazla bilgi için diğer
cevabıma

137

Arasındaki fark HEAD (şimdiki şube veya geçerli dal üzerinde son kararlı durum), endeksi (aka. Evreleme alan) ve çalışma ağacının (eyaletinde dosyaları çıkış olarak) açıklanan "1.3 Git Temelleri "Üç Devletleri" bölümünde " Pro Git kitabının Scott Chacon (Creative Commons lisanslı) bölümü .

İşte bu bölümden gösteren resim:

Yerel İşlemler - çalışma dizini ve hazırlama alanı (dizin) ve git deposu (HEAD)

Yukarıdaki resimde "çalışma dizini", "çalışma ağacı" ile aynıdır, "evreleme alanı" git "index" için alternatif bir addır ve HEAD , şu anda teslim alınan şubeye işaret eder. git dizini (depo) "

Not git commit -adeğişiklikleri sahne ve tek adımda taahhüt ederim.


1
"Bir resim bin kelime değerinde bir olup". Teşekkürler Jakub .. Ve bağlantı için teşekkürler.
Joyce Babu

5
Not: Günümüzde working treetercih ediliyor gibi görünüyor working directory. Bkz. Github.com/git/git/commit/…
VonC

3
Hazırlama Alanı "index" adlı tek bir dosyada bulunduğundan ve bu dizin dosyasının .git dizininin kökünde olduğu için bu resim tam olarak doğru değildir. Bu nedenle repo'yu .git dizini olarak tanımlarsanız, hazırlama alanı teknik olarak repo içinde olur. Üçüncü sütun, kullanıma alınan dosyaların bir taahhüt nesnesinden geldiğini ve taahhüt vermenin bir taahhüt nesnesine yeni bir ağaç yazdığını belirtmek için "HEAD Kök ağacı nesnesi" olarak daha iyi etiketlenir - her iki taahhüt nesnesi de HEAD tarafından işaret edilir.
Jazimov

@Jazimov Muhtemelen haklısınız, ancak yazdığı gibi, ünlü Pro Git kitabından bu resmi çekti ve bir bağlantı sağladı. Bu nedenle, eğer resim iyileştirilebiliyorsa veya hatta yanlışsa, birileri bu kitabın yazarlarına söylemelidir ... Genel olarak, bunu yapmaya istekli olurdum, ama dürüst olmak gerekirse, hala bir git acemiyim ve henüz yapmadım ne dediğini anladım, bu yüzden bu durumda kesinlikle yanlış kişi benim.
Binarus

@Binarus: Bunun gibi görüntülerin toptan çoğaltılmasındaki tehlike, bir yazar / kitap tarafından yapılan bir "yanlış beyan" yaymaya hizmet etmesidir. Bence bu, gerçek anlamıyla işlevsel yorumların bir örneğidir: Gerçek anlamda, repo'yu .git klasörü altındaki her şey olarak tanımlarsanız, aslında indeks repoda bulunur. Bununla birlikte, işlevsel anlamda, dizin Git'in DAG'yi repoda tutmasına yardımcı olur ve bunun dışında bir varlık olduğu düşünülebilir.
Jazimov

64

Sizin çalışma ağaç şu anda üzerinde çalışıyoruz dosyalarında aslında budur.

HEADen son teslim aldığınız dalın veya taahhüdün bir göstergesidir ve bunu yaparsanız yeni bir taahhüdün üst öğesi olacaktır. Örneğin siz iseniz, masterşube, daha sonra HEADişaret eder masterve taahhüt zaman, yeni taahhüt o revizyonu soyundan olacak masterkadar sivri ve masteryeni işlemeye noktaya güncellenecektir.

Endeks yeni hazırlanmış taahhüt bir evreleme alandır. Temel olarak, dizinin içeriği yeni taahhüdüne girecek olan şeydir (bunu yaparsanız git commit -a, Git'in taahhütte bulunmadan önce bildikleri dosyalara tüm değişiklikleri otomatik olarak ekler, bu nedenle çalışma ağacınızın mevcut içeriğini işler ). git addçalışma ağacından dizininize dosya ekler veya günceller.


Açıklama için çok teşekkürler Brian. Yani, çalışma ağacı tüm taahhüt edilmemiş değişiklikleri içerir. Değişikliklerimi git command -a ile yaparsam, o zaman Çalışma Ağacı ve Dizinim aynı olur. Merkez repoma ittiğimde üçü de aynı olacak. Doğrumuyum?
Joyce Babu

3
@Vinod Çok fazla. Çalışma ağacınızda Git'in bilmediği dosyalara sahip olabilirsiniz ve bunlarla uğraşmayacaksınız git commit -a(bunları eklemeniz gerekir git add), bu nedenle çalışma ağacınızda dizininizin, yerel deponuzun veya Uzak deponuzda yok.
Brian Campbell

2
@Vinod: Çalışma ağacı ve dizin çalışmadan aynı olabilir (git add, çalışma ağacından dizini günceller ve git checkout <path> çalışma ağacını dizinden güncelleştirir). HEADen son işlem anlamına gelir, bu nedenle işlem yaptığınızda HEADdizine uyan yeni işleminize güncelleme yaparsınız . Push'un bununla pek bir ilgisi yok - yerel repodaki uzak maç dallarında dallar yapıyor.
Cascabel

45

Çalışma ağacı

Çalışma ağacınız şu anda üzerinde çalışmakta olduğunuz dosyalardır.

Git endeksi

  • Git "index", git deposuna kaydedilmesini istediğiniz dosyaları yerleştirdiğiniz yerdir.

  • Dizin, önbellek , dizin önbelleği , geçerli dizin önbelleği , hazırlama alanı , aşamalı dosyalar olarak da bilinir .

  • Dosyaları git deposuna "teslim etmeden" (checkin) başlamadan önce, dosyaları git "dizinine" koymanız gerekir.

  • Dizin çalışma dizini değil : gibi bir komut yazabilirsiniz git statusve git size çalışma dizininizdeki hangi dosyaların git dizinine eklendiğini söyler (örneğin, git add filenamekomutu kullanarak ).

  • Dizin git deposu değildir: git dizinindeki dosyalar, git command komutunu kullanırsanız git git deposuna kaydedilecek dosyalardır.


1
Git 2.5'in birden fazla çalışma ağacı getireceğini unutmayın ( stackoverflow.com/a/30185564/6309 ). +1
VonC

3
"Dizin çalışma dizini değil"% 100 doğru olduğundan emin değilim. "Dizin Çalışma Dizini Değil, ancak tüm çalışma dizinini + bir sonraki işlem yapmak istediğiniz değişiklikleri içerir" olmalıdır. Kanıt? reset --hard HEADendeksinizin == çalışma ağacınız olduğundan emin olmak için bir git deposuna gidin . an then: mkdir history && git checkout-index --prefix history/ -aSonuç, history/dizindeki tüm çalışma ağacınızın bir kopyasıdır . Ergo git index> = git çalışma dizini
Adam Kurkiewicz

3
Dizin çalışma dizini değildir ve çalışma dizinini içermesi gerekmez. Dizin sadece git deposu içinde işlemek istediğiniz bilgileri depolayan bir dosyadır.
Boon

3
"" İndex ", çalışma ağacının içeriğinin bir anlık görüntüsünü içerir ve bir sonraki işlemin içeriği olarak alınan bu anlık görüntüdür. Bu nedenle, çalışma dizininde herhangi bir değişiklik yaptıktan sonra ve command komutunu çalıştırmadan önce, yeni veya değiştirilmiş dosyaları dizine eklemek için add komutunu kullanmalıdır "( git-scm.com/docs/git-add )
anth

3
@AdamKurkiewicz: ve adımlarını echo untracked-data > untracked-fileönce, önce veya sonra yaparsanız kanıt başarısız olur . Bunu bulacaksınız izlenmeyen dosyasıdır değil de dizine. Ayrıca, çalışma ağacına dokunmadan önce dizini değiştirmek zor olsa da (kullanmanız gerekir ) , hem dizini hem de çalışma ağacını bağımsız olarak değiştirebilirsiniz . git reset --HARDgit checkout-indexhistorygit update-index --index-info
17'de torek
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.