原文:Jgit的使用笔记 - Stars-One的杂货小窝

之前整的一个系统,涉及到git代码的推送,是通过cmd命令去推送的,然后最近在产品验收的时候,测试部门随意填了个git仓库,然后导致仓库代码被覆盖了,还好本地留有备份,没出现啥大问题

然后就计划于是就改为使用Jgit库来实现推送代码的功能,本能够验证远程仓库是否有代码,如果有代码,则后台不会去推送

Jgit是eclipse的写的一个集合git操作的java库

本文主要是记录一下如何使用Jgit创建一个本地Git仓库并将代码推送到远程仓库,未涉及的操作可以参考下列罗列的参考链接

使用

1.引入依赖

<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>4.4.1.201607150455-r</version>
</dependency>

由于我是JDK8,所以还是使用的较低的版本

PS:注意高版本由于依赖的JDK版本也是高版本的,低版本的JDK环境可能引用后使用报错,所以各位看情况升级版本

Jgit其中重要的3个类:Git,Repository和Command类

Git对象包含一个Repository对象

而Command主要就是有各种关于Git的操作,如push,pull等

2.获取Git对象

首先,jgit中提供了Git的一个对象,后续的所有的相关add commit push等操作,都是通过此对象来实现的。

有三种方法可以获取Git对象:

1.通过初始化创建

File dirFile = new File("D:\\temp\\mygit");
Git git = Git.init(dirFile)
.setDirectory(dirFile)
.call();

如果mygit文件夹已经包含有了.git文件夹,需要使用下面第二个方法,如果是使用此方法会抛出一个异常

所以建议可以判断一下是否有.git文件夹从而执行不同的方法来获取Git对象

这里需要注意的是,Git.init()方法返回的是一个InitCommand对象,之后通过call()方法来执行命令得到Git对象

InitCommand这个从字眼上就可以看出,是用来实现初始化的的一个命令对象

InitCommand实际上是继承于TransportCommand类,后续的像pushpull等操作也是有其对应的command对象供我们使用,这里先暂时简单提一下。

2.打开已有的本地Git仓库

如果当前的本地文件夹已存在有.git的文件夹,可以通过open()来打开

File dirFile = new File("D:\\temp\\mygit")
Git open = Git.open(dirFile);

3.通过clone创建


String gitUserName = "";
String gitUserPwd = "";
CredentialsProvider provider = new UsernamePasswordCredentialsProvider(gitUserName, gitUserPwd); //生成身份信息 Git git = Git.cloneRepository()
.setBranch("main")
.setURI(templateProjectUrl) //设置git远端URL
.setDirectory(dirFile) //设置本地仓库位置
.setCredentialsProvider(provider) //设置身份验证
.call(); //启动命令

3.命令操作

添加命令

相当于git add .

AddCommand addCommand = git.add();

//将新文件纳入git管理,不含删除的文件
addCommand.addFilepattern(".").call();

提交命令

git.commit().setMessage("删除文件").call();

设置远程仓库地址

如果获取Git对象是通过初始化命令,则需要给Git对象设置远程仓库地址

RemoteSetUrlCommand remoteSetUrlCommand = git.remoteSetUrl();
String pushUrl = "https://git.linewellcloud.com/TJYR/TJ000003/SZYDYYYF/product/swan/test/gittest";
remoteSetUrlCommand.setUri(new URIish(pushUrl));
remoteSetUrlCommand.setName("origin");
remoteSetUrlCommand.call();

创建分支命令

推送需要传递一个本地分支,所以需要创建分支

需要判断下本地是否已有该分支了,有就不需要创建了


/**
* 获取对应分支
*
* @param git
* @param branchName
* @return
* @throws GitAPIException
*/
private Ref getMainRef(Git git, String branchName) throws GitAPIException {
//判断一下本地是否存在有main分支
List<Ref> refList = git.branchList().call();
String brancheNameStr = "refs/heads/" + branchName;
for (Ref ref : refList) {
if (ref.getName().equals(brancheNameStr)) {
return ref;
}
}
return git.branchCreate().setName(branchName).call();
}

推送命令

推送需要本地分支的信息及对应的用户凭证信息

Ref mainRef = getMainRef(git, "main");
//push命令调用call方法后可以得到推送结果
Iterable<PushResult> origin = git.push().add(mainRef).setRemote("origin").setCredentialsProvider(provider).call();
for (PushResult pushResult : origin) {
Collection<RemoteRefUpdate> remoteUpdates = pushResult.getRemoteUpdates();
for (RemoteRefUpdate remoteUpdate : remoteUpdates) {
RemoteRefUpdate.Status status = remoteUpdate.getStatus();
System.out.println(remoteUpdate.getRemoteName() + ": " + status.name());
}
}
//记得关闭
git.close();

示例

1.正常流程创建本地Git仓库并推送远程Git仓库

Git命令如下:

git clone https://git.linewellcloud.com/TJYR/TJ000003/SZYDYYYF/product/swan/test/gittest2.git
cd gittest2
touch README.md
git add README.md
git commit -m "add README"
git push -u origin main

Jgit代码:

public void testPush() throws GitAPIException, URISyntaxException {
//Git账号和密码
String gitUserName = "usernmae";
String gitUserPwd = "123456"; CredentialsProvider provider = new UsernamePasswordCredentialsProvider(gitUserName, gitUserPwd); //生成身份信息
//指定Git仓库克隆的本地文件夹
File dirFile = new File("D:\\temp\\gittest3"); //git远程仓库地址
String pushUrl = "https://git.linewellcloud.com/TJYR/TJ000003/SZYDYYYF/product/swan/test/te1111.git"; Git newGit = Git.cloneRepository()
.setDirectory(dirFile)
.setURI(pushUrl)
.setCredentialsProvider(provider)
.call();
//模拟在文件夹中添加代码文件
FileUtil.writeString("a text", FileUtil.file(dirFile, "my.txt"), Charsets.UTF_8); AddCommand addCommand = newGit.add(); //将新文件纳入git管理,不含删除的文件
addCommand.addFilepattern(".").call(); //将已删除的文件纳入git管理,不含新文件
//addCommand.addFilepattern(".").setUpdate(true).call(); newGit.commit().setMessage("提交操作").call(); Ref mainRef = getMainRef(newGit, "main"); //输出结果
Iterable<PushResult> origin = newGit.push().add(mainRef).setCredentialsProvider(provider).setRemote("origin").call();
for (PushResult pushResult : origin) {
Collection<RemoteRefUpdate> remoteUpdates = pushResult.getRemoteUpdates();
for (RemoteRefUpdate remoteUpdate : remoteUpdates) {
RemoteRefUpdate.Status status = remoteUpdate.getStatus();
System.out.println(remoteUpdate.getRemoteName() + ": " + status.name());
}
} newGit.close(); //关闭
} /**
* 判断本地仓库是否存在有某分支,如果没有则创建
*/
private Ref getMainRef(Git git, String branchName) throws GitAPIException { List<Ref> refList = git.branchList().call();
String brancheNameStr = "refs/heads/" + branchName;
for (Ref ref : refList) {
if (ref.getName().equals(brancheNameStr)) {
return ref;
}
}
return git.branchCreate().setName(branchName).call();
}

2.已有文件夹推送远程Git仓库

命令:

推送现有文件夹

cd existing_folder
git remote add origin https://git.linewellcloud.com/TJYR/TJ000003/SZYDYYYF/product/swan/test/gittest.git
git add .
git commit -m "Initial commit"
git push -u origin main

推送现有的 Git 仓库

cd existing_repo
git remote add origin https://git.linewellcloud.com/TJYR/TJ000003/SZYDYYYF/product/swan/test/gittest.git
git push -u origin main

Jgit代码:

public void testInitAndPush() throws GitAPIException, URISyntaxException, IOException {
//Git账号和密码
String gitUserName = "usernmae";
String gitUserPwd = "123456";
//git远程仓库地址
String pushUrl = "https://git.linewellcloud.com/TJYR/TJ000003/SZYDYYYF/product/swan/test/gittest.git";
CredentialsProvider provider = new UsernamePasswordCredentialsProvider(gitUserName, gitUserPwd); //生成身份信息 //本地已存在的文件夹
File dirFile = new File("D:\\temp\\gittest3"); //这里我是加了个判断条件
boolean flag = false;
File[] files = dirFile.listFiles();
for (File file : files) {
if (file.getName().equals(".git")) {
flag = true;
break;
}
}
Git git;
if (!flag) {
//如果文件夹还没有创建git仓库,则调用创建git本地仓库(推送现有文件夹)
git = Git.init().setDirectory(dirFile).call(); }else{
//如果已有git本地仓库,则直接打开(推送现有的 Git 仓库)
git = Git.open(dirFile);
} //设置远程仓库的地址
RemoteSetUrlCommand remoteSetUrlCommand = git.remoteSetUrl();
remoteSetUrlCommand.setUri(new URIish(pushUrl));
remoteSetUrlCommand.setName("origin");
remoteSetUrlCommand.call(); git.add().addFilepattern(".").call();
git.commit().setMessage("初次提交").call(); //判断一下本地是否存在有main分支
Ref mainRef = getMainRef(git, "main"); //输出结果
Iterable<PushResult> origin = git.push().add(mainRef).setCredentialsProvider(provider).setRemote("origin").call();
for (PushResult pushResult : origin) {
Collection<RemoteRefUpdate> remoteUpdates = pushResult.getRemoteUpdates();
for (RemoteRefUpdate remoteUpdate : remoteUpdates) {
RemoteRefUpdate.Status status = remoteUpdate.getStatus();
System.out.println(remoteUpdate.getRemoteName() + ": " + status.name());
}
} git.close();
} /**
* 判断本地仓库是否存在有某分支,如果没有则创建
*/
private Ref getMainRef(Git git, String branchName) throws GitAPIException { List<Ref> refList = git.branchList().call();
String brancheNameStr = "refs/heads/" + branchName;
for (Ref ref : refList) {
if (ref.getName().equals(brancheNameStr)) {
return ref;
}
}
return git.branchCreate().setName(branchName).call();
}

补充-判断远程仓库是否为空

public boolean isRemoteGitEmpty(String remoteUrl) throws GitAPIException {
String gitUserName = "wanxingxing";
String gitUserPwd = "13556710asd"; CredentialsProvider provider = new UsernamePasswordCredentialsProvider(gitUserName, gitUserPwd); //生成身份信息 Collection<Ref> call = Git.lsRemoteRepository().setRemote(remoteUrl).setCredentialsProvider(provider).call();
if (call.isEmpty()) {
return true;
} else {
for (Ref ref : call) {
System.out.println(ref.getName());
}
return false;
}
}

参考

Jgit的使用笔记的更多相关文章

  1. 《Apache kafka实战》读书笔记-kafka集群监控工具

    <Apache kafka实战>读书笔记-kafka集群监控工具 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 如官网所述,Kafka使用基于yammer metric ...

  2. git-简单流程(学习笔记)

    这是阅读廖雪峰的官方网站的笔记,用于自己以后回看 1.进入项目文件夹 初始化一个Git仓库,使用git init命令. 添加文件到Git仓库,分两步: 第一步,使用命令git add <file ...

  3. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  4. SQL Server技术内幕笔记合集

    SQL Server技术内幕笔记合集 发这一篇文章主要是方便大家找到我的笔记入口,方便大家o(∩_∩)o Microsoft SQL Server 6.5 技术内幕 笔记http://www.cnbl ...

  5. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  6. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  7. NET Core-学习笔记(三)

    这里将要和大家分享的是学习总结第三篇:首先感慨一下这周跟随netcore官网学习是遇到的一些问题: a.官网的英文版教程使用的部分nuget包和我当时安装的最新包版本不一致,所以没法按照教材上给出的列 ...

  8. springMVC学习笔记--知识点总结1

    以下是学习springmvc框架时的笔记整理: 结果跳转方式 1.设置ModelAndView,根据view的名称,和视图渲染器跳转到指定的页面. 比如jsp的视图渲染器是如下配置的: <!-- ...

  9. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  10. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

随机推荐

  1. docker -v 和Dockerfile 中VOLUME 区别

    在学习Dockerfile的过程中有个VOLUME命令,很多教程或书中说的是用来定义匿名卷的,其作用如下: 容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文 ...

  2. Docker 部署 Kibana

    Docker 部署 Kibana 本篇主要介绍 使用 Docker 部署 kibana 用于操作 Elasticsearch 使用. 1. 前置准备 1.1 Elasticsearch 准备 可以先准 ...

  3. python今日分享(内置方法)

    目录 一.习题详解 二.数据类型的内置方法理论 三.整型相关操作 四.浮点型相关操作 五.字符串相关操作 六.列表相关操作 今日详解 一.习题详解 1.计算1-100所有数据之和 all_num = ...

  4. MyBatis(入参的类型和日志记录)

    入参的类型是对象 1. 新增的参数是对象 2. 空值的处理,占位符 字段,jdbcType=VARCHAR          字符串 字段,jdbcType=DATE                  ...

  5. 洛谷 P5607 [Ynoi2013] 无力回天 NOI2017

    人生第一道Ynoi,开心 Description https://www.luogu.com.cn/problem/P5607 Solution 拿到这个题,看了一下,发现询问要求最大异或和,怎么办? ...

  6. sql面试50题------(21-30)

    文章目录 21.查询不同老师所教不同课程平均分从高到低显示 23.使用分段[100,85),[85,70),[70,60),[<60] 来统计各科成绩,分别统计各分数段人数:课程ID和课程名称 ...

  7. jmeter中获取token和cookie

    ## 登录获取token 1.添加请求 1.1 输入接口中需要携带的参数的值 2.正则表达式提取器提取出值 3.输入token数据 "token":"(.+?)" ...

  8. 9.异步redis

    在使用Python代码操作redis时候,连接.操作.断开都是网络IO #安装支持异步redis的模块 pip3 install aioredis async def execute(address, ...

  9. 题解 SP10500 HAYBALE - Haybale stacking

    前言 想了好久树状数组啥的,后来想想写打个差分再说,结果写完一遍AC了-- 强烈安利 题意 一个由 \(n\) 个元素组成的序列,给出 \(k\) 个操作,每次将 \(a\sim b\) 加上 \(1 ...

  10. Angular SSR 探究

    一般来说,普通的 Angular 应用是在 浏览器 中运行,在 DOM 中对页面进行渲染,并与用户进行交互.而 Angular Universal 是在 服务端 进行渲染(Server-Side Re ...