Linus Torvalds, Git'in hiçbir zaman bir dosyayı izlemediğini söylediğinde ne anlama geliyor?


283

Git'in 2007 yılında Google'daki Teknik Sohbeti sırasında kaç dosyayı işleyebileceği sorulduğunda Linus Torvalds'tan alıntı (43:09):

… Git içeriğinizi izler. Hiçbir zaman tek bir dosyayı izlemez. Git'te bir dosyayı izleyemezsiniz. Yapabileceğiniz tek bir dosyaya sahip bir projeyi izleyebilmenizdir, ancak projenizde tek bir dosya varsa, bunu yapın ve bunu yapabilirsiniz, ancak 10.000 dosyayı izlerseniz, Git bunları hiçbir zaman tek tek dosyalar olarak görmez. Git her şeyi tam içerik olarak düşünüyor. Git'teki tüm tarih, tüm projenin tarihine dayanmaktadır ...

( Burada transkriptler .)

Eğer dalmak zaman Oysa Git kitapta , sen anlatılır ilk şey Git bir dosya ya edilebilmesidir izlenen veya izlenmeyen . Ayrıca bana göre Git'in tüm deneyimi dosya sürümlendirmeye yönelik. Kullanırken git diffveya git statusçıktı dosya başına sunulur. Kullanırken git addayrıca dosya başına seçim yapabilirsiniz. Geçmişi dosya bazında bile inceleyebilirsiniz ve yıldırım hızındadır.

Bu ifade nasıl yorumlanmalıdır? Dosya izleme açısından Git, CVS gibi diğer kaynak kontrol sistemlerinden nasıl farklıdır?


20
reddit.com/r/git/comments/5xmrkv/what_is_a_snapshot_in_git - "Şu anda bulunduğunuz yer için, fark etmeniz gereken daha önemli olan, Git'in dosyaları kullanıcılara sunma biçimi ve bunlarla dahili olarak nasıl ilgilentiği arasında bir fark olduğudur . Kullanıcıya sunulduğu gibi, bir anlık görüntü yalnızca farklar değil tam dosyalar içerir. Ancak dahili olarak evet, Git revizyonları etkin bir şekilde saklayan paket dosyaları oluşturmak için diffs kullanır. " (Bu, örneğin Subversion ile keskin bir kontrasttır.)
user2864740

5
Git dosyaları izlemez, değişiklik kümelerini izler . Çoğu sürüm kontrol sistemi dosyaları izler. Bunun nasıl / neden önemli olabileceğine bir örnek olarak, git için boş bir dizini kontrol etmeyi deneyin (splier: yapamazsınız, çünkü bu "boş" bir değişiklik kümesi).
Elliott Frisch

12
@ElliottFrisch Kulağa doğru gelmiyor. Açıklamanız örneğin darcs'ın yaptıklarına daha yakın . Git, değişiklik kümelerini değil, anlık görüntüleri saklar.
melpomene

4
Bence Git doğrudan bir dosyayı izlemiyor demek. Bir dosya adını ve içeriğini içerir. Git içeriği blob olarak izler. Yalnızca bir blob verildiğinde, karşılık gelen dosya adının ne olduğunu söyleyemezsiniz. Farklı yollar altında farklı adlara sahip birden fazla dosyanın içeriği olabilir. Bir yol adı ve bir damla arasındaki bağlar bir ağaç nesnesinde açıklanmaktadır.
ElpieKay

3
İlgili: Randal Schwartz'ın Linus'un konuşmasını takibi (ayrıca bir Google Tech konuşması) - "... Git'in gerçekten ne hakkında olduğu ... Linus Git'in ne OLMADI" dedi.
Peter Mortensen

Yanıtlar:


316

CVS'de geçmiş dosya başına izlendi. Bir şube, her biri kendi sürüm numarasına sahip kendi çeşitli düzeltmelerine sahip çeşitli dosyalardan oluşabilir. CVS, bireysel dosyaları benzer şekilde izleyen RCS ( Revizyon Kontrol Sistemi ) ' ne dayanıyordu .

Öte yandan Git, tüm projenin durumunun anlık görüntülerini alır. Dosyalar bağımsız olarak izlenmez ve sürümlendirilmez; depodaki bir düzeltme, tek bir dosyaya değil, tüm projenin durumuna işaret eder.

Git bir dosyayı izlemeyi ifade ettiğinde, basitçe projenin geçmişine dahil edileceği anlamına gelir. Linus'un konuşması Git bağlamındaki dosyaları izlemekten değil, CVS ve RCS modelini Git'te kullanılan anlık görüntü modeliyle karşılaştırıyordu.


4
Bu nedenle CVS ve Subversion'da $Id$dosyadaki gibi etiketleri kullanabilirsiniz . Tasarım farklı olduğu için git'te aynı şey işe yaramaz.
gerrit

58
Ve içerik beklediğiniz gibi bir dosyaya bağlı değildir. Bir dosyanın kodunun% 80'ini diğerine taşımayı deneyin. Git, mevcut dosyalarda kodu yeni taşıdığınızda bile bir dosya taşıma +% 20 değişiklik algıladı.
allo

13
@allo Bunun bir yan etkisi olarak, git diğerlerinin yapamayacağı bir şey yapabilir: iki dosya birleştirildiğinde ve "git blame -C" kullandığınızda git her iki geçmişi de aşağıya bakabilir. Dosya tabanlı izlemede, orijinal dosyalardan hangisinin gerçek orijinal olduğunu seçmeniz gerekir ve diğer satırların tümü yepyeni görünür.
Izkata

1
@allo, Izkata - Ve bu sorgulama varlık (geçmişleri ve başvurulan ağaçlar ve lekeler arasındaki farkları işlemek) sorgu anda repo içeriğini analiz yerine gerektiren bütün bu out işleri işlemekten varlık ve insan kullanıcısının doğru bir şekilde belirtmesini veya sentezlemesini bu bilgileri kesinleştirme zamanında - ne de aracı dağıtmadan önce bu yeteneği ve karşılık gelen meta veri şemasını tasarlamak ve uygulamak için repo aracı geliştiricisi. Torvalds böyle analiz ancak zamanla daha iyi olacak savundu ve tüm geçmişi her git repo gün bir fayda sağlayacaktır çünkü.
Jeremy

1
@allo Yep ve git'in bir dosya düzeyinde çalışmadığı gerçeğini ortaya çıkarmak için, bir dosyadaki tüm değişiklikleri bir kerede yapmak zorunda bile değilsiniz; dosyadaki diğer değişiklikleri taahhüt dışında bırakarak rastgele satır aralıkları uygulayabilirsiniz. Elbette bunun için kullanıcı arayüzü neredeyse o kadar basit değil, çoğu bunu yapmıyor, ancak nadiren kullanımları var.
Alvin Thompson

103

Katılıyorum brian m. carlson'un yanıtı : Linus, en azından kısmen, dosya ve taahhüt odaklı sürüm kontrol sistemlerini birbirinden ayırıyor. Ama bence bundan daha fazlası var.

Gelen kitabımda takıldı ve bitmiş asla olabilir, ben ile gelip çalıştı taksonomisinde sürüm kontrol sistemleri için. Taksonomimde burada ilgilendiğimiz terim , sürüm kontrol sisteminin atomisitesidir . Şu anda ne olduğuna bakın sayfa 22. Bir VCS dosya düzeyinde atomisiteye sahip olduğunda, aslında her dosya için bir geçmiş vardır. VCS, dosyanın adını ve her noktada dosyada ne olduğunu hatırlamalıdır.

Git bunu yapmaz. Git'in yalnızca bir taahhüt geçmişi vardır; taahhüt, atomite birimidir ve tarih , depodaki taahhütler kümesidir. Bir komutun hatırladığı şey, verilerdir - dosya adları ve bu dosyaların her biriyle birlikte gelen içeriklerle dolu bir ağaç - artı bazı meta veriler: örneğin, taahhüdü, ne zaman ve neden yapan ve dahili Git karma kimliğini taahhüt ana üst taahhüt. (Bu ebeveyn ve tüm kaydedilmesini ve velilerine okuyarak oluşturduğu yönettiği acycling grafiği, olan bir depoda tarih.)

Bir VCS'nin işleme yönelik olabileceğini, ancak yine de veriyi dosyaya göre saklayabileceğini unutmayın. Bu bazen önemli olan bir uygulama detayıdır ve Git de bunu yapmaz. Bunun yerine, her bir taahhüt bir , ağaç nesnesini dosya adlarını , modları kodlayan (yani bu dosya yürütülebilir mi? Değil) ve gerçek dosya içeriğine bir işaretçi içeren ağacı . İçeriğin kendisi bağımsız olarak bir blob nesnesinde saklanır . Bir taahhüt nesnesi gibi, bir blob içeriğine özgü bir karma kimliği alır - ancak yalnızca bir kez görünebilen bir taahhütten farklı olarak, blob birçok taahhütte görünebilir. Bu nedenle Git'teki temel dosya içeriği doğrudan bir damla olarak depolanır ve daha sonra dolaylı olarak sağlama nesnesi içinde (doğrudan veya dolaylı olarak) karma kimliği kaydedilen bir ağaç nesnesinde.

Git'ten size aşağıdakileri kullanarak bir dosyanın geçmişini göstermesini istediğinizde:

git log [--follow] [starting-point] [--] path/to/file

Git'in gerçekte yaptığı şey Git'in sahip olduğu tek geçmiş olan taahhüt geçmişini , ancak şu durumlarda size bu taahhütlerden hiçbirini göstermemek :

  • taahhüt bir birleşik olmayan bir taahhüttür ve
  • bu taahhüdün üst öğesi de dosyaya sahiptir, ancak üst öğedeki içerik farklıdır veya taahhüdün üst öğesinde hiç dosya yok

(ancak bu koşulların bazıları ek git logseçeneklerle değiştirilebilir ve Git'i tarihin bazı taahhütlerini tamamen atlatan Tarih Sadeleştirme adlı yan etkiyi tanımlamak çok zor). Burada gördüğünüz dosya geçmişi depoda tam olarak mevcut değil, bir anlamda: bunun yerine, gerçek tarihin sadece sentetik bir altkümesi. Farklı git logseçenekler kullanırsanız farklı bir "dosya geçmişi" alırsınız !


Eklenecek başka bir şey, Git'in sığ klonlar gibi şeyler yapmasına izin vermesidir. Sadece kafa taahhüdünü ve bahsettiği tüm lekeleri geri alması gerekiyor. Değişiklik kümeleri uygulayarak dosyaları yeniden oluşturmanız gerekmez.
Wes Toleman

@WesToleman: bunu kesinlikle kolaylaştırıyor. Mercurial deltaları, ara sıra sıfırlamalarla depolar ve Mercurial millet orada sığ klonlar eklemeyi düşünürken ("sıfırlama" fikri nedeniyle mümkündür), henüz yapmamışlardır (çünkü daha teknik bir zorluktur).
torek

@torek Git'in bir dosya geçmişi isteğine yanıt vermesiyle ilgili açıklamanızla ilgili bir şüphem var, ancak kendi doğru sorusunu hak ettiğini düşünüyorum: stackoverflow.com/questions/55616349/…
Simón Ramírez Amaya

@torek Kitabınıza olan bağlantı için teşekkürler, bunun gibi başka bir şey görmedim.
gnarledRoot

17

Kafa karıştırıcı bit burada:

Git bunları asla tek tek dosyalar olarak görmez. Git her şeyi tam içerik olarak düşünüyor.

Git genellikle kendi deposundaki nesnelerin yerine 160 bit karmaları kullanır. Bir dosya ağacı temel olarak her birinin içeriğiyle (ve bazı meta verilerle) ilişkili adların ve karmaların listesidir.

Ancak 160 bit karması içeriği benzersiz olarak tanımlar (git veritabanının evreninde). İçerik olarak karmaları olan bir ağaç, içeriğindeki içeriği içerir .

Bir dosyanın içeriğinin durumunu değiştirirseniz, karması değişir. Ancak karması değişirse, dosya adının içeriğiyle ilişkili karması da değişir. Bu da "dizin ağacının" karmasını değiştirir.

Git veritabanı bir dizin ağacını sakladığında, bu dizin ağacı tüm alt dizinlerin ve içindeki tüm dosyaların içeriğini ima eder ve içerir .

Lekelere veya diğer ağaçlara (değişmez, tekrar kullanılabilir) işaretçilerle bir ağaç yapısında düzenlenir, ancak mantıksal olarak tüm ağacın tüm içeriğinin tek bir anlık görüntüsüdür. Temsil git veritabanında düz veri içeriği değil, mantıksal olarak onun veri ve başka bir şey tümüdür.

Ağacı bir dosya sistemine serileştirdiyseniz, tüm .git klasörlerini sildiyseniz ve git'e ağacı tekrar veritabanına eklemesini söylediyseniz, sonunda veritabanına hiçbir şey eklemezsiniz - öğe zaten orada olurdu.

Git'in hash değerlerini değişmez verilere referans sayıcı bir işaretçi olarak düşünmek yardımcı olabilir.

Bunun üzerine bir uygulama oluşturduysanız, belge, katmanları olan, grupları olan ve nesneleri olan bir grup sayfadır.

Bir nesneyi değiştirmek istediğinizde, nesne için tamamen yeni bir grup oluşturmanız gerekir. Bir grubu değiştirmek istiyorsanız, yeni bir sayfa gerektiren ve yeni bir belge gerektiren yeni bir katman oluşturmanız gerekir.

Tek bir nesneyi her değiştirdiğinizde, yeni bir belge oluşturur. Eski belge var olmaya devam ediyor. Yeni ve eski belge içeriklerinin çoğunu paylaşır - aynı sayfalara sahiptirler (1 hariç). Bu sayfa aynı katmanlara sahip (1 hariç). Bu katman aynı gruplara sahiptir (1 hariç). Bu grup aynı nesnelere sahiptir (1 hariç).

Aynı şekilde, mantıksal olarak bir kopyasını kastediyorum, ama uygulama açısından aynı değişmez nesneye sadece referans olarak sayılan bir işaretçi.

Git deposu buna çok benzer.

Bu, belirli bir git değişiklik kümesinin işleme iletisini (karma kodu olarak) içerdiği, çalışma ağacını içerdiği ve üst değişikliklerini içerdiği anlamına gelir.

Bu üst düzey değişiklikler, üst düzey değişikliklerini içerir.

Git repo'sunun tarih içeren kısmı değişiklik zinciri. Bu değişiklik dizini "dizin" ağacının üzerindeki bir seviyede değiştirir - "dizin" ağacından, bir değişiklik kümesine ve değişiklik zincirine benzersiz şekilde erişemezsiniz.

Bir dosyaya ne olduğunu öğrenmek için, bir değişiklik kümesinde bu dosyayla başlarsınız. Bu değişiklik kümesinin bir geçmişi var. Genellikle bu tarihte, bazen aynı içeriğe sahip aynı adlı dosya bulunur. İçerik aynıysa, dosyada değişiklik yapılmamıştır. Farklıysa, bir değişiklik var ve tam olarak ne olduğunu çözmek için iş yapılması gerekiyor.

Bazen dosya gitti; ancak, "dizin" ağacının aynı içeriğe (aynı karma koduna) sahip başka bir dosyası olabilir, bu yüzden bu şekilde izleyebiliriz (not; bu nedenle bir dosyayı bir kesinleştirme işleminden ayrı olarak taşıma taahhüdü istiyorsunuz -Düzenle). Ya da aynı dosya adı ve dosyayı kontrol ettikten sonra yeterince benzer.

Yani git birlikte bir "dosya geçmişi" patchwork olabilir.

Ancak bu dosya geçmişi, dosyanın bir sürümünden diğerine olan bir bağlantıdan değil, "tüm değişiklik kümesinin" etkin bir şekilde ayrıştırılmasıyla gelir.


12

seyahatseverlerin Git adlı kaydedilmesini bir "blob" için ağacında bir yol bağlayan bir dosya ağacı anlık oluşur ve bir grafik tarihini takip işlemek olduğunu temelde demektir "git dosyalarını izlemez" kaydedilmesini . Geri kalan her şey "git log" ve "git blame" gibi komutlarla anında yeniden oluşturulur. Bu yeniden yapılandırma, çeşitli seçeneklerle dosya tabanlı değişiklikler aramasının ne kadar zor olması gerektiği söylenebilir. Varsayılan sezgisel tarama, bir blobun dosya ağacında herhangi bir değişiklik yapmadan ne zaman değiştiğini veya bir dosyanın öncekinden farklı bir blob ile ilişkili olduğunu belirleyebilir. Git'in kullandığı sıkıştırma mekanizmaları blob / dosya sınırları hakkında pek fazla umursamıyor. İçerik zaten bir yerde ise, bu, çeşitli lekeleri ilişkilendirmeden depo büyümesini küçük tutacaktır.

Şimdi depo bu. Git'in ayrıca çalışan bir ağacı vardır ve bu çalışma ağacında izlenen ve izlenmeyen dosyalar vardır. Sadece izlenen dosyalar dizine kaydedilir (hazırlama alanı? Önbellek?) Ve yalnızca orada izlenenler depoya aktarır.

Dizin dosya yönelimlidir ve işlemek için bazı dosya yönelimli komutlar vardır. Ancak depoda sonuçlanan, sadece dosya ağacı anlık görüntüleri ve ilişkili blob verileri ve taahhüdün ataları şeklinde taahhüt eder.

Git dosya geçmişlerini ve yeniden adlarını izlemediğinden ve etkinliği bunlara bağlı olmadığından, Git önemsiz olmayan geçmişler için ilgilendiğiniz geçmişi / farkları / suçlamaları üretene kadar bazen farklı seçeneklerle birkaç kez denemeniz gerekir.

Subversion gibi yeniden yapılandırmak yerine kayıt yapan sistemlerde durum farklı geçmişleri . Kayıtlı değilse, bunu duymazsınız.

Aslında bir kerede, ayırma ağaçlarını Git'i kontrol ederek ve sonra etkilerini çoğaltan bir komut dosyası oluşturarak karşılaştıran bir diferansiyel yükleyici oluşturdum. Bazen tüm ağaçlar taşındığından, bu, her şeyin üreteceği üzerine yazmaktan / silmekten çok daha küçük diferansiyel montajcılar üretti.


7

Git bir dosyayı doğrudan izlemez, ancak deponun anlık görüntülerini izler ve bu anlık görüntüler dosyalardan oluşur.

İşte bakmanın bir yolu.

Diğer sürüm kontrol sistemlerinde (SVN, Rational ClearCase), bir dosyaya sağ tıklayıp değişiklik geçmişini alabilirsiniz .

Git'te bunu yapan doğrudan bir komut yoktur. Bu soruya bakın . Kaç farklı cevabın olduğuna şaşıracaksınız. Basit bir cevap yoktur çünkü Git SVN veya ClearCase'in yaptığı gibi değil, sadece bir dosyayı izlemez .


5
Sanırım söylemeye çalıştığın şeyi alıyorum, ama "Git'te bunu yapan doğrudan bir komut yok" bağlandığın sorunun cevabı ile doğrudan çelişiyor. O sürüm tüm depo seviyesinde olur doğru olsa da, tipik olarak elde etmek için yollar yükler vardır şeyi birden komutları sahip bir dosyanın geçmişi çok kanıt olmadığını göstermek için bu yüzden, Git'te.
Joe Lee-Moyet

Bağladığınız sorunun ilk birkaç cevabını sıyırdım ve hepsi git logya da bunun üzerine inşa edilmiş bir program (veya aynı şeyi yapan bazı takma adlar). Ancak Joe'nun da söylediği gibi birçok farklı yol olsa bile, bu da şube tarihini göstermek için de geçerlidir. (ayrıca git log -p <file>yerleşiktir ve tam olarak bunu yapar)
Voo

SVN'nin dosya başına değişiklikleri dahili olarak depoladığından emin misiniz? Henüz bir süredir kullanmadım, ancak proje dosya yapısının yansımasından ziyade sürüm kimlikleri gibi adlandırılmış dosyalara sahip olduğumu belli belirsiz hatırlıyorum.
Artur Biesiadowski

3

"İçeriği" tesadüfen izlemek, boş dizinleri izlememeye neden olan şeydir.
Bu nedenle, bir klasörün son dosyasına gittiğinizde klasörün kendisi silinir .

Bu her zaman geçerli değildi ve yalnızca Git 1.4 (Mayıs 2006), "içerik izleme" politikasını 443f833 taahhüdü kıldı :

git status: boş dizinleri atla ve izlenmeyen tüm dosyaları göstermek için -u ekle

Varsayılan olarak, --others --directory içeriği olmadan (çıktının karışıklığını gidermek için) ilginç olmayan dizinleri (kullanıcının dikkatini çekmek için) göstermek için kullanırız.
Boş dizinleri göstermek mantıklı değildir, bu yüzden --no-empty-directorybunu yaptığımızda geçer .

verilmesi -u (veya --untracked), kullanıcının tüm izlenmemiş dosyaları almasına izin vermek için bu karışıklığı devre dışı bırakır.

Bu yıllar sonra Ocak 2011'de yankılandı 8fe533 , Git v1.7.4 taahhüdü ile tekrarlandı:

Bu genel kullanıcı arayüzü felsefesine uygundur: git boş dizinleri değil içeriği izler.

Bu arada, Git 1.4.3 (Eylül 2006) ile Git, izlenmeyen içeriği boş olmayan klasörlerle sınırlandırmaya başlar ve 2074cb0 taahhüdü ile :

tamamen izlenmeyen dizinlerin içeriğini değil, yalnızca bu dizinin adını (artı bir son '/ ') .

İçeriği izlemek , git suçunun çok erken bir zamanda yapılmasına izin veren şeydir (Git 1.4.4, Ekim 2006, taahhüt cee7f24 ) daha performanslı olmasına :

Daha da önemlisi, iç yapısı içeriği destekleyecek şekilde tasarlanmıştır aynı işlemden birden fazla yol alınmasına izin vererek hareketini (diğer bir deyişle kes ve yapıştır) daha kolay .

Git 1.5.0 (Git 2006, taahhüt 366bfcb ) ile Git API'sına git add ekleyen şey de (içerik izleme ).

'git add' dizinine birinci sınıf kullanıcı dostu bir arayüz yap

Bu, endeksten bahsetmeden uygun bir zihinsel model kullanarak endeksin gücünü öne çıkarır.
Örneğin, tüm teknik tartışmanın git-add man sayfasından nasıl tahliye edildiğine bakın.

Taahhüt edilecek tüm içerikler birlikte eklenmelidir.
Bu içeriğin yeni dosyalardan mı yoksa değiştirilmiş dosyalardan mı geldiği önemli değildir.
Sadece git-add ile ya da git-commit sağlayarak -a(sadece bilinen dosyalar için) eklemeniz yeterlidir .

Yapılan budur Yani git add --interactiveaynı Git 1.5.0 ile mümkün ( 5cde71d taahhüt )

Seçimi yaptıktan sonra , dizindeki seçili yollar için çalışan ağaç dosyalarının içeriğini yerleştirmek üzere boş bir satırla yanıtlayın .

Bu nedenle, bir dizindeki tüm içeriği özyinelemeli olarak kaldırmak için -r, yalnızca dizin adını değil, seçeneği de geçmeniz gerekir <path>(yine de Git 1.5.0, taahhüt 9f95069 ).

Dosya 1 yerine dosya içeriğini görmek, 1de70db dosyasında açıklanan gibi birleştirme senaryosuna izin veren şeydir (Git v2.18.0-rc0, Nisan 2018)

Yeniden adlandırma / ekleme çakışmasıyla aşağıdaki birleştirmeyi düşünün:

  • A tarafı: değiştir foo, ilgisiz eklebar
  • B tarafı: yeniden adlandırın foo->bar(ancak modu veya içeriği değiştirmeyin)

Bu durumda, orijinal foo, A foo ve B'nin üç yönlü birleşimi, A'nın sahip olduğu aynı mod / içerikle baristenen bir yol adına neden olacaktır . Böylece A, dosya için doğru moda ve içeriğe sahipti ve doğru yol adına (yani ) sahipti .barfoo
bar

Taahhüt 37b65ce , Git v2.21.0-rc0, Aralık 2018, son zamanlarda çarpışma çatışması çözümlerini iyileştirdi.
Ve bbafc9c firther, yeniden adlandırma / yeniden adlandırma (2to1) çakışmalarının işlenmesini iyileştirerek dosya içeriğini dikkate almanın önemini gösterir :

  • Yerine de dosyaları depolamak collide_path~HEADve collide_path~MERGE, dosyaları iki yönlü birleşti ve kaydedilen olancollide_path .
  • Dizinde yeniden adlandırılan tarafta bulunan yeniden adlandırılmış dosyanın sürümünü kaydetmek yerine (yeniden adlandırılmadan tarihin yan tarafında dosyada yapılan değişiklikleri göz ardı ederek), yeniden adlandırılmış dosyada üç yönlü içerik birleştirme yapıyoruz sonra da 2. veya 3. aşamada saklayın.
  • Her yeniden adlandırma için içerik birleştirmenin çakışma içerebileceğinden ve yeniden adlandırılan iki dosyayı birleştirmemiz gerektiğinden, iç içe geçmiş çakışma işaretçileriyle sonuçlanabileceğimizi unutmayın.
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.