如何使用JGIT在远程仓库获取提交详情记录
- 第一步:获取一个GIT对象
- 第二步:根据GIT对象获取所有的版本号
- 第三步:根据筛选的版本号获取指定的记录
这个是JGIT的API:https://download.eclipse.org/jgit/docs/jgit-2.0.0.201206130900-r/apidocs/org/eclipse/jgit/lib/Ref.html
第一步:获取一个GIT对象
在远程获取GIT时,大部分的时候第一步操作就是将远程仓库的项目克隆到本地,然后对本地的项目进行操作。不同与SVN,SVN可以无需将远程项目克隆到本地。
克隆分为两种,
第一:未使用JGIT之前,所需要的项目已经在本地GIT仓库存在了。
这种情况,需要使用Git.open(new File(“D:\GitCloneRepository” + File.separator + this.pjName));这个方法打开本地的GIT库获取一个GIT对象。
第二:本地没有,这时候就需要去远程仓库获取,代码在下面。克隆的时候需要设置远程的url、远程git的用户名和密码,然后指定本地仓库的位置即可。
下面的代码里,我还获取了,克隆下来项目的所有分支。并展示当前所使用的是哪个分支
!!!!!!JGIT远程获取时,默认获取master分支,使用setCheckFetchedObjects(true)方法,可以克隆所有分支到本地,然后从本地切换分支来操作。(本人使用)
切换分支方法: git.checkout().setCreateBranch(false).setName(branch).call();
public class GitUtil {
private Git git;// git对象
private String userName;// 资源库账户
private String pwd;// 密码
private String giturl;// git地址
private String pjName;// 项目名
private String branch;// 分支名
public GitUtil2(String userName, String pwd, String giturl, String pjName, String branch) throws Exception {
this.userName = userName;
this.pwd = pwd;
this.giturl = giturl;
this.pjName = pjName;
this.branch = branch;
// 如果是空,则默认使用master分支
if (null == branch || "".equals(branch)) {
branch = "master";
}
// 初始化一个git
initGit();
}
/**
* @方法简介:初始化一个GIT对象
*/
public void initGit() throws Exception {
// 如果目录存在就先更新后open
if (new File("D:\\GitCloneRepository" + File.separator + this.pjName).exists()) {
this.git = Git.open(new File("D:\\GitCloneRepository" + File.separator + this.pjName));
FetchResult resule = this.git.fetch()// 如果已经存在该库,就使用fetch刷新一下
.setCredentialsProvider(new UsernamePasswordCredentialsProvider(this.userName, this.pwd))//远程登录git的凭证
.setCheckFetchedObjects(true)
.call();
if (resule == null) {
throw new AppException("获取的Git对象已失效");
}
// 切换分支
git.checkout().setCreateBranch(false).setName(branch).call();
// 查看当前分支
//System.out.println(git.getRepository().getBranch());
} else {
// 如果不存在就clone
this.git = Git.cloneRepository().setURI(this.giturl)
.setCredentialsProvider(new UsernamePasswordCredentialsProvider(this.userName, this.pwd))
.setCloneAllBranches(true)//获取所有分支
.setDirectory(new File(DwtmNames.GitClonePath + File.separator + this.pjName))//指定本地clone库
.call();
// 查看所clone下的项目的所有分支
int c = 0;
List<Ref> call = this.git.branchList().call();
for (Ref ref : call) {
System.out.println("Branch: " + ref + " " + ref.getName() + " " + ref.getObjectId().getName());
c++;
}
System.out.println("Number of branches: " + c);
}
}
第二步:根据GIT对象获取所有的版本号
本人的需求是根据版本号的提交时间来筛选时间段内的记录,所以我获取到所有的版本号与提交时间,然后根据时间判断。
以下是获取所有版本号的代码:
/**
* @方法简介: 获取所有的版本号与版本号对应的时间戳
*/
public ArrayList<HashMap<String, Object>> getGitVersion()
throws NoHeadException, GitAPIException, BusinessException, AppException {
Iterable<RevCommit> logIterable = this.git.log().call();
Iterator<RevCommit> logIterator = logIterable.iterator();//获取所有版本号的迭代器
if (logIterator == null) {
throw new BusinessException("该项目暂无日志记录");
}
int row = 0;
ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
while (logIterator.hasNext()) {
HashMap<String, Object> map = new HashMap<String, Object>();
RevCommit commit = logIterator.next();
Date commitDate = commit.getAuthorIdent().getWhen(); //提交时间
String commitPerson = commit.getAuthorIdent().getName() ; //提交人
String commitID = commit.getName(); //提交的版本号(之后根据这个版本号去获取对应的详情记录)
map.put("version", commitID);
map.put("commitDate", commitDate);
map.put("commitPerson", commitPerson);
list.add(row, map);
row++;
}
return list;
}
第三步:根据筛选的版本号获取指定的记录
所谓的筛选版本号是根据个人需求来筛选,所以我就没有写自己的筛选,各位可以根据自己的需求来写。
我所了解到JGIT在根据版本号获取记录时,只能根据单个版本号来获取详情,不能根据范围来获取,但是JGIT有Range方法来设定获取范围,只不过这个方法是获取两个版本号之间的信息,这个信息依然只是版本号而不是详情记录。所以我只能根据筛选的多个版本号循环进行单个查询。
GIT存储记录的数据结构是Tree,所以JGIT提供对应的树结构对象TreeWalk,这个树对象的使用我还没有掌握,我所查到的相关资料比较少,各位谅解。
/**
* @方法简介 :根据指定版本号获取版本号下面的详情记录
*
*/
@SuppressWarnings("resource")
public HashMap<String, Object> getCommitLogList(String revision) throws Exception {
HashMap<String, Object> map = new HashMap<String, Object>();
// 通过git获取项目库
Repository repository = this.git.getRepository();
// 根据所需要查询的版本号查新ObjectId
ObjectId objId = repository.resolve(revision);
//根据版本号获取指定的详细记录
Iterable<RevCommit> allCommitsLater = git.log().add(objId).call();
if (allCommitsLater == null) {
throw new Exception("该提交版本下无当前查询用户的提交记录");
}
Iterator<RevCommit> iter = allCommitsLater.iterator();
RevCommit commit = iter.next();//提交对象
Date commitDate = commit.getAuthorIdent().getWhen();//提交时间
map.put("commitDate", commitDate);
String commitPerson = commit.getAuthorIdent().getName();//提交人
map.put("commitPerson", commitPerson);
String message = commit.getFullMessage();//提交日志
map.put("message", message);
// 给存储库创建一个树的遍历器
TreeWalk tw = new TreeWalk(repository);
// 将当前commit的树放入树的遍历器中
tw.addTree(commit.getTree());
commit = iter.next();
if (commit != null) {
tw.addTree(commit.getTree());
} else {
return null;
}
tw.setRecursive(true);
RenameDetector rd = new RenameDetector(repository);
rd.addAll(DiffEntry.scan(tw));
//获取到详细记录结果集 在这里就能获取到一个版本号对应的所有提交记录(详情!!!)
List<DiffEntry> list = rd.compute();
map.put("list", list);
return map;
}
我的使用就到此结束了,提交和回滚操作我没有使用到,网上的相关资料比较多一些,初次写这种东西,看到的人如有好的建议请指出,本人虚心接受。