fix: 处理 mr 过程中分支被删除的情况
This commit is contained in:
@@ -66,6 +66,7 @@ public enum RCode {
|
||||
GIT_PARENT_COMMITID_NOT_FOUND(203003, "Parent commitId not found"),
|
||||
GIT_BINARY_CONFLICT_ERROR(203004, "Binary file conflict found; resolve conflicts in binary files manually"),
|
||||
GIT_MERGE_NOT_SUPPORTED(203005, "Cannot merge in the {0} state"),
|
||||
GIT_MERGE_TARGET_BRANCH_NOT_EXIST(203006, "The target branch {0} does not exist."),
|
||||
|
||||
|
||||
// Runner
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package net.geedge.asw.module.app.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import net.geedge.asw.module.app.entity.ApplicationEntity;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mapper
|
||||
public interface ApplicationDao extends BaseMapper<ApplicationEntity>{
|
||||
|
||||
List<ApplicationEntity> queryList(Page page, Map<String, Object> params);
|
||||
}
|
||||
@@ -28,6 +28,8 @@ public interface IGitService {
|
||||
|
||||
void deleteBranch(String workspaceId, String branch);
|
||||
|
||||
boolean isBranchExists(String workspaceId, String branch);
|
||||
|
||||
List<Map<Object, Object>> listBranchCommit(String workspaceId, String branch, String path);
|
||||
|
||||
String getParentCommitId(String workspaceId, String branch, String commitId);
|
||||
|
||||
@@ -120,8 +120,10 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
switch (mergeRequestStatus) {
|
||||
case OPEN: {
|
||||
newCommitId = gitService.getLatestCommitId(workspaceId, sourceBranch);
|
||||
// open 状态下,获取 sourceBranch,targetBranch 冲突文件
|
||||
conflictFileList = gitService.getConflictFilePathInBranches(workspaceId, sourceBranch, targetBranch);
|
||||
if (gitService.isBranchExists(workspaceId, targetBranch)) {
|
||||
// open 状态下,获取 sourceBranch,targetBranch 冲突文件
|
||||
conflictFileList = gitService.getConflictFilePathInBranches(workspaceId, sourceBranch, targetBranch);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLOSED:
|
||||
@@ -231,7 +233,7 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
* merge operation
|
||||
*
|
||||
* @param mrId
|
||||
* @param action merge|close
|
||||
* @param action merge|close
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@@ -252,6 +254,11 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
String message = entity.getTitle();
|
||||
String workspaceId = entity.getWorkspaceId();
|
||||
|
||||
// 检查 tgtBranch 是否存在
|
||||
if (T.BooleanUtil.negate(gitService.isBranchExists(workspaceId, tgtBranch))) {
|
||||
throw new ASWException(RCode.GIT_MERGE_TARGET_BRANCH_NOT_EXIST.setParam(tgtBranch));
|
||||
}
|
||||
|
||||
// merge
|
||||
try {
|
||||
gitService.mergeBranch(workspaceId, srcBranch, tgtBranch, message, null);
|
||||
@@ -259,17 +266,17 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
entity.setEndCommitId(latestCommitId);
|
||||
entity.setStatus(MergeRequestStatus.MERGED.toString());
|
||||
} catch (Exception e) {
|
||||
log.error(e, "[newMr] [merge error] [workspaceId: {}] [srcBranch: {}] [tgtBranch: {}] [msg: {}]", workspaceId, srcBranch, tgtBranch, e.getMessage());
|
||||
log.error(e, "[mergeMr] [merge error] [workspaceId: {}] [srcBranch: {}] [tgtBranch: {}] [msg: {}]", workspaceId, srcBranch, tgtBranch, e.getMessage());
|
||||
throw new ASWException(RCode.GIT_MERGE_FAILED.setParam(e.getMessage()));
|
||||
}
|
||||
|
||||
// remove source branch
|
||||
if (1 == entity.getRemoveSourceBranch()) {
|
||||
try {
|
||||
log.info("[newMr] [remove source branch] [workspaceId: {}] [branch: {}]", workspaceId, srcBranch);
|
||||
log.info("[mergeMr] [remove source branch] [workspaceId: {}] [branch: {}]", workspaceId, srcBranch);
|
||||
gitService.deleteBranch(workspaceId, srcBranch);
|
||||
} catch (Exception e) {
|
||||
log.error(e, "[newMr] [remove source branch error] [workspaceId: {}] [branch: {}] [msg: {}]", workspaceId, srcBranch, e.getMessage());
|
||||
log.error(e, "[mergeMr] [remove source branch error] [workspaceId: {}] [branch: {}] [msg: {}]", workspaceId, srcBranch, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,6 +315,7 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
public String toString() {
|
||||
return "open";
|
||||
}
|
||||
|
||||
public boolean canMerge() {
|
||||
return true;
|
||||
}
|
||||
@@ -317,6 +325,7 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
public String toString() {
|
||||
return "merged";
|
||||
}
|
||||
|
||||
public boolean canMerge() {
|
||||
return false;
|
||||
}
|
||||
@@ -326,6 +335,7 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
public String toString() {
|
||||
return "closed";
|
||||
}
|
||||
|
||||
public boolean canMerge() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,14 @@ package net.geedge.asw.module.app.service.impl;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.log.Log;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import net.geedge.asw.common.util.ASWException;
|
||||
import net.geedge.asw.common.util.RCode;
|
||||
import net.geedge.asw.common.util.T;
|
||||
import net.geedge.asw.module.app.entity.ApplicationMergeEntity;
|
||||
import net.geedge.asw.module.app.service.IApplicationMergeService;
|
||||
import net.geedge.asw.module.app.service.IGitService;
|
||||
import net.geedge.asw.module.app.service.impl.ApplicationMergeServiceImpl.MergeRequestStatus;
|
||||
import net.geedge.asw.module.sys.entity.SysUserEntity;
|
||||
import net.geedge.asw.module.sys.service.ISysUserService;
|
||||
import net.geedge.asw.module.workspace.entity.WorkspaceEntity;
|
||||
@@ -37,7 +41,6 @@ import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.eclipse.jgit.treewalk.filter.PathFilter;
|
||||
import org.eclipse.jgit.util.io.DisabledOutputStream;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -50,7 +53,6 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -80,8 +82,7 @@ public class GitServiceImpl implements IGitService {
|
||||
private IWorkspaceService workspaceService;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("virtualThreadExecutor")
|
||||
private ExecutorService virtualThreadExecutor;
|
||||
private IApplicationMergeService applicationMergeService;
|
||||
|
||||
/**
|
||||
* is binary file
|
||||
@@ -257,17 +258,36 @@ public class GitServiceImpl implements IGitService {
|
||||
|
||||
@Override
|
||||
public void deleteBranch(String workspaceId, String branchName) {
|
||||
log.info("[deleteBranch] [begin] [workspaceId: {}] [branch: {}]", workspaceId, branchName);
|
||||
try (Git git = this.getGitInstance(workspaceId)) {
|
||||
git.branchDelete()
|
||||
.setBranchNames(branchName)
|
||||
.setForce(true)
|
||||
.call();
|
||||
|
||||
// OPEN 状态,mr 源分支被删除,mr 记录直接删掉
|
||||
applicationMergeService.remove(new LambdaQueryWrapper<ApplicationMergeEntity>()
|
||||
.eq(ApplicationMergeEntity::getWorkspaceId, workspaceId)
|
||||
.eq(ApplicationMergeEntity::getSourceBranch, branchName)
|
||||
.eq(ApplicationMergeEntity::getStatus, MergeRequestStatus.OPEN.toString())
|
||||
);
|
||||
} catch (GitAPIException e) {
|
||||
log.error(e, "[deleteBranch] [error] [workspaceId: {}] [branchName: {}]", workspaceId, branchName);
|
||||
throw new ASWException(RCode.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBranchExists(String workspaceId, String branch) {
|
||||
try (Git git = this.getGitInstance(workspaceId)) {
|
||||
Ref ref = git.getRepository().findRef(T.StrUtil.concat(true, LOCAL_BRANCH_PREFIX, branch));
|
||||
return null != ref;
|
||||
} catch (IOException e) {
|
||||
log.error(e, "[isBranchExists] [workspaceId: {}] [branch: {}]", workspaceId, branch);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<Object, Object>> listBranchCommit(String workspaceId, String branch, String path) {
|
||||
List<Map<Object, Object>> resultList = T.ListUtil.list(true);
|
||||
@@ -1228,70 +1248,6 @@ public class GitServiceImpl implements IGitService {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解决冲突提交到 srcBranch
|
||||
* 提交指定 srcBranch,tgtBranch 最新 commitId,像 merge commit 一样
|
||||
*
|
||||
* @param workspaceId
|
||||
* @param srcBranch
|
||||
* @param tgtBranch
|
||||
* @param commitId
|
||||
* @param commitMessage
|
||||
* @param files
|
||||
*/
|
||||
// @Override
|
||||
// public void resolveMrConflicts(String workspaceId, String srcBranch, String tgtBranch, String commitId, String commitMessage, List<Map<String, String>> files) {
|
||||
// try (Git git = this.getGitInstance(workspaceId);
|
||||
// Repository repository = git.getRepository();
|
||||
// TreeWalk treeWalk = new TreeWalk(repository);
|
||||
// RevWalk revWalk = new RevWalk(repository)) {
|
||||
//
|
||||
// ObjectId srcBranchLatestCommitId = repository.resolve(srcBranch);
|
||||
//
|
||||
// // branch tree
|
||||
// treeWalk.addTree(revWalk.parseTree(srcBranchLatestCommitId));
|
||||
// treeWalk.setRecursive(true);
|
||||
//
|
||||
// DirCache newTree = DirCache.newInCore();
|
||||
// DirCacheBuilder newTreeBuilder = newTree.builder();
|
||||
//
|
||||
// List<String> updateFilePath = files.stream().map(map -> T.MapUtil.getStr(map, "path")).collect(Collectors.toList());
|
||||
// while (treeWalk.next()) {
|
||||
// String pathString = treeWalk.getPathString();
|
||||
// // 先删
|
||||
// if (!updateFilePath.contains(pathString)) {
|
||||
// DirCacheEntry entry = new DirCacheEntry(pathString);
|
||||
// entry.setFileMode(treeWalk.getFileMode(0));
|
||||
// entry.setObjectId(treeWalk.getObjectId(0));
|
||||
// newTreeBuilder.add(entry);
|
||||
// }
|
||||
// }
|
||||
// // 后增
|
||||
// for (Map<String, String> map : files) {
|
||||
// String path = T.MapUtil.getStr(map, "path");
|
||||
// DirCacheEntry dirCacheEntry = new DirCacheEntry(path);
|
||||
// dirCacheEntry.setFileMode(FileMode.REGULAR_FILE);
|
||||
//
|
||||
// String content = T.MapUtil.getStr(map, "content");
|
||||
// ObjectId objectId = this.insertBlobFileToDatabase(repository, content.getBytes());
|
||||
// dirCacheEntry.setObjectId(objectId);
|
||||
// newTreeBuilder.add(dirCacheEntry);
|
||||
// }
|
||||
// newTreeBuilder.finish();
|
||||
//
|
||||
// // merge commit
|
||||
// ObjectId parentId1 = ObjectId.fromString(commitId);
|
||||
// RevCommit revCommit = revWalk.parseCommit(repository.resolve(tgtBranch));
|
||||
// ObjectId parentId2 = revCommit.getId();
|
||||
//
|
||||
// boolean success = this.commitIndex(repository, srcBranch, newTree, parentId1, parentId2, commitMessage);
|
||||
// log.info("[resolveMrConflicts] [workspaceId: {}] [srcBranch: {}] [tgtBranch: {}] [commitId: {}] [success: {}]", workspaceId, srcBranch, tgtBranch, commitId, success);
|
||||
// } catch (IOException | ConcurrentRefUpdateException e) {
|
||||
// log.error(e, "[resolveMrConflicts] [error] [workspaceId: {}] [srcBranch: {}] [tgtBranch: {}] [commitId: {}]", workspaceId, srcBranch, tgtBranch, commitId);
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* commit
|
||||
*
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="net.geedge.asw.module.app.dao.ApplicationDao">
|
||||
<resultMap id="appResult" type="net.geedge.asw.module.app.entity.ApplicationEntity">
|
||||
<result property="id" column="id"/>
|
||||
<result property="name" column="name"/>
|
||||
<result property="tags" column="tags"/>
|
||||
<result property="packageName" column="package_name"/>
|
||||
<result property="website" column="website"/>
|
||||
<result property="provider" column="provider"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="properties" column="properties" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
|
||||
<result property="description" column="description"/>
|
||||
<result property="createTimestamp" column="create_timestamp"/>
|
||||
<result property="updateTimestamp" column="update_timestamp"/>
|
||||
<result property="createUserId" column="create_user_id"/>
|
||||
<result property="updateUserId" column="update_user_id"/>
|
||||
<result property="workspaceId" column="workspace_id"/>
|
||||
<result property="opVersion" column="op_version"/>
|
||||
|
||||
<association property="createUser" columnPrefix="cu_" javaType="net.geedge.asw.module.sys.entity.SysUserEntity">
|
||||
<id property="id" column="id"/>
|
||||
<result property="name" column="name"/>
|
||||
<result property="userName" column="user_name"/>
|
||||
</association>
|
||||
|
||||
<association property="updateUser" columnPrefix="uu_" javaType="net.geedge.asw.module.sys.entity.SysUserEntity">
|
||||
<id property="id" column="id"/>
|
||||
<result property="name" column="name"/>
|
||||
<result property="userName" column="user_name"/>
|
||||
</association>
|
||||
</resultMap>
|
||||
|
||||
<select id="queryList" resultMap="appResult">
|
||||
SELECT
|
||||
app.*,
|
||||
cu.id as cu_id,
|
||||
cu.name as cu_name,
|
||||
cu.user_name as cu_user_name,
|
||||
uu.id as uu_id,
|
||||
uu.name as uu_name,
|
||||
uu.user_name as uu_user_name
|
||||
FROM
|
||||
application app
|
||||
left join sys_user cu on app.create_user_id = cu.id
|
||||
left join sys_user uu on app.update_user_id = uu.id
|
||||
<where>
|
||||
<if test="params.ids != null and params.ids != ''">
|
||||
app.id in
|
||||
<foreach item="id" collection="params.ids.split(',')" separator="," open="(" close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="params.q != null and params.q != ''">
|
||||
AND ( locate(#{params.q}, app.name) OR locate(#{params.q}, app.description) )
|
||||
</if>
|
||||
<if test="params.workspaceId != null and params.workspaceId != ''">
|
||||
AND app.workspace_id = #{params.workspaceId}
|
||||
</if>
|
||||
</where>
|
||||
<if test="params.orderBy == null or params.orderBy == ''">
|
||||
ORDER BY app.id
|
||||
</if>
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -155,5 +155,7 @@ INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_
|
||||
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (247, '203004', 'GIT_BINARY_CONFLICT_ERROR', '发现二进制文件冲突;手动解决二进制文件中的冲突', 'zh', '', 'admin', 1724030366000);
|
||||
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (248, '203005', 'GIT_MERGE_NOT_SUPPORTED', 'Cannot merge in the {0} state', 'en', '', 'admin', 1724030366000);
|
||||
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (249, '203005', 'GIT_MERGE_NOT_SUPPORTED', '无法在{0}状态下合并', 'zh', '', 'admin', 1724030366000);
|
||||
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (250, '203006', 'GIT_MERGE_TARGET_BRANCH_NOT_EXIST', 'The target branch {0} does not exist.', 'en', '', 'admin', 1724030366000);
|
||||
INSERT INTO `sys_i18n`(`id`, `name`, `code`, `value`, `lang`, `remark`, `update_user_id`, `update_timestamp`) VALUES (251, '203006', 'GIT_MERGE_TARGET_BRANCH_NOT_EXIST', '目标分支 {0} 不存在', 'zh', '', 'admin', 1724030366000);
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
Reference in New Issue
Block a user