Jgit

Jgit 提供了一些方法可以让java连接git远程仓库进行获取信息,操作的一个插件,maven直接导入使用了

GitOperation

提供方法获取jgit实例

public class GitOperation {

    private static final String DEFAULT_BRANCH = "test";

    private final TransportConfigCallback transportConfigCallback;

    public GitOperation(TransportConfigCallback transportConfigCallback) {
        this.transportConfigCallback = transportConfigCallback;
    }

    public GitInstance cloneRepo(String repoUrl, Long requestId) {
        File path = new File(String.format("workspace/deploy/%s", requestId));

        return cloneRepo(repoUrl, path);
    }

    private GitInstance cloneRepo(String repoUrl, File repoPath) {
        try {
            Git git;
            if (!repoPath.exists()) {
                git = Git.cloneRepository()
                        .setURI(repoUrl)
                        .setBranch(DEFAULT_BRANCH)
                        .setDirectory(repoPath)
                        .setTransportConfigCallback(transportConfigCallback)
                        .call();
            } else {
                git = Git.open(repoPath);
            }
            return new GitInstance(git, repoUrl, transportConfigCallback);
        } catch (GitAPIException | IOException ex) {
            throw new IllegalStateException("克隆仓库失败", ex);
        }
    }

    public boolean existBranch(String branch, String repoUrl) {
        try {
            Collection<Ref> refs = Git.lsRemoteRepository()
                    .setRemote(repoUrl)
                    .setTransportConfigCallback(transportConfigCallback)
                    .call();
            return refs.stream().anyMatch(it -> it.getName().contains(branch));
        } catch (GitAPIException exception) {
            throw new NotFoundAppException("查找所有分支失败");
        }
    }
}

GitInstance

提供git的基本操作

public class GitInstance implements Closeable {

    private final Git git;
    private final String repoUrl;
    private final TransportConfigCallback transportConfigCallback;

    public GitInstance(Git git, String repoUrl, TransportConfigCallback transportConfigCallback) {
        this.git = git;
        this.repoUrl = repoUrl;
        this.transportConfigCallback = transportConfigCallback;
    }

    public String getRepoUrl() {
        return repoUrl;
    }

    public File getWorkTree() {
        return git.getRepository().getWorkTree();
    }

    public RevCommit commit(String message) {
        try {
            return git.commit()
                    .setMessage(message)
                    .setAll(true)
                    .call();
        } catch (GitAPIException ex) {
            throw new IllegalStateException("git commit failed", ex);
        }
    }

    public void merge(String name) {
        try {
            ObjectId ref = git.getRepository().resolve(name);
            git.merge()
                    .include(ref)
                    .setStrategy(MergeStrategy.THEIRS)
                    .call();
        } catch (GitAPIException | IOException ex) {
            throw new IllegalStateException("git merge failed", ex);
        }
    }

    public void pull(String name) {
        try {
            git.pull()
                    .setRemote("origin")
                    .setRemoteBranchName(name)
                    .setStrategy(MergeStrategy.THEIRS)
                    .setTransportConfigCallback(transportConfigCallback)
                    .call();
        } catch (GitAPIException ex) {
            throw new IllegalStateException("git pull failed", ex);
        }
    }

    public void branchCreate(String name) {
        try {
            git.checkout()
                    .setName(name)
                    .setCreateBranch(true)
                    .call();
        } catch (GitAPIException ex) {
            throw new IllegalStateException("git branch create failed", ex);
        }
    }

    public void add(String filePattern) {
        try {
            git.add()
                    .addFilepattern(filePattern)
                    .call();
        } catch (GitAPIException ex) {
            throw new IllegalStateException("git add failed", ex);
        }
    }

    public void addAll() {
        add(".");
    }

    public void tag(String name) {
        try {
            git.tag()
                    .setName(name)
                    .call();
        } catch (GitAPIException ex) {
            throw new IllegalStateException("git tag failed", ex);
        }
    }

    public void push() {
        try {
            git.push()
                    .setPushAll()
                    .setTransportConfigCallback(transportConfigCallback)
                    .call();
        } catch (GitAPIException ex) {
            throw new IllegalStateException("git push failed", ex);
        }
    }

    public void checkout(String branchName) {
        try {
            git.checkout()
                    .setName(branchName)
                    .call();
        } catch (GitAPIException ex) {
            throw new IllegalStateException("git checkout branch failed", ex);
        }
    }

    public void checkoutRemote(String name) {
        try {
            git.checkout()
                    .setName(name)
                    .setStartPoint("origin/" + name)
                    .setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
                    .setCreateBranch(true)
                    .call();
        } catch (GitAPIException ex) {
            throw new IllegalStateException("git checkout remote branch failed", ex);
        }
    }

    public List<String> getAllBranch() {
        List<String> branchList = new ArrayList<>();
        try {
            List<Ref> call = git.branchList().setListMode(ListBranchCommand.ListMode.REMOTE).call();
            for (Ref ref : call) {
                String branchName = ref.getName();
                int index = branchName.lastIndexOf("/");
                branchList.add(branchName.substring(index + 1));
            }
        } catch (GitAPIException ex) {
            throw new IllegalStateException("failed to get all the branch", ex);
        }
        return branchList;
    }

    public List<String> getFileCommitLog(String file) {
        List<String> commitIdList = new ArrayList<>();
        try {
            Iterable<RevCommit> call = git.log().addPath(file).call();
            for (RevCommit revCommit : call) {
                String[] split = revCommit.getId().toString().split(" ");
                String commitId = split[1].substring(0, 8);
                commitIdList.add(commitId);
            }
            return commitIdList;
        } catch (GitAPIException ex) {
            throw new IllegalStateException("failed to get branch", ex);
        }
    }

    @Override
    public void close() {
        git.close();
    }

    public Repository getRepository() {
        return git.getRepository();
    }
}

获取某一次提交的内容(某个提交ID)

public String getDataSql(String commitId, String path, GitInstance git) {
        try {
            Repository repository = git.getRepository();
            // 根据所需要查询的版本号查新ObjectId
            ObjectId objId = repository.resolve(commitId);
            RevWalk walk = new RevWalk(repository);
            RevCommit revCommit = walk.parseCommit(objId);
            RevTree revTree = revCommit.getTree();
            TreeWalk treeWalk = TreeWalk.forPath(repository, path, revTree);
            ObjectId blobId = treeWalk.getObjectId(0);
            ObjectLoader loader = repository.open(blobId);
            byte[] bytes = loader.getBytes();
            String sql = "";
            if (bytes.length > 0) {
                sql = new String(bytes);
            }
            return sql;
        } catch (Exception exception) {
            throw new RuntimeException(exception);
        }
    }

获取所有所有分支提交信息

页面上有分页,只能手写一个分页

if (gitOperation.existBranch(branch, model.getRepoUrl())) {
  try {
    gitInstance.checkout(branch);
  } catch (Exception ex) {
    gitInstance.checkoutRemote(branch);
  }
  Repository repository = gitInstance.getRepository();
  try (RevWalk revWalk = new RevWalk(repository)) {
    Ref head = repository.findRef("refs/heads/" + branch);
    revWalk.markStart(revWalk.parseCommit(head.getObjectId()));
    for (RevCommit revCommit : revWalk) {
      //if (commitModelList.size() == paginatedParam.getSize() * paginatedParam.getIndex()) break;
      PersonIdent authorIdent = revCommit.getAuthorIdent();
      String commitUser = authorIdent.getName();
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      String date = sdf.format(authorIdent.getWhen());
      String message = revCommit.getFullMessage();
      String commitId = revCommit.getId().toString();
      commitModelList.add(new CommitModel(date, commitUser, message, commitId));
    }
    revWalk.dispose();
    //Collections.reverse(commitModelList);
    return Result.success(new HashMap<String, Object>() {
      {
        put("resultList", commitModelList.stream().skip((long) (paginatedParam.getIndex() - 1) * paginatedParam.getSize()).limit(paginatedParam.getSize()).collect(Collectors.toList()));
        put("count", commitModelList.size());
      }
    });
  } catch (IOException e) {
    throw new UnsupportedOperationException("未知异常,请联系管理员");
  }
}

切换分支

首先本地切换分支,如果本地分支没有就会报错,直接catch然后切换线上分支即可

try {
    gitInstance.checkout(buildModel.getBranch());
} catch (Exception e) {
    gitInstance.checkoutRemote(buildModel.getBranch());
}

获取某个文件的提交记录

获取某个文件的提交记录,在这个项目里遇到个问题,有的文件的提交记录不在这个文件提交记录列表中

 public List<String> getFileCommitLog(String file) {
        List<String> commitIdList = new ArrayList<>();
        try {
            Iterable<RevCommit> call = git.log().addPath(file).call();
            for (RevCommit revCommit : call) {
                String[] split = revCommit.getId().toString().split(" ");
                String commitId = split[1].substring(0, 8);
                commitIdList.add(commitId);
            }
            return commitIdList;
        } catch (GitAPIException ex) {
            throw new IllegalStateException("failed to get branch", ex);
        }
    }

获取所有的分支

public List<String> getAllBranch() {
    List<String> branchList = new ArrayList<>();
    try {
        List<Ref> call = git.branchList().setListMode(ListBranchCommand.ListMode.REMOTE).call();
        for (Ref ref : call) {
            String branchName = ref.getName();
            int index = branchName.lastIndexOf("/");
            branchList.add(branchName.substring(index + 1));
        }
    } catch (GitAPIException ex) {
        throw new IllegalStateException("failed to get all the branch", ex);
    }
    return branchList;
}

其他的基本方法

public RevCommit commit(String message) {
    try {
        return git.commit()
                .setMessage(message)
                .setAll(true)
                .call();
    } catch (GitAPIException ex) {
        throw new IllegalStateException("git commit failed", ex);
    }
}

public void merge(String name) {
    try {
        ObjectId ref = git.getRepository().resolve(name);
        git.merge()
                .include(ref)
                .setStrategy(MergeStrategy.THEIRS)
                .call();
    } catch (GitAPIException | IOException ex) {
        throw new IllegalStateException("git merge failed", ex);
    }
}

public void pull(String name) {
    try {
        git.pull()
                .setRemote("origin")
                .setRemoteBranchName(name)
                .setStrategy(MergeStrategy.THEIRS)
                .setTransportConfigCallback(transportConfigCallback)
                .call();
    } catch (GitAPIException ex) {
        throw new IllegalStateException("git pull failed", ex);
    }
}

public void branchCreate(String name) {
    try {
        git.checkout()
                .setName(name)
                .setCreateBranch(true)
                .call();
    } catch (GitAPIException ex) {
        throw new IllegalStateException("git branch create failed", ex);
    }
}

public void add(String filePattern) {
    try {
        git.add()
                .addFilepattern(filePattern)
                .call();
    } catch (GitAPIException ex) {
        throw new IllegalStateException("git add failed", ex);
    }
}

public void addAll() {
    add(".");
}

public void tag(String name) {
    try {
        git.tag()
                .setName(name)
                .call();
    } catch (GitAPIException ex) {
        throw new IllegalStateException("git tag failed", ex);
    }
}

public void push() {
    try {
        git.push()
                .setPushAll()
                .setTransportConfigCallback(transportConfigCallback)
                .call();
    } catch (GitAPIException ex) {
        throw new IllegalStateException("git push failed", ex);
    }
}