2010-06-30 16 views
20

मुझे कुछ स्रोत कोड प्राप्त हुए और इसके लिए गिट का उपयोग करने का निर्णय लिया क्योंकि मेरे सहकर्मी ने mkdir $VERSION आदि दृष्टिकोण का उपयोग किया था। हालांकि कोड का अतीत वर्तमान में महत्वहीन प्रतीत होता है, फिर भी मैं इसे विकास प्रक्रिया को बेहतर ढंग से समझने के लिए गिट नियंत्रण के तहत रखना चाहता हूं। तो:अतीत को एक गिट भंडार में कैसे प्रीपेड करें?

उन पिछले संस्करणों को मेरे पहले से मौजूद गिट रेपो में रखने का सुविधाजनक तरीका क्या है? वर्तमान में कोई रिमोट रेपो नहीं है इसलिए मुझे पुनर्लेखन इतिहास पर कोई फर्क नहीं पड़ता है, लेकिन रिमोट रिपॉजिटरीज़ को खाते में ले जाने वाला एक समाधान निश्चित रूप से तब तक पसंद किया जाएगा जब तक कि यह अधिक जटिल नहीं होता है। एक स्क्रिप्ट के लिए बोनस पॉइंट्स जो किसी निर्देशिका या संग्रह फ़ाइल आधारित इतिहास के आधार पर किसी भी अधिक बातचीत की आवश्यकता नहीं है।

+1

यह भी देखें [संपादित करें/संशोधित/संशोधित/गिट में प्रारंभिक/मूल/आरंभिक प्रतिबद्धता बदलें?] (Http://stackoverflow.com/q/2119480/456814), [गिट के साथ प्रोजेक्ट की पहली प्रतिबद्धता बदलें?] (http://stackoverflow.com/q/2246208/456814), और [गिट: पहली/प्रारंभिक/मूल प्रतिबद्धता से पहले क्या जोड़ना है?] (http://stackoverflow.com/q/16762160/456814)। –

+0

@ कूपकेक धन्यवाद, मैंने कभी भी आपके लिंक –

उत्तर

21

पुराने स्नैपशॉट्स आयात करने के लिए, आपको Git's contrib/fast-import directory उपयोगी में कुछ टूल मिलते हैं। या, यदि आप पहले से ही एक निर्देशिका में प्रत्येक वर्ष स्नैपशॉट है, तो आप कुछ इस तरह कर सकते हैं: एक बार

cd work && git fetch ../import master:old-history 

:

# Assumes the v* glob will sort in the right order 
# (i.e. zero padded, fixed width numeric fields) 
# For v1, v2, v10, v11, ... you might try: 
#  v{1..23}  (1 through 23) 
#  v?{,?}  (v+one character, then v+two characters) 
#  v?{,?{,?}} (v+{one,two,three} characters) 
#  $(ls -v v*) (GNU ls has "version sorting") 
# Or, just list them directly: ``for d in foo bar baz quux; do'' 
(git init import) 
for d in v*; do 
    if mv import/.git "$d/"; then 
     (cd "$d" && git add --all && git commit -m"pre-Git snapshot $d") 
     mv "$d/.git" import/ 
    fi 
done 
(cd import && git checkout HEAD -- .) 

फिर अपने काम भंडार में वर्ष लाने का इतिहास आपके पास पुराने इतिहास और आपके गिट-आधारित इतिहास दोनों एक ही भंडार में हैं, आपके पास प्रीपेड ऑपरेशन के लिए कुछ विकल्प हैं: ग्राफ्ट्स और प्रतिस्थापन।

ग्राफ्ट एक मौजूदा प्रतिस्थापन तंत्र (संभावित रूप से अस्थायी रूप से) विभिन्न मौजूदा प्रतिबद्धताओं के अभिलेखागार को संपादित करते हैं। Grafts $GIT_DIR/info/grafts फ़ाइल द्वारा नियंत्रित होते हैं (gitrepository-layout manpage के "जानकारी/grafts" के तहत वर्णित)।

INITIAL_SHA1=$(git rev-list --reverse master | head -1) 
TIP_OF_OLD_HISTORY_SHA1=$(git rev-parse old-history) 
echo $INITIAL_SHA1 $TIP_OF_OLD_HISTORY_SHA1 >> .git/info/grafts 
जगह में भ्रष्टाचार (मूल प्रारंभिक प्रतिबद्ध किसी भी माता-पिता नहीं था, भ्रष्टाचार यह एक माता पिता को दे दिया), आप के माध्यम से खोज और बढ़ाया इतिहास को देखने के सभी सामान्य Git उपकरणों का उपयोग कर सकते हैं

(जैसे git log अब आपको अपने काम के बाद पुराना इतिहास दिखाना चाहिए)।

ग्राफ्ट के साथ मुख्य समस्या यह है कि वे आपके भंडार तक ही सीमित हैं। लेकिन, यदि आप निर्णय लेते हैं कि उन्हें इतिहास का स्थायी हिस्सा होना चाहिए, तो आप उन्हें बनाने के लिए गिट फ़िल्टर-शाखा का उपयोग कर सकते हैं (पहले .git डीआईआर का टैर/ज़िप बैकअप बनाएं; गिट फ़िल्टर-शाखा बचाएगा मूल रेफरी, लेकिन कभी-कभी सादे बैकअप का उपयोग करना आसान होता है)।

git filter-branch --tag-name-filter cat -- --all 
rm .git/info/grafts 

प्रतिस्थापन तंत्र नया है (Git 1.6.5 +), लेकिन वे एक प्रति-आदेश आधार (git --no-replace-objects …) पर निष्क्रिय किया जा सकता है और वे आसान साझा करने के लिए धक्का दिया जा सकता है। प्रतिस्थापन व्यक्तिगत वस्तुओं (ब्लब्स, पेड़, काम करता है, या एनोटेटेड टैग) पर काम करता है, इसलिए तंत्र भी अधिक सामान्य है। प्रतिस्थापन तंत्र git replace manpage में प्रलेखित है। व्यापकता के कारण, "prepending" सेटअप एक छोटे से अधिक शामिल है (हम एक नए बजाय सिर्फ नए माता पिता के नामकरण के लिए प्रतिबद्ध बनाने के लिए):

# the last commit of old history branch 
oldhead=$(git rev-parse --verify old-history) 
# the initial commit of current branch 
newinit=$(git rev-list master | tail -n 1) 
# create a fake commit based on $newinit, but with a parent 
# (note: at this point, $oldhead must be a full commit ID) 
newfake=$(git cat-file commit "$newinit" \ 
     | sed "/^tree [0-9a-f]\+\$/aparent $oldhead" \ 
     | git hash-object -t commit -w --stdin) 
# replace the initial commit with the fake one 
git replace -f "$newinit" "$newfake" 

शेयरिंग इस प्रतिस्थापन स्वत: नहीं है।प्रतिस्थापन साझा करने के लिए आपको (या सभी) refs/replace का हिस्सा धक्का देना होगा।

git push some-remote 'refs/replace/*' 

आप प्रतिस्थापन स्थायी बनाने के लिए, Git फिल्टर शाखा का उपयोग का निर्णय लेते हैं (grafts के साथ के रूप में ही है, पहले अपने .git निर्देशिका के टार/ज़िप बैकअप बनाने):

git filter-branch --tag-name-filter cat -- --all 
git replace -d $INITIAL_SHA1 
+0

धन्यवाद के लिए अधिसूचना नहीं देखी, यह एक छोटे परीक्षण सबसेट के लिए बहुत अच्छा काम करता है, अब पूर्ण पर बंद है :) (मैंने प्रतिस्थापन विकल्प का उपयोग किया) –

+0

यह मेरे लिए कोई मुद्दा नहीं है पल, लेकिन मैं वैसे भी पूछूंगा: 'गिट फ़िल्टर-शाखा' से पहले बिंदु पर प्रतिस्थापन-विकल्प का उपयोग इतिहास को फिर से लिखना नहीं है और इसलिए साझा करना आसान है, है ना? –

+2

* गिट फ़िल्टर शाखा * के बिना, न तो ग्राफ्ट, न ही प्रतिस्थापन वास्तव में इतिहास को फिर से लिखते हैं (वे केवल डीएजी को प्रतिबद्ध करते हैं जैसे कि उन्होंने इतिहास को फिर से लिखा था)। प्रतिस्थापन के लाभ 1 हैं) उन्हें कमांड लाइन तर्क या पर्यावरण चर द्वारा अक्षम किया जा सकता है, 2) उन्हें धक्का दिया जा सकता है, 3) वे किसी ऑब्जेक्ट पर काम करते हैं, न केवल माता-पिता के "attritubes"। प्रतिस्थापन को धक्का देने की क्षमता उन्हें सामान्य गिट प्रोटोकॉल के माध्यम से साझा करना आसान बनाता है (आप भ्रष्टाचार प्रविष्टियों को साझा कर सकते हैं, लेकिन आपको उन्हें प्रचारित करने के लिए कुछ "बैंड से बाहर" तंत्र (यानी पुश/फ़ेच नहीं) का उपयोग करना होगा)। –

1

सबसे आसान तरीका निश्चित रूप से एक नया गिट रेपो बनाना है, इतिहास को पहले प्रस्तुत करने के लिए और फिर पुराने रेपो के पैच को फिर से लागू करना है। लेकिन मैं एक समाधान पसंद करूंगा जो स्वचालन द्वारा कम समय ले रहा है।

2

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

यह संदेश: http://marc.info/?l=git&m=119636089519572 में सबसे अच्छा प्रलेखन है जो मुझे मिल सकता है।

आप अपने प्री-गिट इतिहास से संबंधित कामों का अनुक्रम तैयार करेंगे, फिर गिट का उपयोग करके उत्पन्न किए गए पहले प्रतिबद्धता के अभिभावक के रूप में गिट को उस अनुक्रम में अंतिम प्रतिबद्धता का उपयोग करने के लिए .git/info/grafts फ़ाइल का उपयोग करें।

+1

+1 आह हाँ, मैं देखता हूं, धन्यवाद। यह [क्रिस जॉन्सन के उत्तर] में भ्रष्टाचार-विकल्प के रूप में विस्तृत है (http://stackoverflow.com/questions/3147097/how-to-prepend-the-past-to-a-git-repository/3148117#3148117) –

संबंधित मुद्दे