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

news2024/11/17 19:34:39

最近设计基于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()l

        Repository 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.coloradmin.cn/o/730225.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

查看自己所有的工程提交次数

git branch -r --contains [ hash index] 远程仓库是否包含当前的提交 我写的注释什么的很少出现 日期的英文, 所以很好统计 #!/bin/bashCOUNTS0 DATE$(date | awk {print $2}) DIRS$(ls) CHECK_URLgit10.0.128.128:sw/ INDEX0 TODAY$(date | awk {printf "%s %s %s"…

Nginx代理nginx.conf配置——反向代理(对WebSocket支持)

一、需求说明 基于Nginx代理nginx.conf配置——反向代理&#xff0c;如果要添加websocket支持&#xff0c;需要进行如下配置 二、配置内容 在http中添加一下配置&#xff0c;添加对websocket支持 http {# 配置其它内容map $http_upgrade $connection_upgrade {default upgra…

国赛试题解析1:SW3模拟办事处与防火墙之间运行OSPFv2协议

试题内容:(4)SW3模拟办事处产品和营销接口配置为loopback,模拟接口up。SW3模拟办事处与FW2之间运行OSPFv2协议,进程2,区域2,SW3模拟办事处发布loopback2、产品和营销。 SW3模拟 办事处 loopback2 10.1.3.2/32 2001:10:1:3::2/128 vlan110(产品) 10.1.110.1/24

【教学类-36-07】对称蝴蝶(midjounery-niji)(涂色、裁剪、游戏(飞舞的蝴蝶))

作品展示 一、利用midjounery获得简笔画样式的“蝴蝶” Animal Mask , simple stroke, cartoon, black and white outline, uncolored NIJI 5 二、图片切割 用以下代码把上面文件夹里所有的2048*2048的单张图片切割程2*2 # 参考网址&#xff1a;https://blog.csdn.net/weixi…

2023年计算机科学与信息技术国际会议(ECCSIT 2023) | Ei Scopus双检索

会议简介 Brief Introduction 2023年计算机科学与信息技术国际会议(ECCSIT 2023) 会议时间&#xff1a;2023年12月15日-17日 召开地点&#xff1a;中国北海 大会官网&#xff1a;www.eccsit.org 2023年计算机科学与信息技术国际会议(ECCSIT 2023)由西南交通大学、西南财经大学、…

使用easyexcel出现的错误

说明&#xff1a;easyexcel&#xff08;官网&#xff1a;https://easyexcel.opensource.alibaba.com/&#xff09;是阿里巴巴提供的&#xff0c;用于项目中读取/导出excel文件的工具&#xff0c;本文介绍使用easyexcel常见的两种错误。 错误一&#xff1a;java.lang.NoSuchMet…

代谢组学分析 PCA PLS-DA OPLS-DA 在R语言中的实现

主成分分析&#xff08;Principal Component Analysis&#xff0c;PCA&#xff09;是一种无监督降维方法&#xff0c;能够有效对高维数据进行处理。但PCA对相关性较小的变量不敏感&#xff0c;而PLS-DA&#xff08;Partial Least Squares-Discriminant Analysis&#xff0c;偏最…

el-table 添加合计,合计某一列

效果图&#xff1a; 1. 使用elementui 官网上的方法 如果是只要是数值&#xff0c;就要合并&#xff0c;就只设置show-summary 即可。 2. html&#xff1a; <!--cell-style 改变某一列行的背景色 --><!-- tree-props 配置树形子表row-click: 单击事件highlight-cu…

node修改版本、npm修改版本、yarn无法加载文件、node_modules\sharp: Command failed解决方法

1、node修改版本 步骤1&#xff1a;从node官网下载node压缩包或者exe文件 如果是下载的是exe文件就直接找到原来的node.exe文件替换掉就可以了&#xff0c;环境变量配置不变 如果是下载的node压缩包&#xff0c;需要解压后&#xff0c;修改本地的环境变量配置&#xff08;查看步…

微服务实例构建成 docker 镜像实例

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

抖音seo源码部署搭建--代码分享

一、 开发环境搭建 抖音SEO源码部署环境搭建可以分为以下几个步骤&#xff1a; 安装必要的软件和工具&#xff1a;需要安装Node.js、NPM、Git等软件和工具&#xff0c;具体安装方法可以参考官方文档。 下载源码&#xff1a;从GitHub或其他源码托管平台下载抖音SEO源码。 安装…

SpringBoot 配置文件:什么时配置文件?配置文件能干什么?

文章目录 &#x1f387;前言1.配置文件的格式2. properties配置文件说明2.1 properties基本语法2.2 读取配置文件 3. yml 配置文件说明3.1 yml 基本语法 4.properties与yml 对比 &#x1f387;前言 学习一个东西&#xff0c;我们先要知道它有什么用处。整个项目中所有重要的数…

Vscode 绿色系清新主题

炎炎夏日&#xff0c;上班上的心浮气躁&#xff0c;敲代码的时候&#xff0c;只觉昏昏沉沉&#xff0c;浑浑噩噩... 给vscode换一个一个清新美好的绿色主题&#xff0c;充满活力和希望吧。 朋友们&#xff0c;收藏起来&#xff0c;每个季节换一个主题&#xff0c;打工快乐&am…

[工业互联-14]:机器人操作系统与ROS

目录 第1章 简介 第2章 历史 第3章 特点 &#xff08;1&#xff09;点对点设计 &#xff08;2&#xff09;不依赖编程语言 &#xff08;3&#xff09;精简与集成 &#xff08;4&#xff09;便于测试 &#xff08;5&#xff09;开源 &#xff08;6&#xff09;强大的库及…

LVS-DR负载群集的优势和部署实例

目录 一、DR模式数据包流向分析 二、DR模式的特点 三、DR模式中需要解决的问题 四、LVS-DR部署实例 1.配置NFS共享存储器 2.配置节点web服务&#xff08;两台的配置相同&#xff09; 3.配置LVS负载调度器 一、DR模式数据包流向分析 1.Client 客户端发送请求到 Director …

OpenCV库实现了一个简单的图像放缩工具

这里是详细的代码解析: #include <opencv2/opencv.hpp> // 引入OpenCV主要库。 #include <opencv2/highgui/highgui.hpp> // 引入高级GUI模块,它包含用于显示图像和获取用户输入的函数。 #include <opencv2/imgproc/imgproc.hpp> // 引入图像处理模块,它…

mysql数据类型char和varchar的区别

&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389;&#x1f389;&#x1f389;&#x1f389;&…

如何将Windows的文件存储到铁威马NAS里?

总是能听到小伙伴问&#xff0c;有没有办法可以省去登入TOS的操作就可以直接存取铁威马NAS上的文件及资料呢&#xff1f;很简单&#xff0c;其实只要将NAS的共享文件夹映射到Windows的网络驱动器&#xff0c;就饿可以让我们节省登入TOS的操作直接存取TNAS的文件&#xff0c;编辑…

如何打造工程师文化?

目录 一、打造工程师文化的步骤&#xff1a;二、成功案例&#xff1a;三、失败案例及教训&#xff1a; 打造工程师文化是一个复杂而又关键的任务&#xff0c;它需要公司在组织结构、价值观、领导风格以及员工福利等方面做出全面的调整。下面是一个针对打造工程师文化的详细步骤…

[mj_robot_sim]多关节机器人仿真软件介绍

全称&#xff1a;Multi-Joints Robot Simulator 代码地址&#xff1a;https://github.com/Jelatine/mj_robot_sim 设计目的 个人学习opengl的技术落地尝试设计一个跨平台、轻量级的机器人仿真软件&#xff0c;方便调试机器人 特性 轻量级&#xff0c;接口简单易用跨平台&…