2013-12-12 8 views
9

स्रोत कोड को पुन: सक्रिय करते समय, कभी-कभी आपको किसी फ़ाइल के अंदर टेक्स्ट के बड़े ब्लॉक या यहां तक ​​कि एक नई फ़ाइल को स्थानांतरित करने की आवश्यकता होती है। आप एक शाखा refactored बना सकते हैं और दूर के लिए प्रतिबद्ध:स्थानांतरित सामग्री का पालन करने के लिए गिट को बताएं (केवल फ़ाइलों को स्थानांतरित नहीं किया गया)

$git checkout master 
$git branch refactored 
$git checkout refactored 
<move code around> 
$git commit -m "refactored code" 

हालांकि, लोगों को वर्ष पूर्व refactor शाखा के शीर्ष पर प्रतिबद्ध हो सकता है, कोड है कि ले जाया गया था बदल रहा है:

$git checkout master 
<change code that was moved elsewhere on branch refactored> 
$git commit -m "bugfix" 

शाखा refactored पर, आप तो master में किए गए परिवर्तनों को शामिल करना चाहते हैं:

$git checkout refactored 
$git merge master 
<giant merge conflict> 

यह एक बड़ा मर्ज संघर्ष की ओर जाता है। अगर गिट को बताने का कोई तरीका था कि सामग्री को आसानी से स्थानांतरित किया गया था, तो स्वचालित रूप से विलय करना संभव होना चाहिए।

<fix conflicts> 
$git commit -m "merge master into refactored" 
$git checkout master 
<change more code> 
$git commit -m "bugfix2" 
$git checkout refactored 
$git merge master 
<another giant merge conflict> 

बिल्कुल इस परिहार्य है:

बदतर बात यह है कि, संघर्ष को हल करने और इसे करने से जाने के बाद भी, Git अभी भी संकल्प उपयोग नहीं कर सकते आगे मर्ज के यह पता लगाने की है? मैंने git rerere को आजमाया है और यह यहां संघर्षों को हल नहीं कर सकता है। क्या किसी भी तरह से गिट एक विलोपन और सम्मिलन के बजाय, वास्तविक चाल के रूप में टेक्स्ट के ब्लॉक को स्थानांतरित करने के लिए देख सकता है? यदि यह नहीं हो सकता है, तो विलय विवादों को कम करने के लिए सबसे अच्छा तरीका क्या है, यदि आपको थोड़ी देर के लिए दो समांतर शाखाएं रखने की आवश्यकता है?

हालांकि यह moving the contents of a complete file के लिए काफी आसान है, लेकिन मुझे केवल भाग को स्थानांतरित करने या उसी फ़ाइल के अंदर जाने पर जानकारी नहीं मिल सका।

इसके अलावा, यदि इसके लिए कोई समाधान है, तो git blame का व्यवहार कोड पर क्या होगा? क्या यह रिफैक्टरिंग प्रतिबद्धता को इंगित करेगा, या इसे अनदेखा करेगा? क्या बाद में हासिल करने का कोई तरीका है?

मामले में किसी को भी रुचि है, मैं (बहुत कम) भंडार मैं on pastebin

संभावित समाधानों

के परीक्षण के लिए उपयोग कर रहा हूँ के एक बेस 64 इनकोडिंग tar.gz डाल दिया

एक संभावित समाधान प्रदर्शन किया जा सकता है प्री-रिफैक्चरर्ड शाखा में हुए बदलावों के साथ एक (स्वचालित रूप से) संपादित पैच को लागू करके विलय करें। क्या ऐसा करने के लिए सॉफ्टवेयर विकसित किया गया है? इस दृष्टिकोण का उपयोग करके मुझे लगता है कि, चूंकि यह गिट के लिए पारदर्शी है, git blame रिफैक्टरिंग प्रतिबद्धता को इंगित करेगा।

मुझे the same question, applied to diff मिला है। किसी मौजूदा गैर-स्वामित्व कार्यान्वयन में कोई उल्लेख नहीं है, लेकिन वहां एक एल्गोरिदम का उल्लेख है जो ब्लॉक आंदोलन को ट्रैक करता है

+0

मैं सुझाव है कि आप और अधिक बनाने के लिए प्रतिबद्ध हैं। जब आप बहुत अधिक डेटा बदलते हैं, तो आपके पास अधिक प्रतिबद्धता होती है, कोड विलय करते समय कम समस्या होती है। – sensorario

+0

@ सेंसरोरियो जो सामान्य रूप से एक अच्छा सुझाव है। मुझे यकीन नहीं है कि आप इसे रीफैक्टरिंग के लिए कैसे लागू करेंगे, हालांकि - एक समय में एक फ़ंक्शन/छोटे ब्लॉक को स्थानांतरित करने में मदद नहीं की जा रही है – goncalopp

+0

यदि आप फ़ाइलों को बदलते हैं तो आपके पास दो अलग-अलग सामग्री होती है। हां, अगर आप किसी फ़ाइल से किसी फ़ंक्शन को किसी अन्य स्थान पर ले जाते हैं। यदि आप संघर्ष को कम करना चाहते हैं, तो अधिक से अधिक काम करें। प्रयास करें। – sensorario

उत्तर

1

दुर्भाग्य से आप निर्मित गिट मर्ज रणनीतियों को जहां तक ​​मैं बता सकता हूं, को प्रतिस्थापित नहीं कर सकता। इसका मतलब है कि आप संघर्ष को रोक नहीं सकते हैं, हालांकि आप उन्हें हल करने के लिए एक बुद्धिमान उपकरण का उपयोग कर सकते हैं।

यह एक Semantic Merge दिलचस्प लग रहा है, यह भी used by git

+0

मैंने उदाहरण भंडार पर सेमेन्टिक मेर्ज की कोशिश की है। सबसे पहले, लिनक्स पर, यह 80 एमबी निर्भरताओं का परिचय देता है - प्लास्टिक्सकैम से बहुत सारे पैकेज और मोनो प्रतीत होता है। विलय को 'गिट मेरेटूल' का उपयोग करके मैन्युअल रूप से किया जाना है, और उपकरण को बातचीत की आवश्यकता है ("शुरू करने के लिए वापसी पर हिट करें") और एक जीयूआई का उपयोग करता है (इसे सीएलआई, एएफएआईसीटी से नहीं चलाया जा सकता है)। आखिरकार, यह मेरे उदाहरण में संघर्षों को मर्ज करने में असफल रहा, "पार्सिंग त्रुटियां पाई गईं, पेड़ असंगत हो सकते हैं"। मुझे यकीन नहीं है कि टूल वास्तव में कुछ भी कर रहा है, क्योंकि मुझे तब एक त्रुटि मिलती है "ऑब्जेक्ट रेफरेंस ऑब्जेक्ट के इंस्टेंस पर सेट नहीं है"। – goncalopp

+0

निष्पक्ष होने के लिए, मैंने इसे उबंटू 12.04 एलटीएस (सटीक पांगोलिन) पर आज़माया है, जो आवश्यक रूप से समर्थित नहीं है ('हम केवल डेबियन 6.0 के लिए समर्थन की गारंटी देते हैं, लेकिन यह भंडार नए डेबियन संस्करणों (जैसे 7.0, के लिए भी लक्षित किया जा सकता है) उदाहरण) और उबंटू वितरण (विशेष रूप से एलटीएस संस्करण) ') – goncalopp

0

हो सकता है यह इस अतिरिक्त प्रयास से बचने के लिए संभव नहीं है, लेकिन फिर कि कैसे Git काम करने के लिए माना जाता है है:

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

(Wincent Colaiuta's blog से)

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

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