2013-06-20 8 views
7

मैं लंबे समय से गिट का उपयोग कर रहा हूं, लेकिन हाल ही में दिलचस्प चाल का सामना करना पड़ा जो आपको विलय के दौरान फ़ाइल परिवर्तन इतिहास को वापस करने की अनुमति देता है। यहाँ ठीक करने के चरण है:गिट विवादों के साथ विलय के दौरान फ़ाइल परिवर्तन इतिहास खोने की अनुमति देता है

मैं दो फ़ाइलों के साथ Git भंडार है और एक प्रतिबद्ध:

$ git branch 
    * master 
$ git log --oneline 
    80c8d5a Initial commit 
$ git log --oneline -- README 
    80c8d5a Initial commit 
$ ls 
    README conflict_file 

मैं नए प्रयोगात्मक शाखा बना रहा हूं और README और conflict_file फ़ाइल को बदलने:

$ checkout -b experiment 
    Switched to branch 'experiment' 
$ vim README 
$ vim conflict_file 
$ git commit -am "Experimental changes" 
    [experiment cdbc988] Experimental changes 
    2 files changed, 2 insertions(+) 
$ git log --oneline -- README 
    cdbc988 Experimental changes 
    80c8d5a Initial commit 

$ git checkout master 
    Switched to branch 'master' 
$ vim conflict_file 
$ git commit -am "Master changes" 
    [master ad8b68e] Master changes 
    1 file changed, 1 insertion(+) 
:

मास्टर शाखा और संपादित conflict_file करने के लिए वापस जा रहे हैं (मर्ज के दौरान संघर्ष करने के लिए)

निम्नलिखित में मेरी भंडार की स्थिति:

$ git log --oneline --decorate --graph --all 
    * ad8b68e (HEAD, master) Master changes 
    | * cdbc988 (experiment) Experimental changes 
    |/ 
    * 80c8d5a Initial commit 

प्रयोगात्मक शाखा के साथ विलय करने के लिए कोशिश कर रहा है:

$ git merge experiment 
    Auto-merging conflict_file 
    CONFLICT (content): Merge conflict in conflict_file 
    Automatic merge failed; fix conflicts and then commit the result. 
$ git mergetool 
    <merging conflict in conflict_file> 

यहाँ है चाल:

$ git reset HEAD README 
    Unstaged changes after reset: 
    M  README 
$ git commit 
    [master 909139f] Merge branch 'experiment' 
$ git log --oneline -- README 
    80c8d5a Initial commit 

मैं परिवर्तन खो और का इतिहास README फ़ाइल जो प्रयोगात्मक शाखा में पेश की गई थी प्रायोगिक परिवर्तन प्रतिबद्ध। क्या कोई टिप्पणी कर सकता है कि यह इस विचार से कैसे संबंधित है कि गिट को सभी बदलावों के बारे में पता है? क्या इस परिदृश्य से बचना संभव है? यह हमारी कंपनी में एक समस्या बन सकता है, क्योंकि मर्ज डेवलपर्स के लिए ऑपरेशन की अनुमति है, लेकिन वे गलती से किसी के परिवर्तन को हटा सकते हैं।

+1

'गिट लॉग' करने के लिए '--full-history' विकल्प आज़माएं। _history simplification_ के बारे में मैन पेज को भी पढ़ें: "डिफ़ॉल्ट मोड ... पेड़ की अंतिम स्थिति को समझाते हुए सबसे सरल इतिहास।" – chirlu

+0

आप क्यों आश्चर्यचकित हैं कि 'README' फ़ाइल में किए गए परिवर्तन चले गए हैं? आपने स्पष्ट रूप से अनुरोध किया है कि 'गीट रीसेट हेड रीडमे' के साथ होने के लिए। – Chronial

+0

'git log --follow - 'को आमंत्रित करना' – erkfel

उत्तर

7

कोई इतिहास खो गया नहीं है: प्रयोगात्मक शाखा में बने README में परिवर्तन अभी भी 210fdc1 प्रतिबद्ध है।यह विलय प्रतिबद्धता का हिस्सा नहीं है 909139f पूरी तरह से है क्योंकि आपने विलय को अंतिम रूप देने से पहले इसे स्पष्ट रूप से वापस कर दिया है।

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

  1. एक मर्ज प्रतिबद्ध संशोधित करने तक सीमित नहीं है सिर्फ फाइलों मर्ज आधार के बाद से छुआ, या यहाँ तक कि केवल फाइलों विरोधात्मक परिवर्तन किया है। वास्तव में, यह अपने सभी माता-पिता से पूरी तरह अलग हो सकता है।

    पाठ्यक्रम का "बिल्कुल अलग" नहीं है जो कोई सिफारिश करेगा, क्योंकि यह विलय के बारे में सभी की धारणाओं को तोड़ देगा। हालांकि, यह विलय प्रतिबद्धता में दस्तावेज़ फ़ाइलों को विस्तारित करने के लिए सही अर्थ बना सकता है, और कुछ विलय विवादों को हल करने के लिए अतिरिक्त फ़ाइलों को बदलने की आवश्यकता हो सकती है।

  2. जब आप git log -- some_path पर कॉल करते हैं, तो इतिहास सरलीकरण नामक एक प्रक्रिया को बुलाया जाता है। चूंकि मैन पेज इसका वर्णन करता है, git log केवल उन लोगों को प्रदर्शित करने का प्रयास करेगा जो "यह निर्दिष्ट करने के लिए पर्याप्त हैं कि निर्दिष्ट पथ से मेल खाने वाली फाइलें कैसे होती हैं"। आपके मामले में, प्रारंभिक प्रतिबद्धता README की वर्तमान स्थिति को समझाने के लिए पर्याप्त है (क्योंकि README अभी भी एक ही सामग्री है, या फिर यह दिखाया गया है।

    आप --full-history का उपयोग कर सकते हैं, संभवतः --simplify-merges, या कुछ अन्य इतिहास सरलीकरण विकल्पों के साथ। वे, साथ ही प्रतिबद्धताओं (जो ऊपर उल्लिखित से अधिक जटिल हैं) के लिए सटीक नियम हैं, एक विस्तृत उदाहरण के साथ described in the git log man page हैं।

+0

मैंने इस विचार पर मेरी उम्मीद पर आधारित किया कि फ़ाइल परिवर्तन के इतिहास में प्रत्येक परिवर्तन को ट्रैक किया जाना चाहिए और सहेजा जाना चाहिए, मेरी अपेक्षा है कि 909139 एफ में फ़ाइल रीडमे में 3 बदलाव हों। वही व्यवहार यदि आप एक ब्रंच का उपयोग कर रहे हैं और जब आप कुछ बदलाव करते हैं और फिर इन परिवर्तनों को पूर्ववत करते हैं, तो '--amend' का उपयोग किये बिना 2 अलग-अलग काम होंगे और वे आपके लिए' गिट लॉग 'में दिखाए जाएंगे। – erkfel

+0

हम अपने संगठन में गिट पेश करने की कोशिश कर रहे हैं, डेवलपर्स यूआई द्वारा कोड तक पहुंचने के लिए प्रतिबद्ध/विलय/पुश और गेरिट/गिटहब के लिए आईडीई का उपयोग कर रहे हैं, हमारे पास गिट उपयोग नीतियां जैसे अक्षम बल पुश, फीचर शाखाएं आदि हैं। लोगों ने उपयोग करना शुरू किया गिट और हमें शिकायतें मिलती हैं कि परिवर्तनों को खोना बहुत आसान है। – erkfel

+0

जांच के बाद हम समझते हैं कि यह मेरे उदाहरण में गलत विलय का परिणाम है, जब लोग विवादों के दौरान कुछ गलत करते हैं और गलती से रीसेट (और फिर हटाते हैं) परिवर्तन करते हैं। जब वे कुछ बदलावों के गायब होने का जिक्र करते हैं तो वे गेरिट/गिटहब जाते हैं, फ़ाइल इतिहास की जांच करें और यह न देखें कि परिवर्तन भी शुरू नहीं किए गए थे। यह बहुत भ्रमित है। केवल गहरी जांच गलत विलय को खोजने में मदद करती है। – erkfel

1

आप नहीं वास्तव में परिवर्तन को खो दिया है, तो आप सिर्फ अभी तक README फाइल करने के लिए परिवर्तन चेक इन नहीं किया है, ताकि वे अपने git log आदेशों द्वारा दिखाया प्रतिबद्ध किसी में नहीं हैं:

* 9b8ede8 (HEAD, master) Merge branch 'experiment' 
|\ 
| * 210fdc1 (experiment) Experimental 
* | d0c1637 Master changes 
|/ 
* b558d42 Initial commit 

(मेरी SHA के निश्चित रूप से अलग हैं) और:

$ git status 
# On branch master 
# Changes not staged for commit: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# modified: README 
# 
# Untracked files: 
# (use "git add <file>..." to include in what will be committed) 
# 
# conflict_file.orig 
no changes added to commit (use "git add" and/or "git commit -a") 

@Chronial टिप्पणी में बताया गया है, आप स्पष्ट रूप से Git एक git reset --mixed (--mixed डिफ़ॉल्ट है) फ़ाइल के ऐसा करने के लिए कहा था README तब- HEAD पर, जो (आपके मामले में) ad8b68e था।

था आप अपने विरोध हुआ मर्ज (git mergetool से पहले) के बीच में git status चलाने के लिए, तो आप इस देखा होगा:

$ git status 
# On branch master 
# You have unmerged paths. 
# (fix conflicts and run "git commit") 
# 
# Changes to be committed: 
# 
# modified: README 
# 
# Unmerged paths: 
# (use "git add <file>..." to mark resolution) 
# 
# both modified:  conflict_file 
# 

git mergetool कदम संघर्ष का समाधान करता है, एक ही में conflict_file चलती रेडी-टू-प्रतिबद्ध ऊपर README के रूप में राज्य - लेकिन reset --mixed के बाद, README "प्रतिबद्धताओं के लिए चरणबद्ध परिवर्तन" के लिए "परिवर्तन किए जाने के लिए परिवर्तन" से चलता है।

+0

उत्तर देने के लिए धन्यवाद, कृपया मेरी टिप्पणियों को" चिर्लू "उत्तर में देखें। – erkfel

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