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

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

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

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

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

На данный момент я сделал 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 и после некоторого возни с "fetch" мне удалось получить вещи. Но потом у меня возникли проблемы с возвратом в a_repo_git, а затем в SVN. Это было в основном методом проб и ошибок.

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

Ответы [ 2 ]

3 голосов
/ 10 марта 2009

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

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

Инициировать два репозитория 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 / branch_name_of_A). То же самое относится и к B.

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

В этом случае путь file: /// - это путь к репозиторию 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"

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

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

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

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

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

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

Надеюсь, это кому-нибудь поможет!

Ура, Alex

2 голосов
/ 04 марта 2009

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

A 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 не поддерживает параллельные проверки нескольких веток в одном репо. Возможно, вы захотите заглянуть в подмодули для интеграции нескольких репозиториев.

...