DevOps系列文章 之 Java使用jgit管理git仓库

最近设计基于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引入:

        <!-- jgit --><dependency><groupId>org.eclipse.jgit</groupId><artifactId>org.eclipse.jgit</artifactId><version>5.8.0.202006091008-r</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency>

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<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

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()lRepository repository = getRepositoryFromDir("D:\\\\SoftwareDev\\\\Code\\\\auto-cicd-store\\\\git-res");List<String> 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<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;}}

读取已有仓库的日志:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/15728.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用黑盒测试在 Go 中重写 Bash 脚本

目录 前言&#xff1a; 开始 准备工作 描述行为&#xff1a;Bats 简介 行为描述&#xff1a;陷阱 描述行为&#xff1a;设计测试 重写&#xff1a;让我们开始用go吧&#xff01; 重构和更新&#xff1a;实现胜利 结论 前言&#xff1a; 使用黑盒测试在Go中重写Bash脚本…

百度--搜索引擎是怎么实现的--如何制作一个搜索浏览器

1.搜索引擎是怎么实现的&#xff1f; 搜索引擎是通过以下步骤实现的&#xff1a; 网页抓取&#xff08;Crawling&#xff09;&#xff1a;搜索引擎会使用网络爬虫&#xff08;Web Crawler&#xff09;自动地从互联网上抓取网页内容。爬虫按照一定的规则遍历网页并提取网页内容…

做题遇见的PHP函数汇总

mb_substr函数 mb_substr() 函数返回字符串的一部分&#xff0c;之前学过 substr() 函数&#xff0c;它只针对英文字符&#xff0c;如果要分割的中文文字则需要使用 mb_substr() 语法&#xff1a; mb_substr ( $str ,$start [, $length NULL [, $encoding mb_encoding() ]] …

docker中运行RabbitMq的启用插件指南

我们使用 Docker 来运行 RabbitMQ&#xff0c;有时需要启用一些插件&#xff0c;这个与正常安装的启用插件的步骤会有所不同。以下是在 Docker 中启用 RabbitMQ 插件的一般步骤&#xff1a; 首先&#xff0c;确认已经将 rabbitmq_delayed_message_exchange-3.12.0.ez 插件文件复…

adb: failed to install .\xxxxxx.apk: Failure [INSTALL_FAILED_USER_RESTRICTED

开发者模式和USB调试均已打开&#xff0c;adb安装时报错。看了一下&#xff0c;小米手机还需要开启USB安装才行。 问题已解决

《永劫无间》免费!《永劫无间》配置要求如何?

《永劫无间》于2021年7月8日开启不删档测试&#xff0c;8月12日在Steam全球公测&#xff0c;终于赶在两周年&#xff0c;2023年7月14日的炎炎夏日转为免费游戏。在《永劫无间》中&#xff0c;玩家可以选择不同的英雄&#xff0c;每个英雄都有独特的技能和风格&#xff0c;通过搜…

深入解析Redis的LRU与LFU算法实现

作者&#xff1a;vivo 互联网服务器团队 - Luo Jianxin 重点介绍了Redis的LRU与LFU算法实现&#xff0c;并分析总结了两种算法的实现效果以及存在的问题。 一、前言 Redis是一款基于内存的高性能NoSQL数据库&#xff0c;数据都缓存在内存里&#xff0c; 这使得Redis可以每秒轻…

【Python】Python项目打包发布(五)(制作Windows安装包)

Python项目打包发布汇总 【Python】Python项目打包发布&#xff08;一&#xff09;&#xff08;基于Pyinstaller打包多目录项目&#xff09; 【Python】Python项目打包发布&#xff08;二&#xff09;&#xff08;基于Pyinstaller打包PyWebIO项目&#xff09; 【Python】Pytho…

视图与索引的详细用法

视图与索引的详细用法 1.视图的主要作用包括&#xff1a;1.简化查询&#xff1a;2.数据安全性&#xff1a;3.数据抽象&#xff1a; 2.索引简介1.索引的作用主要有以下几个方面&#xff1a;1.快速定位数&#xff1a;2. 提高查询性能3.加速排序和连接操作4.维护数据完整性 3.索引…

从0开始学架构-架构的定义

从0开始学架构-架构的定义 文章目录 从0开始学架构-架构的定义系统与子系统模块与组件框架与架构软件框架&#xff08;Software framework&#xff09;软件架构区别 重新定义架构&#xff1a;4R 架构软件架构重新定义 三组容易混淆的概念&#xff1a; 系统与子系统模块与组件框…

机器学习算法之决策树(decision tree)

1 决策树算法介绍 决策树(Decision Tree,又称为判定树)算法是机器学习中常见的一类算法&#xff0c;是一种以树结构形式表达的预测分析模型。决策树属于监督学习&#xff08;Supervised learning&#xff09;&#xff0c;根据处理数据类型的不同&#xff0c;决策树又为分类决策…

在 Jetpack Compose 中使用 BottomAppBar

简介 Jetpack Compose 是一个现代化的、声明式的 UI 工具包&#xff0c;它使我们能够更方便地构建 Android 的用户界面。本篇文章将介绍如何在 Jetpack Compose 中使用 BottomAppBar 来创建底部应用栏。 什么是 BottomAppBar? BottomAppBar 是一个在屏幕底部的应用栏&#x…