我已经开始使用git-svn来完成我的一些工作,以便能够进行本地提交。这适用于使用标准svn布局的项目。最近我开始研究一个分为多个连接模块的Java项目(20-25),每个模块在同一个svn repo中有自己的根文件夹,并有自己的trunk / branches / tags。
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仓库中跟踪所有模块的所有中继?这样我就可以在我的git存储库中获得这样的目录布局:
module-1
module-2
module-N
答案 0 :(得分:2)
不幸的是,不,没有办法做到这一点。一个问题是没有什么能阻止两个或多个模块具有相同名称的分支。然后,在git-svn中,当你给它分支名称时,它怎么知道你在说哪个模块?
这个问题的真正原因在于Subversion分支不是一流的概念,而在git中它们是。 git-svn能够使用或多或少的kludge来解决这个问题,但如果repo具有“非标准”布局(例如你正在使用的那个),那么kludge会崩溃。
我的建议:写一个脚本给git-svn rebase
所有人。
答案 1 :(得分:0)
我发现自己和你一样,发现没有标准的方法可以做到这一点。但是,环顾四周,我发现了一个帮助实现这一目标的策略,并且我基于此创建了一个power shell脚本。我无法记住来源,或者我会给予他们信任。我会解释一下,但我更容易看到脚本和评论。
您可以使用此脚本,或者如果不使用windows / powershell,则可以使用此脚本。好消息是,一旦你为每个子模块设置了你自己的git repos,如果出现故障,它真的很快/很容易删除新的" master" git repo,对脚本进行更改,然后重新运行,因为它是全局的。
请注意,有些情况没有处理,比如子模块的文件夹与另一个子模块相同(如果你有一个名为BIN的子模块,那么你的其他子模块就有一个子模块) BIN子文件夹,它会失败)。另外,在开始之前,请确保所有子模块git repos都是最新的!
您可以在此要点中查看脚本: 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;
}