猿问

Git2go:如何处理简单的合并冲突

对于一个简单的实时编码环境,我正在编写一个 git add、commit 和 push 函数,当两个用户在文件的同一部分编码时,除了冲突的情况外,它工作正常。它正确执行冲突分析并加载结果:


// Live-Editor, Processing / Javascript

fill(130, 52, 130);

<<<<<<< HEAD

textSize(130);

=======

textSize(120);

>>>>>>> master

text( "𝄠",160, 100);

显示 git 风格的差异。但是当我在编辑器中进行更改并再次添加/提交/推送时,它会导致同样的冲突。就好像它没有“记住”冲突已经存在并再次出现。(与 git 命令行行为不同。)


这是我的代码(我去掉了错误处理以使其更短......)


// Add

repo, err := git.OpenRepository(dir)

index, err := repo.Index()

err = index.AddAll([]string{}, git.IndexAddDefault, nil)

err = index.Write()  

treeId, err := index.WriteTreeTo(repo)

tree, err := repo.LookupTree(treeId)


// Commit

sig := &git.Signature{

    Name:  userName,

    Email: userName + "@" + beego.AppConfig.String("userdata::emailserver"),

    When:  time.Now(),

}

var currentCommit *git.Oid

if firstCommit == true {

    _, err = repo.CreateCommit("HEAD", sig, sig, message, tree)

} else {

    currentBranch, err := repo.Head()

    currentTip, err := repo.LookupCommit(currentBranch.Target())

    currentCommit, err = repo.CreateCommit("HEAD", sig, sig, message, tree, currentTip)

}


remote, err := repo.LookupRemote("origin")


// Pull

if firstCommit == false {

    // Pull possible changes from remote repo

    err = remote.Fetch([]string{}, nil, "")

    remoteBranch, err := repo.LookupReference("refs/remotes/origin/master")

    annotatedCommit, err := repo.AnnotatedCommitFromRef(remoteBranch)


    // Do the merge analysis

    mergeHeads := make([]*git.AnnotatedCommit, 1)

    mergeHeads[0] = annotatedCommit

    analysis, _, err := repo.MergeAnalysis(mergeHeads)


    if analysis&git.MergeAnalysisUpToDate == 0 && analysis&git.MergeAnalysisNormal != 0 {


        err := repo.Merge([]*git.AnnotatedCommit{annotatedCommit}, nil, nil)


        }


    }

}


// Push

err = remote.Push([]string{"refs/heads/master"}, nil, sig, message)

我猜关键部分是在// Check for conflicts不知何故使 git 目录处于一种让我们执行相同分析的状态之后。我考虑过在用户进行更改并再次提交项目后不进行分析,但与此同时另一个用户可能已经更改了远程仓库中的某些内容。


如何用 git2go 处理此类冲突的好方法?


幕布斯7119047
浏览 128回答 1
1回答

暮色呼如

我解决了这个问题。碰撞检测工作正常。如果发生无法自动解决的冲突,则将控制权交还给用户。他进行了更改,而这些更改在冲突分析再次发生之前并未提交。这是完整的代码(“合并提交(以防——现在希望解决——冲突)之后的部分至关重要。”)://////////////////////////////////////////////////////////// GitAddCommitPushfunc GitAddCommitPush(userName string, dir string, message string, firstCommit bool) error {&nbsp; &nbsp; ///////////////////////////////////////////////////////////////////////&nbsp; &nbsp; // Add&nbsp; &nbsp; //&nbsp; &nbsp; // 1 Open repository&nbsp; &nbsp; repo, err := git.OpenRepository(dir)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; beego.Error("OpenRepository - ", err)&nbsp; &nbsp; }&nbsp; &nbsp; // 2 Retrieve index&nbsp; &nbsp; index, err := repo.Index()&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Index - ", err)&nbsp; &nbsp; }&nbsp; &nbsp; // 3 Remember if we had conflicts before we added everything to the index&nbsp; &nbsp; indexHadConflicts := index.HasConflicts()&nbsp; &nbsp; // 4 Add everything to the index&nbsp; &nbsp; err = index.AddAll([]string{}, git.IndexAddDefault, nil)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; beego.Error("AddAll - ", err)&nbsp; &nbsp; }&nbsp; &nbsp; // 5 Write the index (so git knows about it)&nbsp; &nbsp; err = index.Write()&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Write - ", err)&nbsp; &nbsp; }&nbsp; &nbsp; // 6 Write the current index tree to the repo&nbsp; &nbsp; treeId, err := index.WriteTreeTo(repo)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; beego.Error("WriteTreeTo - ", err)&nbsp; &nbsp; }&nbsp; &nbsp; /////////////////////////////////////////////////////////////////////////////////////////////&nbsp; &nbsp; // Commit&nbsp; &nbsp; //&nbsp; &nbsp; // 1 Retrieve the tree we just wrote (git's reference of it that it made in the last step)&nbsp; &nbsp; tree, err := repo.LookupTree(treeId)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; beego.Error("LookupTree - ", err)&nbsp; &nbsp; }&nbsp; &nbsp; // 2 Create a signature&nbsp; &nbsp; sig := &git.Signature{&nbsp; &nbsp; &nbsp; &nbsp; Name:&nbsp; userName,&nbsp; &nbsp; &nbsp; &nbsp; Email: userName + "@" + beego.AppConfig.String("userdata::emailserver"),&nbsp; &nbsp; &nbsp; &nbsp; When:&nbsp; time.Now(),&nbsp; &nbsp; }&nbsp; &nbsp; // 3 Get remote now (as we need it for both, fetch and later push )&nbsp; &nbsp; remote, err := repo.LookupRemote("origin")&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; remote, err = repo.CreateRemote("origin", repo.Path())&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("CreateRemote - ", err)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; // 4 Read the remote branch&nbsp; &nbsp; remoteBranch, err := repo.LookupReference("refs/remotes/origin/master")&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Fetch 2 - ", err)&nbsp; &nbsp; }&nbsp; &nbsp; // 5 Determine if this is a first commit ...&nbsp; &nbsp; if firstCommit == true {&nbsp; &nbsp; &nbsp; &nbsp; // 5a ... then create a new one&nbsp; &nbsp; &nbsp; &nbsp; _, err = repo.CreateCommit("HEAD", sig, sig, message, tree)&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; // 5b ... or retrieve current head&nbsp; &nbsp; &nbsp; &nbsp; currentBranch, err := repo.Head()&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Head - ", err)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // 6 Retrieve current commit&nbsp; &nbsp; &nbsp; &nbsp; currentTip, err := repo.LookupCommit(currentBranch.Target())&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("LookupCommit - ", err)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // 7 Create a new one on top&nbsp; &nbsp; &nbsp; &nbsp; currentCommit, err := repo.CreateCommit("HEAD", sig, sig, message, tree, currentTip)&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("CreateCommit - ", err)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; ////////////////////////////////////////////////////////////////////////////////////&nbsp; &nbsp; &nbsp; &nbsp; // Merge commit (in case of -- now hopefully resolved -- conflicts)&nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; &nbsp; &nbsp; &nbsp; // 1 If there were conflicts, do the merge commit&nbsp; &nbsp; &nbsp; &nbsp; if indexHadConflicts == true {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 2 Retrieve the local commit&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; localCommit, err := repo.LookupCommit(currentCommit)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Fetch 11 - ", err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 3 Retrieve the remote commit&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; remoteCommit, err := repo.LookupCommit(remoteBranch.Target())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Fetch 12 - ", err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 4 Create a new one&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; repo.CreateCommit("HEAD", sig, sig, "Merge commit", tree, localCommit, remoteCommit)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 5 Clean up&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; repo.StateCleanup()&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; ///////////////////////////////////////////////////////////////////////////////////&nbsp; &nbsp; &nbsp; &nbsp; // Pull (Fetch and Commit)&nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; &nbsp; &nbsp; &nbsp; // 1 Fetch it (pull without commit)&nbsp; &nbsp; &nbsp; &nbsp; err = remote.Fetch([]string{}, nil, "")&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Fetch 1 - ", err)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // 2 Perform an annotated commit&nbsp; &nbsp; &nbsp; &nbsp; annotatedCommit, err := repo.AnnotatedCommitFromRef(remoteBranch)&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Fetch 3 - ", err)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // 3 Do the merge analysis&nbsp; &nbsp; &nbsp; &nbsp; mergeHeads := make([]*git.AnnotatedCommit, 1)&nbsp; &nbsp; &nbsp; &nbsp; mergeHeads[0] = annotatedCommit&nbsp; &nbsp; &nbsp; &nbsp; analysis, _, err := repo.MergeAnalysis(mergeHeads)&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Fetch 4 - ", err)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // 4 Check if something happend&nbsp; &nbsp; &nbsp; &nbsp; if analysis&git.MergeAnalysisUpToDate == 0 && analysis&git.MergeAnalysisNormal != 0 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 5 Yes! First just merge changes&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err := repo.Merge([]*git.AnnotatedCommit{annotatedCommit}, nil, nil); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Fetch 5 - ", err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 6 Retrieve the index after that treatment&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; index, err := repo.Index()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Fetch 6 - ", err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 7 Check for conflicts&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if index.HasConflicts() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 7a There are not automaticly solvable conflicts ... give them back to the user&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Trace("Conflicts! Write new index and return.", index)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; err = index.Write()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Write - ", err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return errors.New("Conflicts")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 8 Write the new tree&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; treeId, err := index.WriteTree()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Fetch 9 - ", err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 9 Retrieve the new tree&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tree, err := repo.LookupTree(treeId)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Fetch 10 - ", err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 10 Retrieve the local commit&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; localCommit, err := repo.LookupCommit(currentCommit)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Fetch 11 - ", err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 11 Retrieve the remote commit&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; remoteCommit, err := repo.LookupCommit(remoteBranch.Target())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Fetch 12 - ", err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 12 Create a new one&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; repo.CreateCommit("HEAD", sig, sig, "Merge commit", tree, localCommit, remoteCommit)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 13 Clean up&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; repo.StateCleanup()&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; //////////////////////////////////////////////////////////////////////////////////////////////////////&nbsp; &nbsp; // Push&nbsp; &nbsp; err = remote.Push([]string{"refs/heads/master"}, nil, sig, message)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; beego.Error("Push - ", err)&nbsp; &nbsp; }&nbsp; &nbsp; return err}
随时随地看视频慕课网APP

相关分类

Go
我要回答