Git'in bu durumda tam olarak nasıl davranacağını öğrenmek için bir deney yaptım. Bu sürüm 2.7.9 ~ rc0 + next.20151210 (Debian sürümü) ile. Temelde sadece aşağıdaki diff uygulayarak ve yeniden git git karma boyutunu 160-bit 4-bit için azalttı:
--- git-2.7.0~rc0+next.20151210.orig/block-sha1/sha1.c
+++ git-2.7.0~rc0+next.20151210/block-sha1/sha1.c
@@ -246,6 +246,8 @@ void blk_SHA1_Final(unsigned char hashou
blk_SHA1_Update(ctx, padlen, 8);
/* Output hash */
- for (i = 0; i < 5; i++)
- put_be32(hashout + i * 4, ctx->H[i]);
+ for (i = 0; i < 1; i++)
+ put_be32(hashout + i * 4, (ctx->H[i] & 0xf000000));
+ for (i = 1; i < 5; i++)
+ put_be32(hashout + i * 4, 0);
}
Sonra birkaç taahhütte bulundum ve aşağıdakileri fark ettim.
- Aynı karmaya sahip bir damla zaten varsa, hiçbir uyarı almazsınız. Her şey yolunda gibi görünüyor, ama birisini klonladığınızda veya geri döndüğünüzde, en son sürümü kaybedeceksiniz (yukarıda açıklananlara uygun olarak).
- Bir ağaç nesnesi zaten varsa ve aynı karma ile bir damla oluşturursanız: Siz itmeye çalışana veya birileri deponuzu klonlayana kadar her şey normal görünecektir. O zaman repo bozuk olduğunu göreceksiniz.
- Bir taahhüt nesnesi zaten varsa ve aynı karma ile bir damla oluşturursanız: # 2 ile aynı - bozuk
- Bir blob zaten varsa ve aynı karma ile bir taahhüt nesnesi yaparsanız, "ref" güncellenirken başarısız olur.
- Bir damla zaten varsa ve aynı karma ile bir ağaç nesnesi yaparsanız. Taahhüt oluşturulurken başarısız olur.
- Bir ağaç nesnesi zaten varsa ve aynı karmaya sahip bir taahhüt nesnesi yaparsanız, "ref" güncellenirken başarısız olur.
- Bir ağaç nesnesi zaten varsa ve aynı karmaya sahip bir ağaç nesnesi yaparsanız, her şey yolunda görünecektir. Ancak taahhütte bulunduğunuzda, tüm havuz yanlış ağaca atıfta bulunacaktır.
- Bir taahhüt nesnesi zaten varsa ve aynı karma ile bir taahhüt nesnesi yaparsanız, her şey yolunda görünecektir. Ancak taahhütte bulunduğunuzda, taahhüt asla oluşturulmayacak ve HEAD işaretçisi eski bir taahhüde taşınacaktır.
- Bir tamamlama nesnesi zaten varsa ve aynı hash değerine sahip bir ağaç nesnesi oluşturursanız, tamamlama oluşturulurken başarısız olur.
# 2 için "git push" komutunu çalıştırdığınızda genellikle böyle bir hata alırsınız:
error: object 0400000000000000000000000000000000000000 is a tree, not a blob
fatal: bad blob object
error: failed to push some refs to origin
veya:
error: unable to read sha1 file of file.txt (0400000000000000000000000000000000000000)
dosyayı silip "git checkout file.txt" dosyasını çalıştırırsanız.
# 4 ve # 6 için, genellikle böyle bir hata alırsınız:
error: Trying to write non-commit object
f000000000000000000000000000000000000000 to branch refs/heads/master
fatal: cannot update HEAD ref
çalıştırırken. Bu durumda, yeni bir karma oluşturacağından (değişen zaman damgası nedeniyle) genellikle "git commit" yazabilirsiniz.
# 5 ve # 9 için genellikle böyle bir hata alırsınız:
fatal: 1000000000000000000000000000000000000000 is not a valid 'tree' object
"git commit" çalıştırırken
Birisi bozuk deponuzu klonlamaya çalışırsa, genellikle şöyle bir şey görür:
git clone (one repo with collided blob,
d000000000000000000000000000000000000000 is commit,
f000000000000000000000000000000000000000 is tree)
Cloning into 'clonedversion'...
done.
error: unable to read sha1 file of s (d000000000000000000000000000000000000000)
error: unable to read sha1 file of tullebukk
(f000000000000000000000000000000000000000)
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry the checkout with 'git checkout -f HEAD'
Beni "endişelendiren", iki durumda (2,3) havuzun herhangi bir uyarı yapılmadan bozulmasına neden olması ve 3 durumda (1,7,8) her şeyin yolunda görünmesi, ancak depo içeriğinin beklediğinizden farklı olmasıdır. olmak. Klonlayan veya çeken kişiler, sahip olduğunuzdan farklı bir içeriğe sahip olacaktır. 4,5,6 ve 9 vakaları iyi, çünkü bir hata ile duracak. En azından her durumda bir hata ile başarısız olsaydı daha iyi olacağını düşünüyorum.