一、jgit是什么
如果你想在一个 Java 程序中使用 Git ,有一个功能齐全的 Git 库,那就是 JGit 。 JGit 是一个用 Java 写成的功能相对健全的 Git 的实现,它在 Java 社区中被广泛使用。 JGit 项目由 Eclipse 维护。
二、引入jgit
<jgit.version>6.6.0.202305301015-r</jgit.version>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>${jgit.version}</version>
</dependency>
三、操作简介
1、初始化git环境
#初始化git环境
CredentialsProvider credential = GitUtils.createCredentialsProvider(cicdPropertiesInfo.getUserName(), cicdPropertiesInfo.getPassWord());
Git git = GitUtils.getGit(cicdPropertiesInfo.getGitUrl(), credential, localFilePath);
2、创建新分支
String targetBranchName = "release_" + System.currentTimeMillis();
String test = GitUtils.createBranch(git, credential, targetBranchName);
3、checkout
GitUtils.checkout(git, credential, cicdPropertiesInfo.getBranchName());
4、分支融合
MergeResult mergeResult = GitUtils.mergeBranch(git, cicdPropertiesInfo.getBranchName(), targetBranchName);
5、代码提交
boolean jgitCommit = GitUtils.commitFiles(git, credential, "*", "jgit commit");
四、封装的工具类
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.*;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.SymbolicRef;
import org.eclipse.jgit.transport.*;
import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
/**
* Git工具类
*
* @author chentiefeng
* @date 2021/2/10 14:02
*/
@Slf4j
public class GitUtils {
/**
* 提交文件到仓库 (包括新增的、更改的、删除的)
*
* @param git
* @param credential
* @param filePattern
* @param commitMessage
* @return
* @throws GitAPIException
* @throws IOException
*/
public static boolean commitFiles(Git git, CredentialsProvider credential, String filePattern, String commitMessage) throws GitAPIException, IOException {
//添加
git.add().addFilepattern(filePattern).call();
git.add().addFilepattern(filePattern).setUpdate(true).call();
//提交
git.commit().setMessage(commitMessage).call();
//推送到远程
Iterable<PushResult> pushResults = git.push().setCredentialsProvider(credential).call();
printCommitPushResult(pushResults, git.getRepository().getBranch(), commitMessage);
return true;
}
/**
* 打印提交文件的日志
*
* @param results
*/
private static void printCommitPushResult(Iterable<PushResult> results, String branchName, String commitMessage) {
log.info("git add && git commit -m '{}'", commitMessage);
log.info("git push");
for (PushResult result : results) {
RemoteRefUpdate remoteRefUpdate = result.getRemoteUpdate(GitBranchType.LOCAL.getPrefix() + branchName);
if (Status.OK.equals(remoteRefUpdate.getStatus())) {
log.info("remote: " + result.getMessages().substring(0, result.getMessages().length() - 1));
} else {
log.error("remote: " + result.getMessages());
}
log.info("To {}", result.getURI());
}
}
/**
* 删除分支
*
* @param git
* @param credential
* @param branchName
* @return
* @throws GitAPIException
* @throws IOException
*/
public static boolean removeBranch(Git git, CredentialsProvider credential, String branchName) throws GitAPIException, IOException {
// master分支不能删除
if ("master".equals(branchName)) {
return false;
}
String oldBranch = git.getRepository().getBranch();
//如果要删除的分支等于当前分支,切换到master
if (oldBranch.equals(branchName)) {
git.checkout().setName("master").call();
}
git.branchDelete().setBranchNames(GitBranchType.LOCAL.getPrefix() + branchName).setForce(true).call();
git.branchDelete().setBranchNames(GitBranchType.REMOTE.getPrefix() + branchName).setForce(true).call();
//推送到远程
String branchFullName = GitBranchType.LOCAL.getPrefix() + branchName;
RefSpec refSpec = new RefSpec(":" + branchFullName).setForceUpdate(true);
Iterable<PushResult> results = git.push().setCredentialsProvider(credential).setRefSpecs(refSpec).call();
printRemoveBranchResult(results, branchFullName, branchName);
return true;
}
/**
* 打印删除分支的日志
*
* @param results
* @param branchFullName
*/
private static void printRemoveBranchResult(Iterable<PushResult> results, String branchFullName, String branchName) {
log.info("git push origin --delete {}", branchName);
for (PushResult result : results) {
RemoteRefUpdate remoteRefUpdate = result.getRemoteUpdate(branchFullName);
if (Status.OK.equals(remoteRefUpdate.getStatus())) {
log.info("remote: " + result.getMessages().substring(0, result.getMessages().length() - 1));
} else {
log.error("remote: " + result.getMessages());
}
log.info("To {}", result.getURI());
log.info("- [deleted] {}", branchName);
}
}
/**
* 创建分支
*
* @param git
* @param branchName
* @return
* @throws GitAPIException
* @throws IOException
*/
public static String createBranch(Git git, CredentialsProvider credential, String branchName) throws GitAPIException, IOException {
//如果本地存在分支,直接返回
if (getBranches(git, GitBranchType.LOCAL).contains(branchName)) {
return branchName;
}
//如果远端存在分支,则创建本地分支
if (getBranches(git, GitBranchType.REMOTE).contains(branchName)) {
String oldBranch = git.getRepository().getBranch();
git.checkout().setName(branchName).setCreateBranch(true).call();
git.checkout().setName(oldBranch).call();
return branchName;
}
//新建分支
git.branchCreate().setName(branchName).call();
String oldBranch = git.getRepository().getBranch();
git.checkout().setName(branchName).call();
//推送到远程
git.push().setCredentialsProvider(credential).call();
git.checkout().setName(oldBranch).call();
return branchName;
}
/**
* 获取所有分支
*
* @param git
* @param branchType 分支类型,分为本地分支和远程分支
* @return
* @throws GitAPIException
* @throws IOException
*/
public static List<String> getBranches(Git git, GitBranchType branchType) throws GitAPIException, IOException {
if (GitBranchType.LOCAL.equals(branchType)) {
List<Ref> refs = git.branchList().call();
return refs.stream().map(ref -> ref.getName().substring(GitBranchType.LOCAL.getPrefix().length()))
.collect(Collectors.toList());
} else {
List<Ref> refs = git.getRepository().getRefDatabase().getRefs();
return refs.stream().filter(item -> !(item instanceof SymbolicRef))
.filter(item -> item.getName().startsWith(GitBranchType.REMOTE.getPrefix()))
.map(ref -> ref.getName().substring(GitBranchType.REMOTE.getPrefix().length()))
.collect(Collectors.toList());
}
}
/**
* 获取git对象
*
* @param gitUrl git的http路径
* @param credentialsProvider 认证
* @param localPath 本地路径
* @return
* @throws IOException
* @throws GitAPIException
*/
public static Git getGit(String gitUrl, CredentialsProvider credentialsProvider, String localPath) throws IOException, GitAPIException {
if (new File(localPath).exists()) {
return Git.open(new File(localPath));
} else {
return Git.cloneRepository().setCredentialsProvider(credentialsProvider).setURI(gitUrl)
.setDirectory(new File(localPath)).call();
}
}
/**
* 关闭git
*
* @param git
*/
public static void closeGit(Git git) {
git.close();
}
/**
* 创建Git认证信息
*
* @param username
* @param password
* @return
*/
public static CredentialsProvider createCredentialsProvider(String username, String password) {
return new UsernamePasswordCredentialsProvider(username, password);
}
/**
* 代码合并
*
* @param git
* @param sourceBranchName
* @param targetBranchName
* @return
* @throws Exception
*/
public static MergeResult mergeBranch(Git git, String sourceBranchName, String targetBranchName) throws Exception {
Ref refdev = git.checkout().setName(sourceBranchName).call(); //切换源头分支获取源头分支信息
git.checkout().setName(targetBranchName).call(); //切换回被合并分支
// git merge [sourceBranchName]
MergeResult mergeResult = git.merge().include(refdev) // 合并源头分支到目标分支
.setCommit(true) // 设置合并后同时提交
.setFastForward(MergeCommand.FastForwardMode.NO_FF)// 分支合并策略,--ff代表快速合并, --no-ff代表普通合并
.setMessage("Merge sourceBranchName into targetBranchName.") //设置提交信息
.call();
return mergeResult;
}
/**
* 拉代码
*
* @param git
* @param credentialsProvider
* @return
* @throws Exception
*/
public static PullResult pull(Git git, CredentialsProvider credentialsProvider, String branchName) throws Exception {
PullResult call = git.pull().setCredentialsProvider(credentialsProvider).setRemoteBranchName(branchName).call();
return call;
}
public static void checkout(Git git, CredentialsProvider credentialsProvider, String branchName) throws Exception {
git.pull().setCredentialsProvider(credentialsProvider).setRemoteBranchName(branchName).call();
boolean existBranch = false;
//列出所有的分支名称,判断分支是否存在
List<Ref> branchList = git.branchList().setListMode(ListBranchCommand.ListMode.ALL).call();
for (Ref ref : branchList) {
if (("refs/remotes/origin/" + branchName).equals(ref.getName())) {
existBranch = true;
}
}
if (!existBranch) {
log.error("分支{}不存在,请确认", branchName);
throw new RuntimeException(
"分支" + branchName + "不存在,请确认");
}
boolean existLocalBranch = false;
branchList = git.branchList().call();
for (Ref ref : branchList) {
if (ref.getName().equals("refs/heads/" + branchName)) {
existLocalBranch = true;
}
}
if (existLocalBranch) {
// 存在则切换本地分支
git.checkout().setName(branchName).call();
} else {
// 不存在则切换为远程分支
git.checkout().setCreateBranch(true).setName(branchName)
.setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
.setStartPoint("origin/" + branchName).call();
}
}
}