【git】基于JGit通过ssh-url拉取指定commit-id的代码
实现
1️⃣ pom
依赖:
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>6.6.0.202305301015-r</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.jsch</artifactId>
<version>6.5.0.202303070854-r</version>
</dependency>
2️⃣ JschConfigSessionFactory
配置:
JSch与JGit
JSch
是一个纯 Java 实现的 SSH2 协议库,它提供了在 Java 程序中进行 SSH 通信的功能。JSch
允许你在 Java 应用程序中使用 SSH 协议进行远程命令执行、文件传输和端口转发等操作。
JGit
是一个用于访问 Git 版本控制系统的 Java 库,它提供了在 Java 应用程序中与 Git 仓库进行交互的功能。JGit
是 Eclipse Foundation 的一个项目,旨在为 Java 开发者提供一个功能齐全且易于集成的 Git 客户端库。
JschConfigSessionFactory
是基于 JSch
的一个辅助类,用于在 JGit
中配置 SSH 会话工厂。
配置
SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
@Override
protected void configure(OpenSshConfig.Host host, Session session) {
// 设置 SSH 客户端在连接远程服务器时不进行严格的主机密钥检查
session.setConfig("StrictHostKeyChecking", "no");
}
@Override
protected JSch createDefaultJSch(FS fs) throws JSchException {
JSch jSch = super.createDefaultJSch(fs);
// 添加私钥文件用于身份验证
jSch.addIdentity(privateKey);
return jSch;
}
};
JschConfigSessionFactory
工作流程
在JGit
中,首先createSession()
方法被调用,方法内部调用getJSch()
获取JSch
实例,再调用JSch
实例的getSession()
方法获取Session
对象。
getJSch()
方法被调用时,createDefaultJSch()
方法于内部被调用。
原始的createDefaultJSch()
方法中,configureJSch()
方法会被调用,但原始的configureJSch()
方法内部为空。
createSession()
方法中会调用configure()
方法。
主机密钥检查
主机密钥检查(Host Key Checking)是在 SSH 连接过程中进行的一种安全机制,用于验证远程主机的身份和防止中间人攻击。
在 SSH 连接过程中,当客户端(例如使用 JSch 库的应用程序)首次连接到一个远程主机时,远程主机会返回自己的公钥。为了确保连接的远程主机是预期的主机而不是中间人,客户端会对远程主机的公钥进行验证。
主机密钥检查的过程如下:
客户端收到远程主机的公钥。
客户端会将远程主机的公钥与本地存储的已知主机密钥进行比较。
- 如果已知主机密钥列表中存在与远程主机公钥匹配的密钥,表示该远程主机的身份是可信的,连接将继续进行。
- 如果已知主机密钥列表中不存在匹配的密钥,表示该远程主机的身份是不可信的或是首次连接的主机,客户端会触发主机密钥检查流程。
- 主机密钥检查的具体行为取决于 SSH 客户端的配置:
- 如果客户端的配置指定了接受新的主机密钥,客户端将自动接受远程主机的公钥,并将其添加到已知主机密钥列表中。这种配置一般用于自动化脚本等场景。
- 如果客户端的配置要求用户手动确认新的主机密钥,客户端会提示用户确认该主机的公钥指纹是否可信。用户需要进行手动确认才能继续连接。
- 如果客户端的配置指定了拒绝新的主机密钥,连接将被终止,并抛出异常或给出相应的错误提示。
3️⃣ 指定一不存在或为空的目录
Path tempDirectory = Paths.get("d:/tmp");
4️⃣ 基于JGit拉代码
try (Git git = Git.cloneRepository()
.setURI(sshUrl)
// 用于在回调中将自定义的session工厂配置到JGit中
.setTransportConfigCallback(transport -> {
SshTransport sshTransport = (SshTransport) transport;
sshTransport.setSshSessionFactory(sshSessionFactory);
})
.setDirectory(new File(String.valueOf(tempDirectory)))
// 禁用自动`checkout`,使得工作目录下不会出现克隆的文件,便于后续拉取指定id的代码
.setNoCheckout(true)
.call()) {
// 解析commit-id
ObjectId commitObjectId = git.getRepository().resolve(commitId);
//
git.checkout().setName(commitObjectId.getName()).call();
}
完整代码
public interface CloneGithubRepository {
public static String privateKey = "C:\\Users\\UserName\\.ssh\\id_ecdsa";
public static String sshUrl = "git@github.com:username/repository_name.git";
public static String commitId = "68d18ccbf5605f16a15f8fb66c21a8b6776c6d8c";
public static void main(String[] args) throws GitAPIException, IOException {
// Set SSH credentials and authentication method
SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
@Override
protected void configure(OpenSshConfig.Host host, Session session) {
session.setConfig("StrictHostKeyChecking", "ask");
}
@Override
protected JSch createDefaultJSch(FS fs) throws JSchException {
JSch jSch = super.createDefaultJSch(fs);
jSch.addIdentity(privateKey);
return jSch;
}
};
Path tempDirectory = Paths.get("d:/tmp");
// Clone or fetch a repository
try (Git git = Git.cloneRepository()
.setURI(sshUrl)
.setTransportConfigCallback(transport -> {
SshTransport sshTransport = (SshTransport) transport;
sshTransport.setSshSessionFactory(sshSessionFactory);
})
.setDirectory(new File(String.valueOf(tempDirectory)))
.setNoCheckout(true)
.call()) {
ObjectId commitObjectId = git.getRepository().resolve(commitId);
git.checkout().setName(commitObjectId.getName()).call();
}
System.out.println(tempDirectory);
}
}
Bug清单
(1) Caused by: com.jcraft.jsch.JSchException: invalid privatekey: [B@6591f517
原因:ssh免密格式OPENSSH不支持
重新生成:ssh-keygen -t rsa -m PEM
ssh-keygen -t rsa
- 这个命令生成的 RSA 密钥对使用的是默认的密钥格式(OpenSSH 格式)。
ssh-keygen -t rsa -m PEM
- 这个命令生成的 RSA 密钥对使用的是 PEM 格式(Privacy-Enhanced Mail)。不同之处在于,生成的密钥使用了 PEM 编码。
PEM 格式是一种基于 Base64 编码的文本格式,常用于表示密钥、证书和其他加密相关数据。PEM 格式的密钥可以在许多软件和系统中使用,包括一些 Web 服务器、证书颁发机构等。
- 这个命令生成的 RSA 密钥对使用的是 PEM 格式(Privacy-Enhanced Mail)。不同之处在于,生成的密钥使用了 PEM 编码。
(2)
Caused by: org.eclipse.jgit.errors.NoRemoteRepositoryException: git@github.com:username/repository-name.git:
ERROR: You're using an RSA key with SHA-1, which is no longer allowed.
Please use a newer client or a different key type.
原因:2022年3月15日起,github不再支持SHA-1的加密方式。
重新生成:ssh-keygen -t ecdsa -m PEM
ssh-keygen指令选项概述
-t keytype
:指定要生成的密钥类型,如 rsa、dsa、ecdsa 或 ed25519。
- 示例:ssh-keygen -t rsa
-b bits
:指定生成密钥时使用的位数。
- 示例:ssh-keygen -b 4096
-C comment
:为生成的密钥添加注释。
- 示例:ssh-keygen -C "My Key"
-f filename
:指定生成的密钥文件的名称和路径。
- 示例:ssh-keygen -f /path/to/mykey
-N passphrase
:设置生成的密钥的密码短语(passphrase),用于加密私钥。
- 示例:ssh-keygen -N "mypassword"
- 在 SSH 中,passphrase(密码短语)是为了增加私钥的安全性而设置的一种额外保护层。当你生成或使用一个使用密码短语保护的私钥时,每次使用该私钥时都需要提供密码短语才能解锁私钥。
-p
:更改私钥的密码短语(passphrase)。
- 示例:ssh-keygen -p -f /path/to/mykey
-q
:静默模式,减少命令输出。
- 示例:ssh-keygen -q
-i
:导入其他格式的密钥文件并转换为 SSH 格式。
- 示例:ssh-keygen -i -f /path/to/otherkey
-e
:将密钥文件转换为其他格式。
- 示例:ssh-keygen -e -f /path/to/mykey
-R hostname
:从 known_hosts 文件中删除指定主机的记录。
- 示例:ssh-keygen -R example.com
-m
:用于指定生成的密钥文件的格式或导入/导出密钥时的编码格式
-m PEM
:指定生成的密钥文件使用 PEM 格式编码。这是一种常见的编码格式,适用于多种应用场景。-m PKCS8
:指定生成的私钥文件使用 PKCS#8 格式编码。这种格式常用于导入和导出私钥,特别是与其他工具和系统的集成。-m RFC4716
:指定生成的密钥文件使用 RFC 4716 格式编码。该格式与 OpenSSH 兼容,可以用于与其他 SSH 实现进行交互。-m SSH2
:指定生成的密钥文件使用 SSH2 格式编码。这是 OpenSSH 的早期格式,不常用于现代应用,仅用于特定的兼容性需求。-m FINGERPRINT
:显示密钥的指纹信息。
【git】基于JGit通过ssh-url拉取指定commit-id的代码的更多相关文章
- git从远程仓库gitLab上拉取指定分支到本地仓库
例如:将gitLab 上的dev分支拉取到本地 1>与远程仓库建立连接:git remote add origin XXXXX.git 2>使用git branch 查看本地是否具有dev ...
- git pull 冲突拉取不到新的代码
本地文件已经有冲突或者在pull的过程中拉取的文件和本地文件冲突时,拉取不到新的代码,git pull出现报错,如下: 这个时候,如果你有两种选择,如果你需要这些改动,那个你就需要手动解决冲突,然后a ...
- 使用VSTS的Git进行版本控制(六)——拉取请求
使用VSTS的Git进行版本控制(六)--拉取请求 在将代码合并到主干之前,拉取请求让团队对特性分支的更改提供反馈.审阅人可以通过建议修改留下评论,并投票批准或拒绝代码. 任务1:在Visual St ...
- git如何拉取指定分支的代码
问题背景: 新项目还在开发阶段,没有正式对外发布,所以开发同事合并代码到develop上(或者其他名称分支上),而不是到master分支上 通过git拉取代码的时候,默认拉取的是master分支,如下 ...
- (转)GitHub Desktop 拉取 GitHub上 Tag 版本代码
转自:GitHub Desktop 拉取 GitHub上 Tag 版本代码 一直在使用 GitHub Desktop 图形化 git 管理工具,统一项目框架版本时需要切换到ThinkPHP Tag 分 ...
- 2017.6.30 使用git新建项目、仓库并拉取、提交代码
1.在码云上新建一个项目rms 2.在本地指定位置新建仓库,生成.git文件夹 3.同步远程仓库,并拉取最新代码 远程仓库默认名为orgin.可以修改,这里就是用默认名了. 注意:这里使用ssh方式的 ...
- git中如何切换分支,拉取分支,合并分支
idea中如何使用git来做分支的切换合并: https://blog.csdn.net/autfish/article/details/52513465 本地分支与远程分支: https://seg ...
- git clone新项目后如何拉取分支代码到本地
1.git clone git@git.n.xxx.com:xxx/xxx.git 2.git fetch origin dev 命令来把远程dev分支拉到本地 3.checkout -b de ...
- git clone新项目后如何拉取其他分支代码到本地
1.git clone git@git.n.xxx.com:xxx/xxx.git 2.git fetch origin dev 命令来把远程dev分支拉到本地 - - 解读:git fetch命令用 ...
- git 拉取指定的远程分支(三种方式)
直接拉取 git clone -b ants git@github.com:Ants-double/CareerJava.git git clone -b 远程分支名 仓库地址 本地已经有相关的仓库代 ...
随机推荐
- 20-优化配置介绍、HMR
webpack性能优化 开发环境性能优化 生产环境性能优化 开发环境性能优化 优化打包构建速度 HMR 优化代码调试 source-map 生产环境性能优化 优化打包构建速度 oneOf babel缓 ...
- 在web浏览器中如何操作复合IC卡
在web浏览器中如何操作复合IC卡呢, 对于使用javascript的工程师而言,非常简单,只需要几行代码即可实现.当然在写代码之前, 需要安装友我NFC读写器web插件, 然后插上NFC读写器YW- ...
- Qt第三方库QtAV--- ubuntu编译与运行
Qt第三方库QtAV--- ubuntu编译与运行 今天又要接触这个,把一些错误或者不足的地方重新补充下!!!由于前面一段时间,项目中需要借助QtAV接口进行视频播放,特此记录下整个配置过程.整个代码 ...
- Java常见的线程池的创建及使用
文章目录 线程池是什么? 线程池的主要参数 线程池的拒绝策略 创建线程池的方式 关闭线程池 大家好,我是Leo!今天准备和大家一起分享的知识是线程池,刚好今天在看八股文,就顺带写一下并把一些实践的例子 ...
- 2023-05-08:我们定义了一个函数 countUniqueChars(s) 来统计字符串 s 中的唯一字符, 并返回唯一字符的个数。 例如:s = “LEETCODE“ ,则其中 “L“, “T
2023-05-08:我们定义了一个函数 countUniqueChars(s) 来统计字符串 s 中的唯一字符, 并返回唯一字符的个数. 例如:s = "LEETCODE" ,则 ...
- 2023-04-16:给定一个长度为N的数组,值一定在0~N-1范围,且每个值不重复 比如,arr = [4, 2, 0, 3, 1] 0 1 2 3 4 把0想象成洞
2023-04-16:给定一个长度为N的数组,值一定在0~N-1范围,且每个值不重复 比如,arr = [4, 2, 0, 3, 1] 0 1 2 3 4 把0想象成洞,任何非0数字都可以来到这个洞里 ...
- 2022-04-27:Alice 有一个下标从 0 开始的数组 arr ,由 n 个正整数组成。她会选择一个任意的 正整数 k 并按下述方式创建两个下标从 0 开始的新整数数组 lower 和 hig
2022-04-27:Alice 有一个下标从 0 开始的数组 arr ,由 n 个正整数组成.她会选择一个任意的 正整数 k 并按下述方式创建两个下标从 0 开始的新整数数组 lower 和 hig ...
- 2022-02-11:单词缩写。 给定一个由n个不重复非空字符串组成的数组,你需要按照以下规则为每个单词生成最小的缩写。 初始缩写由起始字母+省略字母的数量+结尾字母组成。 若存在冲突,亦即多于一个单
2022-02-11:单词缩写. 给定一个由n个不重复非空字符串组成的数组,你需要按照以下规则为每个单词生成最小的缩写. 初始缩写由起始字母+省略字母的数量+结尾字母组成. 若存在冲突,亦即多于一个单 ...
- 2021-05-28:跳跃游戏 II。给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可
2021-05-28:跳跃游戏 II.给定一个非负整数数组,你最初位于数组的第一个位置.数组中的每个元素代表你在该位置可以跳跃的最大长度.你的目标是使用最少的跳跃次数到达数组的最后一个位置.假设你总是 ...
- vue对vue-giant-tree进行节点操作
vue 项目中使用到了vue-giant-tree这个使用ztree封装的树形插件,在对其节点进行操作时遇到了无法向传统的jquery那样获取到ztreeObj:而导致了无法控制节点dom:浪费了许多 ...