如何使用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;
	}

我的使用就到此结束了,提交和回滚操作我没有使用到,网上的相关资料比较多一些,初次写这种东西,看到的人如有好的建议请指出,本人虚心接受。