如果你想在一个 Java 程序中使用 Git ,有一个功能齐全的 Git 库,那就是 JGit 。 JGit 是一个用 Java 写成的功能相对健全的 Git 的实现,它在 Java 社区中被广泛使用。 JGit 项目由 Eclipse 维护,它的主页

依赖添加

有很多种方式可以将 JGit 依赖加入到你的项目,并依靠它去写代码。 最简单的方式也许就是使用 Maven 。你可以通过在你的 pom.xml 文件里的 标签中增加像下面这样的片段来完成这个整合。

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

在你读到这段文字时 version 很可能已经更新了,所以请浏览 http://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit 以获取最新的仓库信息。 当这一步完成之后, Maven 就会自动获取并使用你所需要的 JGit 库。

项目实践

在搭建我的博客的过程中,因为该博客是部署在自己的服务器上,需要在ci自动编译完成后,实现自动部署到我的服务器上(该步实现的方式很多,通过开放git接口,有编译部署的时候自动拉取到我的服务器就是其中的一个方法)

以下主要使用了pull拉取方法

package com.easy.jGit.controller;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.*;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Repository;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import java.io.File; @RestController
@Slf4j
public class JGitController { /**
* git仓路径
*/
final String patch = "/opt/webapps/blog/.git"; /**
* 代码分支
*/
final String branch = "origin/gh-pages"; /**
* 拉取
*
* @return
*/
@RequestMapping("/pull")
public String pull() {
String result;
Repository repo = null;
try {
repo = new FileRepository(new File(patch));
Git git = new Git(repo); log.info("开始重置");
//重置
git.reset()
.setMode(ResetCommand.ResetType.HARD)
.setRef(branch).call(); log.info("开始拉取"); //拉取
git.pull()
.setRemote("origin")
.setRemoteBranchName("gh-pages")
.call();
result = "拉取成功!";
log.info(result);
} catch (Exception e) {
result = e.getMessage();
} finally {
if (repo != null) {
repo.close();
}
}
return result;
} /**
* 重置
*
* @return
*/
@RequestMapping("/reset")
public String reset() {
String result; Repository repo = null;
try {
repo = new FileRepository(new File(patch));
Git git = new Git(repo);
git.reset().setMode(ResetCommand.ResetType.HARD).setRef(branch).call();
result = "重置成功!"; } catch (Exception e) {
result = e.getMessage();
} finally {
if (repo != null) {
repo.close();
}
}
return result;
} /**
* 恢复
*/
@RequestMapping("/revert")
public String revert() {
String result; Repository repo = null;
try {
repo = new FileRepository(new File(patch));
Git git = new Git(repo);
git.revert().call();
result = "恢复成功!"; } catch (Exception e) {
result = e.getMessage();
} finally {
if (repo != null) {
repo.close();
}
}
return result;
} /**
* 克隆
*
* @return
*/
@RequestMapping("/clone")
public String clone() {
String result;
try {
Git.cloneRepository()
.setURI("https://github.com/smltq/blog.git")
.setDirectory(new File("/blog"))
.call();
result = "克隆成功了!";
} catch (GitAPIException e) {
result = e.getMessage();
e.printStackTrace();
}
return result;
} /**
* 状态
*/
@RequestMapping("/status")
public static void status() {
File RepoGitDir = new File("/blog/.git");
Repository repo = null;
try {
repo = new FileRepository(RepoGitDir.getAbsolutePath());
Git git = new Git(repo);
Status status = git.status().call();
log.info("Git Change: " + status.getChanged());
log.info("Git Modified: " + status.getModified());
log.info("Git UncommittedChanges: " + status.getUncommittedChanges());
log.info("Git Untracked: " + status.getUntracked());
} catch (Exception e) {
log.info(e.getMessage());
} finally {
if (repo != null) {
repo.close();
}
}
}
}

.travis.yml 源文件

language: node_js # 设置语言
node_js: stable # 设置相应版本
cache:
apt: true
directories:
- node_modules # 缓存不经常更改的内容
before_install:
- export TZ='Asia/Shanghai' # 更改时区
- npm install hexo-cli -g
#- chmod +x ./publish-to-gh-pages.sh # 为shell文件添加可执行权限
install:
- npm install # 安装hexo及插件
script:
- hexo clean # 清除
- hexo g # 生成
after_script:
- git clone https://${GH_REF} .deploy_git
- cd .deploy_git
- git checkout master:gh-pages
- cd ../
- mv .deploy_git/.git/ ./public/
- cd ./public
- git config user.name "tqlin"
- git config user.email "smltq@126.com"
# add commit timestamp
- git add .
- git commit -m "Travis CI Auto Builder at `date +"%Y-%m-%d %H:%M"`"
- git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:gh-pages && curl http://49.235.170.100:8787/pull
- curl http://49.235.170.100:8787/pull #这里调用上面实现的拉取接口
branches:
only:
- master # 只监测master分支
env:
global:
- GH_REF: github.com/smltq/blog.git #设置GH_REF

基本概念

  • Repository 包括所有的对象和引用,用来管理源码

  • AnyObjectId 表示SHA1对象,可以获得SHA1的值,进而可以获得git对象

  • Ref 引用对象,表示.git/refs下面的文件引用 Ref HEAD = repository.getRef("refs/heads/master");

  • RevWalk 可以遍历提交对象,并按照顺序返回提交对象

  • RevCommit 代表一个提交对象

  • RevTag 代表标签对象

  • RevTree 代表树对象

其它常用命令

大多数 JGit 会话会以 Repository 类作为起点,你首先要做的事就是创建一个它的实例。 对于一个基于文件系统的仓库来说(JGit 允许其它的存储模型),用 FileRepositoryBuilder 完成它。

// 创建一个新仓库
Repository newlyCreatedRepo = FileRepositoryBuilder.create(
new File("/tmp/new_repo/.git"));
newlyCreatedRepo.create(); // 打开一个存在的仓库
Repository existingRepo = new FileRepositoryBuilder()
.setGitDir(new File("my_repo/.git"))
.build();

当你拥有一个 Repository 实例后,你就能对它做各种各样的事。比如:

// 获取引用
Ref master = repo.getRef("master"); // 获取该引用所指向的对象
ObjectId masterTip = master.getObjectId(); // Rev-parse
ObjectId obj = repo.resolve("HEAD^{tree}"); // 装载对象原始内容
ObjectLoader loader = repo.open(masterTip);
loader.copyTo(System.out); // 创建分支
RefUpdate createBranch1 = repo.updateRef("refs/heads/branch1");
createBranch1.setNewObjectId(masterTip);
createBranch1.update(); // 删除分支
RefUpdate deleteBranch1 = repo.updateRef("refs/heads/branch1");
deleteBranch1.setForceUpdate(true);
deleteBranch1.delete(); // 配置
Config cfg = repo.getConfig();
String name = cfg.getString("user", null, "name");

提交命令

AddCommand可以把工作区的内容添加到暂存区。

Git git = Git.open(new File("D:\\source-code\\temp\\.git"));
git.add().addFilepattern(".").call(); // 相当与git add -A添加所有的变更文件git.add().addFilepattern("*.java")这种形式是不支持的
git.add().addFilepattern("src/main/java/").call(); // 添加目录,可以把目录下的文件都添加到暂存区
//jgit当前还不支持模式匹配的方式,例如*.java

CommitCommand用于提交操作

Git git =Git.open(new File("D:\\source-code\\temp\\user1\\.git"));
CommitCommand commitCommand = git.commit().setMessage("master 23 commit").setAllowEmpty(true);
commitCommand.call();

status命令

    Git git = Git.open(new File("D:\\source-code\\temp-1\\.git"));
Status status = git.status().call(); //返回的值都是相对工作区的路径,而不是绝对路径
status.getAdded().forEach(it -> System.out.println("Add File :" + it)); //git add命令后会看到变化
status.getRemoved().forEach(it -> System.out.println("Remove File :" + it)); ///git rm命令会看到变化,从暂存区删除的文件列表
status.getModified().forEach(it -> System.out.println("Modified File :" + it)); //修改的文件列表
status.getUntracked().forEach(it -> System.out.println("Untracked File :" + it)); //工作区新增的文件列表
status.getConflicting().forEach(it -> System.out.println("Conflicting File :" + it)); //冲突的文件列表
status.getMissing().forEach(it -> System.out.println("Missing File :" + it)); //工作区删除的文件列表

log命令

LogCommand相当于git log命令

//提取某个作者的提交,并打印相关信息
Git git = Git.open(new File("D:\\source-code\\temp-1\\.git"));
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Iterable<RevCommit> results = git.log().setRevFilter(new RevFilter() {
@Override
public boolean include(RevWalk walker, RevCommit cmit)
throws StopWalkException, MissingObjectException, IncorrectObjectTypeException, IOException {
return cmit.getAuthorIdent().getName().equals("xxxxx dsd");
} @Override
public RevFilter clone() {
return this;
}
}).call();
results.forEach(commit -> {
PersonIdent authoIdent = commit.getAuthorIdent();
System.out.println("提交人: " + authoIdent.getName() + " <" + authoIdent.getEmailAddress() + ">");
System.out.println("提交SHA1: " + commit.getId().name());
System.out.println("提交信息: " + commit.getShortMessage());
System.out.println("提交时间: " + format.format(authoIdent.getWhen()));
});

fetch命令

fetch命令

Repository rep = new FileRepository("D:\\source-code\\temp-1\\.git");
Git git = new Git(rep);
git.pull().setRemote("origin").call();
//fetch命令提供了setRefSpecs方法,而pull命令并没有提供,所有pull命令只能fetch所有的分支
git.fetch().setRefSpecs("refs/heads/*:refs/heads/*").call();

push命令

而PushCommand和git push相同,一般都需要我们提供用户名和密码,需要用到CredentialsProvider类

Repository rep = new FileRepository("D:\\source-code\\temp-1\\.git");
Git git = new Git(rep);
git.push().setCredentialsProvider(new UsernamePasswordCredentialsProvider("myname", "password")).call();

clone命令

CloneCommand等价与git clone命令

Git.cloneRepository().setURI("https://admin@localhost:8443/r/game-of-life.git")
.setDirectory(new File("D:\\source-code\\temp-1")).call();

RevWalk API

以下代码实现这样一个功能,查找某个文件的历史记录,并把每个提交的文件内容打印出来。

 DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Repository repository = new RepositoryBuilder().setGitDir(new File("D:\\source-code\\temp-1\\.git")).build();
try (RevWalk walk = new RevWalk(repository)) {
Ref head = repository.findRef("HEAD");
walk.markStart(walk.parseCommit(head.getObjectId())); // 从HEAD开始遍历,
for (RevCommit commit : walk) {
RevTree tree = commit.getTree(); TreeWalk treeWalk = new TreeWalk(repository, repository.newObjectReader());
PathFilter f = PathFilter.create("pom.xml");
treeWalk.setFilter(f);
treeWalk.reset(tree);
treeWalk.setRecursive(false);
while (treeWalk.next()) {
PersonIdent authoIdent = commit.getAuthorIdent();
System.out.println("提交人: " + authoIdent.getName() + " <" + authoIdent.getEmailAddress() + ">");
System.out.println("提交SHA1: " + commit.getId().name());
System.out.println("提交信息: " + commit.getShortMessage());
System.out.println("提交时间: " + format.format(authoIdent.getWhen())); ObjectId objectId = treeWalk.getObjectId(0);
ObjectLoader loader = repository.open(objectId);
loader.copyTo(System.out); //提取blob对象的内容
}
}
}

其它更多命令参考官网

资料

Spring Boot、Cloud 学习项目

JGit----将 Git 嵌入你的应用的更多相关文章

  1. JAVA 使用jgit管理git仓库

    最近设计基于gitops新的CICD方案,需要通过java读写git仓库,这里简单记录下. JGit是一款pure java的软件包,可以读写git仓库,下面介绍基本使用. 引入jgit maven引 ...

  2. Git中文版教程

    1. 起步 1.1 关于版本控制 1.2 Git 简史 1.3 Git 基础 1.4 命令行 1.5 安装 Git 1.6 初次运行 Git 前的配置 1.7 获取帮助 1.8 总结 2. Git 基 ...

  3. Git Pro Book

    目录 2nd Edition (2014) Switch to 1st Edition Download Ebook The entire Pro Git book, written by Scott ...

  4. java操作git简单实现

    记录瞬间 import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.ListBranchCommand; import org.ecli ...

  5. 如何在Ubuntu 16.04安装的Git【转】

    转自:https://www.howtoing.com/how-to-install-git-on-ubuntu-16-04/ 介绍 现代软件开发中不可或缺的工具是某种版本控制系统. 版本控制系统允许 ...

  6. 通过jgit一次性升级fastjson版本

    背景:笔者所在公司经历了三次fastjson的升级,由于集群,工程数量众多,每次升级都很麻烦.因此开发了一个java的升级工具. 功能介绍: 功能介绍:一个jar文件,通过java -jar命令,输入 ...

  7. JGit、SvnKit - 版本提交日志(1)提取

    1.相关开源jar包  1>使用JGIT访问git项目  2>使用SVNkit访问svn Git官方JGit使用教程指导 2.Git历史提交日志导出到文件 在项目根目录执行如下命令,将日志 ...

  8. 探讨 Git 代码托管平台的若干问题

    关于 Git 版本控制软件种类繁多,维基百科收录的最早的版本控制系统是 1972 年贝尔实验室开发的 Source Code Control System.1986 年 Concurrent Vers ...

  9. 探讨 Git 代码托管平台的若干问题 - 2019 版

    关于 Git 版本控制软件种类繁多,维基百科收录的最早的版本控制系统是 1972 年贝尔实验室开发的 Source Code Control System.1986 年 Concurrent Vers ...

随机推荐

  1. Java学习总结之基本数据类型

    Java的数据类型分为基本数据类型和引用数据类型, 今天总结的是基本数据类型.在Java中,一共有八种基本数据类型,分别为整数类型(byte,short,int,long).浮点类型(float,do ...

  2. DAY 3 数论专场

    2019-07-23 今天的题目一个比一个神仙,很早之前就在讨论今天是不是晚上回宾馆就没脑子了,后来发现,是中午.... 一上午就讲了一个PPT,然而标题就两个子---数论... 这谁顶的住....整 ...

  3. webpack的npm扩展使用

    一.NPM的扩展使用 (1)  npm init:初始化一个Node.js项目------创建必须的package.json文件 npm init -y:创建必须的package.json文件 (2) ...

  4. Python字典 你必须知道的用法系列

    本文Python版本为3.7.X,阅读本文之前需了解python字典的基本用法. 介绍 字典(dict)是Python中内置的一个数据结构,由多个键值对组成,键(key)和值(value)用冒号分隔, ...

  5. redhat 配置eth0网卡

                 redhat 找不到eth0等网卡设备 Serenity关注                                                         ...

  6. PHP Laravel-包含你自己的帮助函数

    你可能想创建一个在应用的任何地方都可以访问的函数,这个教程将帮你实现

  7. 阿里云开源 image-syncer 工具,容器镜像迁移同步的终极利器

    为什么要做这个工具? 由于阿里云上的容器服务 ACK 在使用成本.运维成本.方便性.长期稳定性上大大超过公司自建自维护 Kubernets 集群,有不少公司纷纷想把之前自己维护 Kubernetes ...

  8. 创建和销毁对象——用私有构造器或者枚举类型强化Singleton属性

    参考资料:<Effective Java>.<Java核心技术 卷1>.https://www.cnblogs.com/zhaosq/p/10135362.html 基础回顾 ...

  9. 利用Xshell配置ssh免密码登录虚拟机,进行虚拟机与物理机的传输

    先说一下 Xshell如何无密连接虚拟机: ssh登录提供两种认证方式:口令(密码)认证方式和密钥认证方式.其中口令(密码)认证方式是我们最常用的一种,这里介绍密钥认证方式登录到linux的方法.使用 ...

  10. 判断DataGridView是否选中某行

    if (this.Drawing_GridView.SelectedColumns.Count == 0)//判断是否选中某行 { }