fix: ASW-162 解决 mr commits,changes 展示信息有误问题

This commit is contained in:
shizhendong
2024-11-13 17:20:24 +08:00
parent cba1251bf3
commit facde0a4e1
6 changed files with 103 additions and 76 deletions

View File

@@ -15,7 +15,8 @@ public class ApplicationMergeEntity {
private String id;
private String sourceBranch;
private String targetBranch;
private String commitId;
private String startCommitId;
private String endCommitId;
private String title;
private Integer removeSourceBranch = 0;
private String description;

View File

@@ -32,6 +32,8 @@ public interface IGitService {
String getLatestCommitId(String workspaceId, String branch);
String getMergeBase(String workspaceId, String branchA, String branchB);
ObjectId insertBlobFileToDatabase(Repository repository, byte[] data) throws IOException;
List<Map<Object, Object>> getDiffFileListInCommits(String workspaceId, String newCommitId, String oldCommitId);
@@ -52,7 +54,7 @@ public interface IGitService {
Map<Object, Object> infoApplicationFileContent(String workspaceId, String branch, String applicationName, String commitId, String file);
List<Map<Object, Object>> listCommitAfterMergeBase(String workspaceId, String srcBranch, String tgtBranch);
List<Map<Object, Object>> listCommitRange(String workspaceId, String newCommitId, String oldCommitId);
List<String> getConflictFilePathInBranches(String workspaceId, String srcBranch, String tgtBranch);

View File

@@ -39,15 +39,6 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
ApplicationMergeEntity entity = this.getById(mrId);
T.VerifyUtil.is(entity).notEmpty(RCode.SYS_RECORD_NOT_FOUND);
String commitId = entity.getCommitId();
if (T.StrUtil.isNotEmpty(commitId)) {
try {
Map<Object, Object> infoCommit = gitService.infoCommit(entity.getWorkspaceId(), commitId);
entity.setCommit(infoCommit);
} catch (Exception e) {
}
}
SysUserEntity user = userService.getById(entity.getCreateUserId());
entity.setCreateUser(user);
return entity;
@@ -57,18 +48,6 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
public Page queryList(Map<String, Object> params) {
Page page = new Query(ApplicationMergeEntity.class).getPage(params);
List<ApplicationMergeEntity> list = this.getBaseMapper().queryList(page, params);
for (ApplicationMergeEntity mergeEntity : list) {
String commitId = mergeEntity.getCommitId();
if (T.StrUtil.isNotEmpty(commitId)) {
try {
Map<Object, Object> infoCommit = gitService.infoCommit(mergeEntity.getWorkspaceId(), commitId);
mergeEntity.setCommit(infoCommit);
} catch (Exception e) {
}
}
}
page.setRecords(list);
return page;
}
@@ -81,6 +60,13 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
// 默认状态
entity.setStatus(MergeRequestStatus.OPEN.toString());
// start_commit_id
String workspaceId = entity.getWorkspaceId();
String sourceBranch = entity.getSourceBranch();
String targetBranch = entity.getTargetBranch();
String mergeBase = gitService.getMergeBase(workspaceId, sourceBranch, targetBranch);
entity.setStartCommitId(mergeBase);
// save
this.save(entity);
@@ -95,12 +81,24 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
T.VerifyUtil.is(entity).notEmpty(RCode.SYS_RECORD_NOT_FOUND);
String workspaceId = entity.getWorkspaceId();
String sourceBranch = entity.getSourceBranch();
String targetBranch = entity.getTargetBranch();
String oldCommitId = entity.getStartCommitId();
String newCommitId = null;
MergeRequestStatus mergeRequestStatus = MergeRequestStatus.getInstance(entity.getStatus());
switch (mergeRequestStatus) {
case OPEN: {
newCommitId = gitService.getLatestCommitId(workspaceId, entity.getSourceBranch());
break;
}
case CLOSED:
case MERGED: {
newCommitId = entity.getEndCommitId();
break;
}
}
// 获取 sourceBranch targetBranch 共同祖先之后, sourceBranch 的提交记录
List<Map<Object, Object>> listCommitAfterMergeBase = gitService.listCommitAfterMergeBase(workspaceId, sourceBranch, targetBranch);
return listCommitAfterMergeBase;
// newCommitId-oldCommitId 期间的提交信息
List<Map<Object, Object>> commitRange = gitService.listCommitRange(workspaceId, newCommitId, oldCommitId);
return commitRange;
}
@Override
@@ -113,14 +111,28 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
String targetBranch = entity.getTargetBranch();
// 获取 sourceBranch,targetBranch 合并冲突文件
List<String> conflictFileList = gitService.getConflictFilePathInBranches(workspaceId, sourceBranch, targetBranch);
List<String> conflictFileList = T.ListUtil.list(true);
// src branch changed files
String oldCommitId = entity.getStartCommitId();
String newCommitId = null;
MergeRequestStatus mergeRequestStatus = MergeRequestStatus.getInstance(entity.getStatus());
switch (mergeRequestStatus) {
case OPEN: {
newCommitId = gitService.getLatestCommitId(workspaceId, sourceBranch);
// open 状态下,获取 sourceBranch,targetBranch 冲突文件
conflictFileList = gitService.getConflictFilePathInBranches(workspaceId, sourceBranch, targetBranch);
break;
}
case CLOSED:
case MERGED: {
newCommitId = entity.getEndCommitId();
break;
}
}
// 获取 sourceBranch,targetBranch 文件差异
String commitA = gitService.getLatestCommitId(workspaceId, sourceBranch);
String commitB = gitService.getLatestCommitId(workspaceId, targetBranch);
List<Map<Object, Object>> diffFileListInCommits = gitService.getDiffFileListInCommits(workspaceId, commitA, commitB);
List<Map<Object, Object>> diffFileListInCommits = gitService.getDiffFileListInCommits(workspaceId, newCommitId, oldCommitId);
List<String> finalConflictFileList = conflictFileList;
diffFileListInCommits.parallelStream()
.forEach(m -> {
T.MapUtil.renameKey(m, "oldContent", "sourceContent");
@@ -132,19 +144,19 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
String sourcePath = T.MapUtil.getStr(m, "sourcePath");
String targetPath = T.MapUtil.getStr(m, "targetPath");
m.put("conflict", false);
if (conflictFileList.contains(sourcePath) || conflictFileList.contains(targetPath)) {
if (finalConflictFileList.contains(sourcePath) || finalConflictFileList.contains(targetPath)) {
m.put("conflict", true);
}
});
Map<Object, Object> sourceCommit = gitService.infoCommit(workspaceId, commitA);
Map<Object, Object> targetCommit = gitService.infoCommit(workspaceId, commitB);
Map<Object, Object> sourceCommit = gitService.infoCommit(workspaceId, oldCommitId);
Map<Object, Object> targetCommit = gitService.infoCommit(workspaceId, newCommitId);
Map<Object, Object> m = T.MapUtil.builder()
.put("sourceBranch", sourceBranch)
.put("targetBranch", targetBranch)
.put("sourceCommitId", commitA)
.put("targetCommitId", commitB)
.put("sourceCommitId", oldCommitId)
.put("targetCommitId", newCommitId)
.put("sourceCommit", sourceCommit)
.put("targetCommit", targetCommit)
.put("files", diffFileListInCommits)
@@ -243,7 +255,7 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
// merge
try {
String commitId = gitService.mergeBranch(workspaceId, srcBranch, tgtBranch, message, null);
entity.setCommitId(commitId);
entity.setEndCommitId(commitId);
entity.setStatus(MergeRequestStatus.MERGED.toString());
} catch (Exception e) {
log.error(e, "[newMr] [merge error] [workspaceId: {}] [srcBranch: {}] [tgtBranch: {}] [msg: {}]", workspaceId, srcBranch, tgtBranch, e.getMessage());
@@ -263,7 +275,7 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
// update
this.update(new LambdaUpdateWrapper<ApplicationMergeEntity>()
.eq(ApplicationMergeEntity::getId, mrId)
.set(ApplicationMergeEntity::getCommitId, entity.getCommitId())
.set(ApplicationMergeEntity::getEndCommitId, entity.getEndCommitId())
.set(ApplicationMergeEntity::getStatus, entity.getStatus())
.set(ApplicationMergeEntity::getMessage, entity.getMessage())
);
@@ -273,9 +285,12 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
String updateStatus = StrUtil.equals(MergeRequestStatus.OPEN.toString(), entity.getStatus()) ? MergeRequestStatus.CLOSED.toString() : entity.getStatus();
entity.setStatus(updateStatus);
// 关闭请求,保留当前 src branch last commit = end_commit_id
String latestCommitId = gitService.getLatestCommitId(entity.getWorkspaceId(), entity.getSourceBranch());
this.update(new LambdaUpdateWrapper<ApplicationMergeEntity>()
.eq(ApplicationMergeEntity::getId, mrId)
.set(ApplicationMergeEntity::getStatus, updateStatus)
.set(ApplicationMergeEntity::getEndCommitId, latestCommitId)
);
return entity;
}

View File

@@ -27,7 +27,6 @@ import org.eclipse.jgit.merge.MergeStrategy;
import org.eclipse.jgit.merge.RecursiveMerger;
import org.eclipse.jgit.merge.ThreeWayMerger;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.revwalk.filter.RevFilter;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
@@ -338,6 +337,19 @@ public class GitServiceImpl implements IGitService {
}
}
@Override
public String getMergeBase(String workspaceId, String branchA, String branchB) {
try (Git git = this.getGitInstance(workspaceId);
Repository repository = git.getRepository();) {
ObjectId branchAId = repository.resolve(branchA);
ObjectId branchBId = repository.resolve(branchB);
return this.getMergeBase(repository, branchAId, branchBId);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 获取 commitIdA -> commitIdB 文件差异
*
@@ -348,6 +360,7 @@ public class GitServiceImpl implements IGitService {
*/
@Override
public List<Map<Object, Object>> getDiffFileListInCommits(String workspaceId, String commitIdA, String commitIdB) {
log.info("[getDiffFileListInCommits] [begin] [workspaceId: {}] [commitIdA: {}] [commitIdB: {}]", workspaceId, commitIdA, commitIdB);
try (Git git = this.getGitInstance(workspaceId);
Repository repository = git.getRepository();
RevWalk revWalk = new RevWalk(repository);
@@ -940,51 +953,45 @@ public class GitServiceImpl implements IGitService {
}
/**
* 获取 srcBranch tgtBranch 共同祖先之后, srcBranch 的提交记录
* commit range
* 沿着 parent(0) 的主路径提交列表,忽略所有分支路径的提交
*
* @param workspaceId
* @param srcBranch
* @param tgtBranch
* @param newCommitId
* @param oldCommitId
* @return
*/
@Override
public List<Map<Object, Object>> listCommitAfterMergeBase(String workspaceId, String srcBranch, String tgtBranch) {
log.info("[listCommitAfterMergeBase] [begin] [workspaceId: {}] [srcBranch: {}] [tgtBranch: {}]", workspaceId, srcBranch, tgtBranch);
public List<Map<Object, Object>> listCommitRange(String workspaceId, String newCommitId, String oldCommitId) {
log.info("[listCommitRange] [begin] [workspaceId: {}] [newCommitId: {}] [oldCommitId: {}]", workspaceId, newCommitId, oldCommitId);
List<Map<Object, Object>> commitList = T.ListUtil.list(true);
try (Git git = this.getGitInstance(workspaceId);
Repository repository = git.getRepository();) {
ObjectId branch1Id = repository.resolve(srcBranch);
ObjectId branch2Id = repository.resolve(tgtBranch);
// Find the merge base
String mergeBaseId = this.getMergeBase(repository, branch1Id, branch2Id);
log.info("[listCommitAfterMergeBase] [mergeBase: {}]", mergeBaseId);
if (T.StrUtil.isEmpty(mergeBaseId)) {
return commitList;
}
// Walk branch1's commits since the merge base
try (RevWalk revWalk = new RevWalk(repository)) {
revWalk.sort(RevSort.TOPO);
RevCommit revCommit = revWalk.parseCommit(repository.resolve(newCommitId));
RevCommit mergeBase = revWalk.parseCommit(ObjectId.fromString(mergeBaseId));
revWalk.markStart(revWalk.parseCommit(branch1Id));
revWalk.markUninteresting(mergeBase);
for (RevCommit commit : revWalk) {
commitList.add(this.buildAswCommitInfo(commit));
List<String> parentIds = Arrays.stream(commit.getParents()).map(RevCommit::getName).collect(Collectors.toList());
if (parentIds.contains(mergeBaseId)) {
Set<ObjectId> visitedCommits = new HashSet<>();
while (revCommit != null && !visitedCommits.contains(revCommit.getId())) {
if (oldCommitId != null && revCommit.getId().getName().equals(oldCommitId)) {
break;
}
commitList.add(this.buildAswCommitInfo(revCommit));
visitedCommits.add(revCommit.getId());
// 沿着 parent(0) 前进
if (revCommit.getParentCount() > 0) {
revCommit = revWalk.parseCommit(revCommit.getParent(0));
} else {
revCommit = null;
}
}
} catch (IOException e) {
log.error(e, "[listCommitRange] [error]");
throw new RuntimeException(e);
} finally {
log.info("[listCommitRange] [finshed] [workspaceId: {}] [commits size: {}]", workspaceId, commitList.size());
}
} catch (IOException e) {
log.error(e, "[listCommitAfterMergeBase] [error]");
throw new RuntimeException(e.getMessage());
} finally {
log.info("[listCommitAfterMergeBase] [finshed] [workspaceId: {}] [commits size: {}]", workspaceId, commitList.size());
}
return commitList;
}
@@ -1162,8 +1169,8 @@ public class GitServiceImpl implements IGitService {
return mergeBase.getName();
} catch (Exception e) {
log.error(e, "Failed to determine merge base");
throw new RuntimeException(e);
}
return null;
}
/**

View File

@@ -7,7 +7,8 @@
<id column="id" property="id"/>
<result column="source_branch" property="sourceBranch"/>
<result column="target_branch" property="targetBranch"/>
<result column="commit_id" property="commitId"/>
<result column="start_commit_id" property="startCommitId"/>
<result column="end_commit_id" property="endCommitId"/>
<result column="title" property="title"/>
<result column="remove_source_branch" property="removeSourceBranch"/>
<result column="description" property="description"/>

View File

@@ -361,7 +361,8 @@ CREATE TABLE `application_merge` (
`id` VARCHAR(64) NOT NULL COMMENT '主键',
`source_branch` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '源分支',
`target_branch` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '目标分支',
`commit_id` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '提交ID',
`start_commit_id` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '起始提交ID,即source和target分支的共同parent id',
`end_commit_id` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '终止提交ID,记录合并后的commit id',
`title` VARCHAR(4096) NOT NULL DEFAULT '' COMMENT '标题',
`remove_source_branch` int(1) NOT NULL DEFAULT 0 COMMENT '是否删除源分支, 1删除;0不删除 默认0',
`description` text NOT NULL DEFAULT '' COMMENT '描述信息',