jgit

如果您想知道如何在JGit中执行git initgit checkout等基本的Git命令,请继续阅读。

本教程概述了最常用的git命令及其在JGit中的对应命令。 它逐步执行以下步骤:创建存储库,从远程获取内容,向历史记录添加文件或从历史记录中删除文件,检查历史记录,最后将更改推回原始存储库。

JGit提供了一个类似于Git高级命令的API。 代替

git commit -m "My first commit"

在命令行上,您将编写

git.commit().setMessage( "My first commit" ).call();

在JGit中。

所有JGit命令都有一个call()方法,设置该命令后,该方法将用于实际执行它。 这些类以各自的Git命令后缀Command命名。 尽管某些命令提供了公共构造函数,但建议使用Git工厂类来创建命令实例,如上例所示。

获取图书馆

但是在进一步研究JGit API之前,让我们先掌握该库。 获取JGit的最常见方法可能是从Maven存储库中。 但是,如果您更喜欢OSGi捆绑软件,那么还可以使用p2存储库。 下载页面列出了集成库所需的信息。

在本文的范围内,将称为核心库的项目集成到project / bundle org.eclipse.jgit中就足够了。 如果您对JGit源代码存储库中的内容感兴趣,我建议阅读JGit源代码简介。

创建一个仓库

首先,我们需要一个存储库。 为了掌握这种情况,我们可以初始化一个新的存储库或克隆一个现有的存储库。

InitCommand使我们可以创建一个空的存储库。 下一行

Git git = Git.init().setDirectory( "/path/to/repo" ).call();

将在给setDirectory()的位置创建一个带有工作目录的存储库。 .git目录将直接位于/path/to/repo/.git中。 有关InitCommand的详细说明,请阅读使用JGit初始化Git存储库 。

可以使用CloneCommand克隆现有的存储库

Git git = Git.cloneRepository().setURI( "https://github.com/eclipse/jgit.git" ).setDirectory( "/path/to/repo" ).call();

上面的代码会将JGit存储库克隆到本地目录“ path / to / repo”中。 CloneCommand的所有选项在如何使用JGit克隆Git存储库中进行了详细介绍 。

如果您碰巧已经要使用现有的本地存储库,则可以按照如何使用JGit访问Git存储库中所述进行操作 。

完成后关闭Git

请注意,如果不再需要关闭未显式关闭(git.close())的命令,则返回InitCommand或CloneCommand之类的Git实例的命令可能会泄漏文件句柄。

幸运的是,Git实现了AutoCloseable,因此您可以使用try-with-resources语句 。

填充存储库

现在我们有了一个存储库,我们可以开始填充其历史记录。 但是,为了提交文件,我们首先需要将其添加到所谓的索引(也称为暂存区)中。 commit命令将仅考虑在索引中添加(或从索引中删除)的文件。

因此,JGit命令是–您猜到了– AddCommand。

DirCache index = git.add().addFilePattern( "readme.txt" ).call();

因此,以上行将文件readme.txt添加到索引中。 值得注意的是,文件的实际内容被复制到索引中。 这意味着以后对文件的修改将不包含在索引中,除非再次添加它们。

给addFilePattern()提供的路径必须相对于工作目录根目录。 如果路径未指向现有文件,则将其忽略。

尽管方法名称暗示也可以接受模式,但是以前的JGit支持是有限的。 传递“。” 将以递归方式添加工作目录中的所有文件。 但是尚不支持本地Git中可用的fileglob(例如* .java)。

可以检查JGit中名为DirCache的call()返回的索引,以验证它是否确实包含我们期望的内容。 其getEntryCount()方法返回文件总数,而getEntry()返回指定位置的条目。

现在,一切准备就绪,可以使用CommitCommand来将更改存储在存储库中。

RevCommit commit = git.commit().setMessage( "Create readme file" ).call();

至少必须指定消息,否则call()会发出NoMessageException投诉。 但是,允许输入空消息。 如果未使用相应标记的方法表示作者和提交者,则将其从配置中删除。

返回的RevCommit用消息,作者,提交者,时间戳记来描述提交,当然还指向构成该提交的文件和目录树的指针。

与需要添加新文件或更改文件的方式相同,需要明确删除已删除的文件。 RmCommand与AddCommand是对等的,并且可以以相同的方式使用(当然会产生相反的结果)。

DirCache index = git.rm().addFilepattern( "readme.txt" ).call();

上一行将再次删除给定的文件。 由于它是存储库中的唯一文件,因此当询问其中的条目数时,返回的索引将返回零。

除非指定了setCached(true),否则该文件还将从工作目录中删除。 由于Git不跟踪目录,因此RmCommand还会删除给定文件的空父目录。

删除不存在文件的尝试将被忽略。 但是与AddCommand不同,RmCommand在其addFilepattern()方法中不接受通配符。 所有要删除的文件都需要单独指定。

在下一次提交时,这些更改将存储在存储库中。 请注意,创建一个空的提交是完全合法的,即在执行之前没有添加或删除文件的提交。 虽然我不知道一个合适的用例。

储存库状态

status命令列出了索引与当前HEAD提交或工作目录之间具有差异的文件,以及索引或Git未跟踪的文件。

StatusCommand以其最简单的形式收集属于该存储库的所有文件的状态:

Status status = git.status().call();

Status对象的获取器应该是不言自明的。 它们返回处于方法名描述状态的文件名集。 例如,将readme.txt文件添加到如上所示的索引中之后,status.getAdded()将返回一个集合,其中包含刚添加的文件的路径。

如果根本没有差异,也没有未跟踪的文件,则Status.isClean()将返回true。 顾名思义,如果存在未提交的更改,则返回Status.hasUncommittedChanges()true。

使用addPath(),可以将StatusCommand配置为仅显示某些文件的状态。 给定的路径必须命名文件或目录。 不存在的路径将被忽略,并且不支持正则表达式或通配符。

Status status = git.status().addPath( "documentation" ).call();

在上面的示例中,将递归计算“文档”目录下所有文件的状态。

浏览存储库

现在,该存储库具有(较小的)历史记录,我们将研究该命令以列出现有提交。

JGit的git log对应物的最简单形式允许列出当前HEAD可以访问的所有提交。

Iterable<RevCommit> iterable = git.log().call();

返回的迭代器可用于遍历LogCommand找到的所有提交。

对于更高级的用例,我建议直接使用RevWalk API,该类与LogCommand也使用相同的类。 除了提供更大的灵活性之外,它还避免了可能发生的资源泄漏,因为LogCommand内部使用的RevWalk永远不会关闭。

例如,其markStart()方法还可用于列出其他分支(或更普遍地说,其他引用 )可到达的提交。

不幸的是,仅接受ObjectId,因此需要首先解析所需的引用。 JGit中的ObjectId封装了一个SHA-1哈希,该哈希指向Gits对象数据库中的一个对象。 此处,指向提交的ObjectId是必需的,在这种情况下解析意味着获取特定引用所指向的ObjectId。

放在一起,看起来就像下面的代码片段:

Repository repository = git.getRepository()
try( RevWalk revWalk = new RevWalk( repository ) ) {ObjectId commitId = repository.resolve( "refs/heads/side-branch" );revWalk.markStart( revWalk.parseCommit( commitId ) );for( RevCommit commit : revWalk ) {System.out.println( commit.getFullMessage );}
}

获取分支“侧分支”所指向的提交ID,然后指示RevWalk从那里开始遍历历史记录。 因为markStart()需要RevCommit,所以RevWalk的parseCommit()用于将提交ID解析为实际的提交。

一旦RevWalk设置好,该代码段就会在提交上循环以打印每次提交的消息。
try-with-resource语句可确保完成后将关闭RevWalk。 请注意,多次调用markStart()以便在遍历中包含多个引用是合法的。

RevWalk也可以配置为通过匹配提交对象本身的属性或匹配其表示的目录树的路径来过滤提交。 如果事先知道,则可以将不感兴趣的提交及其祖先链从输出中排除。 当然可以对输出进行排序,例如按日期或拓扑排序(所有孩子都在父母之前)。 但是这些功能不在本文讨论范围之内,但可能会在以后的文章中进行介绍。

与远程存储库交换

通常,本地存储库是从远程存储库克隆的。 并且本地所做的更改最终应发布到原始存储库。 为此,需要使用git push的对应项PushCommand。

最简单的形式将当前分支推送到其相应的远程分支。

Iterable<PushResult> iterable = local.push().call();
PushResult pushResult = iterable.iterator().next();
Status status = pushResult.getRemoteUpdate( "refs/heads/master" ).getStatus();

该命令返回一个可迭代的PushResults。 在上述情况下,迭代器仅包含一个元素。 为了验证推送是否成功,可以要求pushResult返回给定分支的RemoteRefUpdate。

RemoteRefUpdate详细描述了更新内容以及更新方式。 但它也有一个状态属性,用于总结结果。 并且如果状态返回OK,我们可以放心操作成功。

即使该命令在没有给出任何建议的情况下也可以运行,但是它具有许多选项,在下面仅列出了更常用的选项。 默认情况下,该命令将推送到名为“ origin”的默认遥控器。 使用setRemote()可以指定其他远程存储库的URL或名称。 如果其他分支比当前应该推refspecs可以与setRefSpec()来指定。 可以使用setPushTags()来控制是否也应传送标签。 最后,如果不确定是否需要结果,则可以使用空运行选项来模拟推送操作。

现在,我们已经了解了如何将本地对象传输到远程存储库,我们将了解相反的方向。 FetchCommand的用法与推入命令非常相似,并且默认设置也可以成功使用。

FetchResult fetchResult = local.fetch().call();
TrackingRefUpdate refUpdate = fetchResult.getTrackingRefUpdate( "refs/remotes/origin/master" );
Result result = refUpdate.getResult();

如果不进行进一步的配置,该命令将从与默认远程服务器上当前分支相对应的分支中获取更改。

FetchResult提供有关操作结果的详细信息。 对于每个受影响的分支,都可以获取TrackingRefUpdate实例。 最有趣的可能是getResult()的返回值,该值总结了更新的结果。 此外,它还包含有关以下信息的信息:使用哪个远程引用(getRemoteName())更新了哪个本地引用(getLocalBame()),以及更新前后本地引用指向的对象id(getOldObjectId()和getNewObjectid())。

如果远程存储库需要身份验证,则可以使用与所有与远程存储库通信的命令相同的方式来准备PushCommand和FetchCommand。

  • 可以在“ JGit身份验证说明”文章中找到详细的讨论。

结束语JGit入门

现在轮到您向Tkae JGit兜风了。 不难理解高级JGit API。 如果您知道要使用什么git命令,则可以轻松猜测JGit中要使用的类和方法。

尽管并非所有Git命令行的精妙之处都可用,但它对最常用的功能提供了可靠的支持。 而且,如果有一些关键的缺失,您通常可以使用JGit的低级API来解决该限制。

整篇文章中显示的摘录是一系列学习测试的摘录。

  • 完整版本可以在这里找到: https : //gist.github.com/rherrmann/433adb44b3d15ed0f0c7

如果您仍然有困难或问题,请发表评论或向友好而乐于助人的JGit社区寻求帮助。

翻译自: https://www.javacodegeeks.com/2015/12/getting-started-jgit.html

jgit

jgit_JGit入门相关推荐

  1. 用Construct 2制作入门小游戏~

    今天在软导课上了解到了Construct 2这个神器,本零基础菜鸟决定尝试做一个简单的小游戏(实际上是入门的教程啊= = 首先呢,肯定是到官网下载软件啊,点击我下载~ 等安装完毕后我便按照新手教程开始 ...

  2. Docker入门六部曲——Swarm

    原文链接:http://www.dubby.cn/detail.html?id=8738 准备工作 安装Docker(版本最低1.13). 安装好Docker Compose,上一篇文章介绍过的. 安 ...

  3. Docker入门六部曲——Stack

    原文链接:http://www.dubby.cn/detail.html?id=8739 准备知识 安装Docker(版本最低1.13). 阅读完Docker入门六部曲--Swarm,并且完成其中介绍 ...

  4. Docker入门六部曲——服务

    原文链接:http://www.dubby.cn/detail.html?id=8735 准备 已经安装好Docker 1.13或者以上的版本. 安装好Docker Compose.如果你是用的是Do ...

  5. 【springboot】入门

    简介: springBoot是spring团队为了整合spring全家桶中的系列框架做研究出来的一个轻量级框架.随着spring4.0推出而推出,springBoot可以説是J2SEE的一站式解决方案 ...

  6. SpringBoot (一) :入门篇 Hello World

    什么是SpringBoot Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不 ...

  7. 入门指南目录页 -PaddlePaddle 飞桨 入门指南 FAQ合集-深度学习问题

    入门指南目录页 -PaddlePaddle 飞桨 入门指南 FAQ合集 GT_Zhang关注 0.1012019.08.01 18:43:34字数 1,874阅读 795 Hi,欢迎各位来自Paddl ...

  8. 5 分钟入门 Google 最强NLP模型:BERT

    BERT (Bidirectional Encoder Representations from Transformers) 10月11日,Google AI Language 发布了论文 BERT: ...

  9. 命名实体识别入门教程(必看)

    关于开发自己的命名实体识别先期思路: 虽然网上有很多相关代码,但实际如何入门材料较少,故整理下: CRF:先期可以用人民日报语料库去做,步骤如下: https://blog.csdn.net/hude ...

最新文章

  1. 布袋除尘器过滤风速多少_布袋除尘器处理风量、过滤风速、过滤面积及阻力的选型计算...
  2. shell脚本详解(二)——条件测试、if语句和case分支语句
  3. 面向对象知识点之statickeyword的使用
  4. 太阳能板清洗机器人科沃斯_科沃斯推出水清洗扫地机器人 要把打扫做的更彻底...
  5. vuex 源码分析_前端入门之(vuex-router-sync解析)
  6. linux磁盘管理(挂载,分区)
  7. python将数据保存为pdf
  8. PS白底证件照换蓝底背景,头发边缘精细处理
  9. Activiti工作流的流转任务和结束任务
  10. ECNUOJ 2616 游黄山
  11. pthread编译时报错的解决方法
  12. WEB前端 VS 后端,学哪个就业前景更好
  13. 必收藏的实用网站(一)
  14. 手机屏幕坏了如何把手机里面的资料取出来_手机进水了怎么办?不同情况处理方法最全归纳!!!...
  15. python基础_字典_列表_元组考试
  16. JS检测是否有企业微信应用程序
  17. 初识Flink,简要介绍Flink
  18. Unity动画☀️6. 翻越障碍物、Vector3.up、射线Physics.Raycast()、Character Controller
  19. 企业ERP系统上线的最后一道防线——ERP系统上线预评估审计
  20. 怎么让拍摄的视频生成二维码,扫描后即可观看?

热门文章

  1. 为什么你的策略游戏没有策略的乐趣呢?
  2. Metro IE10快捷方式 不小心删了
  3. 几个常见的简单的算法(暴力法,递推法,枚举法,递归法,分治法,贪心法,回溯法)
  4. 仿WPS便签,鲨鱼记账app
  5. EasyAR-webAR window系统本地实现流程和期间的出现的各种配置错误
  6. centos 配置DNS服务器地址
  7. 新贵(NEWMEN)魔键 KB-835U 爽手有线键盘 29.9元
  8. SQL语句——对所有员工的薪水按照salary进行按照1-N的排名
  9. 二次开发是什么意思_我为什么推荐选用商业软件来进行在线供排水模型的搭建(科普向)...
  10. 前端gojs各属性使用示例