如何使用jgit库对本地git仓库进行操作?
- 内容介绍
- 文章标签
- 相关推荐
本文共计962个文字,预计阅读时间需要4分钟。
初始化jgit的Git实例:javaprivate String gitDir;
private void ensureGitWorkDir(String gitPath, File dir) throws Exception { if (dir.exists() && dir.isDirectory()) { // 代码省略... }}
@Value("${git.repository.dir}") private String gitDir; private void ensureGitWorkDir(String gitPath, File dir) throws Exception { if (dir.exists() && dir.isDirectory()) { if (ArrayUtils.isEmpty(dir.list(new FilenameFilter() { @Override public boolean accept(File parentDir, String name) { return name.endsWith(".git"); } }))) { gitClone(gitPath, dir); } if (gitRepositoryMap.get(dir.getAbsolutePath()) == null) { gitRepositoryMap.putIfAbsent(dir.getAbsolutePath(), Git.open(dir)); } return; } ReentrantLock lock = getLock(dir.getAbsolutePath()); try { lock.lock(); if (!dir.exists()) { dir.mkdirs(); } if (!dir.isDirectory()) { String path = dir.getAbsolutePath(); dir.renameTo(new File(dir.getAbsoluteFile().getParentFile(), dir.getName() + "_" + System.currentTimeMillis())); dir = new File(path); dir.mkdirs(); } if (ArrayUtils.isEmpty(dir.list())) { gitClone(gitPath, dir); } } finally { lock.unlock(); } } 执行git的clone
private void gitClone(String gitPath, File dir) throws Exception { ReentrantLock lock = getLock(dir.getAbsolutePath()); try { lock.lock(); long time = System.currentTimeMillis(); Git git = Git.cloneRepository().setDirectory(dir).setURI(gitPath).call(); gitRepositoryMap.putIfAbsent(dir.getAbsolutePath(), git); logger.info("================gitClone time {} ms: {}, {}", (System.currentTimeMillis() - time), gitPath, dir.getAbsolutePath()); } finally { lock.unlock(); } } 打tag
/** * 按commit hash来打tag */ public void tagByCommitHash(String gitPath, String branchName, String commitHash, String tagNameNew) throws Exception { tagByRef(gitPath, branchName, commitHash, tagNameNew); } /** * 按branch上的HEAD来打tag */ public void tagByBranchName(String gitPath, String branchName, String tagNameNew) throws Exception { tagByRef(gitPath, branchName, "refs/remotes/origin/" + branchName, tagNameNew); } /** * 按tag来打tag */ public void tagByTagName(String gitPath, String branchName, String tagNameOld, String tagNameNew) throws Exception { tagByRef(gitPath, branchName, "refs/tags/" + tagNameOld, tagNameNew); } private void tagByRef(String gitPath, String branchName, String tagRef, String tagNameNew) throws Exception { File dir = new File(gitDir, DigestUtils.md5DigestAsHex(gitPath.getBytes(StandardCharsets.UTF_8))); ReentrantLock lock = getLock(dir.getAbsolutePath()); try { lock.lock(); ensureGitWorkDir(gitPath, dir); long time = System.currentTimeMillis(); Git git = gitRepositoryMap.get(dir.getAbsolutePath()); git.fetch().setTagOpt(TagOpt.FETCH_TAGS) .setRefSpecs(new RefSpec("refs/heads/*:refs/remotes/origin/*")) .call(); // 判断tag是否已存在 List tagList = git.tagList().call(); if (tagList != null) { for (Ref ref : tagList) { if (ref.getName().endsWith(tagNameNew)) { throw new RuntimeException( String.format("tag %s already exists: %s, %s", tagNameNew, gitPath, dir.getAbsolutePath())); } } } // 打tag: 先判断旧tag、branch或commit是否存在,然后打tag并push ObjectId objectId = null; if (tagRef.contains("/")) { Ref ref = git.getRepository().findRef(tagRef); if (null != ref) objectId = ref.getObjectId(); } else { objectId = git.getRepository().resolve(tagRef + "^{commit}"); } if (objectId == null) { throw new RuntimeException( String.format("tag by %s can't be applied because it not exist: %s, %s", tagRef, gitPath, dir.getAbsolutePath())); } RevWalk walk = new RevWalk(git.getRepository()); RevCommit commit = walk.parseCommit(objectId); Ref tagNew = git.tag().setName(tagNameNew).setObjectId(commit).call(); PushResult pushResult = git.push().add(tagNew).call().iterator().next(); logger.info("================tagByRef time {} ms, {}, {}, {}", (System.currentTimeMillis() - time), gitPath, dir.getAbsolutePath(), pushResult.getRemoteUpdate(tagNew.getName()).getStatus()); } finally { lock.unlock(); } } 合并tag到分支
/** * 合并tag到分支 */ public void mergeTagToBranch(String gitPath, String branchName, String tagName) throws Exception { File dir = new File(gitDir, DigestUtils.md5DigestAsHex(gitPath.getBytes(StandardCharsets.UTF_8))); ensureGitWorkDir(gitPath, dir); ReentrantLock lock = getLock(dir.getAbsolutePath()); try { lock.lock(); long time = System.currentTimeMillis(); Git git = gitRepositoryMap.get(dir.getAbsolutePath()); git.fetch().setTagOpt(TagOpt.FETCH_TAGS) .setRefSpecs(new RefSpec("refs/heads/*:refs/remotes/origin/*")) .call(); git.checkout().setName(branchName).setStartPoint("refs/remotes/origin/" + branchName).setForce(true).call(); Ref ref = git.getRepository().findRef(tagName); if (null == ref) throw new RuntimeException( String.format("pull failed, tag '%s' not exists: %s, %s", tagName, gitPath, dir.getAbsolutePath())); MergeResult mergeResult = git.merge().include(ref) .setFastForward(MergeCommand.FastForwardMode.FF_ONLY) .setMessage(String.format("merge tag '%s' into %s", tagName, branchName)).call(); if (!mergeResult.getMergeStatus().isSuccessful()) { // merge失败时reset git.reset().setMode(ResetCommand.ResetType.HARD).setRef("remotes/origin/" + branchName).call(); throw new RuntimeException(String.format("mergeTagToBranch merge failed: %s, %s, %s, %s", tagName, branchName, gitPath, dir.getAbsolutePath())); } PushResult pushResult = git.push().call().iterator().next(); RemoteRefUpdate.Status pushStatus = pushResult.getRemoteUpdates().iterator().next().getStatus(); if (!pushStatus.equals(RemoteRefUpdate.Status.OK) && !pushStatus.equals(RemoteRefUpdate.Status.UP_TO_DATE)) { git.reset().setMode(ResetCommand.ResetType.HARD).setRef("remotes/origin/" + branchName).call(); throw new RuntimeException(String.format("mergeTagToBranch merge success but push failed: %s, %s, %s, %s", tagName, branchName, gitPath, dir.getAbsolutePath())); } logger.info("================mergeTagToBranch time {} ms, {}, {}, {}, {}, {}", (System.currentTimeMillis() - time), pushStatus, tagName, branchName, gitPath, dir.getAbsolutePath()); } finally { lock.unlock(); } } 判断master分支上是否有commit没有合并到特定分支
/**
* 查询git仓库中,master分支上未合并到本分支的代码;如果有这种代码,返回commit的log信息
*/
public String notMergedCommitsInMaster(String gitPath, String branchName) throws Exception {
File dir = new File(gitDir, DigestUtils.md5DigestAsHex(gitPath.getBytes(StandardCharsets.UTF_8)));
ensureGitWorkDir(gitPath, dir);
ReentrantLock lock = getLock(dir.getAbsolutePath());
try {
lock.lock();
long time = System.currentTimeMillis();
// fetch最新代码
Git git = gitRepositoryMap.get(dir.getAbsolutePath());
git.fetch().setTagOpt(TagOpt.FETCH_TAGS)
.setRefSpecs(new RefSpec("refs/heads/*:refs/remotes/origin/*"))
.call();
// 判断是否有master分支
Ref master = git.getRepository().findRef("refs/remotes/origin/master");
if (master == null) {
throw new RuntimeException(String.format("getNotMergedCommitsInMaster failed, can't find master branch in %s, %s",
gitPath, dir.getAbsolutePath()));
}
// 获取master最新的3条commit log
Iterator
本文共计962个文字,预计阅读时间需要4分钟。
初始化jgit的Git实例:javaprivate String gitDir;
private void ensureGitWorkDir(String gitPath, File dir) throws Exception { if (dir.exists() && dir.isDirectory()) { // 代码省略... }}
@Value("${git.repository.dir}") private String gitDir; private void ensureGitWorkDir(String gitPath, File dir) throws Exception { if (dir.exists() && dir.isDirectory()) { if (ArrayUtils.isEmpty(dir.list(new FilenameFilter() { @Override public boolean accept(File parentDir, String name) { return name.endsWith(".git"); } }))) { gitClone(gitPath, dir); } if (gitRepositoryMap.get(dir.getAbsolutePath()) == null) { gitRepositoryMap.putIfAbsent(dir.getAbsolutePath(), Git.open(dir)); } return; } ReentrantLock lock = getLock(dir.getAbsolutePath()); try { lock.lock(); if (!dir.exists()) { dir.mkdirs(); } if (!dir.isDirectory()) { String path = dir.getAbsolutePath(); dir.renameTo(new File(dir.getAbsoluteFile().getParentFile(), dir.getName() + "_" + System.currentTimeMillis())); dir = new File(path); dir.mkdirs(); } if (ArrayUtils.isEmpty(dir.list())) { gitClone(gitPath, dir); } } finally { lock.unlock(); } } 执行git的clone
private void gitClone(String gitPath, File dir) throws Exception { ReentrantLock lock = getLock(dir.getAbsolutePath()); try { lock.lock(); long time = System.currentTimeMillis(); Git git = Git.cloneRepository().setDirectory(dir).setURI(gitPath).call(); gitRepositoryMap.putIfAbsent(dir.getAbsolutePath(), git); logger.info("================gitClone time {} ms: {}, {}", (System.currentTimeMillis() - time), gitPath, dir.getAbsolutePath()); } finally { lock.unlock(); } } 打tag
/** * 按commit hash来打tag */ public void tagByCommitHash(String gitPath, String branchName, String commitHash, String tagNameNew) throws Exception { tagByRef(gitPath, branchName, commitHash, tagNameNew); } /** * 按branch上的HEAD来打tag */ public void tagByBranchName(String gitPath, String branchName, String tagNameNew) throws Exception { tagByRef(gitPath, branchName, "refs/remotes/origin/" + branchName, tagNameNew); } /** * 按tag来打tag */ public void tagByTagName(String gitPath, String branchName, String tagNameOld, String tagNameNew) throws Exception { tagByRef(gitPath, branchName, "refs/tags/" + tagNameOld, tagNameNew); } private void tagByRef(String gitPath, String branchName, String tagRef, String tagNameNew) throws Exception { File dir = new File(gitDir, DigestUtils.md5DigestAsHex(gitPath.getBytes(StandardCharsets.UTF_8))); ReentrantLock lock = getLock(dir.getAbsolutePath()); try { lock.lock(); ensureGitWorkDir(gitPath, dir); long time = System.currentTimeMillis(); Git git = gitRepositoryMap.get(dir.getAbsolutePath()); git.fetch().setTagOpt(TagOpt.FETCH_TAGS) .setRefSpecs(new RefSpec("refs/heads/*:refs/remotes/origin/*")) .call(); // 判断tag是否已存在 List tagList = git.tagList().call(); if (tagList != null) { for (Ref ref : tagList) { if (ref.getName().endsWith(tagNameNew)) { throw new RuntimeException( String.format("tag %s already exists: %s, %s", tagNameNew, gitPath, dir.getAbsolutePath())); } } } // 打tag: 先判断旧tag、branch或commit是否存在,然后打tag并push ObjectId objectId = null; if (tagRef.contains("/")) { Ref ref = git.getRepository().findRef(tagRef); if (null != ref) objectId = ref.getObjectId(); } else { objectId = git.getRepository().resolve(tagRef + "^{commit}"); } if (objectId == null) { throw new RuntimeException( String.format("tag by %s can't be applied because it not exist: %s, %s", tagRef, gitPath, dir.getAbsolutePath())); } RevWalk walk = new RevWalk(git.getRepository()); RevCommit commit = walk.parseCommit(objectId); Ref tagNew = git.tag().setName(tagNameNew).setObjectId(commit).call(); PushResult pushResult = git.push().add(tagNew).call().iterator().next(); logger.info("================tagByRef time {} ms, {}, {}, {}", (System.currentTimeMillis() - time), gitPath, dir.getAbsolutePath(), pushResult.getRemoteUpdate(tagNew.getName()).getStatus()); } finally { lock.unlock(); } } 合并tag到分支
/** * 合并tag到分支 */ public void mergeTagToBranch(String gitPath, String branchName, String tagName) throws Exception { File dir = new File(gitDir, DigestUtils.md5DigestAsHex(gitPath.getBytes(StandardCharsets.UTF_8))); ensureGitWorkDir(gitPath, dir); ReentrantLock lock = getLock(dir.getAbsolutePath()); try { lock.lock(); long time = System.currentTimeMillis(); Git git = gitRepositoryMap.get(dir.getAbsolutePath()); git.fetch().setTagOpt(TagOpt.FETCH_TAGS) .setRefSpecs(new RefSpec("refs/heads/*:refs/remotes/origin/*")) .call(); git.checkout().setName(branchName).setStartPoint("refs/remotes/origin/" + branchName).setForce(true).call(); Ref ref = git.getRepository().findRef(tagName); if (null == ref) throw new RuntimeException( String.format("pull failed, tag '%s' not exists: %s, %s", tagName, gitPath, dir.getAbsolutePath())); MergeResult mergeResult = git.merge().include(ref) .setFastForward(MergeCommand.FastForwardMode.FF_ONLY) .setMessage(String.format("merge tag '%s' into %s", tagName, branchName)).call(); if (!mergeResult.getMergeStatus().isSuccessful()) { // merge失败时reset git.reset().setMode(ResetCommand.ResetType.HARD).setRef("remotes/origin/" + branchName).call(); throw new RuntimeException(String.format("mergeTagToBranch merge failed: %s, %s, %s, %s", tagName, branchName, gitPath, dir.getAbsolutePath())); } PushResult pushResult = git.push().call().iterator().next(); RemoteRefUpdate.Status pushStatus = pushResult.getRemoteUpdates().iterator().next().getStatus(); if (!pushStatus.equals(RemoteRefUpdate.Status.OK) && !pushStatus.equals(RemoteRefUpdate.Status.UP_TO_DATE)) { git.reset().setMode(ResetCommand.ResetType.HARD).setRef("remotes/origin/" + branchName).call(); throw new RuntimeException(String.format("mergeTagToBranch merge success but push failed: %s, %s, %s, %s", tagName, branchName, gitPath, dir.getAbsolutePath())); } logger.info("================mergeTagToBranch time {} ms, {}, {}, {}, {}, {}", (System.currentTimeMillis() - time), pushStatus, tagName, branchName, gitPath, dir.getAbsolutePath()); } finally { lock.unlock(); } } 判断master分支上是否有commit没有合并到特定分支
/**
* 查询git仓库中,master分支上未合并到本分支的代码;如果有这种代码,返回commit的log信息
*/
public String notMergedCommitsInMaster(String gitPath, String branchName) throws Exception {
File dir = new File(gitDir, DigestUtils.md5DigestAsHex(gitPath.getBytes(StandardCharsets.UTF_8)));
ensureGitWorkDir(gitPath, dir);
ReentrantLock lock = getLock(dir.getAbsolutePath());
try {
lock.lock();
long time = System.currentTimeMillis();
// fetch最新代码
Git git = gitRepositoryMap.get(dir.getAbsolutePath());
git.fetch().setTagOpt(TagOpt.FETCH_TAGS)
.setRefSpecs(new RefSpec("refs/heads/*:refs/remotes/origin/*"))
.call();
// 判断是否有master分支
Ref master = git.getRepository().findRef("refs/remotes/origin/master");
if (master == null) {
throw new RuntimeException(String.format("getNotMergedCommitsInMaster failed, can't find master branch in %s, %s",
gitPath, dir.getAbsolutePath()));
}
// 获取master最新的3条commit log
Iterator

