2015-10-14 8 views
7

मैं कुछ मुझे git pull या git fetch && git merge के परिणाम दे देंगे कि लागू करने के लिए कोशिश कर रहा हूँ। मुझे यह काम मिल रहा है, लेकिन मेरी समस्या यह है कि निम्नलिखित कोड चलाने के बाद, वर्तमान रेपो सोच रहा है कि स्थानीय परिवर्तन किए जाने हैं।Git2go - खींच && विलय

जहाँ तक मैं देख सकता हूं, मुझे विश्वास है कि मैं शायद सही सिर से एनोटेटेड प्रतिबद्धता नहीं बना रहा हूं या मुझे एक और प्रतिबद्धता की आवश्यकता है? (मुझे यकीन नहीं है)।

मेरे कोड इस तरह दिखता है और मैं अटक कर रहा हूँ:

func (repo *Repo) Pull() error { 
    // Get remote 
    remote, err := repo.Remotes.Lookup("origin") 
    if err != nil { 
     remote, err = repo.Remotes.Create("origin", repo.Path()) 
     if err != nil { 
      return err 
     } 
    } 

    // Get the branch 
    branch, err := repo.Branch() 
    if err != nil { 
     return err 
    } 

    // Get the name 
    branchName, err := branch.Name() 
    if err != nil { 
     return err 
    } 

    if err := remote.Fetch([]string{}, &git.FetchOptions{}, ""); err != nil { 
     return err 
    } 

    // Merge 
    remoteRef, err := repo.References.Lookup("refs/remotes/origin/" + branchName) 
    if err != nil { 
     return err 
    } 

    mergeRemoteHead, err := repo.AnnotatedCommitFromRef(remoteRef) 
    if err != nil { 
     return err 
    } 

    mergeHeads := make([]*git.AnnotatedCommit, 1) 
    mergeHeads[0] = mergeRemoteHead 
    if err = repo.Merge(mergeHeads, nil, nil); err != nil { 
     return err 
    } 

    return nil 
} 

इसे चलाने के बाद, मैं परिवर्तन दूरस्थ विलय कर से और कार्यशील निर्देशिका अद्यतन मिलता है, लेकिन यह मुझसे कहता है कि मैं एक प्रतिबद्ध बनाने की जरूरत है।

मुझे लगता है मैं this question की ओ पी के रूप में एक ऐसी ही समस्या है।

उत्तर

7

रास्ता libgit2 के git_merge समारोह है कि प्रलेखित है:

कोई भी परिवर्तन के लिए प्रतिबद्ध है और किसी भी संघर्ष सूचकांक करने के लिए लिखा जाता है के लिए मंचन कर रहे हैं। इस पूर्ण होने के बाद कॉलर्स को रिपॉजिटरी के इंडेक्स का निरीक्षण करना चाहिए, किसी भी विवाद को हल करना और प्रतिबद्धता तैयार करना चाहिए।

तो आपको index has conflicts जांचने के लिए कोड जोड़ना होगा। यदि कोई नहीं है, तो आप commit चरणबद्ध हो सकते हैं। अन्यथा आप शायद उपयोगकर्ता को संघर्षों को हल करने के लिए संकेत देना चाहते हैं।

+0

पर पूरा फ़ंक्शन खोजें क्या आप थोड़ा सा विस्तार कर सकते हैं कि मुझे प्रतिबद्धता क्यों बनाना है? ये 'उत्पत्ति' से आने वाले परिवर्तन हैं। क्या उन्हें मंचन किया जाना चाहिए? क्या यह सिर्फ उन परिवर्तनों को दोबारा नहीं खेलना चाहिए और मुझे एक स्वच्छ कार्यशील निर्देशिका के साथ छोड़ देना चाहिए (बशर्ते कि हमने स्थानीय रूप से कोई बदलाव नहीं किया हो)। यह फ़ंक्शन चरण परिवर्तन स्थानीय रूप से नहीं किया जाता है, और रिमोट से खींचा जाने वाला काम रिकॉर्ड नहीं करता है। – Sthe

+0

libgit2 (और इसकी बाइंडिंग) गिट (चीनी मिट्टी के बरतन) कमांड लाइन की तुलना में निचले स्तर पर काम करती है। विशेष रूप से, git2go का 'मर्ज' बहुत कम करता है जो 'गिट मर्ज' करता है। जबकि डिफ़ॉल्ट रूप से 'गिट मर्ज' फास्ट-फॉरवर्ड विलय को सरल बनाने में सक्षम है (वास्तव में कोई विलय नहीं होता है, '--ff' देखें), git2go का' मर्ज 'स्पष्ट रूप से एक मर्ज बनाता है, भले ही एक फास्ट-फॉरवर्ड था मुमकिन। बदले में एक विलय हमेशा विलय प्रतिबद्ध बनाता है, और कुछ करने के लिए, सूचकांक को पॉप्युलेट किया जाना चाहिए। फिर git2go की 'मर्ज' बहुत कम स्तर है और आपको कोई संघर्ष नहीं होने पर भी स्पष्ट रूप से प्रतिबद्ध करने की आवश्यकता है। – sschuberth

3

ऊपर sschuberth के उत्तर से इनपुट का उपयोग करके, मैं इस समारोह के एक वर्किंग वर्जन को एक साथ रखने में सक्षम था और मैंने सोचा कि मैं सफलता साझा करूंगा। जैसा कि इंगित किया गया है, repo.Merge() libgit2 में फ़ंक्शन (इस मामले में गिट 2go के रूप में) लगभग git pull करता है। मुझे एक समय में एक कदम यह समझाता हूँ (मैं सही स्टैंड):

के रूप में समझाया here, git pull वास्तव में एक git fetch और फिर एक git merge करता है और हम यही करने वाला कर है:

दूरस्थ जानें पुनः प्राप्त करने के

remote, err := repo.Remotes.Lookup("origin") 
if err != nil { 
    return err 
} 

से परिवर्तन दूरस्थ

से परिवर्तन लायें

इसी दूरदराज के संदर्भ

remoteBranch, err := repo.References.Lookup("refs/remotes/origin/branch_name") 
if err != nil { 
    return err 
} 

जाओ अब आप रिमोट से परिवर्तन है, लेकिन उस Git आपको बता कैसे आगे उनसे निपटने के लिए जाने की जरूरत है। तो, विलय विश्लेषण करें।

मर्ज विश्लेषण

annotatedCommit, err := repo.AnnotatedCommitFromRef(remoteBranch) 
if err != nil { 
    return err 
} 

// Do the merge analysis 
mergeHeads := make([]*git.AnnotatedCommit, 1) 
mergeHeads[0] = annotatedCommit 
analysis, _, err := repo.MergeAnalysis(mergeHeads) 
if err != nil { 
    return err 
} 

अब, आप analysis का मूल्य की जाँच करने के जो status value यह की ओर इशारा करता हैं और तदनुसार मर्ज करने की जरूरत को पूरा करें।

टेस्ट दिए गए मान

द्विआधारी स्तर पर परीक्षण करना सुनिश्चित करें, ताकि बिटवाइज़ ऑपरेटर्स का उपयोग करें। उदाहरण के लिए:

if analysis & git.MergeAnalysisUpToDate != 0 { 
    return nil 
} 

यहां कुछ भी नहीं है (मेरे मामले में)। सब कुछ अद्यतित है।

else if analysis & git.MergeAnalysisNormal != 0 { 
    // Just merge changes 
    if err := repo.Merge([]*git.AnnotatedCommit{annotatedCommit}, nil, nil); err != nil { 
     return err 
    } 
    // Check for conflicts 
    index, err := repo.Index() 
    if err != nil { 
     return err 
    } 

    if index.HasConflicts() { 
     return errors.New("Conflicts encountered. Please resolve them.") 
    } 

    // Make the merge commit 
    sig, err := repo.DefaultSignature() 
    if err != nil { 
     return err 
    } 

    // Get Write Tree 
    treeId, err := index.WriteTree() 
    if err != nil { 
     return err 
    } 

    tree, err := repo.LookupTree(treeId) 
    if err != nil { 
     return err 
    } 

    localCommit, err := repo.LookupCommit(head.Target()) 
    if err != nil { 
     return err 
    } 

    remoteCommit, err := repo.LookupCommit(remoteBranchID) 
    if err != nil { 
     return err 
    } 

    repo.CreateCommit("HEAD", sig, sig, "", tree, localCommit, remoteCommit) 

    // Clean up 
    repo.StateCleanup() 
} 

संक्षेप में, उपरोक्त कोड ब्लॉक केवल विलय और परीक्षण के बाद परीक्षण करता है। यदि किसी भी विवाद का सामना करना पड़ता है, तो उनके साथ सौदा करें (शायद उपयोगकर्ता को संकेत दें)। इसके परिणामस्वरूप असामान्य परिवर्तन होंगे, इसलिए एक प्रतिबद्धता के बाद सुनिश्चित करना सुनिश्चित करें।

else if analysis & git.MergeAnalysisFastForward != 0 { 
    // Fast-forward changes 
    // Get remote tree 
    remoteTree, err := repo.LookupTree(remoteBranchID) 
    if err != nil { 
     return err 
    } 

    // Checkout 
    if err := repo.CheckoutTree(remoteTree, nil); err != nil { 
     return err 
    } 

    branchRef, err := repo.References.Lookup("refs/heads/branch_name") 
    if err != nil { 
     return err 
    } 

    // Point branch to the object 
    branchRef.SetTarget(remoteBranchID, "") 
    if _, err := head.SetTarget(remoteBranchID, ""); err != nil { 
     return err 
    } 

} 

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

उपरोक्त मेरे लिए पर्याप्त था। मुझे आशा है कि दृष्टिकोण भी आपकी मदद करेगा। this gist

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