如何使用java来操作git/gitlab?

这篇具有很好参考价值的文章主要介绍了如何使用java来操作git/gitlab?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在我们的学习和开发过程中,git作为一个优秀的分布式版本控制工具是经常会被我们使用到的,那么如何通过java代码来实现Git的更新,提交,推送等操作呢?下面整理了三种实现方式:
1.首先我们会想到的应该是寻找市面上是否已经有了比较成熟的、开源的git客户端。这是我推荐使用一个比较成熟的git客户端——JGit。JGit 是一个轻量级纯 Java 的类库,用来实现 Git 的版本控制系统的访问,以及提供核心的版本控制算法。EGit 这个 Eclipse 上的 Git 插件就是采用 JGit 开发的。
如果你对git和jgit还不熟悉,推荐学习书籍:pro git
下面介绍如何在代码中集成jgit:
(1)在pom.xml中引入如下依赖:

		<dependency>
            <groupId>org.eclipse.jgit</groupId>
            <artifactId>org.eclipse.jgit</artifactId>
            <version>5.12.0.202106070339-r</version>
        </dependency>

(2)编写配置类JgitConfig.java

@Configuration
@ConfigurationProperties(prefix = "jgit")
public class JgitConfig {
    private static String username;
    private static String password;

    public static String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        JgitConfig.username = username;
    }

    public static String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        JgitConfig.password = password;
    }
}

(3)application.yml文件配置

jgit:
  username: #git账号名
  password: #git密码

(4)编写JgitUtil工具类。(注:由于业务原因,方法中需要的localPath参数我是通过数据库获取的,大家用的时候也可以放入配置文件中配置)

@Slf4j
public class JgitUtil {
    /**
     * 生成身份信息
     */
    private static CredentialsProvider provider = new UsernamePasswordCredentialsProvider(JgitConfig.getUsername(), JgitConfig.getPassword());

    public static Git openRpo(String localPath) {
        Git git = null;
        try {
            Repository repository = new FileRepositoryBuilder()
                    .setGitDir(Paths.get(localPath, ".git").toFile())
                    .build();
            git = new Git(repository);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return git;
    }

    /**
     * 初始化(init)——git init
     */
    public static void init(String localPath) throws GitAPIException {
        Git.init().setDirectory(new File(localPath)).call();
    }

    /**
     * 添加到暂存区(Add)git add .
     * git add Delete.txt
     * 删除和移动的文件不能使用git.add(),需要使用git.rm()的方式,就算参数是“.”也需要使用 git.rm()方法
     */
    public static void add(String localPath, String fileName) throws Exception {
        openRpo(localPath).add().addFilepattern(Optional.ofNullable(fileName).orElse(".")).call();
    }

    public static void rm(String localPath, String fileName) throws Exception {
        openRpo(localPath).rm().addFilepattern(fileName).call();
    }

    /**
     * 提交(Commit) git commit -m"first commit"
     */
    public static void commit(String localPath, String commitInfo) throws Exception {
        openRpo(localPath).commit().setMessage(Optional.ofNullable(commitInfo).orElse("default commit info")).call();

    }

    /**
     * 移动(mv)
     */
    public static void mv(String localPath, String sourcePath, String targetPath, File file) {
        System.out.println(sourcePath);
        try {
            File newDir = new File(targetPath);
            if (!newDir.exists()) {
                newDir.mkdirs();
            }
            File newFile = new File(newDir, file.getName());
            boolean success = file.renameTo(newFile);
            if (success) {
                add(localPath, ".");
                rm(localPath, sourcePath);
                commit(localPath, "File moved to new directory");
                push(localPath);
            } else {
                // handle error
                log.error("文件移动异常!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 状态(status) git status
     *
     * @throws Exception
     */
    public static Map<String, String> status(String localPath) throws Exception {
        Map<String, String> map = new HashMap<>();
        Status status = openRpo(localPath).status().call();
        map.put("Added", status.getAdded().toString());
        map.put("Changed", status.getChanged().toString());
        map.put("Conflicting", status.getConflicting().toString());
        map.put("ConflictingStageState", status.getConflictingStageState().toString());
        map.put("IgnoredNotInIndex", status.getIgnoredNotInIndex().toString());
        map.put("Missing", status.getMissing().toString());
        map.put("Modified", status.getModified().toString());
        map.put("Removed", status.getRemoved().toString());
        map.put("UntrackedFiles", status.getUntracked().toString());
        map.put("UntrackedFolders", status.getUntrackedFolders().toString());
        return map;
    }

    /**
     * ===============================分支操作=============================
     */
    /**
     * 创建分支(Create Branch) git branch dev
     *
     * @throws Exception
     */
    public static void branch(String localPath, String branchName) throws Exception {
        openRpo(localPath).branchCreate()
                .setName(branchName)
                .call();
    }

    /**
     * 删除分支(Delete Branch) git branch -d dev
     *
     * @throws Exception
     */
    public static void delBranch(String localPath, String branchName) throws Exception {
        openRpo(localPath).branchDelete()
                .setBranchNames(branchName)
                .call();
    }

    /**
     * 切换分支(Checkout Branch) git checkout dev
     *
     * @throws Exception
     */
    public static void checkoutBranch(String localPath, String branchName) throws Exception {
        openRpo(localPath).checkout()
                .setName(branchName)
                .call();
    }

    /**
     * 所有分支(BranchList) git branch
     *
     * @throws Exception
     */
    public static List<Ref> listBranch(String localPath) throws Exception {
        return openRpo(localPath).branchList().call();
    }

    /**
     * 合并分支(Merge Branch) git merge dev
     *
     * @throws Exception
     */
    public static void mergeBranch(String localPath, String branchName, String commitMsg) throws Exception {
        //切换分支获取分支信息存入Ref对象里
        Ref refdev = openRpo(localPath).checkout().setName(branchName).call();
        //切换回main分支
        openRpo(localPath).checkout().setName("main").call();
        // 合并目标分支
        MergeResult mergeResult = openRpo(localPath).merge().include(refdev)
                //同时提交
                .setCommit(true)
                // 分支合并策略NO_FF代表普通合并, FF代表快速合并
                .setFastForward(MergeCommand.FastForwardMode.NO_FF)
                .setMessage(Optional.ofNullable(commitMsg).orElse("master Merge"))
                .call();
    }

    /**
     * ========================远端仓库操作(Repository)==============================
     */
    /**
     * 推送(Push) git push origin master
     *
     * @throws Exception
     */
    public static void push(String localPath) throws Exception {
        openRpo(localPath).push()
                //设置推送的URL名称如"origin"
                .setRemote("origin")
                //设置需要推送的分支,如果远端没有则创建
                .setRefSpecs(new RefSpec("main"))
                //身份验证
                .setCredentialsProvider(provider)
                .call();
    }

    public static void push(String localPath, String branch) throws Exception {
        openRpo(localPath).push()
                //设置推送的URL名称如"origin"
                .setRemote("origin")
                //设置需要推送的分支,如果远端没有则创建
                .setRefSpecs(new RefSpec(branch))
                //身份验证
                .setCredentialsProvider(provider)
                .call();
    }

    /**
     * /拉取(Pull) git pull origin
     *
     * @throws Exception
     */
    public static void pull(String localPath, String remotePath) throws Exception {
        //判断localPath是否存在,不存在调用clone方法
        File directory = new File(localPath);
        if (!directory.exists()) {
            gitClone(localPath, remotePath, "main");
        }
        openRpo(localPath).pull()
                .setRemoteBranchName("main")
                .setCredentialsProvider(provider)
                .call();
    }

    public static void pull(String localPath, String remotePath, String branch) throws Exception {
        //判断localPath是否存在,不存在调用clone方法
        File directory = new File(localPath);
        if (!directory.exists()) {
            gitClone(localPath, remotePath, branch);
        }
        openRpo(localPath).pull()
                .setRemoteBranchName(branch)
                .setCredentialsProvider(provider)
                .call();
    }

    /**
     * 克隆(Clone) git clone https://xxx.git
     *
     * @throws Exception
     */
    public static void gitClone(String localPath, String remotePath, String branch) throws Exception {
        //克隆
        Git git = Git.cloneRepository()
                .setURI(remotePath)
                .setDirectory(new File(localPath))
                .setCredentialsProvider(provider)
                //设置是否克隆子仓库
                .setCloneSubmodules(true)
                //设置克隆分支
                .setBranch(branch)
                .call();
        //关闭源,以释放本地仓库锁
        git.getRepository().close();
        git.close();

    }
}

(5)直接在对应的业务代码中调用上述工具类中的方法即可。
如果有些朋友还需要集成其他命令,可以了解下这个开源项目:https://github.com/centic9/jgit-cookbook,git的几乎所有操作都在这里面集成了。
2.另外一种方式大家想必也猜到了。既然可以在命令行中执行git命令来操作git,那么能不能通过使用java控制终端来执行git命令呢?答案是肯定的,但前提是需要在你电脑或服务器上先安装好git客户端。
下面是示例代码:

@Slf4j
public class GitUtils {
    public static String executeCommand(String command) {
        StringBuilder output = new StringBuilder();
        Process process;
        try {
            process = Runtime.getRuntime().exec(command);
            process.waitFor();
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                output.append(line).append("\n");
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return output.toString();
    }

    public static void cloneRepository(String remotePath, String localPath) {
        String command = "git clone " + remotePath + " " + localPath;
        String output = executeCommand(command);
        System.out.println(output);
    }

    public static void pull(String localPath,String branch) {
        String command = "git -C " + localPath + " pull origin "+branch;
        String output = executeCommand(command);
        System.out.println(output);
    }

    public static void checkoutBranch(String localPath, String branchName) {
        String command = "git -C " + localPath + " checkout " + branchName;
        String output = executeCommand(command);
        System.out.println(output);
    }

    public static void commit(String localPath, String message) {
        String command = "git -C " + localPath + " commit -a -m \"" + message + "\"";
        String output = executeCommand(command);
        System.out.println(output);
    }

    public static void add(String localPath) {
        String command = "git -C " + localPath + " add .";
        String output = executeCommand(command);
        System.out.println(output);
    }

    public static void push(String localPath) {
        String command = "git -C " + localPath + " push";
        String output = executeCommand(command);
        System.out.println(output);
    }
    public static void mv(File file,String localPath){
        File newDir = new File(localPath);
        if (!newDir.exists()) {
            newDir.mkdirs();
        }
        File newFile = new File(newDir, file.getName());
        boolean success = file.renameTo(newFile);
        if (success) {
            add(localPath);
            commit(localPath,"File moved to new directory");
            push(localPath);
        } else {
            // handle error
            log.error("文件移动异常!");
        }
    }
}

3.如果你的git服务端使用的是gitlab,还可以使用gitlab的api来操作。下面是具体的实现操作:
(1)在gitlab中配置访问令牌。
java 操作git,java,git,gitlab

(2)pom.xml文件中引入依赖。

 <dependency>
            <groupId>org.gitlab4j</groupId>
            <artifactId>gitlab4j-api</artifactId>
            <version>4.19.0</version>
        </dependency>

(3)编写配置类,并在yml文件中配置。

@Configuration
@ConfigurationProperties(prefix = "git")
public class GitConfig {
    public static String hostUrl;
    public static String personalAccessToken;

    public static String getHostUrl() {
        return hostUrl;
    }

    public static void setHostUrl(String hostUrl) {
        GitConfig.hostUrl = hostUrl;
    }

    public static String getPersonalAccessToken() {
        return personalAccessToken;
    }

    public static void setPersonalAccessToken(String personalAccessToken) {
        GitConfig.personalAccessToken = personalAccessToken;
    }
}
git:
  hostUrl: #gitlab访问的ip+端口,如:http://127.0.0.1:8080
  personalAccessToken: #刚刚配置的访问令牌

(4)编写工具类。(注:gitProjId,branch,filePath都可写入配置文件中,gitProjId为gitlab中对应的项目id,filePath为git本地文件路径)文章来源地址https://www.toymoban.com/news/detail-652869.html

public class GitLabApiUtils {

    private static GitLabApi gitLabApi = new GitLabApi(GitConfig.hostUrl, GitConfig.personalAccessToken, null,null);

    public static InputStream getRawFileStreamByProjId(Integer gitProjId, String branch, String filePath) throws GitLabApiException {
        return   gitLabApi.getRepositoryFileApi().getRawFile(gitProjId,branch,filePath);
    }
    public static InputStream getRawFileStreamByGitPath(String gitPath,String branch,String filePath) throws GitLabApiException {
        return   gitLabApi.getRepositoryFileApi().getRawFile(gitPath,branch,filePath);
    }

    public static RepositoryFile getFile(Integer projectId, String filepath, String branch) throws GitLabApiException {
        return gitLabApi.getRepositoryFileApi().getFile(projectId, filepath, branch);
    }

    public static Optional<RepositoryFile> getOptionalFile(Integer projectId, String filepath, String branch) throws GitLabApiException {
        return gitLabApi.getRepositoryFileApi().getOptionalFile(projectId, filepath, branch);
    }

    public static List<Project> getProjects() throws GitLabApiException {
        return gitLabApi.getProjectApi().getProjects();
    }
    //查询文件树结构
    public static List<TreeItem> getFileTree(Integer gitProjId, String branch, String filePath) throws GitLabApiException {
        return gitLabApi.getRepositoryApi().getTree(gitProjId,filePath,branch,true);//默认递归查询
    }
    //获取blob文件列表
    public static List<TreeItem> getFileList(Integer gitProjId, String branch, String filePath) throws GitLabApiException {
        List<TreeItem> tree = gitLabApi.getRepositoryApi().getTree(gitProjId, filePath, branch, true);//默认递归查询  筛选出文件后返回list
        ArrayList<TreeItem> treeItems = new ArrayList<>();
        for (TreeItem treeItem : tree) {
            if ("blob".equals(treeItem.getType().toString()) ) {
                treeItems.add(treeItem);
            }
        }
        return  treeItems;
    }
    public static List<TreeItem> getFileList(String projectPath, String branch, String filePath) throws GitLabApiException {
        return gitLabApi.getRepositoryApi().getTree(projectPath,filePath,branch,true);//默认递归查询  筛选出文件后返回list
    }

    public static synchronized RepositoryFile createFile(Integer gitProjId , RepositoryFile file, String branch, String commit) throws GitLabApiException {
        return  gitLabApi.getRepositoryFileApi().createFile(gitProjId,file,branch,commit);
    }

    public static synchronized RepositoryFile updateFile(Integer gitProjId , RepositoryFile file, String branch, String commit) throws GitLabApiException {
        return  gitLabApi.getRepositoryFileApi().updateFile(gitProjId,file,branch,commit);
    }

    public static RepositoryFile getFileByProjId(Integer gitProjId,String branch,String filePath) throws GitLabApiException {
        return   gitLabApi.getRepositoryFileApi().getFile(gitProjId,filePath,branch);
    }

}

到了这里,关于如何使用java来操作git/gitlab?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Git 如何使用TortoiseGit 操作本地仓库

    方法一:  新建一个文件夹,进入文件夹内部操作 1、右键-- 在这里创建Git 版本库  注意: 不要直接在桌面上操作,否则桌面就是一个仓库 方法二: 1、右键--Git GUI here 方法三: 命令行模式 1、 git init  创建完毕仓库,我们发现,此时我们创建的文件夹下有一个.git 文件已经生成了 并且

    2024年02月12日
    浏览(40)
  • 【Git】如何使用sourcetree进行rebase操作(变基)

    注:接下来的演示操作仍将以SourceTree这个可视化工具为例。 个人感觉rebase这个功能有点多余,其实merge操作已经覆盖了它的功能。可能就是为了让整个commit看起来更顺畅一下,没有那么多的旁路分支,不那么杂乱。虽然个人不是很喜欢这个功能,但是很多开源库的作者再你提

    2024年02月04日
    浏览(50)
  • 在局域网搭建一个带 web 操作页面的 git 版本服务器 - Gitlab

    以下内容为本人的著作,如需要转载,请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/Br0ETd_aNffEZoTAba03Bw 最近到了新团队,只有几部新电脑,然后啥也没有了。老江说需要一个管理工程代码的 git 版本服务器,还说他以前用过 gitlab,于是我就自告奋勇接下了锅,在

    2024年01月19日
    浏览(50)
  • 如何迁移git仓库,gitee仓库迁移到gitlab

    首先 gitee上的仓库为A gitlab上创建一个空仓库为C 1、本机建一个任意名称文件夹:test,cmd进入test文件夹。 2、执行 git clone http://xxx.xxx.xx.10:xxx/xxxxkai/oms.git 克隆gitee的仓库A为B(也就是test文件夹) 2、修改 B仓库的远端指向 2.1重命名B指向的远端仓库 【因为2.2要新增名为origin的链接,

    2023年04月20日
    浏览(61)
  • 【小白教程】如何从0开始配置本地git连接gitlab

    为了配置本地git连接到gitlab,查了不少资料,很多资料都说的不清不楚的,今天我自己终于搞清楚了,把教程写下来给有需要的人。 要从零开始配置本地Git与GitLab的连接,请按照以下步骤进行操作: 安装Git:如果还没有安装Git,请在计算机上安装它。可以从Git官方网站(h

    2024年02月06日
    浏览(46)
  • Git和Gitlab使用

    版本控制概念 :记录开发文件的时间机器 分类 :1.本地版本控制系统、2.集中化的版本控制系统CVS、Subversion(SVN)、3.分布式版本控制系统GIT 产品 :github、git、gitlab 1.介绍 git是一个分布式的代码版本管理软件,而 gitlab, gierrit, github都是git作为基础扩展其他功能开发而来,支持

    2024年02月11日
    浏览(36)
  • Git 命令行教程:如何在 GitLab 中恢复已删除的分支

    在软件开发过程中,版本控制是一个至关重要的环节。Git 是最流行的分布式版本控制系统之一,它能够帮助团队高效地管理代码。然而,有时候会发生意外,例如代码误合、错误的删除等情况,导致重要的开发分支本地和远程不慎被删除。本文将为您介绍如何使用 Git 命令行

    2024年02月12日
    浏览(41)
  • Git & GitLab 使用及规范

    Git安装配置及基本使用 从官网下载安装包,手动完成安装。 打开 Git Bash 命令行工具,执行命令 ssh-keygen -t rsa -C Email-Addresss 生成一个密钥对。 登录到GitLab,点击右上角你的用户头像,点击 Edit Profile settings ,点击 SSH Keys ,点击 Add SSH Key ,填写 Title 栏,复制用户目录下 .ssh

    2024年02月09日
    浏览(38)
  • gitlab的使用方法,详解gitlab操作

    1.导读 本教程主要讲解了GitLab在项目的环境搭建和基本的使用,可以帮助大家在企业中能够自主搭建GitLab服务,并且可以GitLab中的组、权限、项目自主操作。 - GitLab简介 - GitLab环境搭建 - GitLab基本使用(组、权限、用户、项目) 2.GitLab简介 GitLab是整个DevOps生命周期的第一个应用

    2023年04月24日
    浏览(35)
  • 18.(开发工具篇Gitlab)Git如何回退到指定版本

    首先: 使用git log命令查看提交历史,找到想要回退的版本的commit id. 第一步:git reset --hard 命令是强制回到某一个版本。执行后本地工程回退到该版本。 第二步:利用git push -f命令强制推到远程 如下所示: 优点:干净利落,回滚后完全回到最初状态。 缺点: (1)需要找到你要

    2024年02月04日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包