Java操作Git之JGit
Java操作Git之JGit
博文地址:https://www.cnblogs.com/imchentiefeng/articles/java-git-jgit.html
git地址:Java操作Git之JGit.md
背景
最近在做的项目中,有需求需要向git仓库上传文件,于是考虑到了在项目中通过Java代码来操作git仓库,记得以前自己搭建过Gitblit环境,它是一个开源的、基于Java编写的Git服务端,于是下载了Gitblit的源码,看到是基于JGit进行的封装,于是通过查看源码,加上参考JGit API 在线官方文档以及JGit Cookbook,编写了一个供自己使用的工具类,现分享给大家。
开始
1、引入依赖
我这里使用的Maven环境,引入依赖如下:
<!-- https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit -->
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>5.10.0.202012080955-r</version>
</dependency>
2、git分支类型
考虑到仓库分为本地仓库和远端仓库,我创建了一个枚举帮助后面的工具类中使用,如下:
import lombok.Getter;
/**
* git分支类型
*
* @author chentiefeng
* @date 2021/2/10 15:03
*/
@Getter
public enum GitBranchType {
/**
* 本地分支
*/
LOCAL("refs/heads/"),
/**
* 远程分支
*/
REMOTE("refs/remotes/origin/");
/**
* 分支前缀
*/
private String prefix;
GitBranchType(String prefix) {
this.prefix = prefix;
}
}
3、工具类
工具类内容如下:
import com.chen.common.git.enums.GitBranchType;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.SymbolicRef;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.PushResult;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
/**
* Git工具类
* 更多jgit的操作,请看:
* 官方文档:http://archive.eclipse.org/jgit/site/3.7.0.201502260915-r/index.html
* 示例代码:https://github.com/centic9/jgit-cookbook
* @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);
}
}
4、测试工具类
测试如下:
/**
* Git工具类测试
* @author chentiefeng
* @date 2021/2/10 14:02
*/
public class GitUtilsTest {
public static void main(String[] args) throws IOException, GitAPIException {
String gitUrl = "https://gitee.com/smart-it-work/smart-stream.git";
String username = "imchentiefeng@aliyun.com";
String password = "********";
String localDir = "D:\\test\\smart-stream";
CredentialsProvider credential = GitUtils.createCredentialsProvider(username, password);
Git git = GitUtils.getGit(gitUrl, credential, localDir);
List<String> localBranches = GitUtils.getBranches(git, GitBranchType.LOCAL);
List<String> remoteBranches = GitUtils.getBranches(git, GitBranchType.REMOTE);
String test = GitUtils.createBranch(git, credential, "test");
boolean flag = GitUtils.removeBranch(git, credential, "test");
boolean commitFlag = GitUtils.commitFiles(git, credential, ".", "test");
GitUtils.closeGit(git);
}
}

浙公网安备 33010602011771号