GIT'in dosya deltalarını depolamamasına rağmen, önceki dosya sürümlerine geri dönebilir misiniz (sınırsız kez?)


14

Git'in dosya deltalarını saklamadığını okudum . Bu doğruysa, önceki sürümlerde dosya geri almayı nasıl destekler? Tüm dosyayı saklıyorsa, diskteki depo alanının yönetilemeyecek kadar büyük olması için büyümesi gerekir. Git, dosya sürüm 1'e geri alma ve farkları destekliyor mu? Dosyalarla ilgili bir sürüm oluşturma konseptini bile destekliyor mu? Bu bir VCS / DVCS anlayışım ve ihtiyaçlarım için çok önemli. Check-in yaptığım şeyleri önceki sürümlerle karşılaştırabilmem gerekiyor.

Yanıtlar:


44

Git kendi başına bilgi atmaz *. Her dosyanın önceki tüm sürümleri her zaman geri dönüşler, farklar, denetimler vb. İçin kullanılabilir.

Tüm ağaç ve Bireysel dosyalar

Uzlaştırmaya çalıştığınız şey, Git'in geçmiş modelinin tüm ağaca odaklanmış olmasına karşı, tek bir dosyanın eski bir sürümüne erişme fikridir. Tüm ağacın sürümlendirilmesi, on değişikliğin foo.cvar olduğu halini görmek için (örneğin), on foo.cdeğişikliğin öncesine göre on tam ağaç değişikliğini görmek için biraz daha fazla çalışma gerektirir :

# 10 foo.c-changes ago
git show $(git rev-list -n 10 --reverse HEAD -- foo.c | head -1):foo.c

# 10 whole-tree-changes ago
git show HEAD~10:foo.c

Ağacın yönlendirilmesinin faydaları, esas olarak, tüm ağacın çeşitli kısımlarında yapılan karşılıklı bağımlılıkların bir birimi olarak taahhütleri görme yeteneği, genel olarak ekstra yazımdan (takma adlar, komut dosyaları, vb.) Ve CPU zamanından büyük ölçüde ağır basar. geçmiş taahhütleri kazarak geçirdi.

Depolama Verimliliği

Yeni bir nesne (ör. Önceden görülmemiş içeriğe sahip bir dosya) sisteme girdiğinde, "gevşek nesne" olarak düz (zlib) sıkıştırmayla depolanır. Yeterli gevşek nesne biriktiğinde ( gc.autoyapılandırma seçeneğine bağlı olarak veya kullanıcı git gc veya alt düzey paketleme komutlarından birini çalıştırdığında ), Git birçok gevşek nesneyi tek bir “paket dosyasına” toplar.

Bir paket dosyasındaki nesneler ya düz sıkıştırılmış veriler (gevşek nesnelerle aynı, sadece diğer nesnelerle birlikte paketlenmiş) ya da başka bir nesneye karşı sıkıştırılmış deltalar olarak saklanabilir. Deltalar yapılandırılabilir derinliklere ( pack.depth) zincirlenebilir ve herhangi bir uygun nesneye karşı yapılabilir ( pack.windowGit'in en iyi delta tabanını ne kadar geniş aradığını kontrol eder; eğer geçmişte ilgisiz bir dosyanın bir sürümü bir taban verirse bir taban olarak kullanılabilir iyi delta sıkıştırma). Derinlik ve pencere boyutu yapılandırmalarının delta sıkıştırma motoruna verdiği enlem, genellikle CVS tarzı basit bir sürümden sonraki / önceki sürüm “fark” sıkıştırmasına göre daha iyi bir delta sıkıştırması ile sonuçlanır.

Bir Git havuzunun (tam geçmiş ve sıkıştırılmamış bir çalışma ağacı ile) tek bir SVN kasasından (sıkıştırılmamış çalışma ağacı ve bozulmamış kopya ile) genellikle daha az yer kaplamasına izin verebilen bu agresif delta sıkıştırmasıdır (normal zlib sıkıştırması ile birlikte).

Bkz Nasıl Git Mağazaları Nesneleri ve Packfile bölümleri Git Topluluk Kitabı . Ayrıca git pack-objects manpage .

* Git'in işlemlerini “geçmişi yeniden yazarak” ve git reset gibi komutlarla söyleyebilirsiniz , ancak bu durumlarda Git, yeni atılan işlemlerin bir süreliğine “askıda kaldığını”, sadece ihtiyacınız olduğuna karar vermeniz durumunda. Bkz git reflog ve git eriği .


3
+1, yalnızca sağladığınız bilgilerin miktarı ve ayrıntısı için.
Tamara Wijsman

3
Ayrıca Git, deltalar yerine dosyaların anlık görüntülerini kullandığından, geçmişte uzun bir yoldan gitmek aslında daha kolaydır. 20 işlemden önce bir dosya görmeniz gerektiğini düşünün. Deltalarla, 20 değişiklik kümesini geri almanız gerekir; anlık görüntülerle, sadece doğru anlık görüntüyü alırsınız. Geçmişiniz ne kadar uzun olursa, avantaj o kadar büyük olur. Mevcut sürüm ve bu bir arasında diff görmek istiyorsanız, oldukça vb geri alınan, yeniden yapıl, yapılmış ne karar vermek zorunda değil, sadece tek fark var
Nathan Uzun

Chris, Git içlerinde oldukça iyi bir tutuş var gibi görünüyor. Bu konuda bir şansınız var mı? stackoverflow.com/questions/5176225/…
Nathan Long

@ChrisJohnsen Lütfen bunu anlamama yardım et. Söylediklerinize dayanarak Git, Subversion'a benzer (veya daha iyi) depolama verimliliği elde edebilir mi? Çok sayıda değişiklik içeren bir dosyayı defalarca yürütürsem, 100 GB'a 1 GB değerinde veri kaydedilebileceğini biliyorum. Git de aynısını yapabilir mi?
Alireza Noori

@AlirezaNoori: Her şey verilerin niteliğine ve yakalanan değişikliklere (dosyanın boyutu, dosyanın sıkıştırılabilirliği, değişikliklerin boyutu ve yeri vb.) Bağlıdır. Böyle bir şey kesinlikle mümkün olmalıdır (ayrıntılara bağlı olarak). Genel olarak Git'in paket dosyaları, SVN sunucularının kullandığı (ters mi? SVN gelişimini takip etmiyorum…) kesinlikle ters kronolojik deltalara kıyasla delta sıkıştırması için daha geniş bir taban seçiminden yararlanabilir. Aklınızda belirli bir sorunuz varsa, ilgili tüm ayrıntıları içeren yeni bir soru sormayı düşünmelisiniz.
Chris Johnsen

1

Aynı sayfada okunabilir:

...

Sonuç olarak Git, kaynak kodu ağacının altındaki hiçbir düzeyde dosya düzeltme ilişkilerini açıkça kaydetmez.

...

Tek bir dosyanın değişiklik geçmişini tüm projeye göre incelemek biraz daha pahalıdır. Belirli bir dosyayı etkileyen değişikliklerin geçmişini elde etmek için Git genel geçmişte yürümeli ve her değişikliğin bu dosyayı değiştirip değiştirmediğini belirlemelidir. Bununla birlikte, geçmişi inceleme yöntemi Git'in rastgele bir dosya kümesindeki değişiklikleri gösteren tek bir geçmişe eşit verimlilikle üretim yapmasına izin verir. Örneğin, kaynak ağacın bir alt dizini ve bununla ilişkili bir genel başlık dosyası çok yaygın bir durumdur.

...

Böylece bir dosyanın önceki revizyonlarına geri dönebilir ve iki dosyayı karşılaştırabilirsiniz.


1

git aslında dosyaların deltalarını kaydeder, ancak tüm dosya ağacının deltası olarak kaydeder.

Sürümler arasındaki farkları görmek için aşağıdakilerden birini yapın:

  1. git diff - son teslim edilen sürüm ile değiştirilmiş ancak git addüzerinde çalıştırılmamış dosyalar arasındaki farkları gösterir .
  2. git diff --cached - önceki sürüm ile git addçalıştırılan, ancak kaydedilmemiş tüm dosyaların arasındaki farkları gösterir
  3. git diff commitid - geçerli çalışma dizini ile taahhütte belirtilen bir önceki işlem arasındaki farkları gösterir
  4. git diff commita..commitb - a ve b olmak üzere iki işlem arasındaki farkları gösterir. Taahhütler, dallar veya etiketler gibi sembolik adlar da olabilir.

Bu cevap gerçekten doğru değil. Tüm bu komutlar, tüm ağacın yanı sıra rastgele bir dosya kümesine uygulanabilir - sadece sonuna dosya adlarını ekleyin ...
naught101
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.