2012-02-28 13 views
46

गिट एक-दूसरे के समान वस्तुओं को संग्रहीत करने के लिए डेल्टा संपीड़न का उपयोग करता है।क्या गिट बाइनरी diff एल्गोरिदम (डेल्टा स्टोरेज) मानकीकृत है?

क्या यह एल्गोरिदम मानकीकृत है और अन्य उपकरणों में भी उपयोग किया जाता है? प्रारूप का वर्णन करने वाले दस्तावेज क्या हैं? क्या यह xdelta/VCDIFF/RFC 3284 के साथ संगत है?

उत्तर

58

मुझे लगता है कि diff pack files के लिए इस्तेमाल किया algo वहाँ delta encoding में से एक से जुड़ा हुआ था: initially (2005) xdelta, और फिर libXDiff
लेकिन फिर, जैसा कि नीचे दिया गया है, यह एक कस्टम कार्यान्वयन में स्थानांतरित हो गया।

Git packfiles में deltification करता है केवल:

वैसे भी, mentioned here के रूप में।
लेकिन जब आप एसएसएच गिट के माध्यम से धक्का देते हैं तो दूसरी तरफ से एक पैक फ़ाइल उत्पन्न होती है, दूसरी तरफ नहीं है, और वे पैक पतले पैक हैं, इसलिए उनके पास डेल्टा भी है ... लेकिन रिमोट साइड फिर उन पतली को बेस जोड़ता है पैक उन्हें स्टैंडअलोन बनाते हैं।

(ध्यान दें:। कई packfiles बनाने, या विशाल packfile में जानकारी पुन: प्राप्त महंगा है, और इसका कारण बताएं Git अच्छी तरह से विशाल फाइल या विशाल रेपो प्रबंधन नहीं करती है
"git with large files" पर अधिक देखें)

असल packfiles और deltification और (LibXDiff, नहीं xdelta) था, क्या से मुझे याद है यू:

This thread भी हमें याद दिलाता है nderstand, मूल रूप से नेटवर्क बैंडविड्थ (जो डिस्क स्पेस से अधिक महंगा है) की वजह से, और I/O प्रदर्शन बहुत बड़ी ढीली वस्तुओं की बजाय एकल मिमी फ़ाइल का उपयोग करने के कारण।

इस 2008 thread में लिबक्सडिफ़ का उल्लेख किया गया है।

हालांकि, तब से, algo कोई 2011 thread illustrates के रूप में विकसित किया गया है, शायद एक कस्टम एक में, और diff-delta.c के शीर्षक बताते हैं:

तो, सख्ती से Git में कहा जाए तो वर्तमान कोड libxdiff कोड के साथ किसी भी समानता सहन नहीं करता है।
हालांकि दोनों कार्यान्वयन के पीछे मूल एल्गोरिदम एक ही
है।
libxdiff संस्करण का अध्ययन करना संभवतः यह काम करने के तरीके को समझने के लिए आसान है। packfiles the Git Book पर

/* 
* diff-delta.c: generate a delta between two buffers 
* 
* This code was greatly inspired by parts of LibXDiff from Davide Libenzi 
* http://www.xmailserver.org/xdiff-lib.html 
* 
* Rewritten for GIT by Nicolas Pitre <[email protected]>, (C) 2005-2007 
*/ 

अधिक:

packfile format

+3

अंतिम algo जब मैं 2011 धागा जैसे http पढ़ा है, एक कस्टम एक हो सकता है: //git.661346.n2.nabble.com/diff-ing-files-td6446460.html – VonC

+0

2008 में, libXDiff का स्पष्ट रूप से उपयोग किया गया था: http://git.661346.n2.nabble.com/libxdiff-and-patience- diff-td1452272.html – VonC

+0

वह 2011 धागा एक अच्छा लिंक है। चॉइस उद्धरण: "तो, सख्ती से बोलते हुए, गिट में वर्तमान कोड libxdiff कोड के साथ कोई समानता नहीं लेता है। हालांकि दोनों कार्यान्वयन के पीछे मूल एल्गोरिदम समान है।" – Thilo

19

Git डेल्टा एन्कोडिंग आधारित कॉपी/डालने है।

इसका मतलब है कि व्युत्पन्न फ़ाइल opcodes जो प्रति निर्देश प्रतिनिधित्व कर सकते हैं की एक अनुक्रम के रूप में एन्कोड किया गया है: या प्रविष्टि निर्देशों (जैसे आधार फ़ाइल y बाइट्स से प्रतिलिपि ऑफसेट एक्स लक्ष्य बफर में से शुरू) (जैसे: डालने लक्ष्य बफर में अगला एक्स बाइट्स)।

एक बहुत ही सरल उदाहरण (कागज 'डेल्टा संपीड़न के लिए फाइल सिस्टम का समर्थन' से लिया गया), पर विचार हम में पाठ "प्रॉक्सी     कैश" को बदलने के लिए एक डेल्टा बफर बनाना चाहते हैं कि "कैश     प्रॉक्सी के रूप में "। जिसके परिणामस्वरूप निर्देश होना चाहिए:

  1. कॉपी (आधार बफर से प्रतिलिपि 'कैश') ऑफसेट 7 से 5 बाइट्स
  2. सम्मिलित दो आधार से रिक्त स्थान
  3. कॉपी 5 बाइट्स ऑफसेट 0 (कॉपी 'प्रॉक्सी' से बफर)

कौन सा के लिए git एन्कोडिंग अनुवाद हो जाता है:

(बाइट्स 1-3 पहले अनुदेश का प्रतिनिधित्व करते हैं)

  • 0x91 (10,010,001) है, जो
    • 0x80 (10000000) में विभाजित है
    • 0x01 (00000001) (का अर्थ है 'अग्रिम (सबसे महत्वपूर्ण बिट सेट यह निर्देश एक' आधार से उत्पादन के लिए प्रति 'बनाता है) एक बाइट और आधार ऑफसेट)
    • 0x10 (00,010,000) (अग्रिम एक बाइट के रूप में उपयोग और लंबाई के रूप में उपयोग)
  • 0x07 (ऑफसेट)
  • 0x05 (लम्बाई)

(बाइट्स 4-6 दूसरा अनुदेश का प्रतिनिधित्व करते हैं)

  • 0x02
  • 0x20 (अंतरिक्ष) (के बाद से MSB सेट नहीं है, इस 'उत्पादन में अगले दो बाइट्स डालने' का अर्थ है)
  • 0x20 (अंतरिक्ष)

(बाइट्स 7-8 पिछले अनुदेश का प्रतिनिधित्व करते हैं)

  • 0x90 (10,010,000) है, जो
    • 0x80 (10000000) (का अर्थ है 'प्रतिलिपि')
    • 0x10 (00,010,000) में विभाजित (अग्रिम एक बाइट और लंबाई के रूप में उपयोग)
  • 0x05 (है लंबाई)

सूचना है कि पिछले प्रतिलिपि शिक्षा में निर्दिष्ट नहीं है एक ऑफसेट जो ऑफसेट 0. अन्य बिट्स प्रति opcode में भी जब बड़ा ऑफसेट/लंबाई की जरूरत है स्थापित किया जा सकता मतलब है।में इस उदाहरण 8 बाइट्स है, जो एक संपीड़न के ज्यादा के बाद से लक्ष्य बफर 12 बाइट्स है नहीं दे रहा है

परिणाम डेल्टा बफर है, लेकिन यह एक बहुत बड़ा फर्क कर सकते हैं जब इस एन्कोडिंग बड़े पाठ के लिए लागू फ़ाइलें।

मैंने हाल ही में node.js library को जिथब पर धक्का दिया है जो गिट डेल्टा एन्कोडिंग का उपयोग करके दोनों diff/पैच फ़ंक्शन लागू करता है। code अधिक पठनीय होना चाहिए और गिट स्रोत में से एक की टिप्पणी की है, जिसे अत्यधिक अनुकूलित किया गया है।

मैंने कुछ tests भी लिखा है जो को प्रत्येक उदाहरण में उपरोक्त प्रारूप के साथ आउटपुट आउटपुट का उपयोग करते हैं।

+0

निम्नलिखित आलेख में कुछ उपयोगी जानकारी भी शामिल है: http://stefan.saasen.me/articles/git-clone-in-haskell-from-the-bottom-up/#pack_file_format –

3

क्या यह एल्गोरिदम मानकीकृत है और अन्य उपकरणों में भी उपयोग किया जाता है?

पैक प्रारूप सार्वजनिक एपीआई का हिस्सा है: पुश और फ़ेच ऑपरेशंस के लिए उपयोग किए जाने वाले स्थानांतरण प्रोटोकॉल नेटवर्क पर कम डेटा भेजने के लिए इसका उपयोग करते हैं।

उन्हें संदर्भ के अलावा कम से कम दो अन्य प्रमुख गिट कार्यान्वयन में लागू किया गया है: JGit और libgit2

इसलिए, यह बहुत संभावना नहीं है कि प्रारूप में पिछड़े असंगत परिवर्तन होंगे, और उस अर्थ में "मानकीकृत" माना जा सकता है।

डॉक्स से इस अद्भुत फ़ाइल का वर्णन करता है लीनुस द्वारा एक ई-मेल पर एक अजीब टिप्पणी के रूप में पैक एल्गोरिथ्म में इस्तेमाल heuristics: https://github.com/git/git/blob/v2.9.1/Documentation/technical/pack-heuristics.txt

+1

अच्छा बिंदु (और मेरे " ऐतिहासिक "उत्तर)। +1 – VonC

+0

@ वॉनसी धन्यवाद! यह सवाल काफी खुला है, और आपका उत्तर और थियागो दोनों में उपयोगी अंतर्दृष्टि भी शामिल है। यह आपको लोगों की तरह अन्य महान प्रोग्रामर के बगल में एक जवाब देने में खुशी देता है। :) –