java 操作git

​ 实现功能:借助jgit实现拉取文件,并返回文件路径清单

xml 复制代码
<!-- 依赖库 版本号有自行选择,只是需要注意支持的jdk版本即可,我使用的是jdk1.8-->
<dependency>
  <groupId>org.eclipse.jgit</groupId>
  <artifactId>org.eclipse.jgit</artifactId>
  <version>5.13.2.202306221912-r</version>
</dependency>
java 复制代码
// 还是用的 hutool和 lombok ,没有引入相关依赖的可以删除相关代码,使用类似代码替代。
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.PullResult;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;

import javax.validation.constraints.NotNull;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class GitUtil {

    /**
     * 克隆git库.
     * @param url
     * @param localPath
     */
    public static void cloneRepository(String url, String localPath) {
        try {
            Git git = Git.cloneRepository()
                    .setURI(url)
                    .setDirectory(new File(localPath))
                    .call();
            Repository repository = git.getRepository();
            repository.close();
            log.info("Cloned repository successfully from {} to {}", url, localPath);
        } catch (GitAPIException e) {
            log.error("Failed to clone repository from {} to {}", url, localPath, e);
        } catch (Exception e) {
            log.error("Failed to clone repository from {} to {}", url, localPath, e);
        }
    }

    /**
     * 初始化本地git库.
     * @param localPath
     */
    public static void initRepository(String localPath) {
        try {
            Git git = Git.init()
                    .setDirectory(new File(localPath))
                    .call();
            Repository repository = git.getRepository();
            repository.close();
            log.info("Initialized repository successfully at {}", localPath);
        } catch (GitAPIException e) {
            log.error("Failed to initialize repository at {}", localPath, e);
        } catch (Exception e) {
            log.error("Failed to initialize repository at {}", localPath, e);
        }
    }

    /**
     * 添加
     * @param git
     */
    public static void addAll(Git git) {
        try {
            git.add().addFilepattern(".").call();
            log.info("Added all files to staging area");
        } catch (GitAPIException e) {
            log.error("Failed to add all files to staging area", e);
        } catch (Exception e) {
            log.error("Failed to add all files to staging area", e);
        }
    }

    /**
     * 提交
     * @param git
     * @param message
     */
    public static void commit(Git git, String message) {
        try {
            git.commit().setMessage(message).call();
            log.info("Committed changes with message: {}", message);
        } catch (GitAPIException e) {
            log.error("Failed to commit changes with message: {}", message, e);
        } catch (Exception e) {
            log.error("Failed to commit changes with message: {}", message, e);
        }
    }

    /**
     * 依据本地目录获取本地git库
     * @param localPath
     * @return
     */
    public static Repository getRepository(String localPath) {
        FileRepositoryBuilder builder = new FileRepositoryBuilder();
        try {
            return builder.setGitDir(new File(localPath + "/.git"))
                    .readEnvironment()
                    .findGitDir()
                    .build();
        } catch (Exception e) {
            log.error("Failed to open repository at {}", localPath, e);
            return null;
        }
    }

    private static CanonicalTreeParser getTreeByObjectId(Git git, ObjectId objectId) throws Exception {
        try (ObjectReader reader = git.getRepository().newObjectReader();) {
            CanonicalTreeParser treeIter = new CanonicalTreeParser();
            treeIter.reset(reader, objectId);
            return treeIter;
        }
    }

    private static String getChangeType(DiffEntry diffEntry) {
        if (StrUtil.equals("/dev/null", diffEntry.getNewPath())) {
            return "del";
        }
        if (StrUtil.equals("/dev/null", diffEntry.getOldPath())) {
            return "add";
        }
        return "update";
    }

    private static void addDiifToMap(@NotNull Map<String, List<String>> changeInfoMap, @NotNull DiffEntry diffEntry) {
        String changeType = getChangeType(diffEntry);
        List<String> fileNameList = changeInfoMap.get(changeType);
        if (fileNameList == null) {
            changeInfoMap.put(changeType, new ArrayList<>());
            fileNameList = changeInfoMap.get(changeType);
        }
        fileNameList.add(StrUtil.equals("del", changeType) ? diffEntry.getOldPath() : diffEntry.getNewPath());
    }

    /**
     * 拉取文件并返回拉取的文件清单
     * @param repository
     * @return 返回 del(删除)、add(新增)、update(更新)的文件清单
     */
    public static Map<String, List<String>> pull(Repository repository) {
        Map<String, List<String>> changeInfoMap = new HashMap<>();
        try (Git git = new Git(repository);) {
            // 1.拉取前记录当前的版本号.
            FetchResult fetchResult = git.fetch().call();
            ObjectId oldHead = git.getRepository().resolve("HEAD^{tree}");
            // 2.拉取并记录拉取后的版本号
            PullResult result = git.pull().call();
            ObjectId newHead = git.getRepository().resolve("HEAD^{tree}");
            // 3.计算差异清单。
            List<DiffEntry> diffs = git.diff()
                    .setNewTree(getTreeByObjectId(git, newHead))
                    .setOldTree(getTreeByObjectId(git, oldHead))
                    .call();
            for (DiffEntry entry : diffs) {
                addDiifToMap(changeInfoMap,entry);
            }
        } catch (GitAPIException e) {
            log.error("Failed to pull changes from remote repository", e);
        } catch (Exception e) {
            log.error("Failed to pull changes from remote repository", e);
        }
        return changeInfoMap;
    }
}

使用方式:

复制代码
1.	在将代码库拉取到本地的目录中(也可以通过上面的代码,直接从远程仓库克隆到本地目录中)
2.	使用pull方法即可针对指定目录的git库进行拉取并返回拉取的文件清单,以做其他用处。

以上仅为案例,实际功能还需要配合其他逻辑实现。

相关推荐
枫叶落雨22215 分钟前
ShardingSphere 介绍
java
花花鱼20 分钟前
Spring Security 与 Spring MVC
java·spring·mvc
do better myself33 分钟前
网站源码如何部署和加入GIT仓库的
git
言慢行善1 小时前
sqlserver模糊查询问题
java·数据库·sqlserver
专吃海绵宝宝菠萝屋的派大星1 小时前
使用Dify对接自己开发的mcp
java·服务器·前端
大数据新鸟2 小时前
操作系统之虚拟内存
java·服务器·网络
Tong Z2 小时前
常见的限流算法和实现原理
java·开发语言
凭君语未可2 小时前
Java 中的实现类是什么
java·开发语言
He少年2 小时前
【基础知识、Skill、Rules和MCP案例介绍】
java·前端·python
克里斯蒂亚诺更新2 小时前
myeclipse的pojie
java·ide·myeclipse