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 id;
private String sourceBranch; private String sourceBranch;
private String targetBranch; private String targetBranch;
private String commitId; private String startCommitId;
private String endCommitId;
private String title; private String title;
private Integer removeSourceBranch = 0; private Integer removeSourceBranch = 0;
private String description; private String description;

View File

@@ -32,6 +32,8 @@ public interface IGitService {
String getLatestCommitId(String workspaceId, String branch); String getLatestCommitId(String workspaceId, String branch);
String getMergeBase(String workspaceId, String branchA, String branchB);
ObjectId insertBlobFileToDatabase(Repository repository, byte[] data) throws IOException; ObjectId insertBlobFileToDatabase(Repository repository, byte[] data) throws IOException;
List<Map<Object, Object>> getDiffFileListInCommits(String workspaceId, String newCommitId, String oldCommitId); 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); 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); 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); ApplicationMergeEntity entity = this.getById(mrId);
T.VerifyUtil.is(entity).notEmpty(RCode.SYS_RECORD_NOT_FOUND); 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()); SysUserEntity user = userService.getById(entity.getCreateUserId());
entity.setCreateUser(user); entity.setCreateUser(user);
return entity; return entity;
@@ -57,18 +48,6 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
public Page queryList(Map<String, Object> params) { public Page queryList(Map<String, Object> params) {
Page page = new Query(ApplicationMergeEntity.class).getPage(params); Page page = new Query(ApplicationMergeEntity.class).getPage(params);
List<ApplicationMergeEntity> list = this.getBaseMapper().queryList(page, 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); page.setRecords(list);
return page; return page;
} }
@@ -81,6 +60,13 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
// 默认状态 // 默认状态
entity.setStatus(MergeRequestStatus.OPEN.toString()); 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 // save
this.save(entity); this.save(entity);
@@ -95,12 +81,24 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
T.VerifyUtil.is(entity).notEmpty(RCode.SYS_RECORD_NOT_FOUND); T.VerifyUtil.is(entity).notEmpty(RCode.SYS_RECORD_NOT_FOUND);
String workspaceId = entity.getWorkspaceId(); String workspaceId = entity.getWorkspaceId();
String sourceBranch = entity.getSourceBranch(); String oldCommitId = entity.getStartCommitId();
String targetBranch = entity.getTargetBranch(); 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 的提交记录 // newCommitId-oldCommitId 期间的提交信息
List<Map<Object, Object>> listCommitAfterMergeBase = gitService.listCommitAfterMergeBase(workspaceId, sourceBranch, targetBranch); List<Map<Object, Object>> commitRange = gitService.listCommitRange(workspaceId, newCommitId, oldCommitId);
return listCommitAfterMergeBase; return commitRange;
} }
@Override @Override
@@ -113,14 +111,28 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
String targetBranch = entity.getTargetBranch(); String targetBranch = entity.getTargetBranch();
// 获取 sourceBranch,targetBranch 合并冲突文件 // 获取 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 文件差异 List<Map<Object, Object>> diffFileListInCommits = gitService.getDiffFileListInCommits(workspaceId, newCommitId, oldCommitId);
String commitA = gitService.getLatestCommitId(workspaceId, sourceBranch); List<String> finalConflictFileList = conflictFileList;
String commitB = gitService.getLatestCommitId(workspaceId, targetBranch);
List<Map<Object, Object>> diffFileListInCommits = gitService.getDiffFileListInCommits(workspaceId, commitA, commitB);
diffFileListInCommits.parallelStream() diffFileListInCommits.parallelStream()
.forEach(m -> { .forEach(m -> {
T.MapUtil.renameKey(m, "oldContent", "sourceContent"); T.MapUtil.renameKey(m, "oldContent", "sourceContent");
@@ -132,19 +144,19 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
String sourcePath = T.MapUtil.getStr(m, "sourcePath"); String sourcePath = T.MapUtil.getStr(m, "sourcePath");
String targetPath = T.MapUtil.getStr(m, "targetPath"); String targetPath = T.MapUtil.getStr(m, "targetPath");
m.put("conflict", false); m.put("conflict", false);
if (conflictFileList.contains(sourcePath) || conflictFileList.contains(targetPath)) { if (finalConflictFileList.contains(sourcePath) || finalConflictFileList.contains(targetPath)) {
m.put("conflict", true); m.put("conflict", true);
} }
}); });
Map<Object, Object> sourceCommit = gitService.infoCommit(workspaceId, commitA); Map<Object, Object> sourceCommit = gitService.infoCommit(workspaceId, oldCommitId);
Map<Object, Object> targetCommit = gitService.infoCommit(workspaceId, commitB); Map<Object, Object> targetCommit = gitService.infoCommit(workspaceId, newCommitId);
Map<Object, Object> m = T.MapUtil.builder() Map<Object, Object> m = T.MapUtil.builder()
.put("sourceBranch", sourceBranch) .put("sourceBranch", sourceBranch)
.put("targetBranch", targetBranch) .put("targetBranch", targetBranch)
.put("sourceCommitId", commitA) .put("sourceCommitId", oldCommitId)
.put("targetCommitId", commitB) .put("targetCommitId", newCommitId)
.put("sourceCommit", sourceCommit) .put("sourceCommit", sourceCommit)
.put("targetCommit", targetCommit) .put("targetCommit", targetCommit)
.put("files", diffFileListInCommits) .put("files", diffFileListInCommits)
@@ -243,7 +255,7 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
// merge // merge
try { try {
String commitId = gitService.mergeBranch(workspaceId, srcBranch, tgtBranch, message, null); String commitId = gitService.mergeBranch(workspaceId, srcBranch, tgtBranch, message, null);
entity.setCommitId(commitId); entity.setEndCommitId(commitId);
entity.setStatus(MergeRequestStatus.MERGED.toString()); entity.setStatus(MergeRequestStatus.MERGED.toString());
} catch (Exception e) { } catch (Exception e) {
log.error(e, "[newMr] [merge error] [workspaceId: {}] [srcBranch: {}] [tgtBranch: {}] [msg: {}]", workspaceId, srcBranch, tgtBranch, e.getMessage()); 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 // update
this.update(new LambdaUpdateWrapper<ApplicationMergeEntity>() this.update(new LambdaUpdateWrapper<ApplicationMergeEntity>()
.eq(ApplicationMergeEntity::getId, mrId) .eq(ApplicationMergeEntity::getId, mrId)
.set(ApplicationMergeEntity::getCommitId, entity.getCommitId()) .set(ApplicationMergeEntity::getEndCommitId, entity.getEndCommitId())
.set(ApplicationMergeEntity::getStatus, entity.getStatus()) .set(ApplicationMergeEntity::getStatus, entity.getStatus())
.set(ApplicationMergeEntity::getMessage, entity.getMessage()) .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(); String updateStatus = StrUtil.equals(MergeRequestStatus.OPEN.toString(), entity.getStatus()) ? MergeRequestStatus.CLOSED.toString() : entity.getStatus();
entity.setStatus(updateStatus); entity.setStatus(updateStatus);
// 关闭请求,保留当前 src branch last commit = end_commit_id
String latestCommitId = gitService.getLatestCommitId(entity.getWorkspaceId(), entity.getSourceBranch());
this.update(new LambdaUpdateWrapper<ApplicationMergeEntity>() this.update(new LambdaUpdateWrapper<ApplicationMergeEntity>()
.eq(ApplicationMergeEntity::getId, mrId) .eq(ApplicationMergeEntity::getId, mrId)
.set(ApplicationMergeEntity::getStatus, updateStatus) .set(ApplicationMergeEntity::getStatus, updateStatus)
.set(ApplicationMergeEntity::getEndCommitId, latestCommitId)
); );
return entity; 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.RecursiveMerger;
import org.eclipse.jgit.merge.ThreeWayMerger; import org.eclipse.jgit.merge.ThreeWayMerger;
import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.revwalk.filter.RevFilter; import org.eclipse.jgit.revwalk.filter.RevFilter;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder; 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 文件差异 * 获取 commitIdA -> commitIdB 文件差异
* *
@@ -348,6 +360,7 @@ public class GitServiceImpl implements IGitService {
*/ */
@Override @Override
public List<Map<Object, Object>> getDiffFileListInCommits(String workspaceId, String commitIdA, String commitIdB) { 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); try (Git git = this.getGitInstance(workspaceId);
Repository repository = git.getRepository(); Repository repository = git.getRepository();
RevWalk revWalk = new RevWalk(repository); RevWalk revWalk = new RevWalk(repository);
@@ -940,51 +953,45 @@ public class GitServiceImpl implements IGitService {
} }
/** /**
* 获取 srcBranch tgtBranch 共同祖先之后, srcBranch 的提交记录 * commit range
* 沿着 parent(0) 的主路径提交列表,忽略所有分支路径的提交
* *
* @param workspaceId * @param workspaceId
* @param srcBranch * @param newCommitId
* @param tgtBranch * @param oldCommitId
* @return * @return
*/ */
@Override public List<Map<Object, Object>> listCommitRange(String workspaceId, String newCommitId, String oldCommitId) {
public List<Map<Object, Object>> listCommitAfterMergeBase(String workspaceId, String srcBranch, String tgtBranch) { log.info("[listCommitRange] [begin] [workspaceId: {}] [newCommitId: {}] [oldCommitId: {}]", workspaceId, newCommitId, oldCommitId);
log.info("[listCommitAfterMergeBase] [begin] [workspaceId: {}] [srcBranch: {}] [tgtBranch: {}]", workspaceId, srcBranch, tgtBranch);
List<Map<Object, Object>> commitList = T.ListUtil.list(true); List<Map<Object, Object>> commitList = T.ListUtil.list(true);
try (Git git = this.getGitInstance(workspaceId); try (Git git = this.getGitInstance(workspaceId);
Repository repository = git.getRepository();) { 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)) { try (RevWalk revWalk = new RevWalk(repository)) {
revWalk.sort(RevSort.TOPO); RevCommit revCommit = revWalk.parseCommit(repository.resolve(newCommitId));
RevCommit mergeBase = revWalk.parseCommit(ObjectId.fromString(mergeBaseId)); Set<ObjectId> visitedCommits = new HashSet<>();
revWalk.markStart(revWalk.parseCommit(branch1Id)); while (revCommit != null && !visitedCommits.contains(revCommit.getId())) {
revWalk.markUninteresting(mergeBase); if (oldCommitId != null && revCommit.getId().getName().equals(oldCommitId)) {
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)) {
break; 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; return commitList;
} }
@@ -1162,8 +1169,8 @@ public class GitServiceImpl implements IGitService {
return mergeBase.getName(); return mergeBase.getName();
} catch (Exception e) { } catch (Exception e) {
log.error(e, "Failed to determine merge base"); 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"/> <id column="id" property="id"/>
<result column="source_branch" property="sourceBranch"/> <result column="source_branch" property="sourceBranch"/>
<result column="target_branch" property="targetBranch"/> <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="title" property="title"/>
<result column="remove_source_branch" property="removeSourceBranch"/> <result column="remove_source_branch" property="removeSourceBranch"/>
<result column="description" property="description"/> <result column="description" property="description"/>

View File

@@ -361,7 +361,8 @@ CREATE TABLE `application_merge` (
`id` VARCHAR(64) NOT NULL COMMENT '主键', `id` VARCHAR(64) NOT NULL COMMENT '主键',
`source_branch` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '源分支', `source_branch` VARCHAR(256) NOT NULL DEFAULT '' COMMENT '源分支',
`target_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 '标题', `title` VARCHAR(4096) NOT NULL DEFAULT '' COMMENT '标题',
`remove_source_branch` int(1) NOT NULL DEFAULT 0 COMMENT '是否删除源分支, 1删除;0不删除 默认0', `remove_source_branch` int(1) NOT NULL DEFAULT 0 COMMENT '是否删除源分支, 1删除;0不删除 默认0',
`description` text NOT NULL DEFAULT '' COMMENT '描述信息', `description` text NOT NULL DEFAULT '' COMMENT '描述信息',