fix: mr 解决冲突接口 改为: clone,ckeckout,merge,add,commit,push 操作流程
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package net.geedge.asw.module.app.service;
|
||||
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
|
||||
import org.eclipse.jgit.dircache.DirCache;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
@@ -11,6 +12,8 @@ import java.util.Map;
|
||||
|
||||
public interface IGitService {
|
||||
|
||||
Git getGitInstance(String workspaceId);
|
||||
|
||||
Repository initRepository(String workspaceId);
|
||||
|
||||
Map<Object, Object> infoCommit(String workspaceId, String commitId);
|
||||
@@ -29,9 +32,11 @@ public interface IGitService {
|
||||
|
||||
String getLatestCommitId(String workspaceId, String branch);
|
||||
|
||||
ObjectId insertBlobFileToDatabase(Repository repository, byte[] data) throws IOException;
|
||||
|
||||
List<Map<Object, Object>> getDiffFileListInCommits(String workspaceId, String newCommitId, String oldCommitId);
|
||||
|
||||
String mergeBranch(String workspaceId, String sourceBranch, String targetBranch, String message) throws RuntimeException;
|
||||
String mergeBranch(String workspaceId, String sourceBranch, String targetBranch, String message, List<Map<String, String>> resolveConflictFileContent) throws RuntimeException;
|
||||
|
||||
List<Map<Object, Object>> listApplication(String workspaceId, String branch, String q);
|
||||
|
||||
@@ -53,8 +58,6 @@ public interface IGitService {
|
||||
|
||||
List<Map<Object, Object>> getConflictFileInfoInBranches(String workspaceId, String srcBranch, String tgtBranch);
|
||||
|
||||
void resolveMrConflicts(String workspaceId, String srcBranch, String tgtBranch, String commitId, String commitMessage, List<Map<String, String>> files);
|
||||
|
||||
boolean commitIndex(Repository repo, String branch, DirCache index, ObjectId parentId1, ObjectId parentId2, String message) throws IOException, ConcurrentRefUpdateException;
|
||||
|
||||
}
|
||||
|
||||
@@ -211,7 +211,8 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
String commitMessage = T.MapUtil.getStr(body, "commitMessage");
|
||||
List<Map<String, String>> files = T.MapUtil.get(body, "files", List.class, new ArrayList());
|
||||
|
||||
gitService.resolveMrConflicts(workspaceId, sourceBranch, targetBranch, commitId, commitMessage, files);
|
||||
// 反过来合并
|
||||
gitService.mergeBranch(workspaceId, targetBranch, sourceBranch, commitMessage, files);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,7 +242,7 @@ public class ApplicationMergeServiceImpl extends ServiceImpl<ApplicationMergeDao
|
||||
|
||||
// merge
|
||||
try {
|
||||
String commitId = gitService.mergeBranch(workspaceId, srcBranch, tgtBranch, message);
|
||||
String commitId = gitService.mergeBranch(workspaceId, srcBranch, tgtBranch, message, null);
|
||||
entity.setCommitId(commitId);
|
||||
entity.setStatus(MergeRequestStatus.MERGED.toString());
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -46,7 +46,9 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@@ -107,6 +109,7 @@ public class GitServiceImpl implements IGitService {
|
||||
/**
|
||||
* get git instance
|
||||
*/
|
||||
@Override
|
||||
public Git getGitInstance(String workspaceId) {
|
||||
File repoDir = this.getRepoDirPath(workspaceId);
|
||||
try {
|
||||
@@ -436,7 +439,7 @@ public class GitServiceImpl implements IGitService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mergeBranch(String workspaceId, String srcBranch, String tgtBranch, String message) throws RuntimeException {
|
||||
public String mergeBranch(String workspaceId, String srcBranch, String tgtBranch, String message, List<Map<String, String>> resolveConflictFileContent) throws RuntimeException {
|
||||
log.info("[mergeBranch] [begin] [workspaceId: {}] [srcBranch: {}] [tgtBranch: {}]", workspaceId, srcBranch, tgtBranch);
|
||||
// prepare a new folder for the cloned repository
|
||||
File localPath = T.FileUtil.file(net.geedge.asw.common.util.Constants.TEMP_PATH, T.StrUtil.uuid());
|
||||
@@ -475,29 +478,51 @@ public class GitServiceImpl implements IGitService {
|
||||
.call();
|
||||
|
||||
MergeResult.MergeStatus mergeStatus = mergeResult.getMergeStatus();
|
||||
if (mergeStatus.isSuccessful()) {
|
||||
log.info("[mergeBranch] [merge success]");
|
||||
|
||||
// push
|
||||
Iterable<PushResult> pushResultIterable = git.push()
|
||||
.setRemote("origin")
|
||||
.add(tgtBranch)
|
||||
.call();
|
||||
for (PushResult pushResult : pushResultIterable) {
|
||||
for (RemoteRefUpdate update : pushResult.getRemoteUpdates()) {
|
||||
if (update.getStatus() != RemoteRefUpdate.Status.OK && update.getStatus() != RemoteRefUpdate.Status.UP_TO_DATE) {
|
||||
log.error("[mergeBranch] [push error] [remote: {}] [status: {}]", update.getRemoteName(), update.getStatus());
|
||||
String errorMessage = "Push failed: " + update.getStatus();
|
||||
throw new RuntimeException(errorMessage);
|
||||
log.info("[mergeBranch] [merge status: {}]", mergeStatus);
|
||||
if (!mergeStatus.isSuccessful()) {
|
||||
// 解决冲突
|
||||
if (mergeStatus == MergeResult.MergeStatus.CONFLICTING && T.CollUtil.isNotEmpty(resolveConflictFileContent)) {
|
||||
Map<String, int[][]> conflicts = mergeResult.getConflicts();
|
||||
for (Map.Entry<String, int[][]> entry : conflicts.entrySet()) {
|
||||
String conflictFilePath = entry.getKey();
|
||||
Map<String, String> map = resolveConflictFileContent.stream()
|
||||
.filter(m -> T.StrUtil.equals(conflictFilePath, T.MapUtil.getStr(m, "path")))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (null != map) {
|
||||
Path filePath = Paths.get(localPath.getAbsolutePath(), conflictFilePath);
|
||||
Files.write(filePath, T.MapUtil.getStr(map, "content").getBytes(StandardCharsets.UTF_8));
|
||||
git.add().addFilepattern(conflictFilePath).call();
|
||||
}
|
||||
}
|
||||
git.commit().setMessage(message).call();
|
||||
} else {
|
||||
// 其他类型的合并错误,抛出异常
|
||||
String errorMessage = String.format("Merge failed: %s, Conflicts: %s", mergeStatus, mergeResult.getConflicts());
|
||||
throw new RuntimeException(errorMessage);
|
||||
}
|
||||
return mergeResult.getNewHead().getName();
|
||||
} else {
|
||||
log.error("[mergeBranch] [merge failed] [mergeStatus: {}] [conflict: {}]", mergeStatus, T.JSONUtil.toJsonStr(mergeResult.getConflicts()));
|
||||
String errorMessage = String.format("Merge failed: %s, Conflicts: %s", mergeStatus, T.JSONUtil.toJsonStr(mergeResult.getConflicts()));
|
||||
throw new RuntimeException(errorMessage);
|
||||
}
|
||||
|
||||
// push
|
||||
Iterable<PushResult> pushResultIterable = git.push()
|
||||
.setRemote("origin")
|
||||
.add(tgtBranch)
|
||||
.call();
|
||||
for (PushResult pushResult : pushResultIterable) {
|
||||
for (RemoteRefUpdate update : pushResult.getRemoteUpdates()) {
|
||||
if (update.getStatus() != RemoteRefUpdate.Status.OK && update.getStatus() != RemoteRefUpdate.Status.UP_TO_DATE) {
|
||||
log.error("[mergeBranch] [push error] [remote: {}] [status: {}]", update.getRemoteName(), update.getStatus());
|
||||
String errorMessage = "Push failed: " + update.getStatus();
|
||||
throw new RuntimeException(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null != mergeResult.getNewHead()) {
|
||||
return mergeResult.getNewHead().getName();
|
||||
}
|
||||
// 解决冲突合并的情况下无法从 mergeResult 中获取提交信息,查询最新提交信息返回
|
||||
return this.getLatestCommitId(workspaceId, srcBranch);
|
||||
} catch (Exception e) {
|
||||
log.error(e, "[mergeBranch] [error] [workspaceId: {}]", workspaceId);
|
||||
throw new RuntimeException(e.getMessage());
|
||||
@@ -1072,7 +1097,8 @@ public class GitServiceImpl implements IGitService {
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
private ObjectId insertBlobFileToDatabase(Repository repository, byte[] data) throws IOException {
|
||||
@Override
|
||||
public ObjectId insertBlobFileToDatabase(Repository repository, byte[] data) throws IOException {
|
||||
try (ObjectInserter inserter = repository.getObjectDatabase().newInserter()) {
|
||||
ObjectId blobId = inserter.insert(Constants.OBJ_BLOB, data);
|
||||
inserter.flush();
|
||||
@@ -1201,58 +1227,58 @@ public class GitServiceImpl implements IGitService {
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
// @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
|
||||
@@ -1326,6 +1352,7 @@ public class GitServiceImpl implements IGitService {
|
||||
* @throws IOException
|
||||
* @throws ConcurrentRefUpdateException
|
||||
*/
|
||||
@Override
|
||||
public boolean commitIndex(Repository repo, String branch, DirCache index, ObjectId parentId1, ObjectId parentId2, String message) throws IOException, ConcurrentRefUpdateException {
|
||||
boolean success = false;
|
||||
try (ObjectInserter odi = repo.newObjectInserter()) {
|
||||
|
||||
Reference in New Issue
Block a user