git项目的文件夹更新不到_Java如何直接访问git?到时候,可以做个项目进度自动更新功能?!...

如果你想在一个 Java 程序中使用 Git ,有一个功能齐全的 Git 库,那就是 JGit 。JGit 是一个用 Java 写成的功能相对健全的 Git 的实现,它在 Java 社区中被广泛使用。JGit 项目由 Eclipse 维护,它的主页[1]

依赖添加

有很多种方式可以将 JGit 依赖加入到你的项目,并依靠它去写代码。最简单的方式也许就是使用 Maven 。你可以通过在你的 pom.xml 文件里的 标签中增加像下面这样的片段来完成这个整合。

    org.eclipse.jgitorg.eclipse.jgit5.5.1.201910021850-r

在你读到这段文字时 version 很可能已经更新了,所以请浏览 http://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit 以获取最新的仓库信息。当这一步完成之后, Maven 就会自动获取并使用你所需要的 JGit 库。

项目实践

在搭建我的博客[2]的过程中,因为该博客是部署在自己的服务器上,需要在 ci[3] 自动编译完成后,实现自动部署到我的服务器上(该步实现的方式很多,通过开放 git 接口,有编译部署的时候自动拉取到我的服务器就是其中的一个方法)

以下主要使用了 pull 拉取方法

package com.easy.jGit.controller;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.*;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Repository;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;

@RestController
@Slf4j
public class JGitController {

    /**
     * git仓路径
     */
    final String patch = "/opt/webapps/blog/.git";

    /**
     * 代码分支
     */
    final String branch = "origin/gh-pages";

    /**
     * 拉取
     *
     * @return
     */
    @RequestMapping("/pull")
    public String pull() {
        String result;
        Repository repo = null;
        try {
            repo = new FileRepository(new File(patch));
            Git git = new Git(repo);

            log.info("开始重置");
            //重置
            git.reset()
                    .setMode(ResetCommand.ResetType.HARD)
                    .setRef(branch).call();

            log.info("开始拉取");

            //拉取
            git.pull()
                    .setRemote("origin")
                    .setRemoteBranchName("gh-pages")
                    .call();
            result = "拉取成功!";
            log.info(result);
        } catch (Exception e) {
            result = e.getMessage();
        } finally {
            if (repo != null) {
                repo.close();
            }
        }
        return result;
    }

    /**
     * 重置
     *
     * @return
     */
    @RequestMapping("/reset")
    public String reset() {
        String result;

        Repository repo = null;
        try {
            repo = new FileRepository(new File(patch));
            Git git = new Git(repo);
            git.reset().setMode(ResetCommand.ResetType.HARD).setRef(branch).call();
            result = "重置成功!";

        } catch (Exception e) {
            result = e.getMessage();
        } finally {
            if (repo != null) {
                repo.close();
            }
        }
        return result;
    }

    /**
     * 恢复
     */
    @RequestMapping("/revert")
    public String revert() {
        String result;

        Repository repo = null;
        try {
            repo = new FileRepository(new File(patch));
            Git git = new Git(repo);
            git.revert().call();
            result = "恢复成功!";

        } catch (Exception e) {
            result = e.getMessage();
        } finally {
            if (repo != null) {
                repo.close();
            }
        }
        return result;
    }

    /**
     * 克隆
     *
     * @return
     */
    @RequestMapping("/clone")
    public String clone() {
        String result;
        try {
            Git.cloneRepository()
                    .setURI("https://github.com/smltq/blog.git")
                    .setDirectory(new File("/blog"))
                    .call();
            result = "克隆成功了!";
        } catch (GitAPIException e) {
            result = e.getMessage();
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 状态
     */
    @RequestMapping("/status")
    public static void status() {
        File RepoGitDir = new File("/blog/.git");
        Repository repo = null;
        try {
            repo = new FileRepository(RepoGitDir.getAbsolutePath());
            Git git = new Git(repo);
            Status status = git.status().call();
            log.info("Git Change: "   status.getChanged());
            log.info("Git Modified: "   status.getModified());
            log.info("Git UncommittedChanges: "   status.getUncommittedChanges());
            log.info("Git Untracked: "   status.getUntracked());
        } catch (Exception e) {
            log.info(e.getMessage());
        } finally {
            if (repo != null) {
                repo.close();
            }
        }
    }
}

.travis.yml 源文件[4]

language: node_js # 设置语言
node_js: stable   # 设置相应版本
cache:
  apt: true
  directories:
    - node_modules # 缓存不经常更改的内容
before_install:
  - export TZ='Asia/Shanghai' # 更改时区
  - npm install hexo-cli -g
  #- chmod  x ./publish-to-gh-pages.sh  # 为shell文件添加可执行权限
install:
  - npm install # 安装hexo及插件
script:
  - hexo clean  # 清除
  - hexo g      # 生成
after_script:
  - git clone https://${GH_REF} .deploy_git
  - cd .deploy_git
  - git checkout master:gh-pages
  - cd ../
  - mv .deploy_git/.git/ ./public/
  - cd ./public
  - git config user.name  "tqlin"
  - git config user.email "smltq@126.com"
  # add commit timestamp
  - git add .
  - git commit -m "Travis CI Auto Builder at `date  "%Y-%m-%d %H:%M"`"
  - git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:gh-pages && curl http://49.235.170.100:8787/pull
  - curl http://49.235.170.100:8787/pull   #这里调用上面实现的拉取接口
branches:
  only:
    - master # 只监测master分支
env:
  global:
    - GH_REF: github.com/smltq/blog.git #设置GH_REF

基本概念

  • Repository 包括所有的对象和引用,用来管理源码
  • AnyObjectId 表示 SHA1 对象,可以获得 SHA1 的值,进而可以获得 git 对象
  • Ref 引用对象,表示. git/refs 下面的文件引用 Ref HEAD = repository.getRef("refs/heads/master");
  • RevWalk 可以遍历提交对象,并按照顺序返回提交对象
  • RevCommit 代表一个提交对象
  • RevTag 代表标签对象
  • RevTree 代表树对象

其它常用命令

大多数 JGit 会话会以 Repository 类作为起点,你首先要做的事就是创建一个它的实例。对于一个基于文件系统的仓库来说(JGit 允许其它的存储模型),用 FileRepositoryBuilder 完成它。

// 创建一个新仓库
Repository newlyCreatedRepo = FileRepositoryBuilder.create(
    new File("/tmp/new_repo/.git"));
newlyCreatedRepo.create();

// 打开一个存在的仓库
Repository existingRepo = new FileRepositoryBuilder()
    .setGitDir(new File("my_repo/.git"))
    .build();

当你拥有一个 Repository 实例后,你就能对它做各种各样的事。比如:

// 获取引用
Ref master = repo.getRef("master");

// 获取该引用所指向的对象
ObjectId masterTip = master.getObjectId();

// Rev-parse
ObjectId obj = repo.resolve("HEAD^{tree}");

// 装载对象原始内容
ObjectLoader loader = repo.open(masterTip);
loader.copyTo(System.out);

// 创建分支
RefUpdate createBranch1 = repo.updateRef("refs/heads/branch1");
createBranch1.setNewObjectId(masterTip);
createBranch1.update();

// 删除分支
RefUpdate deleteBranch1 = repo.updateRef("refs/heads/branch1");
deleteBranch1.setForceUpdate(true);
deleteBranch1.delete();

// 配置
Config cfg = repo.getConfig();
String name = cfg.getString("user", null, "name");

提交命令

AddCommand 可以把工作区的内容添加到暂存区。

Git git = Git.open(new File("D:\\source-code\\temp\\.git"));
git.add().addFilepattern(".").call(); // 相当于git add -A添加所有的变更文件git.add().addFilepattern("*.java")这种形式是不支持的
git.add().addFilepattern("src/main/java/").call(); // 添加目录,可以把目录下的文件都添加到暂存区
//jgit当前还不支持模式匹配的方式,例如*.java

CommitCommand 用于提交操作

Git git =Git.open(new File("D:\\source-code\\temp\\user1\\.git"));
CommitCommand commitCommand = git.commit().setMessage("master 23 commit").setAllowEmpty(true);
commitCommand.call();

status 命令

    Git git = Git.open(new File("D:\\source-code\\temp-1\\.git"));
    Status status = git.status().call();        //返回的值都是相对工作区的路径,而不是绝对路径
    status.getAdded().forEach(it -> System.out.println("Add File :"   it));      //git add命令后会看到变化
    status.getRemoved().forEach(it -> System.out.println("Remove File :"   it));  ///git rm命令会看到变化,从暂存区删除的文件列表
    status.getModified().forEach(it -> System.out.println("Modified File :"   it));  //修改的文件列表
    status.getUntracked().forEach(it -> System.out.println("Untracked File :"   it)); //工作区新增的文件列表
    status.getConflicting().forEach(it -> System.out.println("Conflicting File :"   it)); //冲突的文件列表
    status.getMissing().forEach(it -> System.out.println("Missing File :"   it));    //工作区删除的文件列表

log 命令

LogCommand 相当于 git log 命令

//提取某个作者的提交,并打印相关信息
Git git = Git.open(new File("D:\\source-code\\temp-1\\.git"));
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Iterable results = git.log().setRevFilter(new RevFilter() {
    @Override
    public boolean include(RevWalk walker, RevCommit cmit)
       throws StopWalkException, MissingObjectException, IncorrectObjectTypeException, IOException {return cmit.getAuthorIdent().getName().equals("xxxxx dsd");
    }
    @Override
    public RevFilter clone() {return this;
            }
        }).call();
results.forEach(commit -> {
    PersonIdent authoIdent = commit.getAuthorIdent();
    System.out.println("提交人:  "   authoIdent.getName()   "        authoIdent.getEmailAddress()   ">");
    System.out.println("提交SHA1:  "   commit.getId().name());
    System.out.println("提交信息:  "   commit.getShortMessage());
    System.out.println("提交时间:  "   format.format(authoIdent.getWhen()));
});

fetch 命令

fetch 命令

Repository rep = new FileRepository("D:\\source-code\\temp-1\\.git");
Git git = new Git(rep);
git.pull().setRemote("origin").call();
//fetch命令提供了setRefSpecs方法,而pull命令并没有提供,所有pull命令只能fetch所有的分支
git.fetch().setRefSpecs("refs/heads/*:refs/heads/*").call();

push 命令

而 PushCommand 和 git push 相同,一般都需要我们提供用户名和密码,需要用到 CredentialsProvider 类

Repository rep = new FileRepository("D:\\source-code\\temp-1\\.git");
Git git = new Git(rep);
git.push().setCredentialsProvider(new UsernamePasswordCredentialsProvider("myname", "password")).call();

clone 命令

CloneCommand 等价与 git clone 命令

Git.cloneRepository().setURI("https://admin@localhost:8443/r/game-of-life.git")
                .setDirectory(new File("D:\\source-code\\temp-1")).call();

RevWalk API

以下代码实现这样一个功能,查找某个文件的历史记录,并把每个提交的文件内容打印出来。

 DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 Repository repository = new RepositoryBuilder().setGitDir(new File("D:\\source-code\\temp-1\\.git")).build();
 try (RevWalk walk = new RevWalk(repository)) {
     Ref head = repository.findRef("HEAD");
     walk.markStart(walk.parseCommit(head.getObjectId())); // 从HEAD开始遍历,
     for (RevCommit commit : walk) {
         RevTree tree = commit.getTree();

         TreeWalk treeWalk = new TreeWalk(repository, repository.newObjectReader());
         PathFilter f = PathFilter.create("pom.xml");
         treeWalk.setFilter(f);
         treeWalk.reset(tree);
         treeWalk.setRecursive(false);
         while (treeWalk.next()) {
             PersonIdent authoIdent = commit.getAuthorIdent();
             System.out.println("提交人: "   authoIdent.getName()   "    authoIdent.getEmailAddress()   ">");
             System.out.println("提交SHA1: "   commit.getId().name());
             System.out.println("提交信息: "   commit.getShortMessage());
             System.out.println("提交时间: "   format.format(authoIdent.getWhen()));
             ObjectId objectId = treeWalk.getObjectId(0);
             ObjectLoader loader = repository.open(objectId);
             loader.copyTo(System.out);              //提取blob对象的内容
         }
     }
 }

其它更多命令参考官网

资料

  • JGit 示例源码[5]
  • JGit 官方文档[6]

Spring Boot、Cloud 学习项目[7]

参考资料

[1]

它的主页: http://www.eclipse.org/jgit

[2]

我的博客: https://tqlin.cn/

[3]

ci: https://travis-ci.org/

[4]

.travis.yml 源文件: https://github.com/smltq/blog/blob/master/.travis.yml

[5]

JGit 示例源码: https://github.com/smltq/spring-boot-demo/blob/master/jGit

[6]

JGit官方文档: https://wiki.eclipse.org/JGit/User_Guide

[7]

Spring Boot、Cloud 学习项目: https://github.com/smltq/spring-boot-demo


作者:yuntian666

来源链接:

https://blog.csdn.net/smltq/article/details/103492947

16f774527ab0876f2caf51b4e7947a63.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值