最近設(shè)計(jì)基于gitops新的CICD方案,需要通過(guò)java讀寫git倉(cāng)庫(kù),這里簡(jiǎn)單記錄下。
在jgit中,存在最核心的三個(gè)組件:Git類,Repository類。Git類中包含了push commit之類的常見(jiàn)git操作,而Repository則實(shí)現(xiàn)了倉(cāng)庫(kù)的初始化和基本的管理功能。
Git類的實(shí)例都會(huì)持有一個(gè)Repository實(shí)例。
Repository類的初始化
針對(duì)一個(gè)git倉(cāng)庫(kù),我們一般會(huì)有三種方式獲得
1.新建一個(gè)空倉(cāng)庫(kù)
Git git = Git.init().setDirectory(localPath).call()
2.加載一個(gè)已存在的倉(cāng)庫(kù)
Repository repository = builder.setGitDir(repoDir) .readEnvironment() // scan environment GIT_* variables .findGitDir() // scan up the file system tree .build()
3.從遠(yuǎn)程倉(cāng)庫(kù)下載
Git result = Git.cloneRepository() .setURI(REMOTE_URL) .setDirectory(localPath) .call()
JGit是一款pure java的軟件包,可以讀寫git倉(cāng)庫(kù),下面介紹基本使用。
引入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 有一個(gè)Git類,可以用來(lái)執(zhí)行常規(guī)的git操作
憑證管理#
通過(guò)CredentialsProvider
管理憑證,常用的是UsernamePasswordCredentialsProvider
通過(guò)下面代碼初始化:
public static CredentialsProvider createCredential(String userName, String password) {
return new UsernamePasswordCredentialsProvider(userName, password);
}
clone遠(yuǎn)程倉(cāng)庫(kù)#
git 命令:
git clone {repoUrl}
通過(guò)Git.cloneRepository 來(lái)clone遠(yuǎn)程倉(cāng)庫(kù),如果需要憑證,則需要指定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比較簡(jiǎn)單,對(duì)應(yīng)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直接調(diào)用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();
}
讀取已有倉(cāng)庫(kù)#
如果git已經(jīng)clone了,想直接讀取,怎么辦?
public static Repository getRepositoryFromDir(String dir) throws IOException {
return new FileRepositoryBuilder()
.setGitDir(Paths.get(dir, ".git").toFile())
.build();
}
讀取倉(cāng)庫(kù)日志#
可以通過(guò)RevWalk讀取倉(cāng)庫(kù)日志。
- 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;
}
測(cè)試#
我們來(lái)先clone倉(cāng)庫(kù),然后修改,最后push文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-520897.html
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
* |要帶著問(wèn)題去學(xué)習(xí),多猜想多驗(yàn)證|
**/
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 到遠(yuǎn)程倉(cāng)庫(kù)
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
* |要帶著問(wèn)題去學(xué)習(xí),多猜想多驗(yàn)證|
**/
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;
}
}
讀取已有倉(cāng)庫(kù)的日志:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-520897.html
Repository repository = getRepositoryFromDir("GIT_DIR");
List<String> logs = getLogs(repository);
System.out.println(logs);
RevCommit head = getLastCommit(repository);
System.out.println(head.getFullMessage());
到了這里,關(guān)于DevOps系列文章 之 Java使用jgit管理git倉(cāng)庫(kù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!