最近在做一个项目中需要将系统中操作的SQL自动化维护到远程服务器上,git是一个非常强大的代码维护工具,遂对其自动化push做了一些研究,供大家学习参考。
 java git api - jgit的资料还是比较多的,而且git的操作比svn更容易理解,所以毅然决然的在git的道路上越走越远。

       如果你想在一个 Java 程序中使用 Git ,有一个功能齐全的 Git 库,那就是 JGit 。 JGit 是一个用 Java 写成的功能相对健全的 Git 的实现,它在 Java 社区中被广泛使用。 JGit 项目由 Eclipse 维护,它的主页在 http://www.eclipse.org/jgit 。

非常好的例子:https://github.com/centic9/jgit-cookbook

 

下面是我实现的代码,分别包含了如下的功能:

1、在本地文件夹建立起与远程仓库的连接(clone远程仓库到本地)
2   创建本地仓库
3、根据主干master新建分支并同步到远程   
4   切换分支
5、提交并push代码到远程

6、从远程pull代码到本地

所需依赖包:

 <dependency>
		      <groupId>org.eclipse.jgit</groupId>
		      <artifactId>org.eclipse.jgit</artifactId>
		      <version>4.11.0.201803080745-r</version>
        </dependency>
	    <dependency>
		      <groupId>org.eclipse.jgit</groupId>
		      <artifactId>org.eclipse.jgit.archive</artifactId>
		      <version>4.11.0.201803080745-r</version>
	    </dependency>
	    
	    <dependency>
		    <groupId>com.jcraft</groupId>
		    <artifactId>jsch</artifactId>
		    <version>0.1.54</version>
        </dependency>

java文件:

package com.rz.commons.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * Git操作工具类 
 */
public class JGitUtil {
	
	private static String LOCAL_REPO_PATH ;
	private static String LOCAL_REPOGIT_CONFIG;
	private static String REMOTE_REPO_URI;
	private static String INIT_LOCAL_CODE_DIR;
	private static String LOCAL_CODE_CT_SQL_DIR;
    private static String BRANCH_NAME ;
    private static String GIT_USERNAME;
    private static String GIT_PASSWORD ;
    
    public enum SqlTypeEnum{
    	SQL_CALC,EMAIL,MYSQL_TO_HIVE,HIVE_TO_MYSQL
    }
    
    
	final static Logger LOG = LoggerFactory.getLogger(JGitUtil.class);
	final static PropertyUtil prop = PropertyUtil.getInstance();
	
	static{
		
		LOCAL_REPO_PATH = prop.getProperty("local_repo_path"); // D:/workspace/project
		LOCAL_REPOGIT_CONFIG = prop.getProperty("local_repogit_config"); // D:/workspace/project/.git
		REMOTE_REPO_URI = prop.getProperty("remote_repo_uri"); // git@github.com:xxx/project.git
		INIT_LOCAL_CODE_DIR = prop.getProperty("init_local_code_dir"); // D:/workspace
		LOCAL_CODE_CT_SQL_DIR = prop.getProperty("local_code_ct_sql_dir"); // sqlpath/
		BRANCH_NAME = prop.getProperty("branch_name"); // v1.0
		GIT_USERNAME = prop.getProperty("git_username"); // admin
		GIT_PASSWORD = prop.getProperty("git_password"); // admin
	}
	
	
	public static void main(String[] args) {
	
		writeFileToGit(SqlTypeEnum.EMAIL,"xxx","-- 测试hehe \n select * from dual;","test_测试_201806071322","test");
		
	}
	/**
	 * sql脚本文件同步到git仓库
	 * @param qte SQl类型
	 * @param loginName 系统登录名  
	 * @param fileName 文件名  
	 * @param fileContent  文件内容
	 * @param comment  提交说明
	 * @return
	 */
	public static boolean writeFileToGit(SqlTypeEnum qte,String loginName,String sqlConent,String fileName,String comment){
		
		JGitUtil.pull();
		String dest =LOCAL_CODE_CT_SQL_DIR+qte.name().toLowerCase();
		String path = LOCAL_REPO_PATH+"/"+dest;
		File f =new File(path);
		if(!f.exists()){
			f.mkdirs();
		}
		dest=dest+"/"+fileName;
		path=path+"/"+fileName;
		comment=loginName+" option of "+comment;
		return true==JGitUtil.createFile(sqlConent, path)==JGitUtil.commitAndPush(dest,comment);
	}
	
	/** 
	 * 根据主干master新建分支并同步到远程仓库
     * @param branchName 分支名
     * @throws IOException
     * @throws GitAPIException
     */
    public static String newBranch(String branchName) throws IOException{
//        String newBranchIndex = "refs/heads/"+branchName;
          String gitPathURI = "";
//        Git git = null;
//        try {
//            
//            //检查新建的分支是否已经存在,如果存在则将已存在的分支强制删除并新建一个分支
//            List<Ref> refs = git.branchList().call();
//            for (Ref ref : refs) {
//                if (ref.getName().equals(newBranchIndex)) {
//                    System.out.println("Removing branch before");
//                    git.branchDelete().setBranchNames(branchName).setForce(true).call();
//                    break;
//                }
//            }            
//            //新建分支
//            Ref ref = git.branchCreate().setName(branchName).call();
//            //推送到远程
//            git.push().add(ref).call();
//            gitPathURI = remoteRepoURI + " " + "feature/" + branchName;
//        } catch (GitAPIException e) {
//            e.printStackTrace();
//        }
        return gitPathURI;                
    }
	/**
	 * 添加文件
	 * @param fileName
	 * @return
	 */
    public static boolean addFile(String fileName) {

            boolean addFileFlag=true;
            try ( 
            		Git git = Git.open( new File(LOCAL_REPOGIT_CONFIG) );
//            		Git git2 = new Git(new FileRepository(localRepoGitConfig));
                ) {
//            	  File myFile = new File(git.getRepository().getDirectory().getParent(),filePath);
//                if(!myFile.createNewFile()) {
//                    throw new IOException("Could not create file " + myFile);
//                }
                //add file to git
            	String filePath=LOCAL_CODE_CT_SQL_DIR+fileName;
                git.add().addFilepattern(INIT_LOCAL_CODE_DIR).call();
                System.out.println("Added file " + filePath + " to repository at " + git.getRepository().getDirectory());
            }catch (Exception e) {
				e.printStackTrace();
				addFileFlag=false;
			}
          return addFileFlag;
	}
    /**
     * 提交代码到本地仓库
     * @param filePath 文件位置(相对仓库位置:a/b/file)
     * @param comment 提交git内容描述
     * @return
     */
    public static boolean commitFile(String comment) {

        boolean commitFileFlag=true;
        try ( Git git = Git.open( new File(LOCAL_REPOGIT_CONFIG) );) {
            //提交代码到本地仓库
            git.commit().setMessage(comment).call();
            LOG.info("Committed to repository at " + git.getRepository().getDirectory());
        }catch (Exception e) {
			e.printStackTrace();
			commitFileFlag=false;
			LOG.error("commitFile error! \n"+e.getMessage());
		}
        return commitFileFlag;
    }
    
    public static boolean push() {

        boolean pushFlag=true;
        try ( Git git = Git.open( new File(LOCAL_REPOGIT_CONFIG) );) {
            //提交代码到本地仓库
            git.push().call();
            LOG.info("push " + git.getRepository()+File.separator+git.getRepository().getBranch());
        }catch (Exception e) {
			e.printStackTrace();
			pushFlag=false;
			LOG.error("push error! \n"+e.getMessage());
		}
        return pushFlag;
    }
    /**
     * 提交并推送代码至远程服务器
     * @param filePath 提交文件路径(相对路径)
     * @param desc 提交描述
     * @return
     */
    public static boolean commitAndPush(String filePath,String desc){
    	
         boolean commitAndPushFlag=true;
         try ( Git git = Git.open( new File(LOCAL_REPOGIT_CONFIG) );) {
//        	 //创建用户文件的过程
//             File myfile = new File(filePath);
//             myfile.createNewFile();
        	 UsernamePasswordCredentialsProvider provider =new UsernamePasswordCredentialsProvider(GIT_USERNAME,GIT_PASSWORD);
             git.add().addFilepattern(filePath).call();  
             //提交
             git.commit().setMessage(desc).call();   
             //推送到远程
             if(StringUtils.isBlank(GIT_USERNAME) || StringUtils.isBlank(GIT_PASSWORD)){
            	 git.push().setCredentialsProvider(provider).call();
             }else{
            	 git.push().call();
             }
             LOG.info("Commit And Push file " + filePath + " to repository at " + git.getRepository().getDirectory());
         }catch (Exception e) {
 			e.printStackTrace();
 			commitAndPushFlag=false;
 			LOG.error("Commit And Push error! \n"+e.getMessage());
 		 }
         return commitAndPushFlag;
         
    }
    /**
     * 拉取远程代码
     * @param remoteBranchName
     * @return 远程分支名
     */
    
    public static boolean pull(){
    	return pull(BRANCH_NAME);
    }
    public static boolean pull(String remoteBranchName){
    	
    	boolean pullFlag=true;
         try ( Git git = Git.open( new File(LOCAL_REPOGIT_CONFIG) );) {
//        	 UsernamePasswordCredentialsProvider provider =new UsernamePasswordCredentialsProvider(GIT_USERNAME,GIT_PASSWORD);
        	 git.pull()
        	 .setRemoteBranchName(remoteBranchName)
//        	 .setCredentialsProvider(provider)
        	 .call();
         }catch (Exception e) {
			e.printStackTrace();
			pullFlag=false;
		}
    	return pullFlag;
    }
   public static boolean checkout(String branchName){
    	
    	boolean checkoutFlag=true;
         try ( Git git = Git.open( new File(LOCAL_REPOGIT_CONFIG) );) {
        	 git.checkout().setName("refs/heads/"+branchName).setForce(true).call();
         }catch (Exception e) {
			e.printStackTrace();
			checkoutFlag=false;
		}
    	return checkoutFlag;
    }
   public static boolean checkout(){
   	
   	   return checkout(BRANCH_NAME);
   	   
   }
   /**
    *  从远程获取最新版本到本地   不会自动合并 merge 
    * @param branchName
    * @return
    */
   public static boolean fetch(){
   	
   	   boolean fetchFlag=true;
        try ( Git git = Git.open( new File(LOCAL_REPOGIT_CONFIG) );) {
        	git.fetch().setCheckFetchedObjects(true).call();
        }catch (Exception e) {
			e.printStackTrace();
			fetchFlag=false;
		}
   	    return fetchFlag;
   }
 
    /**
     * 拉取新创建的分支到本地
     * @param cloneURL
     * @return
     */
    @SuppressWarnings("static-access")
	public static boolean pullNewBranchToLocal(String cloneURL){
        boolean resultFlag = false;
        String[] splitURL = cloneURL.split(" ");
        String branchName = splitURL[1];
        String fileDir = INIT_LOCAL_CODE_DIR+"/"+branchName;
        //检查目标文件夹是否存在
        File file = new File(fileDir);
        if(file.exists()){
            deleteFolder(file);
        }
        Git git;
        try {
            git = Git.open( new File(LOCAL_REPOGIT_CONFIG) );
            git.cloneRepository().setURI(cloneURL).setDirectory(file).call();
            resultFlag = true;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (GitAPIException e) {
            e.printStackTrace();
        }
        return resultFlag;    
    }
    
    
   private static void deleteFolder(File file){
        if(file.isFile() || file.list().length==0){
            file.delete();
        }else{
            File[] files = file.listFiles();
            for(int i=0;i<files.length;i++){
                deleteFolder(files[i]);
                files[i].delete();
            }
        }
    }
   /**
    * 生成文件写内容
    * @param content 文件内容
    * @param filePath  文件名称
    */
   @SuppressWarnings("unused")
   private static boolean createFile(String content,String filePath){
	   
	  //删除前一天临时目录
//	  File af = new File(filePath+File.separator+DateUtil.getAgoBackDate(-1));
//	  if (af.exists()) {
//		  deleteFolder(af);
//	  }
//	  //创建临时存储目录
//	  File f = new File(filePath+File.separator+DateUtil.getAgoBackDate(0));
//	  if (!f.exists()) {
//		f.mkdirs();
//	  }
//	  if (!fileName.endsWith(".sql")) {
//		  fileName+=".sql";
//	  }
	  boolean createFileFlag=true;
	  File file =new File(filePath);
	  if (!file.exists()) {
		try {
			file.createNewFile();
		} catch (Exception e) {
			e.printStackTrace();
			createFileFlag=false;
		}
	  }
	  try(BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),Charsets.UTF_8));) {
		  bw.write(content);
	  } catch (FileNotFoundException e) {
		e.printStackTrace();
		createFileFlag=false;
	  } catch (IOException e) {
		e.printStackTrace();
		createFileFlag=false;
	  }
	  return createFileFlag;
   }
    /**
     * 创建本地新仓库
     * @param repoPath 仓库地址 D:/workspace/TestGitRepository
     * @return
     * @throws IOException
     */
    public static Repository createNewRepository(String repoPath) throws IOException {
        File localPath = new File(repoPath);
        // create the directory
        Repository repository = FileRepositoryBuilder.create(new File(localPath, ".git"));
        repository.create();
        return repository;
    }
    /**
     * 创建仓库,仅需要执行一次
     */
    public static boolean setupRepository(){
    	boolean setupRepositoryFlag=true;
    	try {
            //设置远程服务器上的用户名和密码
            UsernamePasswordCredentialsProvider provider =new UsernamePasswordCredentialsProvider(GIT_USERNAME,GIT_PASSWORD);
            if(StringUtils.isBlank(GIT_USERNAME) || StringUtils.isBlank(GIT_P点击打开链接ASSWORD)){
            	Git git =Git.cloneRepository().setURI(REMOTE_REPO_URI) //设置远程URI
        				.setBranch("master")   //设置clone下来的分支,默认master
        				.setDirectory(new File(LOCAL_REPO_PATH))  //设置下载存放路径
        				.call();
            }else{
            	Git git =Git.cloneRepository().setURI(REMOTE_REPO_URI) //设置远程URI
        				.setBranch("master")   //设置clone下来的分支,默认master
        				.setDirectory(new File(LOCAL_REPO_PATH))  //设置下载存放路径
        				.setCredentialsProvider(provider) //设置权限验证
        				.call();
            }
		} catch (Exception e) {
			e.printStackTrace();
			setupRepositoryFlag=false;
		}
    	return setupRepositoryFlag;
    }
}点击打开链接ASSWORD)){
            	Git git =Git.cloneRepository().setURI(REMOTE_REPO_URI) //设置远程URI
        				.setBranch("master")   //设置clone下来的分支,默认master
        				.setDirectory(new File(LOCAL_REPO_PATH))  //设置下载存放路径
        				.call();
            }else{
            	Git git =Git.cloneRepository().setURI(REMOTE_REPO_URI) //设置远程URI
        				.setBranch("master")   //设置clone下来的分支,默认master
        				.setDirectory(new File(LOCAL_REPO_PATH))  //设置下载存放路径
        				.setCredentialsProvider(provider) //设置权限验证
        				.call();
            }
		} catch (Exception e) {
			e.printStackTrace();
			setupRepositoryFlag=false;
		}
    	return setupRepositoryFlag;
    }
}

        另,如果你想将 Git 整合进你的应用程序的话,一般来说你有三种可能的选择:启动一个 shell 来使用 Git 的命令行工具;使用 Libgit2;或者使用 JGit。见 资料

   

       

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐