2016-02-12 61 views
2

什么是“git merge-base -fork-point branchA branchB”的jgit等效codeo?什么是“git merge-base -fork-point branchA branchB”的jgit等效物

我试了下面的代码,但我没有得到正确的答案。我正在使用它来寻找分支原点。 foreach.branch(git merge-base -fork-point mybranch theirbranch)将仅为原点生成一个提交ID。

所以,我需要做的就是弄清楚如何在jgit中做到这一点,我有一个计算分支原点的方法,当我不知道它的时候。

private String getMergeBase(Repository repository, ObjectId commitIdA, ObjectId commitIdB) { 
    RevWalk walk = new RevWalk(repository) 
    try { 
     RevCommit revA = walk.lookupCommit(commitIdA) 
     RevCommit revB = walk.lookupCommit(commitIdB) 

     walk.setRevFilter(RevFilter.MERGE_BASE) 
     walk.markStart([revA,revB]) 
     RevCommit mergeBase = walk.next() 
     if (! mergeBase) { return null } 
     return mergeBase.name 
    } catch(Exception e) { 
     project.logger.error("GetMergeBase Failed: ${commitIdA}, ${commitIdB} because ${e.message}") 
    } 
    return null 
} 

回答

1

这里有一个方法来解决它。请注意,我正在使用Gradle/Groovy编写代码,因此代码看起来有点时髦。

  • GETALL分行
  • 为每个分支获得合并基地提交 - 因为所有从主来了,一切都将发现一个
  • 迭代通过提交,并停止在合并基础列表
内发现的第一个

`

/** 
* Obtain GitWorkingCopyLog for all changes on branch with (svn --stop-on-copy equivalent) 
* @param repoDir 
* @return GitWorkingCopyLog 
    */ 
private GitWorkingCopyLog getLogs(File repoDir) { 
    List<RevCommit> commits = [] 
    Git git = openExistingRepository(repoDir) 

    ObjectId head = getHead(git.repository) // tip of current branch 

    // find common merge ancestor branch points for all branches 
    List<String> forkCandidates = mergeBaseForAllBranches(git, head) 

    for (RevCommit r in git.log().call()) { 
    if (r.name in forkCandidates) { 
     break // stop looping on first rev in common merge base 
    } 
    commits.add(r) 
    } 
    return new GitWorkingCopyLog(git.repository, commits) 
} 

/** 
* Generate list of commit ids for merge base with all candidates. All branches come from master 
* so all branches share a common point of origin even if unrelated. 
* @param git jgit controller 
* @param head head revision for target branch 
* @return list of commit ids 
*/ 
private ArrayList mergeBaseForAllBranches(Git git, ObjectId head) { 
    def baseCandidates = [] 
    getBranches(git).each { Ref other -> 
    if (other.objectId != head) { 
     String base = getMergeBase(git.repository, head, other.objectId) 
     baseCandidates.add(base) 
    } 
    } 
    baseCandidates 
} 

/** 
* 
* @param repository 
* @param commitIdA 
* @param commitIdB 
* @return divergence point between the two branches (even if seemingly unrelated all must come back to master) 
*/ 
private String getMergeBase(Repository repository, ObjectId commitIdA, ObjectId commitIdB) { 
    RevWalk walk = new RevWalk(repository) 
    try { 
    RevCommit revA = walk.lookupCommit(commitIdA) 
    RevCommit revB = walk.lookupCommit(commitIdB) 

    walk.setRevFilter(RevFilter.MERGE_BASE) 


    walk.markStart(revA) 
    walk.markStart(revB) 
    RevCommit mergeBase = walk.next() 
    println "\tA: ${revA.name}\n\tB: ${revB.name}\n\tM: ${mergeBase.name}" 
    if (! mergeBase) { return null } 
    return mergeBase.name 
    } catch(Exception e) { 
    project.logger.error("GetMergeBase Failed: ${commitIdA}, ${commitIdB} because ${e.message}") 
    } 
    return null 
} 

/** 
* Get Refs for all branches 
* @param git 
* @return Ref list 
*/ 
private List<Ref> getBranches(Git git) { 
    List<Ref> branchRefs = git.branchList().call() 
    return branchRefs 
} ` 
+0

实际上,这并不适用于所有情况。我决定放弃并使用标签。我只需要这个补丁分支。所有补丁分支都具有与特定发布标签相似的名称。我将修补程序分支名称粘贴到标记名称中,然后使用log tag..HEAD查找所需的更改 –

相关问题