如何用 JGit 做 "git filter-branch --subdirectory <folderName>"
How to do "git filter-branch --subdirectory <folderName>" with JGit
我有很多maven多模块项目(50个左右)。它们每个都有 1 到 4 个子模块。每个多模块项目都位于一个单独的 git 存储库中。由于一个问题,我需要将模块拆分到单独的存储库中。
我有一个 shell 脚本,用于将文件夹(一个 Maven 模块)从 Repo A 移动到 Repo B,保留其 git 历史记录。
#!/bin/sh
# moves a folder from one git repository to another
# moveFolder <absolute repository one path> <repository one folder> <absolute repository two path>
echo "Moving "" from Repository: "" to Repository:"
# prepare repository one
cd
git clean -f -d -x
git checkout -b tmpBranch
git filter-branch -f --subdirectory-filter HEAD
mkdir
mv *
git add .
git commit -a -m "CIRCLE-524: Moved "" into new repository"
#import in repository two
cd
git remote add repositoryOne
git pull repositoryOne tmpBranch
git remote rm repositoryOne
#cleanup
cd
git checkout master
git branch -D tmpBranch
当我只需要为几个项目执行此操作时,我可以手动执行。但是因为我有 50 个多模块项目,所以我喜欢将其自动化。
我可以使用 ProcessBuilder 来执行这个脚本。但是拆分所有模块的过程将在 windows 机器上完成。
(当我手动执行此操作时,我使用的是 Git Bash)
所以我发现 JGit 使用 java 来自动化我的整个过程。我的问题是 git filter-branch -f --subdirectory-filder HEAD
到目前为止我有以下内容。
public static void revWalk(final Git repo) throws NoWorkTreeException, GitAPIException, MissingObjectException, IncorrectObjectTypeException, IOException {
final Ref tmpBranch = checkOutBranch(repo, "tmpBranch");
final Repository repository = repo.getRepository();
try (RevWalk revWalk = new RevWalk(repository)) {
final ObjectId commitId = repository.resolve(tmpBranch.getName());
revWalk.markStart(revWalk.parseCommit(commitId));
for (final RevCommit commit : revWalk) {
System.out.println("Time: " + commit.getAuthorIdent().getWhen() + " Message: " + commit.getShortMessage());
}
}
}
和
public static void fileWalk(final Git repo, final String modulePath) throws IOException {
final Ref head = repo.getRepository().findRef("HEAD");
final RevWalk walk = new RevWalk(repo.getRepository());
final RevCommit commit = walk.parseCommit(head.getObjectId());
final RevTree tree = commit.getTree();
System.out.println("Having tree: " + tree);
final TreeWalk treeWalk = new TreeWalk(repo.getRepository());
treeWalk.addTree(tree);
treeWalk.setRecursive(true);
treeWalk.setFilter(PathFilterGroup.createFromStrings(modulePath));
while (treeWalk.next()) {
System.out.println("found: " + treeWalk.getPathString());
}
walk.close();
treeWalk.close();
}
revWalk
检出一个新的 tmpBranch 进行处理,然后列出所有带有时间和消息的提交。
fileWalk
获取 HEAD 并列出与 modulePath
给定过滤器匹配的所有文件
我想要实现 git filter-branch -f --subdirectory-filder HEAD
我必须将这两种方式结合起来,但老实说,我不知道该怎么做。
你能给我指出正确的方向并给我一些代码示例吗?
回答我自己的问题:
我使用 ProcessBuilder 来执行我给定的脚本并执行了以下操作。
private void executeScript(final String pathToGitBash, final File scriptFileToExecute, final String... arguments) throws IOException, InterruptedException {
final int offset = 4;
final String[] command = new String[arguments.length + offset];
command[0] = pathToGitBash;
command[1] = "--login";
command[2] = "-i";
command[3] = scriptFileToExecute.getAbsolutePath();
for (int i = 0; i < arguments.length; i++) {
command[i + offset] = arguments[i];
}
final ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
final Process process = builder.start();
IOUtils.copy(process.getInputStream(), System.out);
IOUtils.copy(process.getErrorStream(), System.err);
switch (process.waitFor()) {
case 1:
LOGGER.error("Parameters for scripts are not correct.");
break;
case 0:
LOGGER.info("Script seemed to execute properly");
break;
default:
LOGGER.info("Unknown returnCode. Script finished with: {}", process.exitValue());
}
}
要使用 Gitbash 执行它,我需要提供 gitbash/sh.exe 和参数“--login -i”
我有很多maven多模块项目(50个左右)。它们每个都有 1 到 4 个子模块。每个多模块项目都位于一个单独的 git 存储库中。由于一个问题,我需要将模块拆分到单独的存储库中。
我有一个 shell 脚本,用于将文件夹(一个 Maven 模块)从 Repo A 移动到 Repo B,保留其 git 历史记录。
#!/bin/sh
# moves a folder from one git repository to another
# moveFolder <absolute repository one path> <repository one folder> <absolute repository two path>
echo "Moving "" from Repository: "" to Repository:"
# prepare repository one
cd
git clean -f -d -x
git checkout -b tmpBranch
git filter-branch -f --subdirectory-filter HEAD
mkdir
mv *
git add .
git commit -a -m "CIRCLE-524: Moved "" into new repository"
#import in repository two
cd
git remote add repositoryOne
git pull repositoryOne tmpBranch
git remote rm repositoryOne
#cleanup
cd
git checkout master
git branch -D tmpBranch
当我只需要为几个项目执行此操作时,我可以手动执行。但是因为我有 50 个多模块项目,所以我喜欢将其自动化。
我可以使用 ProcessBuilder 来执行这个脚本。但是拆分所有模块的过程将在 windows 机器上完成。
(当我手动执行此操作时,我使用的是 Git Bash)
所以我发现 JGit 使用 java 来自动化我的整个过程。我的问题是 git filter-branch -f --subdirectory-filder HEAD
到目前为止我有以下内容。
public static void revWalk(final Git repo) throws NoWorkTreeException, GitAPIException, MissingObjectException, IncorrectObjectTypeException, IOException {
final Ref tmpBranch = checkOutBranch(repo, "tmpBranch");
final Repository repository = repo.getRepository();
try (RevWalk revWalk = new RevWalk(repository)) {
final ObjectId commitId = repository.resolve(tmpBranch.getName());
revWalk.markStart(revWalk.parseCommit(commitId));
for (final RevCommit commit : revWalk) {
System.out.println("Time: " + commit.getAuthorIdent().getWhen() + " Message: " + commit.getShortMessage());
}
}
}
和
public static void fileWalk(final Git repo, final String modulePath) throws IOException {
final Ref head = repo.getRepository().findRef("HEAD");
final RevWalk walk = new RevWalk(repo.getRepository());
final RevCommit commit = walk.parseCommit(head.getObjectId());
final RevTree tree = commit.getTree();
System.out.println("Having tree: " + tree);
final TreeWalk treeWalk = new TreeWalk(repo.getRepository());
treeWalk.addTree(tree);
treeWalk.setRecursive(true);
treeWalk.setFilter(PathFilterGroup.createFromStrings(modulePath));
while (treeWalk.next()) {
System.out.println("found: " + treeWalk.getPathString());
}
walk.close();
treeWalk.close();
}
revWalk
检出一个新的 tmpBranch 进行处理,然后列出所有带有时间和消息的提交。
fileWalk
获取 HEAD 并列出与 modulePath
我想要实现 git filter-branch -f --subdirectory-filder HEAD
我必须将这两种方式结合起来,但老实说,我不知道该怎么做。
你能给我指出正确的方向并给我一些代码示例吗?
回答我自己的问题:
我使用 ProcessBuilder 来执行我给定的脚本并执行了以下操作。
private void executeScript(final String pathToGitBash, final File scriptFileToExecute, final String... arguments) throws IOException, InterruptedException {
final int offset = 4;
final String[] command = new String[arguments.length + offset];
command[0] = pathToGitBash;
command[1] = "--login";
command[2] = "-i";
command[3] = scriptFileToExecute.getAbsolutePath();
for (int i = 0; i < arguments.length; i++) {
command[i + offset] = arguments[i];
}
final ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
final Process process = builder.start();
IOUtils.copy(process.getInputStream(), System.out);
IOUtils.copy(process.getErrorStream(), System.err);
switch (process.waitFor()) {
case 1:
LOGGER.error("Parameters for scripts are not correct.");
break;
case 0:
LOGGER.info("Script seemed to execute properly");
break;
default:
LOGGER.info("Unknown returnCode. Script finished with: {}", process.exitValue());
}
}
要使用 Gitbash 执行它,我需要提供 gitbash/sh.exe 和参数“--login -i”