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库进行拉取并返回拉取的文件清单,以做其他用处。

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

相关推荐
你喜欢喝可乐吗?21 分钟前
RuoYi-Cloud 验证码处理流程
java·spring cloud·微服务·vue
Java技术小馆1 小时前
langChain开发你的第一个 Agent
java·面试·架构
kangkang-1 小时前
PC端基于SpringBoot架构控制无人机(二):MavLink协议
java·spring boot·后端·无人机
Dcs1 小时前
Anthropic 爆严重安全漏洞!程序员机器沦陷
java
EnigmaCoder1 小时前
Java多线程:核心技术与实战指南
java·开发语言
攀小黑1 小时前
阿里云 使用TST Token发送模板短信
java·阿里云
麦兜*2 小时前
Spring Boot秒级冷启动方案:阿里云FC落地实战(含成本对比)
java·spring boot·后端·spring·spring cloud·系统架构·maven
自由鬼2 小时前
正向代理服务器Squid:功能、架构、部署与应用深度解析
java·运维·服务器·程序人生·安全·架构·代理
长风破浪会有时呀3 小时前
Git 学习笔记
笔记·git·学习
fouryears_234173 小时前
深入拆解Spring核心思想之一:IoC
java·后端·spring