सरल समाधान: विलय के बाद 'काम' शाखा निकालें
संक्षिप्त उत्तर: आप मर्ज सहित (जैसे एक साधारण वर्कफ़्लो के लिए नीचे देखें) आप git का उपयोग कर सकते हैं। अस्थायी कार्य शाखा को हटाने के लिए ' गिट ब्रांच -d वर्क ' के साथ प्रत्येक ' git मर्ज कार्य ' का पालन करना सुनिश्चित करें ।
पृष्ठभूमि की व्याख्या:
मर्ज / डीकमिट समस्या यह है कि जब भी आप एक शाखा को 'git svn dcommit' करते हैं, तो उस शाखा का मर्ज इतिहास 'चपटा' होता है: git इस शाखा में गए सभी मर्ज कार्यों के बारे में भूल जाता है: बस फ़ाइल सामग्री संरक्षित है लेकिन यह तथ्य कि यह सामग्री (आंशिक रूप से) एक विशिष्ट अन्य शाखा से आई है खो गई है। देखें: git svn dcommit स्थानीय शाखाओं के लिए विलय के इतिहास को क्यों खो देती है?
(नोट: इस बारे में बहुत कुछ नहीं है कि git-svn इसके बारे में क्या कर सकता है: svn बस इतना अधिक शक्तिशाली मेरिट मर्ज नहीं समझता है। इसलिए, svn रिपॉजिटरी के अंदर इस मर्ज की जानकारी को किसी भी तरह से प्रस्तुत नहीं किया जा सकता है।)
लेकिन यह पूरी समस्या है। यदि आप 'कार्य' शाखा को 'मास्टर शाखा' में मिलाने के बाद हटाते हैं, तो आपकी गिट रिपॉजिटरी 100% साफ है और बिल्कुल आपकी svn रिपॉजिटरी की तरह दिखती है।
मेरा वर्कफ़्लो:
बेशक, मैंने पहली बार रिमोट svn रिपॉजिटरी को एक स्थानीय गिट रिपॉजिटरी में क्लोन किया (इसमें कुछ समय लग सकता है):
$> git svn clone <svn-repository-url> <local-directory>
सभी काम तब "स्थानीय-निर्देशिका" के अंदर होता है। जब भी मुझे सर्वर से अपडेट प्राप्त करने की आवश्यकता होती है (जैसे 'svn अपडेट'), मैं करता हूं:
$> git checkout master
$> git svn rebase
मैं अपने सभी विकास कार्य एक अलग शाखा 'कार्य' में करता हूं जो इस तरह बनाई गई है:
$> git checkout -b work
बेशक, आप अपने काम के लिए जितनी चाहें उतनी शाखाएँ बना सकते हैं और आप के बीच विलय कर सकते हैं और रिबेट कर सकते हैं। अपने सामान्य काम में, मैं बहुत बार करता हूं:
$> git commit -am '-- finished a little piece of work'
अगला चरण (git rebase -i) वैकल्पिक है - यह सिर्फ इतिहास को svn पर संग्रहीत करने से पहले साफ कर रहा है: एक बार जब मैं एक स्थिर मील के पत्थर पर पहुंच गया जिसे मैं दूसरों के साथ साझा करना चाहता हूं, तो मैं इस 'काम' के इतिहास को फिर से लिखता हूं शाखा करें और प्रतिबद्ध संदेशों को साफ करें (अन्य डेवलपर्स को सभी छोटे कदमों और गलतियों को देखने की ज़रूरत नहीं है जो मैंने रास्ते में किए थे --- बस परिणाम)। इसके लिए, मैं करता हूं
$> git log
और अंतिम वचन की श-1 हैश की नकल करें जो कि svn रिपॉजिटरी में लाइव है (जैसा कि git-svn-id द्वारा दर्शाया गया है)। फिर मैं फोन करता हूं
$> git rebase -i 74e4068360e34b2ccf0c5869703af458cde0cdcb
बस हमारे पिछले svn प्रतिबद्ध के श -१ हैश की बजाय मेरा पेस्ट करें। आप विवरण के लिए 'git help rebase' के साथ प्रलेखन पढ़ना चाह सकते हैं। संक्षेप में: यह कमांड सबसे पहले आपके कमिट्स को प्रस्तुत करने वाला एक एडिटर खोलता है ---- बस उन सभी कमिट्स के लिए 'पिक' को 'स्क्वैश' में बदलें, जिन्हें आप पिछले कमिट्स के साथ स्क्वैश करना चाहते हैं। बेशक, पहली पंक्ति को 'पिक' के रूप में रहना चाहिए। इस तरह, आप एक या एक से अधिक सार्थक इकाइयों में अपने बहुत से कमिट्स को संघनित कर सकते हैं। सहेजें और संपादक से बाहर निकलें। आपको एक अन्य संपादक मिलेगा जो आपको प्रतिबद्ध लॉग संदेशों को फिर से लिखने के लिए कहेगा।
संक्षेप में: 'कोड हैकिंग' समाप्त करने के बाद, मैं अपनी 'काम' शाखा की मालिश करता हूं, जब तक कि यह नहीं दिखता कि मैं इसे अन्य प्रोग्रामर को कैसे प्रस्तुत करना चाहता हूं (या मैं इतिहास ब्राउज़ करते समय कुछ हफ्तों में काम कैसे देखना चाहता हूं) ।
Svn रिपॉजिटरी में बदलावों को आगे बढ़ाने के लिए, मैं यह करता हूं:
$> git checkout master
$> git svn rebase
अब हम पुरानी 'मास्टर' शाखा में वापस आ गए हैं जो सभी परिवर्तनों के साथ अद्यतन हुई है जो svn रिपॉजिटरी में माध्य समय में हुई है (आपके नए परिवर्तन 'कार्य शाखा' में छिपे हुए हैं)।
यदि ऐसे परिवर्तन हैं जो आपके नए 'कार्य' परिवर्तनों से टकरा सकते हैं, तो आपको अपने नए काम को आगे बढ़ाने से पहले उन्हें स्थानीय रूप से हल करना होगा (नीचे विवरण देखें)। फिर, हम svn में अपने बदलावों को आगे बढ़ा सकते हैं:
$> git checkout master
$> git merge work # (1) merge your 'work' into 'master'
$> git branch -d work # (2) remove the work branch immediately after merging
$> git svn dcommit # (3) push your changes to the svn repository
नोट 1: कमांड 'गिट ब्रांच -d वर्क' काफी सुरक्षित है: यह आपको केवल उन शाखाओं को हटाने की अनुमति देता है जिनकी आपको अब आवश्यकता नहीं है (क्योंकि वे पहले से ही आपकी वर्तमान शाखा में विलय हो चुके हैं)। यदि आप 'मास्टर' शाखा के साथ अपने काम को विलय करने से पहले गलती से इस कमांड को निष्पादित करते हैं, तो आपको एक त्रुटि संदेश मिलता है।
नोट 2: बीच-बीच में अपनी शाखा को 'गिट ब्रांच -d वर्क' से हटाना सुनिश्चित करें मर्जिंग और डीकमिट के : यदि आप डीकमिट के बाद शाखा को हटाने की कोशिश करते हैं, तो आपको एक त्रुटि संदेश मिलता है: जब आप 'git svn dcommit' करते हैं, तो यह भूल जाते हैं कि आपकी शाखा को 'मास्टर' के साथ मिला दिया गया है। आपको इसे 'गिट ब्रांच -D वर्क' से हटाना होगा जो सेफ्टी चेक नहीं करता है।
अब, मैं तुरंत 'मास्टर' शाखा पर गलती से हैकिंग से बचने के लिए एक नई 'कार्य' शाखा बनाता हूं:
$> git checkout -b work
$> git branch # show my branches:
master
* work
Svn पर बदलाव के साथ अपने 'काम' को एकीकृत करना:
यहाँ मैं क्या करता हूँ जब 'git svn rebase' से पता चलता है कि दूसरों ने svn रिपॉजिटरी को तब बदल दिया जब मैं अपनी 'कार्य' शाखा में काम कर रहा था:
$> git checkout master
$> git svn rebase # 'svn pull' changes
$> git checkout work # go to my work
$> git checkout -b integration # make a copy of the branch
$> git merge master # integrate my changes with theirs
$> ... check/fix/debug ...
$> ... rewrite history with rebase -i if needed
$> git checkout master # try again to push my changes
$> git svn rebase # hopefully no further changes to merge
$> git merge integration # (1) merge your work with theirs
$> git branch -d work # (2) remove branches that are merged
$> git branch -d integration # (2) remove branches that are merged
$> git svn dcommit # (3) push your changes to the svn repository
अधिक शक्तिशाली समाधान मौजूद हैं:
प्रस्तुत वर्कफ़्लो सरलीकृत है: यह 'अपडेट / हैक / डॉकमिट' के प्रत्येक दौर के भीतर केवल गिट की शक्तियों का उपयोग करता है --- लेकिन लंबी अवधि के प्रोजेक्ट इतिहास को केवल एसएन रिपॉजिटरी के रूप में रैखिक छोड़ देता है। यह ठीक है अगर आप बस एक विरासत एसवीएन परियोजना में छोटे पहले चरणों में गिट मर्ज का उपयोग शुरू करना चाहते हैं।
जब आप git मर्जिंग के बारे में अधिक परिचित हो जाते हैं, तो अन्य वर्कफ़्लोज़ का पता लगाने के लिए स्वतंत्र महसूस करें: यदि आप जानते हैं कि आप क्या कर रहे हैं, तो आप svn मर्ज के साथ git मर्ज को मिला सकते हैं ( svit मर्ज में मदद करने के लिए git-svn (या समान) का उपयोग करना? )