0


如何使用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")publicclassJgitConfig{privatestaticString username;privatestaticString password;publicstaticStringgetUsername(){return username;}publicvoidsetUsername(String username){JgitConfig.username = username;}publicstaticStringgetPassword(){return password;}publicvoidsetPassword(String password){JgitConfig.password = password;}}

(3)application.yml文件配置

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

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

@Slf4jpublicclassJgitUtil{/**
     * 生成身份信息
     */privatestaticCredentialsProvider provider =newUsernamePasswordCredentialsProvider(JgitConfig.getUsername(),JgitConfig.getPassword());publicstaticGitopenRpo(String localPath){Git git =null;try{Repository repository =newFileRepositoryBuilder().setGitDir(Paths.get(localPath,".git").toFile()).build();
            git =newGit(repository);}catch(IOException e){
            e.printStackTrace();}return git;}/**
     * 初始化(init)——git init
     */publicstaticvoidinit(String localPath)throwsGitAPIException{Git.init().setDirectory(newFile(localPath)).call();}/**
     * 添加到暂存区(Add)git add .
     * git add Delete.txt
     * 删除和移动的文件不能使用git.add(),需要使用git.rm()的方式,就算参数是“.”也需要使用 git.rm()方法
     */publicstaticvoidadd(String localPath,String fileName)throwsException{openRpo(localPath).add().addFilepattern(Optional.ofNullable(fileName).orElse(".")).call();}publicstaticvoidrm(String localPath,String fileName)throwsException{openRpo(localPath).rm().addFilepattern(fileName).call();}/**
     * 提交(Commit) git commit -m"first commit"
     */publicstaticvoidcommit(String localPath,String commitInfo)throwsException{openRpo(localPath).commit().setMessage(Optional.ofNullable(commitInfo).orElse("default commit info")).call();}/**
     * 移动(mv)
     */publicstaticvoidmv(String localPath,String sourcePath,String targetPath,File file){System.out.println(sourcePath);try{File newDir =newFile(targetPath);if(!newDir.exists()){
                newDir.mkdirs();}File newFile =newFile(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
     */publicstaticMap<String,String>status(String localPath)throwsException{Map<String,String> map =newHashMap<>();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
     */publicstaticvoidbranch(String localPath,String branchName)throwsException{openRpo(localPath).branchCreate().setName(branchName).call();}/**
     * 删除分支(Delete Branch) git branch -d dev
     *
     * @throws Exception
     */publicstaticvoiddelBranch(String localPath,String branchName)throwsException{openRpo(localPath).branchDelete().setBranchNames(branchName).call();}/**
     * 切换分支(Checkout Branch) git checkout dev
     *
     * @throws Exception
     */publicstaticvoidcheckoutBranch(String localPath,String branchName)throwsException{openRpo(localPath).checkout().setName(branchName).call();}/**
     * 所有分支(BranchList) git branch
     *
     * @throws Exception
     */publicstaticList<Ref>listBranch(String localPath)throwsException{returnopenRpo(localPath).branchList().call();}/**
     * 合并分支(Merge Branch) git merge dev
     *
     * @throws Exception
     */publicstaticvoidmergeBranch(String localPath,String branchName,String commitMsg)throwsException{//切换分支获取分支信息存入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
     */publicstaticvoidpush(String localPath)throwsException{openRpo(localPath).push()//设置推送的URL名称如"origin".setRemote("origin")//设置需要推送的分支,如果远端没有则创建.setRefSpecs(newRefSpec("main"))//身份验证.setCredentialsProvider(provider).call();}publicstaticvoidpush(String localPath,String branch)throwsException{openRpo(localPath).push()//设置推送的URL名称如"origin".setRemote("origin")//设置需要推送的分支,如果远端没有则创建.setRefSpecs(newRefSpec(branch))//身份验证.setCredentialsProvider(provider).call();}/**
     * /拉取(Pull) git pull origin
     *
     * @throws Exception
     */publicstaticvoidpull(String localPath,String remotePath)throwsException{//判断localPath是否存在,不存在调用clone方法File directory =newFile(localPath);if(!directory.exists()){gitClone(localPath, remotePath,"main");}openRpo(localPath).pull().setRemoteBranchName("main").setCredentialsProvider(provider).call();}publicstaticvoidpull(String localPath,String remotePath,String branch)throwsException{//判断localPath是否存在,不存在调用clone方法File directory =newFile(localPath);if(!directory.exists()){gitClone(localPath, remotePath, branch);}openRpo(localPath).pull().setRemoteBranchName(branch).setCredentialsProvider(provider).call();}/**
     * 克隆(Clone) git clone https://xxx.git
     *
     * @throws Exception
     */publicstaticvoidgitClone(String localPath,String remotePath,String branch)throwsException{//克隆Git git =Git.cloneRepository().setURI(remotePath).setDirectory(newFile(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客户端。
下面是示例代码:

@Slf4jpublicclassGitUtils{publicstaticStringexecuteCommand(String command){StringBuilder output =newStringBuilder();Process process;try{
            process =Runtime.getRuntime().exec(command);
            process.waitFor();BufferedReader reader =newBufferedReader(newInputStreamReader(process.getInputStream()));String line;while((line = reader.readLine())!=null){
                output.append(line).append("\n");}}catch(IOException|InterruptedException e){
            e.printStackTrace();}return output.toString();}publicstaticvoidcloneRepository(String remotePath,String localPath){String command ="git clone "+ remotePath +" "+ localPath;String output =executeCommand(command);System.out.println(output);}publicstaticvoidpull(String localPath,String branch){String command ="git -C "+ localPath +" pull origin "+branch;String output =executeCommand(command);System.out.println(output);}publicstaticvoidcheckoutBranch(String localPath,String branchName){String command ="git -C "+ localPath +" checkout "+ branchName;String output =executeCommand(command);System.out.println(output);}publicstaticvoidcommit(String localPath,String message){String command ="git -C "+ localPath +" commit -a -m \""+ message +"\"";String output =executeCommand(command);System.out.println(output);}publicstaticvoidadd(String localPath){String command ="git -C "+ localPath +" add .";String output =executeCommand(command);System.out.println(output);}publicstaticvoidpush(String localPath){String command ="git -C "+ localPath +" push";String output =executeCommand(command);System.out.println(output);}publicstaticvoidmv(File file,String localPath){File newDir =newFile(localPath);if(!newDir.exists()){
            newDir.mkdirs();}File newFile =newFile(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中配置访问令牌。
在这里插入图片描述

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

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

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

@Configuration@ConfigurationProperties(prefix ="git")publicclassGitConfig{publicstaticString hostUrl;publicstaticString personalAccessToken;publicstaticStringgetHostUrl(){return hostUrl;}publicstaticvoidsetHostUrl(String hostUrl){GitConfig.hostUrl = hostUrl;}publicstaticStringgetPersonalAccessToken(){return personalAccessToken;}publicstaticvoidsetPersonalAccessToken(String personalAccessToken){GitConfig.personalAccessToken = personalAccessToken;}}
git:hostUrl:#gitlab访问的ip+端口,如:http://127.0.0.1:8080personalAccessToken:#刚刚配置的访问令牌

(4)编写工具类。(注:gitProjId,branch,filePath都可写入配置文件中,gitProjId为gitlab中对应的项目id,filePath为git本地文件路径)

publicclassGitLabApiUtils{privatestaticGitLabApi gitLabApi =newGitLabApi(GitConfig.hostUrl,GitConfig.personalAccessToken,null,null);publicstaticInputStreamgetRawFileStreamByProjId(Integer gitProjId,String branch,String filePath)throwsGitLabApiException{return   gitLabApi.getRepositoryFileApi().getRawFile(gitProjId,branch,filePath);}publicstaticInputStreamgetRawFileStreamByGitPath(String gitPath,String branch,String filePath)throwsGitLabApiException{return   gitLabApi.getRepositoryFileApi().getRawFile(gitPath,branch,filePath);}publicstaticRepositoryFilegetFile(Integer projectId,String filepath,String branch)throwsGitLabApiException{return gitLabApi.getRepositoryFileApi().getFile(projectId, filepath, branch);}publicstaticOptional<RepositoryFile>getOptionalFile(Integer projectId,String filepath,String branch)throwsGitLabApiException{return gitLabApi.getRepositoryFileApi().getOptionalFile(projectId, filepath, branch);}publicstaticList<Project>getProjects()throwsGitLabApiException{return gitLabApi.getProjectApi().getProjects();}//查询文件树结构publicstaticList<TreeItem>getFileTree(Integer gitProjId,String branch,String filePath)throwsGitLabApiException{return gitLabApi.getRepositoryApi().getTree(gitProjId,filePath,branch,true);//默认递归查询}//获取blob文件列表publicstaticList<TreeItem>getFileList(Integer gitProjId,String branch,String filePath)throwsGitLabApiException{List<TreeItem> tree = gitLabApi.getRepositoryApi().getTree(gitProjId, filePath, branch,true);//默认递归查询  筛选出文件后返回listArrayList<TreeItem> treeItems =newArrayList<>();for(TreeItem treeItem : tree){if("blob".equals(treeItem.getType().toString())){
                treeItems.add(treeItem);}}return  treeItems;}publicstaticList<TreeItem>getFileList(String projectPath,String branch,String filePath)throwsGitLabApiException{return gitLabApi.getRepositoryApi().getTree(projectPath,filePath,branch,true);//默认递归查询  筛选出文件后返回list}publicstaticsynchronizedRepositoryFilecreateFile(Integer gitProjId ,RepositoryFile file,String branch,String commit)throwsGitLabApiException{return  gitLabApi.getRepositoryFileApi().createFile(gitProjId,file,branch,commit);}publicstaticsynchronizedRepositoryFileupdateFile(Integer gitProjId ,RepositoryFile file,String branch,String commit)throwsGitLabApiException{return  gitLabApi.getRepositoryFileApi().updateFile(gitProjId,file,branch,commit);}publicstaticRepositoryFilegetFileByProjId(Integer gitProjId,String branch,String filePath)throwsGitLabApiException{return   gitLabApi.getRepositoryFileApi().getFile(gitProjId,filePath,branch);}}
标签: java git gitlab

本文转载自: https://blog.csdn.net/ZhengXinMing1998/article/details/131759179
版权归原作者 ZhengXinMing1998 所有, 如有侵权,请联系我们删除。

“如何使用java来操作git/gitlab?”的评论:

还没有评论