如何使用JGit进行"git filter-branch --subdirectory <folderName>"



我有很多Maven多模块项目(约50个(。他们每个人都有1到4个子模块。每个多模型项目都位于单独的GIT存储库中。由于问题,我需要将模块分为单独的存储库。

我有一个shell脚本可以将文件夹(一个Maven模块(从repo a移动到保存其git历史记录的repo b。

#!/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 "$2" from Repository: "$1" to Repository:"$3
# prepare repository one
cd $1
git clean -f -d -x
git checkout -b tmpBranch
git filter-branch -f --subdirectory-filter $2 HEAD
mkdir $2
mv * $2
git add .
git commit -a -m "CIRCLE-524: Moved "$2" into new repository"
#import in repository two
cd $3
git remote add repositoryOne $1
git pull repositoryOne tmpBranch
git remote rm repositoryOne
#cleanup
cd $1
git checkout master
git branch -D tmpBranch

当我只需要做几个项目时,我就可以手动执行此操作。但是因为我喜欢50个多模块项目,所以我喜欢自动化这个。

我可以使用ProcessBuilder执行此脚本。但是,将所有模块拆分的过程将在Windows机器上完成。
(当我手动执行此操作时,我正在使用git bash(

因此,我发现JGIT可以用Java自动化我的整个过程。我的问题是git filter-branch -f --subdirectory-filder $2 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占据了头部,并列出了与modulePath

匹配给定过滤器的所有文件

我想要实现git filter-branch -f --subdirectory-filder $2 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"

最新更新