Несколько проектов SVN в один репозиторий Git?

Я начал использовать 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 /, избегая выполнения операции rebase N раз, но это оставляет меня с макетом каталога, который такой же, как в репозитории svn.

Есть ли способ, которым я могу отслеживать все стволы всех модулей в одном репозитории git? Так что я получаю макет директории, подобный этому, в моем git-репозитории:

module-1
module-2
module-N

2 ответа

Решение

К сожалению, нет, это невозможно сделать. Одна проблема заключается в том, что ничто не мешает двум или более модулям иметь ветвь с одинаковым именем. Затем, в git-svn, когда вы даете ему имя ветки, как он узнает, о каком модуле вы говорите?

Эта проблема действительно связана с тем, что в Subversion ветви не являются первоклассной концепцией, тогда как в git они есть. git-svn может более или менее использовать kludge, чтобы обойти этот факт, но kludge ломается, если репо имеет "нестандартный" макет (например, тот, с которым вы работаете).

Мое предложение: написать сценарий git-svn rebase торговый центр.

Я оказался в той же проблеме, что и вы, и обнаружил, что стандартного способа сделать это не существует. Однако, оглядываясь по сторонам, я узнал о стратегии, помогающей сделать это, и я создал сценарий Power Shell, основанный на этом. Я не могу вспомнить источник, или я бы отдал им должное. Я бы это объяснил, но мне проще увидеть сценарий и комментарии.

Вы можете использовать этот скрипт или, если не используете windows/powershell, сделать на его основе. Хорошо, что если у вас есть отдельные репозитории git для каждого подмодуля, если что-то выходит из строя, очень просто / быстро удалить новое "мастер" репозиторий git, внести изменения в скрипт и просто запустить его снова, так как все местный.

Помните, что есть некоторые случаи, которые не обрабатываются, например, когда у субмодуля есть папка, которая называется такой же, как у другого субмодуля (поэтому, если у вас есть субмодуль с именем BIN, а затем у других ваших субмодулей есть подпапка BIN), не получится). Также убедитесь, что все ваши подмодули git репозитории обновлены, прежде чем вы начнете!

Вы можете проверить сценарий в этой сущности: 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;
    }
Другие вопросы по тегам