"git merge-base --fork-point branchA branchB" 的 jgit 等价物是什么
What's the jgit equivalent for "git merge-base --fork-point branchA branchB"
"git merge-base --fork-point branchA branchB" 的 jgit 等效代码是什么?
我尝试了下面的代码,但没有得到正确的答案。我用它来寻找分支起源。 foreach.branch (git merge-base --fork-point mybranch theirbranch) 将只为原点产生 null 提交 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
}
这里有一个解决方法。请注意,我在 Gradle/Groovy 中编写,因此代码可能看起来有点古怪。
- 获取所有分支
- 为每个分支获取合并基础提交 - 因为所有分支都来自 master,所以都会找到一个
- 遍历提交并停止在合并基础列表中找到的第一个提交
`
/**
* 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
} `
"git merge-base --fork-point branchA branchB" 的 jgit 等效代码是什么?
我尝试了下面的代码,但没有得到正确的答案。我用它来寻找分支起源。 foreach.branch (git merge-base --fork-point mybranch theirbranch) 将只为原点产生 null 提交 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
}
这里有一个解决方法。请注意,我在 Gradle/Groovy 中编写,因此代码可能看起来有点古怪。
- 获取所有分支
- 为每个分支获取合并基础提交 - 因为所有分支都来自 master,所以都会找到一个
- 遍历提交并停止在合并基础列表中找到的第一个提交
`
/**
* 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
} `