JAVA 使用jgit管理git仓库

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

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

引入jgit#

maven引入:

Copy
<!-- https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit --> <dependency> <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit</artifactId> <version>5.6.0.201912101111-r</version> </dependency>

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

凭证管理#

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

通过下面代码初始化:

Copy
public static CredentialsProvider createCredential(String userName, String password) { return new UsernamePasswordCredentialsProvider(userName, password); }

clone远程仓库#

git 命令:

Copy
git clone {repoUrl}

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

Copy
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 命令:

Copy
git commit -a -m '{msg}'

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

Copy
public static void commit(Git git, String message, CredentialsProvider provider) throws GitAPIException { git.add().addFilepattern(".").call(); git.commit() .setMessage(message) .call(); }

push#

git 命令:

Copy
git push origin branchName

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

Copy
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了,想直接读取,怎么办?

Copy
public static Repository getRepositoryFromDir(String dir) throws IOException { return new FileRepositoryBuilder() .setGitDir(Paths.get(dir, ".git").toFile()) .build(); }

读取仓库日志#

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

  • revWalk.parseCommit 可读取一条commit
  • 遍历revWalk,可读取所有日志
Copy
public static List<String> getLogs(Repository repository) throws IOException { return getLogsSinceCommit(repository, null, null); } public static List<String> getLogsSinceCommit(Repository repository, String commit) throws IOException { return getLogsSinceCommit(repository, null, commit); } public static List<String> getLogsSinceCommit(Repository repository, String branch, String commit) throws IOException { if (branch == null) { branch = repository.getBranch(); } Ref head = repository.findRef("refs/heads/" + branch); List<String> 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

Copy
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("http://gitlab.GITHOST.cn/datahub/env-test.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));

读取已有仓库的日志:

Copy
Repository repository = getRepositoryFromDir("GIT_DIR"); List<String> logs = getLogs(repository); System.out.println(logs); RevCommit head = getLastCommit(repository); System.out.println(head.getFullMessage());

小结#

本文讲述了如何通过jgit完成常规的git操作。


作者:Jadepeng
出处:jqpeng的技术记事本--http://www.cnblogs.com/xiaoqi
您的支持是对博主最大的鼓励,感谢您的认真阅读。
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

关注作者

欢迎关注作者微信公众号, 一起交流软件开发:欢迎关注作者微信公众号

posted @   JadePeng  阅读(9422)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示
CONTENTS