Git sembolik bağlantıları nasıl ele alır?


1607

Sembolik bir bağlantı olan bir dosya veya dizinim varsa ve bunu Git deposuna kaydedersem ne olur?

Dosya silinene kadar sembolik bir bağlantı olarak bıraktığını varsayarım ve daha sonra dosyayı eski bir sürümden geri çekerseniz, normal bir dosya oluşturur.

Başvurduğu dosyayı sildiğimde ne yapar? Sadece sarkan bağlantıyı mı yapıyor?


19
.gitignoresimge bağlantısını klasör değil dosya olarak görür.
0xcaff

6
Açıkçası soruda bu cevabın ima ettiğinden daha fazlası var. Örneğin, aşağıdakileri merak ediyorum: veri havuzumda bu depodaki bazı büyük dosyalara bir sym bağlantısı oluşturursam, değişiklikleri iter ve sonra bu değişiklikleri başka bir makineye çekersem ne olur? Büyük dosya her iki konumda da büyük bir dosya olarak saklanacak mı, yoksa yeni makinede bağlantı dosyası orijinal büyük dosyayı gösterecek şekilde sym bağlantısı korunacak mı?
jvriesem

7
Bu eski bir konu ama bu yorum yine de faydalı olabilir. Jviesem'e yanıt olarak, yumuşak bağlantı temelde başka bir dosyanın adıyla bir dosyadır. Farklı bir makineye çektiğinizde, bağlantı indirilecek ve orijinal dosya sistemindeki büyük dosyanın adına sahip olacaktır. Yeni makinede ad geçerli değilse, bağlantının geçersiz bir adı olur. Büyük dosya yeni makineye indirilmez.
lasaro

6
@lasaro, git deposunda kopuk bağlantılardan kaçınmanın yolu, sembolik bağlantıları yaparken her zaman göreli yollar kullanmaktır ../...
Joker

8
Windows'un çoğu sürümünde, bir sembolik bağlantı oluşturmak için yükseltilmiş izinlere ihtiyacınız olduğunu unutmayın. Windows git pullkullanıyorsanız ve symlink yerine bir dosya oluşturuyorsanız, Git istemcinizi yönetici olarak çalıştırmayı deneyin.
axmrnv

Yanıtlar:


1348

Git, bağlantının içeriğini (yani, bağlandığı dosya sistemi nesnesinin yolu) normal bir dosyadaki gibi bir 'blob'da depolar. Daha sonra, adını, modunu ve türünü (bir sembolik bağlantı olması da dahil), içerdiği dizini temsil eden ağaç nesnesine depolar.

Bağlantıyı içeren bir ağaca göz attığınızda, hedef dosya sistemi nesnesinin var olup olmadığına bakılmaksızın nesneyi bir sembolik bağlantı olarak geri yükler.

Symlink'in başvurduğu dosyayı silerseniz Git kontrollü symlink'i hiçbir şekilde etkilemez. Sarkan bir referansınız olacak. Gerekirse geçerli bir şeye işaret etmek için bağlantıyı kaldırmak veya değiştirmek kullanıcıya bağlıdır.


328
BTW. FAT gibi sembolik bağlantıları desteklemeyen bir dosya sistemindeyseniz ve havuzunuz bunları kullanıyorsa, core.symlinksyapılandırma değişkenini false olarak ayarlayabilirsiniz ve sembolik bağlantılar, bağlantı metnini içeren küçük düz metin dosyaları olarak işaretlenir.
Jakub Narębski

14
@ JakubNarębski Bunu daha önce görmüştüm. Repomuzda bir satır içeren bir metin dosyası vardı, kullandığımız kütüphanenin yolu. Amacının ne olduğunu anlayamadım. Şimdi ne olduğunu biliyorum.
Matt K

25
Ben son derece yükseltilmiş cevap yorum yapmaktan çekinmeyin ama "normal bir dosya için olduğu gibi" ifadesi yeni gelenler için yanıltıcı olabilir düşünüyorum.
Matthew Hannigan

10
(düzenleme süresi doldu) Normal bir dosya gibi sadece içeriğin bir blob içinde olması gibi. Kritik fark, normal bir dosya için blob'un dosya içeriğidir, ancak bir sembolik bağlantı için blob, bağlandığı dosyanın yol adına sahiptir. @ JakubNarębski "küçük düz metin dosyaları" ile ilgili .. Onlar küçük ve metin umuyoruz ama tabii bir damla bir kabarcık ve potansiyel olarak büyük ve ikili olabilir. Bkz stackoverflow.com/questions/18411200/... bir dosya bir sembolik bağ olarak yanlış yazmış edilişi için.
Matthew Hannigan

2
Küresel bağlantı ayarlarınızı ve yerel bağlantı ayarlarınızı kontrol ettiğinizden emin olun. Ayarlar TortiseGit veya pencerelerden kopyalandıysa, bunlarla uğraşabilirsiniz symlinks = false.
phyatt

250

Git'in bir dosyayla ne yaptığını, dizine eklediğinizde ne yaptığını görebilirsiniz. Endeks bir ön taahhüt gibidir. Dizin işlendiğinde, dizindeki git checkouther şeyi çalışma dizinine geri getirmek için kullanabilirsiniz . Peki Git, dizine sembolik bir bağlantı eklediğinizde ne yapar?

Öncelikle, sembolik bir bağlantı yapın:

$ ln -s /path/referenced/by/symlink symlink

Git bu dosya hakkında henüz bir şey bilmiyor. git ls-filesindeksinizi incelemenizi sağlar ( -sbaskı statbenzeri çıktı):

$ git ls-files -s ./symlink
[nothing]

Şimdi, sembolik bağlantının içeriğini Git nesne deposuna dizine ekleyerek ekleyin. Dizine bir dosya eklediğinizde Git, içeriğini Git nesne deposunda depolar.

$ git add ./symlink

Peki ne eklendi?

$ git ls-files -s ./symlink
120000 1596f9db1b9610f238b78dd168ae33faa2dec15c 0       symlink

Karma, Git nesne deposunda oluşturulan paketlenmiş nesneye bir referanstır. Deponuzun .git/objects/15/96f9db1b9610f238b78dd168ae33faa2dec15cköküne bakarsanız bu nesneyi inceleyebilirsiniz . Git'in depoda depoladığı, daha sonra kontrol edebileceğiniz dosyadır. Bu dosyayı incelerseniz, çok küçük olduğunu görürsünüz. Bağlı dosyanın içeriğini saklamaz.

(Not 120000, ls-filesçıktıda listelenen moddur . 100644Normal bir dosyaya benzer.)

Ancak Git depodan ve dosya sisteminize baktığınızda bu nesne ile ne yapar? core.symlinksYapılandırmaya bağlıdır . Gönderen man git-config:

core.symlinks

Yanlışsa, sembolik bağlantılar, bağlantı metnini içeren küçük düz dosyalar olarak kullanıma alınır.

Bu nedenle, depodaki sembolik bir bağlantı ile, ödeme yapıldıktan sonra, core.symlinksyapılandırmanın değerine bağlı olarak tam bir dosya sistemi yoluna referansla bir metin dosyası veya uygun bir sembolik bağlantı alırsınız .

Her iki durumda da, sembolik bağlantı tarafından başvurulan veriler depoda saklanmaz.


1
Müthiş cevap
CervEd

147

"Editörün" notu: Bu yayın güncel olmayan bilgiler içerebilir. Lütfen 1.6.1'den beri Git'teki değişikliklerle ilgili yorumları ve bu soruyu inceleyin .

Symlinked dizinleri:

Yumuşak bir bağlantı olan bir dizin olduğunda neler olduğunu not etmek önemlidir. Güncellemeli herhangi bir Git bağlantısı, bağlantıyı kaldırır ve normal bir dizin haline getirir. Ben zor yoldan öğrendim. Burada ve burada bazı bilgiler .

Misal

Önce

 ls -l
 lrwxrwxrwx 1 admin adm   29 Sep 30 15:28 src/somedir -> /mnt/somedir

git add/commit/push

It remains the same

Sonra git pullAND bazı güncellemeler bulundu

 drwxrwsr-x 2 admin adm 4096 Oct  2 05:54 src/somedir

4
İşaretlenmiş dizinlerle ilgili bu uyarıların , sürümlendirilmiş sembolik bağlantılar için geçerli olmadığını belirtmek gerekir . Söz konusu en önemli durum, çalışma ağacının bir kısmını veya tamamını farklı bir yola (daha fazla disk alanı olan farklı bir bölüme söyleyin) bağlayan ve git'i mevcut sembolik üzerinden kodunu kontrol etmeyi bekleyenlerdi. Diğer bir deyişle, dosyalara veya dizinlere sürümlendirilmiş sembolik bağlantılar içeren bir projeniz varsa, normal sembolik bağlantı olarak davranış sembolik bağlantıları koruyacak, sembolik bağlantıları doğru şekilde değiştirecek ve aksi takdirde beklendiği gibi çalışacaktır.
John Whitley

Yukarıdaki davranış git 1.6.5.6 ile test edilmiştir; ama git sürümde bir süredir doğru davranışın doğru olduğundan şüpheleniyorum.
John Whitley

22
Bu davranış git'in tüm sürümlerinde var mı veya bu sorunla giderildi mi?
jbotnik

24
Bu davranış düzeltildi gibi görünüyor, bkz .: stackoverflow.com/a/1943656/1334781
Ron Wertlen

2
Shekar: Son yıllarda git'teki değişiklikleri yansıtacak şekilde cevabınızı düzenleyecek misiniz?
einpoklum
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.