JGit常用功能(提交、回滚、日志查询)—优化
之前写的一篇有些bug,而且里面的概念也没搞清楚,查询了《Git权威指南》后又优化了一下,如下:
public class GitUtil {
private final static String GIT = ".git";
private final static String REF_REMOTES = "refs/remotes/origin/";
/**
* 将文件列表提交到git仓库中
* @param gitRoot git仓库目录
* @param files 需要提交的文件列表
* @param remark 备注
* @return 返回本次提交的版本号
* @throws IOException
*/
public static String commitToGitRepository(String gitRoot, List<String> files, String remark)
throws Exception {
if (StringUtils.isNotBlank(gitRoot) && files != null && files.size() > 0) {
File rootDir = new File(gitRoot);
//初始化git仓库
if (new File(gitRoot + File.separator + GIT).exists() == false) {
Git.init().setDirectory(rootDir).call();
}
//打开git仓库
Git git = Git.open(rootDir);
//判断工作区与暂存区的文件内容是否有变更
List<DiffEntry> diffEntries = git.diff()
.setPathFilter(PathFilterGroup.createFromStrings(files))
.setShowNameAndStatusOnly(true).call();
if (diffEntries == null || diffEntries.size() == 0) {
throw new Exception("提交的文件内容都没有被修改,不能提交");
}
//被修改过的文件
List<String> updateFiles = new ArrayList<String>();
ChangeType changeType;
for (DiffEntry entry : diffEntries) {
changeType = entry.getChangeType();
switch (changeType) {
case ADD:
case COPY:
case RENAME:
case MODIFY:
updateFiles.add(entry.getNewPath());
break;
case DELETE:
updateFiles.add(entry.getOldPath());
break;
}
}
//将文件提交到git仓库中,并返回本次提交的版本号
//1、将工作区的内容更新到暂存区
AddCommand addCmd = git.add();
for (String file : updateFiles) {
addCmd.addFilepattern(file);
}
addCmd.call();
//2、commit
CommitCommand commitCmd = git.commit();
for (String file : updateFiles) {
commitCmd.setOnly(file);
}
RevCommit revCommit = commitCmd.setCommitter("yonge", "[email protected]")
.setMessage(remark).call();
return revCommit.getName();
}
return null;
}
/**
* 回滚到指定版本的上一个版本
* @param gitRoot git仓库目录
* @param diffEntries 需要回滚的文件
* @param revision 版本号
* @param remark 备注
* @return
* @throws Exception
*/
public static boolean rollBackPreRevision(String gitRoot, List<DiffEntry> diffEntries,
String revision, String remark) throws Exception {
if (diffEntries == null || diffEntries.size() == 0) {
throw new Exception("没有需要回滚的文件");
}
Git git = Git.open(new File(gitRoot));
List<String> files = new ArrayList<String>();
//注意:下面的reset命令会将暂存区的内容恢复到指定(revesion)的状态,相当于取消add命令的操作
/*Repository repository = git.getRepository();
RevWalk walk = new RevWalk(repository);
ObjectId objId = repository.resolve(revision);
RevCommit revCommit = walk.parseCommit(objId);
String preVision = revCommit.getParent(0).getName();
ResetCommand resetCmd = git.reset();
for (String file : files) {
resetCmd.addPath(file);
}
resetCmd.setRef(preVision).call();
repository.close();*/
//取出需要回滚的文件,新增的文件不回滚
for (DiffEntry diffEntry : diffEntries) {
if (diffEntry.getChangeType() == ChangeType.DELETE) {
continue;
} else {
files.add(diffEntry.getNewPath());
}
}
if (files.size() == 0) {
throw new Exception("没有需要回滚的文件");
}
//checkout操作会丢失工作区的数据,暂存区和工作区的数据会恢复到指定(revision)的版本内容
CheckoutCommand checkoutCmd = git.checkout();
for (String file : files) {
checkoutCmd.addPath(file);
}
//加了“^”表示指定版本的前一个版本,如果没有上一版本,在命令行中会报错,例如:error: pathspec '4.vm' did not match any file(s) known to git.
checkoutCmd.setStartPoint(revision + "^");
checkoutCmd.call();
//重新提交一次
CommitCommand commitCmd = git.commit();
for (String file : files) {
commitCmd.setOnly(file);
}
commitCmd.setCommitter("yonge", "[email protected]").setMessage(remark).call();
return true;
}
/**
* 获取上一版本的变更记录,如果是新增的文件,不会显示,因为做回滚时不需要回滚新增的文件
* @param gitRoot git仓库目录
* @param revision 版本号
* @return
* @throws Exception
*/
public static List<DiffEntry> rollBackFile(String gitRoot, String revision) throws Exception {
Git git = Git.open(new File(gitRoot));
Repository repository = git.getRepository();
ObjectId objId = repository.resolve(revision);
Iterable<RevCommit> allCommitsLater = git.log().add(objId).call();
Iterator<RevCommit> iter = allCommitsLater.iterator();
RevCommit commit = iter.next();
TreeWalk tw = new TreeWalk(repository);
tw.addTree(commit.getTree());
commit = iter.next();
if (commit != null) {
tw.addTree(commit.getTree());
} else {
throw new Exception("当前库只有一个版本,不能获取变更记录");
}
tw.setRecursive(true);
RenameDetector rd = new RenameDetector(repository);
rd.addAll(DiffEntry.scan(tw));
List<DiffEntry> diffEntries = rd.compute();
if (diffEntries == null || diffEntries.size() == 0) {
return diffEntries;
}
Iterator<DiffEntry> iterator = new ArrayList<DiffEntry>(diffEntries).iterator();
DiffEntry diffEntry = null;
while (iterator.hasNext()) {
diffEntry = iterator.next();
System.out.println("newPath:" + diffEntry.getNewPath() + " oldPath:"
+ diffEntry.getOldPath() + " changeType:"
+ diffEntry.getChangeType());
if (diffEntry.getChangeType() == ChangeType.DELETE) {
iterator.remove();
}
}
return diffEntries;
}
}可能里面还会有一些问题,若发现请留言,谢谢!!
相关推荐
Lzs 2020-10-23
聚合室 2020-11-16
零 2020-09-18
Justhavefun 2020-10-22
ChaITSimpleLove 2020-10-06
周游列国之仕子 2020-09-15
afanti 2020-09-16
88234852 2020-09-15
YClimb 2020-09-15
风雨断肠人 2020-09-04
卖口粥湛蓝的天空 2020-09-15
stulen 2020-09-15
pythonxuexi 2020-09-06
abfdada 2020-08-26
梦的天空 2020-08-25