• JAVA 使用jgit管理git仓库


    最近设计基于gitops新的CICD方案,需要通过java读写git仓库,这里简单记录下。

    JGit是一款pure java的软件包,可以读写git仓库,下面介绍基本使用。

    引入jgit

    maven引入:

            <!-- https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit -->
            <dependency>
                <groupId>org.eclipse.jgit</groupId>
                <artifactId>org.eclipse.jgit</artifactId>
                <version>5.6.0.201912101111-r</version>
            </dependency>
    

    jgit 有一个Git类,可以用来执行常规的git操作

    凭证管理

    通过CredentialsProvider管理凭证,常用的是UsernamePasswordCredentialsProvider

    通过下面代码初始化:

    public static CredentialsProvider createCredential(String userName, String password) {
            return new UsernamePasswordCredentialsProvider(userName, password);
        }
    

    clone远程仓库

    git 命令:

    git clone {repoUrl}
    

    通过Git.cloneRepository 来clone远程仓库,如果需要凭证,则需要指定credentialsProvider

     public static Git fromCloneRepository(String repoUrl, String cloneDir, CredentialsProvider provider) throws GitAPIException {
            Git git = Git.cloneRepository()
                .setCredentialsProvider(provider)
                .setURI(repoUrl)
                .setDirectory(new File(cloneDir)).call();
            return git;
        }
    

    commit

    git 命令:

    git commit -a -m '{msg}'
    

    commit比较简单,对应commit方法, 注意需要先add

        public static void commit(Git git, String message, CredentialsProvider provider) throws GitAPIException {
            git.add().addFilepattern(".").call();
            git.commit()
                .setMessage(message)
                .call();
        }
    

    push

    git 命令:

    git push origin branchName
    

    push直接调用push即可, 需要指定credentialsProvider

       public static void push(Git git, CredentialsProvider provider) throws GitAPIException, IOException {
            push(git,null,provider);
        }
    
        public static void push(Git git, String branch, CredentialsProvider provider) throws GitAPIException, IOException {
            if (branch == null) {
                branch = git.getRepository().getBranch();
            }
            git.push()
                .setCredentialsProvider(provider)
                .setRemote("origin").setRefSpecs(new RefSpec(branch)).call();
        }
    

    读取已有仓库

    如果git已经clone了,想直接读取,怎么办?

     public static Repository getRepositoryFromDir(String dir) throws IOException {
            return new FileRepositoryBuilder()
                .setGitDir(Paths.get(dir, ".git").toFile())
                .build();
        }
    

    读取仓库日志

    可以通过RevWalk读取仓库日志。

    • revWalk.parseCommit 可读取一条commit
    • 遍历revWalk,可读取所有日志
     public static List<String> getLogs(Repository repository) throws IOException {
            return getLogsSinceCommit(repository, null, null);
        }
    
        public static List<String> getLogsSinceCommit(Repository repository, String commit) throws IOException {
            return getLogsSinceCommit(repository, null, commit);
        }
    
        public static List<String> getLogsSinceCommit(Repository repository, String branch, String commit) throws IOException {
            if (branch == null) {
                branch = repository.getBranch();
            }
            Ref head = repository.findRef("refs/heads/" + branch);
            List<String> commits = new ArrayList<>();
            if (head != null) {
                try (RevWalk revWalk = new RevWalk(repository)) {
                    revWalk.markStart(revWalk.parseCommit(head.getObjectId()));
                    for (RevCommit revCommit : revWalk) {
                        if (revCommit.getId().getName().equals(commit)) {
                            break;
                        }
                        commits.add(revCommit.getFullMessage());
                        System.out.println("
    Commit-Message: " + revCommit.getFullMessage());
                    }
                    revWalk.dispose();
                }
            }
    
            return commits;
        }
    
    

    测试

    我们来先clone仓库,然后修改,最后push

     String yaml = "dependencies:
    " +
                "- name: springboot-rest-demo
    " +
                "  version: 0.0.5
    " +
                "  repository: http://hub.hubHOST.com/chartrepo/ainote
    " +
                "  alias: demo
    " +
                "- name: exposecontroller
    " +
                "  version: 2.3.82
    " +
                "  repository: http://chartmuseum.jenkins-x.io
    " +
                "  alias: cleanup
    ";
            CredentialsProvider provider = createCredential("USR_NAME", "PASSWORD");
    
            String cloneDir = "/tmp/test";
    
            Git git = fromCloneRepository("http://gitlab.GITHOST.cn/datahub/env-test.git", cloneDir, provider);
    
            // 修改文件
    
            FileUtils.writeStringToFile(Paths.get(cloneDir, "env", "requirements.yaml").toFile(), yaml, "utf-8");
    	  
    	    // 提交
            commit(git, "deploy(app): deploy  springboot-rest-demo:0.0.5 to env test", provider);
            // push 到远程仓库
            push(git, "master", provider);
    
            git.clean().call();
            git.close();
    
            FileUtils.deleteDirectory(new File(cloneDir));
    

    读取已有仓库的日志:

            Repository repository = getRepositoryFromDir("GIT_DIR");
            List<String> logs = getLogs(repository);
            System.out.println(logs);
    
            RevCommit head = getLastCommit(repository);
            System.out.println(head.getFullMessage());
    

    小结

    本文讲述了如何通过jgit完成常规的git操作。


    作者:Jadepeng
    出处:jqpeng的技术记事本--http://www.cnblogs.com/xiaoqi
    您的支持是对博主最大的鼓励,感谢您的认真阅读。
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    知道这几 个正则表达式,能让你少写 1,000 行代码
    移除手机端a标签点击自动出现的边框和背景
    CSS 元素垂直居中的 6种方法
    当文本超出时出现省略号
    css清除select的下拉箭头样式
    设置透明边框
    js 输出语句document.write()及动态改变元素中内容innerHTML的使用
    LOCAL_EXPORT_××用法
    sprd测试系统跑vts
    C++ const用法
  • 原文地址:https://www.cnblogs.com/xiaoqi/p/jgit.html
Copyright © 2020-2023  润新知