java实现自动化Git操作
最近在做一个项目中需要将系统中操作的SQL自动化维护到远程服务器上,git是一个非常强大的代码维护工具,遂对其自动化push做了一些研究,供大家学习参考。 java git api - jgit的资料还是比较多的,而且git的操作比svn更容易理解,所以毅然决然的在git的道路上越走越远。 如果你想在一个 Java 程序中使用 Git ,有一个功能齐全的 Git 库...
最近在做一个项目中需要将系统中操作的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。见 资料
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)