7

我已经开始在我的一些工作中使用 git-svn 来进行本地提交。这对于使用标准 svn 布局的项目非常有用。最近我开始研究一个 Java 项目,该项目被分成多个连接的模块(20-25),每个模块在同一个 svn 存储库中都有自己的根文件夹,并有自己的主干/分支/标签。

svnrepo/    
  module-1
    trunk
    branches
    tags
  module-N
    trunk
    branches
    tags

我已经用 git svn clone -s /path/to/svnrepo/module[1-N] 克隆了每个模块。“问题”是当我想对所有模块执行 git svn rebase 时,我必须执行 N 次。

我试图做 git svn clone /path/to/svnrepo/ 避免做 N 次 rebase 操作,但这让我的目录布局与 svn repo 中的相同。

有没有一种方法可以在一个 git repo 中跟踪所有模块的所有主干?这样我就可以在我的 git 存储库中获得这样的目录布局:

module-1
module-2
module-N
4

2 回答 2

2

不幸的是,不,没有办法做到这一点。一个问题是没有什么可以阻止两个或多个模块拥有同名的分支。然后,在 git-svn 中,当你给它分支名称时,它怎么知道你在说哪个模块?

这个问题实际上源于这样一个事实,即在 Subversion 中分支不是一流的概念,而在 git 中它们是。git-svn 能够或多或少地使用 kludge 来解决这个事实,但是如果 repo 具有“非标准”布局(例如您正在使用的布局),kludge 就会崩溃。

我的建议:给git-svn rebase他们写一个脚本。

于 2009-05-22T18:41:26.360 回答
0

我发现自己和你遇到了同样的问题,并且发现没有标准的方法可以做到这一点。然而,环顾四周,我发现了一种有助于做到这一点的策略,并在此基础上创建了一个 power shell 脚本。我不记得出处,否则我会给他们功劳。我会解释它,但我更容易看到脚本和评论。

您可以使用此脚本,或者如果不使用 windows/powershell,则基于它进行制作。好消息是,一旦您为每个子模块拥有了自己的 git 存储库,如果出现故障,只需删除新的“主”git 存储库、更改脚本并再次运行它就真的很快/很容易,因为这一切当地的。

请注意,有些情况未处理,例如当一个子模块具有与另一个子模块相同的文件夹时(因此,如果您有一个名为 BIN 的子模块,然后您的其他子模块有一个 BIN 子文件夹,它将失败)。在开始之前,请确保您的所有子模块 git repos 都是最新的!

您可以在此 gist 中查看脚本: Gist Script

如果由于某种原因主旨不正确,我也在这里添加了它(尽管可读性差很多)

$GitReposLocation = "path\to\individual\git\repos"; #1 git repo for each module (you svn cloned each one using std layout)
$MasterGitRepoLocation = "path\to\masterRepo"; #the path where you want your main repo that contains all the modules
git reset --hard;

write-host Creating folder $MasterGitRepoLocation -foregroundcolor "green";
mkdir $MasterGitRepoLocation;

write-host Moving to folder $MasterGitRepoLocation -foregroundcolor "green";
cd $MasterGitRepoLocation;

write-host Creating Git Repository -foregroundcolor "cyan";
git init;

#this is hacky, but we need to have an initial commit
"" > root;
git add root;
write-host Creating root node -foregroundcolor "cyan";
git commit -m "Initial commit to create parent root.";

#we are going to be moving files around, and don't want to move the files we already got in our MasterRepo root/workspace
$NotMoveThesFiles = @();
dir |%{$NotMoveThesFiles+=@($_.FullName) };

$repos = @();
# you should add a repo here if for some reasong you don't want to process that one.
# $repos+=@("SomeRepo");

dir -Path $GitReposLocation -Directory |Where-object{ $repos -NotContains $_.Name }|%{$repos+=@($_.Name) };

# for-each repo....
$repos|%{ 
        $SubRepoName = $_;
        write-host Processing GitRepo $SubRepoName -foregroundcolor "green";        
        $Remote = "remote"+$SubRepoName;        

        #add this git repo (of a module) as a remote of our main repo
        write-host Adding reference to $SubRepoName as remote repo -foregroundcolor  "cyan";
        git remote add -f $Remote $GitReposLocation\$SubRepoName;

        #Merge that sub repo into the main repo. The only problem? It will copy that repo's workspace
        #directly into our main repo Root folder
        write-host Merging remote$SubRepoName/master into master -foregroundcolor  "cyan";
        git merge remote$SubRepoName/master;

        #so now we are going to create a folder with  the name of this module (subRepo)
        #and move everything that is in the Master's root folder to that folder, except of course
        #things that we already had in the root folder before the merge. (in the NotMoveTheseFiles array)

        write-host Moving files got from $SubRepoName to a subdir called $SubRepoName -foregroundcolor  "green";

        #create folder folr the module
        mkdir $SubRepoName;
        #add these new folde to the list of things we don't want to move into it.
        $NotMoveThesFiles+=@($SubRepoName);

        #copy all files not in the NotMoveTheseFiles array into the newly created folder.
        dir |where-object {$NotMoveThesFiles -NotContains $_} |%{git mv $_ $SubRepoName};

        #commit the change where we moved all these files around.
        $CommitMessage = "Moving files got from " + $SubRepoName + " to a subdir called $SubRepoName"
        git commit -m $CommitMessage;
    }
于 2014-03-22T02:04:18.090 回答