Как я могу использовать два проекта SVN и соответствующие ветки git-svn с одним рабочим каталогом?

StackOverflow https://stackoverflow.com/questions/609872

  •  03-07-2019
  •  | 
  •  

Вопрос

Я относительно новичок в Git, но хочу попробовать (по сравнению с SVN и Bazaar).

Может ли кто-нибудь порекомендовать мне рабочий процесс для ситуации, подобной следующей:

  • 1 репозиторий SVN с несколькими проектами
  • 1 рабочая копия "src"

Идея состоит в том, что в «src» мне нужно оформить заказ на проект А, а иногда и на проект Б.Оба проекта имеют несколько ответвлений.

На данный момент я сделал 2 git-клона репозитория SVN, по одному для каждого проекта.(Я бы предпочел --bare репозитории, но он не работает с git svn clone)

Затем я создал репозиторий git в «src» и git remote add projA ..a_repo_git, "git remote add projB ..b_repo_git".

Теперь я могу видеть их обоих из «src», используя «git Remote», и я могу видеть их ветки с помощью «git Remote Show projA».

А теперь беда..

  • Как я могу попасть в «src» любую из ветвей projA/projB?
  • Как я могу изменить их, а затем иметь возможность отправить их обратно (сначала в git_repos или непосредственно в репозиторий SVN)?
  • Это «рабочий процесс» в порядке, или у вас есть идея получше?

Я попробовал в src: git checkout --track -b work_branch projA branch_in_Aи после некоторых возни с «доставкой» мне удалось получить вещи.Но затем у меня возникли проблемы с возвращением его обратно в a_repo_git, а затем в SVN.В основном это был метод проб и ошибок.

Признаюсь, у меня до сих пор проблемы с удаленными ветками!(и я теряюсь, когда мне приходится использовать "origin local_branch:origin_branch" или "origin origin_branch:local_branch", или "origin origin_branch" или "origin/origin_branch"!Вернемся к руководству по Git для дальнейшего чтения.)

Это было полезно?

Решение

Я не обновил вопрос, потому что за последние несколько дней мне удалось работать очень легко и приятно с помощью моего нового репозитория :)

Вот что я сделал в итоге:

Инициализируйте два репозитория SVN в одном каталоге.(Я сейчас не помню, но возможно, что «git init» был выполнен в том же каталоге раньше:

mkdir src && cd src
(not sure about this: git init)
git svn init --stdlayout --prefix=projA/ -RprojA file:///path/to/svn/repo/A
git svn init --stdlayout --prefix=projB/ -RprojB file:///path/to/svn/repo/B

«--stdlayout» означает, что репозитории SVN имеют стандартный формат, со стволом, ветвями и тегами на одном уровне.

Префикс --prefix используется для имени ветки.Когда мы выполняем «git Branch -a», все ветки SVN из проекта A имеют префикс «projA» (например:projA/имя_ветви_A).То же самое касается и Б.

Опция -R устанавливает имя репозитория SVN внутри репозитория git (это имя, которое мы используем с git при обращении к репозиторию/проекту SVN).

Файл:///путь — это путь к репозиторию SVN и в данном случае к проекту внутри репозитория.Я использую «file://», потому что использовал репозиторий в виде плоского файла без сервера.Я уверен, что с http:// он работает нормально и для сервера SVN.

После этого шага из любопытства я заглянул в файл src/.git/config.Две приведенные выше команды создали несколько разделов «svn-remote», по одному для каждого проекта (опция -R), а также общий раздел под названием «svn».Я изменил записи, поэтому там будут только ссылки на проекты.Каждая ссылка имела записи для пути репо (выборка) и для тегов/веток/магистралей.Если вы посмотрите файл, то поймете, что нужно изменить.

После этого я получил содержимое каждого проекта, используя

git svn fetch projA #the contents of project A repo are downloaded
git svn fetch projB #the contents of project B repo are downloaded

Теперь при запуске «git Branch -a» отображаются все ветки из двух репозиториев и главная ветка (локальная).«git Branch -r» не отображал ни одной ветки;вероятно потому, что они "svn-remote", а не "remote"

Текущая «главная» ветка указывала на ствол второго проекта.Я решил от него избавиться, так как это может вызвать проблемы при переключении с одного проекта на другой.

Я создал две новые ветки, указывающие на стволы каждого проекта, затем удалил «главную» ветку:

git checkout -b master_project_A projA/trunk
git checkout -b master_project_B projB/trunk
git branch -D master

А теперь о «рабочем процессе»;работать над проектом А:

git checkout master_project_A #switch to project A
git svn rebase #check for any updates on SVN repo
git checkout -b work_on_A master_project_A #create a branch starting from the master of project A

work work work on work_on_A; commit, etc

git checkout master_project_A #go back to master of project A
git svn rebase #check again for any update on SVN repo
git checkout work_on_A #go back to the work branch
git rebase master_project_A #update branch with any changes from the master of project A
git checkout master_project_A #go back to the master of project A
git merge work_on_A #merge to the master of project A the changes from the work branch
git svn dcommit #commit changes to the SVN repo, in trunk, because master_project_A was pointing to its trunk

Если я хочу извлечь существующую ветку из SVN, я могу сделать это с помощью:

git checkout -b work_on_branch projA/branch_name

work work work

git svn rebase #update any changes from projA/branch_name
git svn dcommit #commit updates back to the branch in the SVN repo

Для проекта Б я могу сделать то же самое.В конце концов, я могу хранить содержимое проекта A или B в одном и том же каталоге «src» и иметь доступ к обоим проектам в репозитории SVN из одного и того же репозитория git!:D

Я до сих пор не понял, как создать локальную ветку, а затем отправить ее в репозиторий SVN — я был близок к этому, но это не сработало.

Кроме того, может быть полезно знать команду «reset» («git reset --hard projPrefix/branch»), но я сломал несколько вещей, используя ее, поэтому, возможно, лучше оставить это на другой раз.

Я надеюсь, что это помогает кому-то!

Ура, Алекс

Другие советы

Давайте сначала рассмотрим более простой случай одного удаленного репозитория и одного локального репозитория.

А remote в локальном репо работает «только» как ссылка на другое репо.Вы можете использовать fetch чтобы получить удаленные объекты в локальное хранилище:

git remote add upstream git://...
git fetch upstream

Теперь все филиалы из upstream на них можно ссылаться локально и работать с ними, используя upstream/branchname.Чтобы действительно работать с удаленной веткой, вам всегда следует создавать локальную ветку, которая отслеживает удаленную ветку:

git checkout -b new_local_branchname upstream/branchname

Теперь вы можете работать локально и коммитить/объединять столько, сколько захотите.В качестве последнего шага вы можете push вы переходите обратно в центральный репозиторий.Важным моментом является то, что AFAIK push может выполнять только ускоренное слияние, то есть загружать изменения и устанавливать новую головку.Поэтому вам необходимо подготовить локальную ветку так, чтобы локальные изменения начинались на кончике удаленной ветки.Вы можете использовать rebase чтобы добиться этого или избежать изменения центрального репозитория, пока вы работаете локально.

Здесь описывается простой рабочий процесс между двумя репозиториями.Теперь конкретный случай с SVN.

git svn усложняет картину, еще больше ограничивая виды изменений, которые вы можете сделать.Как и в случае с удаленными устройствами, вам никогда не следует напрямую изменять ветки svn, а всегда работать с локальной веткой.В отличие от пультов, git svn всегда изменяет коммиты по мере их поступления в репозиторий SVN, чтобы добавить необходимые метаданные.Этот последний факт, вероятно, является причиной многих ваших проблем, поскольку хэши коммитов в ветке SVN всегда будут отличаться от исходных коммитов в ваших локальных ветках.

Наконец, ваш вопрос о нескольких проектах в одном репозитории.

Git не поддерживает параллельные извлечения нескольких веток в одном репозитории.Возможно, вы захотите изучить субмодули для интеграции нескольких репозиториев.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top