libgit2 / git2go

Git to Go; bindings for libgit2. Like McDonald's but tastier.
MIT License
1.93k stars 316 forks source link

Conflict reason does not match the result of the "git merge" command. #850

Open laujinkai opened 2 years ago

laujinkai commented 2 years ago

I am trying to use git2go to write an utility to do automatic merge, in the process of development I encountered a strange phenomenon and do not know how to solve it.

One of my projects will get different conflict reasons than "git merge --no-ff ..." if I merge it with git2go.

The output of "git status" after running "git merge --no-ff ..." shows some unmerged files are "both added", but those same files are shown as "modified" and merged if I run "git status" after merging branch using git2go.

Below is the code snippet I used to do the merge:

func Merge(projectPath, target, message  string) (MergeStatus, error) {
    repo, err := git.OpenRepository(projectPath)
    if err != nil {
        panic(err)
    }
    defer repo.Free()

    commit, err := resolveRefish(repo, target)
    if err != nil {
        panic(err)
    }
    defer commit.Free()

    analysis, _, err := repo.MergeAnalysis([]*git.AnnotatedCommit{commit})
    if err != nil {
        panic(err)
    }

    switch analysis {
    case git.MergeAnalysisNormal, git.MergeAnalysisFastForward:
        break // can merge

    case git.MergeAnalysisUpToDate:
        return AlreadyUpToDate, nil

    case git.MergeAnalysisNone:
        return NothingToMerge, nil

    default:
        panic(fmt.Sprintf("unhandled analysis: %v", analysis))
    }

    mergeOpts := git.MergeOptions{
        TreeFlags: git.MergeTreeFindRenames,
    }
    checkoutOpts := git.CheckoutOptions{
        Strategy: git.CheckoutForce,
    }
    err = repo.Merge([]*git.AnnotatedCommit{commit}, &mergeOpts, &checkoutOpts)
    if err != nil {
        panic(err)
    }

    index, err := repo.Index()
    if err != nil {
        panic(err)
    }
    defer index.Free()

    if index.HasConflicts() {
        return Conflicted, nil
    }

    createMergeCommit(repo, target, message)

    return Merged, nil
}

Is there something wrong with my code that causes this phenomenon?