最近将gitlab中的submodule管理由shell脚本转换为api调用。在网络上找了相关信息(包括官网),上面的使用方式都比较片面。参照样例及探索验证后将完整的使用过程进行记录。以方便他人借鉴。
shell脚本处理方式如下
1、编制shell脚本,内容如下
#!/bin/sh
#源地址
URL_SRC=$1
echo "Source url: $URL_SRC"
#目标地址
URL_DEST=$2
echo "Dest url: $URL_DEST"
# 初始化配置代理项目
function init() {
/usr/local/git/bin/git clone $URL_DEST
}
# 增加设置子模块
function doProxy() {
# 进入proxy文件夹
cd proxy
# 添加代理子模块
/usr/local/git/bin/git submodule add $URL_SRC
# 提交
/usr/local/git/bin/git commit -m "add submodules $URL_SRC to $URL_DEST"
# 提交gitlab
/usr/local/git/bin/git push
}
# 删除配置代理项目proxy文件
function deleteProxyDir(){
# 为了减少不必要麻烦(fatal: 不是 git 仓库(或者直至挂载点 / 的任何父目录)停止在文件系统边界(未设置 GIT_DISCOVERY_ACROSS_FILESYSTEM))
# 当次执行完成后清理proxy文件夹
cd ..
# 删除proxy文件
rm -rf proxy
}
# 1.初始化(获取配置代理项目)
init;
# 2.作业(新增配置项目到代理项目)
doProxy;
# 3.清除proxy目录
deleteProxyDir;
exit 0
2、可以直接执行shell脚本,传递相应参数执行即可。(我们是在java代码中执行脚本)在代码中使用方法
private void addProxyConfigRepostory(Project configProject){
String execFile = "/shell/to/execute/proxy.sh";
String configRepostory = configProject.getHttpUrlToRepo();
String proxyRepostory = configRepostory.substring(0, configRepostory.lastIndexOf(CommonsConstants.PATH_SEPARATOR)+1)
.concat("proxy.git");
ProcessBuilder pb = new ProcessBuilder(execFile, configRepostory, proxyRepostory);
int lastIndex = execFile.lastIndexOf(CommonsConstants.PATH_SEPARATOR);
String directory = "";
if (lastIndex != -1) {
directory = execFile.substring(0, lastIndex);
}
pb.directory(new File(directory));
try {
Process process = pb.start();
int waitF = process.waitFor();
if (waitF == 0) {
log.info("脚本执行成功");
}else{
log.warn("脚本执行失败");
}
} catch (Exception e) {
log.error("脚本执行异常,{0}", e);
}
}
这种方式的弊端是需要安装git客户端程序,为了解决此弊端采用jgit实现。
jgit的好处是不需要安装git客户端程序,由代码完成submodule的维护。使用步骤如下
1、引入jgit(如是maven项目,直接在pom.xml里引入即可,普调java工程则需引入jgit相应的jar)
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>5.9.0.202009080501-r</version>
</dependency>
2、代码中实现
private static void init() {
String projectName = "validation-config-repo-012"; // submodule项目名
File tempDirectory = new File("/tmp/bone-provider/config/submodules");// 临时路径
String gitlabUri = "http://{gitlab-hostname}[{:port}]/{group-path}"; // gitlab地址
String userName = "{user-name}"; // gitlab账号
String password = "{user-passwd}"; // gitlab账号密码
CredentialsProvider credentialsProvider = new UsernamePasswordCredentialsProvider(userName, password);
try {
Git git;
if (tempDirectory.exists()) {
// 临时目录存在,则直接使用,不需要重新clone
git = Git.open(tempDirectory);
} else {
// 不存在,则需要clone到临时目录(可以不clone项目中的submodules相关文件)
git = Git.cloneRepository()
.setURI(gitlabUri + "/proxy.git")
.setCredentialsProvider(credentialsProvider)
.setBranch("master")
// .setCloneSubmodules(true) // 需要submodule文件则需要设置此项为true,默认不克隆拉取submodule中的文件
.setDirectory(tempDirectory)
.call();
}
// 更新临时目录中的submodule信息
git.submoduleUpdate()
.setCredentialsProvider(credentialsProvider)
.call();
// 添加submodule信息
git.submoduleAdd().setName(projectName)
.setURI(gitlabUri + "/" + projectName + ".git")
.setPath(projectName)
.setCredentialsProvider(credentialsProvider)
.call();
//提交
CommitCommand commitCommand = git.commit()
.setCommitter(userName, "administor@banksteel.com")
.setMessage("add submodules " + projectName + ".git to proxy.git");
commitCommand.setCredentialsProvider(credentialsProvider);
commitCommand.call();
//push
git.push()
.setCredentialsProvider(credentialsProvider)
.call();
} catch (Exception ex) {
ex.printStackTrace();
}
}
这样就完成通过jgit完成对submodule的新增管理,删除和更新类似,这里就不赘述。