当前位置 : 主页 > 编程语言 > c++ >

java通过jgit操作git本地仓库

来源:互联网 收集:自由互联 发布时间:2021-06-30
初始化jgit的Git实例 @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 FilenameFi
初始化jgit的Git实例
@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
 
   commitIterator = git.log().setMaxCount(1).add(master.getObjectId()).call().iterator();
            List
  
    masterCommitList = new LinkedList
   
    (); while (commitIterator.hasNext()) { RevCommit commit = commitIterator.next(); masterCommitList.add(commit); } // 判断master分支最新的commit是否在当前分支中 StringBuilder builder = new StringBuilder(); if (masterCommitList.size() > 0) { List
    
      refList = git.branchList().setContains(masterCommitList.get(0).getName()) .setListMode(ListBranchCommand.ListMode.REMOTE).call(); boolean found = false; String refBranchName = "refs/remotes/origin/" + branchName; for (Ref ref : refList) { if (ref.getName().equals(refBranchName)) { found = true; break; } } if (!found) { for (RevCommit revCommit : masterCommitList) { builder.append("commit ").append(revCommit.getName()).append(": ") .append(revCommit.getShortMessage()).append("\n"); } } } logger.info("================getNotMergedCommitsInMaster time {} ms, {}, {}, {}, {}", (System.currentTimeMillis() - time), branchName, gitPath, dir.getAbsolutePath()); return builder.toString(); } finally { lock.unlock(); } }
    
   
  
 
maven依赖
 
            
  
   org.eclipse.jgit
  
            
  
   org.eclipse.jgit
  
            
  
   4.5.0.201609210915-r
  
        
 
网友评论