最近设计基于gitops新的CICD方案,需要通过java读写git仓库,这里简单记录下。

在jgit中,存在最核心的三个组件:Git类,Repository类。Git类中包含了push commit之类的常见git操作,而Repository则实现了仓库的初始化和基本的管理功能。 Git类的实例都会持有一个Repository实例。

Repository类的初始化

针对一个git仓库,我们一般会有三种方式获得 1.新建一个空仓库

Git git = Git.init().setDirectory(localPath).call()

2.加载一个已存在的仓库

Repository repository = builder.setGitDir(repoDir)

.readEnvironment() // scan environment GIT_* variables

.findGitDir() // scan up the file system tree

.build()

3.从远程仓库下载

Git result = Git.cloneRepository()

.setURI(REMOTE_URL)

.setDirectory(localPath)

.call()

JGit是一款pure java的软件包,可以读写git仓库,下面介绍基本使用。

引入jgit#

maven引入:

org.eclipse.jgit

org.eclipse.jgit

5.8.0.202006091008-r

commons-io

commons-io

2.6

jgit 有一个Git类,可以用来执行常规的git操作

凭证管理#

通过CredentialsProvider管理凭证,常用的是UsernamePasswordCredentialsProvider

通过下面代码初始化:

public static CredentialsProvider createCredential(String userName, String password) {

return new UsernamePasswordCredentialsProvider(userName, password);

}

clone远程仓库#

git 命令:

git clone {repoUrl}

通过Git.cloneRepository 来clone远程仓库,如果需要凭证,则需要指定credentialsProvider

public static Git fromCloneRepository(String repoUrl, String cloneDir, CredentialsProvider provider) throws GitAPIException {

Git git = Git.cloneRepository()

.setCredentialsProvider(provider)

.setURI(repoUrl)

.setDirectory(new File(cloneDir)).call();

return git;

}

commit#

git 命令:

git commit -a -m '{msg}'

commit比较简单,对应commit方法, 注意需要先add

public static void commit(Git git, String message, CredentialsProvider provider) throws GitAPIException {

git.add().addFilepattern(".").call();

git.commit()

.setMessage(message)

.call();

}

push#

git 命令:

git push origin branchName

push直接调用push即可, 需要指定credentialsProvider

public static void push(Git git, CredentialsProvider provider) throws GitAPIException, IOException {

push(git,null,provider);

}

public static void push(Git git, String branch, CredentialsProvider provider) throws GitAPIException, IOException {

if (branch == null) {

branch = git.getRepository().getBranch();

}

git.push()

.setCredentialsProvider(provider)

.setRemote("origin").setRefSpecs(new RefSpec(branch)).call();

}

读取已有仓库#

如果git已经clone了,想直接读取,怎么办?

public static Repository getRepositoryFromDir(String dir) throws IOException {

return new FileRepositoryBuilder()

.setGitDir(Paths.get(dir, ".git").toFile())

.build();

}

读取仓库日志#

可以通过RevWalk读取仓库日志。

revWalk.parseCommit 可读取一条commit遍历revWalk,可读取所有日志

public static List getLogs(Repository repository) throws IOException {

return getLogsSinceCommit(repository, null, null);

}

public static List getLogsSinceCommit(Repository repository, String commit) throws IOException {

return getLogsSinceCommit(repository, null, commit);

}

public static List getLogsSinceCommit(Repository repository, String branch, String commit) throws IOException {

if (branch == null) {

branch = repository.getBranch();

}

Ref head = repository.findRef("refs/heads/" + branch);

List commits = new ArrayList<>();

if (head != null) {

try (RevWalk revWalk = new RevWalk(repository)) {

revWalk.markStart(revWalk.parseCommit(head.getObjectId()));

for (RevCommit revCommit : revWalk) {

if (revCommit.getId().getName().equals(commit)) {

break;

}

commits.add(revCommit.getFullMessage());

System.out.println("\nCommit-Message: " + revCommit.getFullMessage());

}

revWalk.dispose();

}

}

return commits;

}

测试#

我们来先clone仓库,然后修改,最后push

package com.devops.autocicdstore.git;

import org.apache.commons.io.FileUtils;

import org.eclipse.jgit.api.Git;

import org.eclipse.jgit.api.errors.GitAPIException;

import org.eclipse.jgit.transport.CredentialsProvider;

import java.io.File;

import java.io.IOException;

import java.nio.file.Paths;

import static com.devops.autocicdstore.git.GetRepositoryMgr.*;

/**

* @Author 虎哥

* @Description //TODO

* |要带着问题去学习,多猜想多验证|

**/

public class TestMain {

public static void main(String[] args) throws GitAPIException, IOException {

String yaml = "dependencies:\n" +

"- name: springboot-rest-demo\n" +

" version: 0.0.5\n" +

" repository: http://hub.hubHOST.com/chartrepo/ainote\n" +

" alias: demo\n" +

"- name: exposecontroller\n" +

" version: 2.3.82\n" +

" repository: http://chartmuseum.jenkins-x.io\n" +

" alias: cleanup\n";

CredentialsProvider provider = createCredential("USR_NAME", "PASSWORD");

String cloneDir = "/tmp/test";

Git git = fromCloneRepository("https://gitee.com/JavaBigDataStudy/auto-cicd-store.git", cloneDir, provider);

// 修改文件

FileUtils.writeStringToFile(Paths.get(cloneDir, "env", "requirements.yaml").toFile(), yaml, "utf-8");

// 提交

commit(git, "deploy(app): deploy springboot-rest-demo:0.0.5 to env test", provider);

// push 到远程仓库

push(git, "master", provider);

git.clean().call();

git.close();

FileUtils.deleteDirectory(new File(cloneDir));

}

}

package com.devops.autocicdstore.git;

import org.eclipse.jgit.api.Git;

import org.eclipse.jgit.api.errors.GitAPIException;

import org.eclipse.jgit.lib.Ref;

import org.eclipse.jgit.lib.Repository;

import org.eclipse.jgit.revwalk.RevCommit;

import org.eclipse.jgit.revwalk.RevWalk;

import org.eclipse.jgit.storage.file.FileRepositoryBuilder;

import org.eclipse.jgit.transport.CredentialsProvider;

import org.eclipse.jgit.transport.RefSpec;

import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;

import java.io.File;

import java.io.IOException;

import java.nio.file.Paths;

import java.util.ArrayList;

import java.util.List;

/**

* @Author 虎哥

* @Description //TODO

* |要带着问题去学习,多猜想多验证|

**/

public class GetRepositoryMgr {

public static CredentialsProvider createCredential(String userName, String password) {

return new UsernamePasswordCredentialsProvider(userName, password);

}

public static void main(String[] args) throws GitAPIException, IOException {

// String localPath = "D:\\SoftwareDev\\Code\\auto-cicd-store\\git-res";

// String remotePath = "https://gitee.com/JavaBigDataStudy/auto-cicd-store.git";

// CredentialsProvider provider = createCredential("XXXX","XXX");

// //1

//

// Git git = fromCloneRepository(remotePath,localPath,provider);

// //2

// commit(git,"test",provider);

// //3

// push(git,"dev",provider);

// //4

// // getLogs()l

Repository repository = getRepositoryFromDir("D:\\\\SoftwareDev\\\\Code\\\\auto-cicd-store\\\\git-res");

List logs = getLogs(repository);

System.out.println(logs);

}

public static Git fromCloneRepository(String repoUrl, String cloneDir, CredentialsProvider provider) throws GitAPIException {

Git git = Git.cloneRepository()

.setCredentialsProvider(provider)

.setURI(repoUrl)

.setDirectory(new File(cloneDir)).call();

return git;

}

public static Repository getRepositoryFromDir(String dir) throws IOException {

return new FileRepositoryBuilder()

.setGitDir(Paths.get(dir, ".git").toFile())

.build();

}

public static void commit(Git git, String message, CredentialsProvider provider) throws GitAPIException {

git.add().addFilepattern(".").call();

git.commit()

.setMessage(message)

.call();

}

public static void push(Git git, CredentialsProvider provider) throws GitAPIException, IOException {

push(git,null,provider);

}

public static void push(Git git, String branch, CredentialsProvider provider) throws GitAPIException, IOException {

if (branch == null) {

branch = git.getRepository().getBranch();

}

git.push()

.setCredentialsProvider(provider)

.setRemote("origin").setRefSpecs(new RefSpec(branch)).call();

}

public static List getLogs(Repository repository) throws IOException {

return getLogsSinceCommit(repository, null, null);

}

public static List getLogsSinceCommit(Repository repository, String commit) throws IOException {

return getLogsSinceCommit(repository, null, commit);

}

public static List getLogsSinceCommit(Repository repository, String branch, String commit) throws IOException {

if (branch == null) {

branch = repository.getBranch();

}

Ref head = repository.findRef("refs/heads/" + branch);

List commits = new ArrayList<>();

if (head != null) {

try (RevWalk revWalk = new RevWalk(repository)) {

revWalk.markStart(revWalk.parseCommit(head.getObjectId()));

for (RevCommit revCommit : revWalk) {

if (revCommit.getId().getName().equals(commit)) {

break;

}

commits.add(revCommit.getFullMessage());

System.out.println("\nCommit-Message: " + revCommit.getFullMessage());

}

revWalk.dispose();

}

}

return commits;

}

}

读取已有仓库的日志:

Repository repository = getRepositoryFromDir("GIT_DIR");

List logs = getLogs(repository);

System.out.println(logs);

RevCommit head = getLastCommit(repository);

System.out.println(head.getFullMessage());

精彩文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。