summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pom.xml7
-rw-r--r--src/main/java/net/geedge/asw/module/app/controller/GitController.java52
-rw-r--r--src/main/java/net/geedge/asw/module/app/service/IGitService.java16
-rw-r--r--src/main/java/net/geedge/asw/module/app/service/impl/GitServiceImpl.java182
4 files changed, 257 insertions, 0 deletions
diff --git a/pom.xml b/pom.xml
index fedbab4..35bc7a9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -179,6 +179,13 @@
<version>2.12.0</version>
</dependency>
+ <!-- https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit -->
+ <dependency>
+ <groupId>org.eclipse.jgit</groupId>
+ <artifactId>org.eclipse.jgit</artifactId>
+ <version>7.0.0.202409031743-r</version>
+ </dependency>
+
</dependencies>
<build>
diff --git a/src/main/java/net/geedge/asw/module/app/controller/GitController.java b/src/main/java/net/geedge/asw/module/app/controller/GitController.java
new file mode 100644
index 0000000..a2719b9
--- /dev/null
+++ b/src/main/java/net/geedge/asw/module/app/controller/GitController.java
@@ -0,0 +1,52 @@
+package net.geedge.asw.module.app.controller;
+
+import net.geedge.asw.common.util.ASWException;
+import net.geedge.asw.common.util.R;
+import net.geedge.asw.common.util.RCode;
+import net.geedge.asw.common.util.T;
+import net.geedge.asw.module.app.service.IGitService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api/v1/workspace")
+public class GitController {
+
+ @Autowired
+ private IGitService gitService;
+
+ @GetMapping("/{workspaceId}/branch")
+ public R listBranch(@PathVariable("workspaceId") String workspaceId,
+ @RequestParam(value = "search", required = false) String search) {
+ List<Map<Object, Object>> list = gitService.listBranch(workspaceId, search);
+ return R.ok().putData("record", list);
+ }
+
+ @GetMapping("/{workspaceId}/branch/{branchName}")
+ public R infoBranch(@PathVariable("workspaceId") String workspaceId, @PathVariable("branchName") String branchName) {
+ Map<Object, Object> record = gitService.infoBranch(workspaceId, branchName);
+ return R.ok().putData("record", record);
+ }
+
+ @PostMapping("/{workspaceId}/branch")
+ public R newBranch(@PathVariable("workspaceId") String workspaceId, @RequestBody Map<String, String> requestBody) {
+ String branch = T.MapUtil.getStr(requestBody, "branch", "");
+ String ref = T.MapUtil.getStr(requestBody, "ref", "");
+ if (T.StrUtil.hasEmpty(branch, ref)) {
+ throw new ASWException(RCode.PARAM_CANNOT_EMPTY);
+ }
+
+ Map<Object, Object> record = gitService.newBranch(workspaceId, branch, ref);
+ return R.ok().putData("record", record);
+ }
+
+ @DeleteMapping("/{workspaceId}/branch/{branchName}")
+ public R deleteBranch(@PathVariable("workspaceId") String workspaceId, @PathVariable("branchName") String branchName) {
+ gitService.deleteBranch(workspaceId, branchName);
+ return R.ok();
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/net/geedge/asw/module/app/service/IGitService.java b/src/main/java/net/geedge/asw/module/app/service/IGitService.java
new file mode 100644
index 0000000..1ec819c
--- /dev/null
+++ b/src/main/java/net/geedge/asw/module/app/service/IGitService.java
@@ -0,0 +1,16 @@
+package net.geedge.asw.module.app.service;
+
+import java.util.List;
+import java.util.Map;
+
+public interface IGitService {
+
+ List<Map<Object, Object>> listBranch(String workspaceId, String search);
+
+ Map<Object, Object> infoBranch(String workspaceId, String branchName);
+
+ Map<Object, Object> newBranch(String workspaceId, String branchName, String ref);
+
+ void deleteBranch(String workspaceId, String branchName);
+
+}
diff --git a/src/main/java/net/geedge/asw/module/app/service/impl/GitServiceImpl.java b/src/main/java/net/geedge/asw/module/app/service/impl/GitServiceImpl.java
new file mode 100644
index 0000000..6110b96
--- /dev/null
+++ b/src/main/java/net/geedge/asw/module/app/service/impl/GitServiceImpl.java
@@ -0,0 +1,182 @@
+package net.geedge.asw.module.app.service.impl;
+
+import cn.hutool.log.Log;
+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.service.IGitService;
+import net.geedge.asw.module.workspace.entity.WorkspaceEntity;
+import net.geedge.asw.module.workspace.service.IWorkspaceService;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Service
+public class GitServiceImpl implements IGitService {
+
+ private final static Log log = Log.get();
+
+ /**
+ * 本地分支引用前缀
+ */
+ public static final String LOCAL_BRANCH_PREFIX = "refs/heads/";
+
+ @Autowired
+ private IWorkspaceService workspaceService;
+
+ /**
+ * get repository path
+ * path= {webRootPath}/workspeace/{workspace.name}
+ */
+ private File getRepoDirPath(String workspaceId) {
+ WorkspaceEntity workspace = workspaceService.getById(workspaceId);
+ File repoDir = T.FileUtil.file(T.WebPathUtil.getRootPath(), "workspeace", workspace.getName());
+ return repoDir;
+ }
+
+ /**
+ * get git instance
+ */
+ private Git getGitInstance(File repoDir) {
+ try {
+ if (T.FileUtil.exist(repoDir) && T.FileUtil.file(repoDir, ".git").exists()) {
+ log.info("[getGitInstance] [open exist repository] [path: {}]", repoDir);
+
+ FileRepositoryBuilder builder = new FileRepositoryBuilder();
+ builder.setGitDir(T.FileUtil.file(repoDir, ".git"));
+ builder.readEnvironment();
+ builder.findGitDir();
+
+ return new Git(builder.build());
+ } else {
+ log.info("[getGitInstance] [init new repository] [path: {}]", repoDir);
+ // init
+ Git git = Git.init().setDirectory(repoDir).call();
+ // config
+ StoredConfig config = git.getRepository().getConfig();
+ config.setString("user", null, "name", "asw");
+ config.setString("user", null, "email", "[email protected]");
+ config.save();
+ return git;
+ }
+ } catch (IOException | GitAPIException | IllegalStateException e) {
+ log.error(e, "[getGitInstance] [error] [path: {}]", repoDir);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public List<Map<Object, Object>> listBranch(String workspaceId, String search) {
+ List<Map<Object, Object>> resultList = T.ListUtil.list(true);
+
+ File repoDir = this.getRepoDirPath(workspaceId);
+ try (Git git = this.getGitInstance(repoDir)) {
+// List<Ref> call = git.branchList().setListMode(ListBranchCommand.ListMode.ALL).call();
+
+ // 默认行为,进查询本地分支
+ List<Ref> call = git.branchList().call();
+ RevWalk revCommits = new RevWalk(git.getRepository());
+
+ for (Ref ref : call) {
+ String branchName = ref.getName();
+ // 返回时去掉前缀
+ branchName = branchName.replaceAll(LOCAL_BRANCH_PREFIX, "");
+ if (T.StrUtil.isNotEmpty(search)) {
+ if (!T.StrUtil.contains(branchName, search)) {
+ continue;
+ }
+ }
+
+ Map<Object, Object> m = T.MapUtil.builder()
+ .put("name", branchName)
+ .build();
+
+ RevCommit commit = revCommits.parseCommit(ref.getObjectId());
+ List<String> parentIds = Arrays.stream(commit.getParents()).map(RevCommit::getName).collect(Collectors.toList());
+
+ Map<Object, Object> m1 = new LinkedHashMap<>();
+ m1.put("id", commit.getName());
+ m1.put("shortId", T.StrUtil.subPre(commit.getName(), 8));
+ m1.put("createdAt", commit.getCommitTime());
+
+ m1.put("title", commit.getShortMessage());
+ m1.put("message", commit.getFullMessage());
+ m1.put("parentIds", parentIds);
+
+ PersonIdent authorIdent = commit.getAuthorIdent();
+ m1.put("authorName", authorIdent.getName());
+ m1.put("authorEmail", authorIdent.getEmailAddress());
+ m1.put("authoredDate", authorIdent.getWhen().getTime());
+
+ PersonIdent committerIdent = commit.getCommitterIdent();
+ m1.put("committerName", committerIdent.getName());
+ m1.put("committerEmail", committerIdent.getEmailAddress());
+ m1.put("committedDate", committerIdent.getWhen().getTime());
+
+ m.put("commit", m1);
+ resultList.add(m);
+ }
+ } catch (GitAPIException | IOException e) {
+ log.error(e, "[listBranch] [error] [workspaceId: {}]", workspaceId);
+ throw new ASWException(RCode.ERROR);
+ }
+ return resultList;
+ }
+
+ @Override
+ public Map<Object, Object> infoBranch(String workspaceId, String branchName) {
+ List<Map<Object, Object>> listBranch = this.listBranch(workspaceId, branchName);
+
+ // 分支不存在
+ if (T.CollUtil.isEmpty(listBranch)) {
+ throw new ASWException(RCode.SYS_RECORD_NOT_FOUND);
+ }
+ return T.CollUtil.getFirst(listBranch);
+ }
+
+ @Override
+ public Map<Object, Object> newBranch(String workspaceId, String branchName, String ref) {
+ File repoDir = this.getRepoDirPath(workspaceId);
+ try (Git git = this.getGitInstance(repoDir)) {
+ git.branchCreate()
+ .setName(branchName)
+ .setStartPoint(ref)
+ .call();
+
+ return this.infoBranch(workspaceId, branchName);
+ } catch (GitAPIException e) {
+ log.error(e, "[newBranch] [error] [workspaceId: {}] [branchName: {}] [ref: {}]", workspaceId, branchName, ref);
+ throw new ASWException(RCode.ERROR);
+ }
+ }
+
+ @Override
+ public void deleteBranch(String workspaceId, String branchName) {
+ File repoDir = this.getRepoDirPath(workspaceId);
+ try (Git git = this.getGitInstance(repoDir)) {
+ git.branchDelete()
+ .setBranchNames(branchName)
+ .call();
+ } catch (GitAPIException e) {
+ log.error(e, "[deleteBranch] [error] [workspaceId: {}] [branchName: {}]", workspaceId, branchName);
+ throw new ASWException(RCode.ERROR);
+ }
+ }
+
+} \ No newline at end of file