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

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

相关推荐
ok!ko2 小时前
设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)
java·设计模式·原型模式
2402_857589362 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
吾爱星辰3 小时前
Kotlin 处理字符串和正则表达式(二十一)
java·开发语言·jvm·正则表达式·kotlin
哎呦没3 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
编程、小哥哥4 小时前
netty之Netty与SpringBoot整合
java·spring boot·spring
IT学长编程5 小时前
计算机毕业设计 玩具租赁系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·计算机毕业设计选题·玩具租赁系统
莹雨潇潇5 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
杨哥带你写代码5 小时前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端
郭二哈6 小时前
C++——模板进阶、继承
java·服务器·c++
A尘埃6 小时前
SpringBoot的数据访问
java·spring boot·后端