Как я могу использовать два проекта SVN и соответствующие ветки git-svn с одним рабочим каталогом?
Я относительно новичок в 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 ответа
Я не обновлял вопрос, потому что за последние несколько дней мне удалось по-настоящему хорошо и легко работать с помощью моего нового репо:)
Вот что я сделал в конце:
Инициируйте два репозитория SVN в одном каталоге. (Я не могу вспомнить в это время, но возможно, что "git init" был сделан в том же каталоге, до того, как:
mkdir src && cd src (не уверен насчет этого: git init) git svn init --stdlayout --prefix=projA/ -RprojA file:/// путь / к /svn/repo/A git svn init --stdlayout --prefix=projB/ -RprojB file:/// путь / к /svn/repo/B
"--Stdlayout" означает, что репозитории SVN находятся в стандартном формате, с транком, ветвями и тегами на одном уровне.
"--Prefix" используется для названия веток. Когда мы выполняем "git branch -a", все ветки SVN из проекта A имеют префикс "projA" (например: projA/branch_name_of_A). То же самое для Б.
Опция -R устанавливает имя репозитория SVN внутри репозитория git (это имя, которое мы используем с git при обращении к репозиторию / проекту SVN)
В этом случае путь file: /// - это путь к репозиторию SVN и к проекту внутри репо. Я использую "file://", потому что я использовал репозиторий с плоскими файлами без сервера. Я уверен, что он работает нормально с http:// для сервера SVN.
После этого шага из любопытства я взглянул на файл src/.git/config. Две вышеупомянутые команды создали несколько разделов "svn-remote", по одному для каждого проекта (опция -R), и общий, называемый "svn". Я изменил записи, так что будут только ссылки на проекты. У каждой ссылки были записи для пути репо (выборки) и для тегов / филиалов / ствола. Если вы посмотрите на файл, вы поймете, что нужно изменить.
После этого я извлек содержимое каждого проекта, используя
git svn fetch projA # загружено содержимое проекта Репо git svn fetch projB # загружено содержимое проекта B repo
Теперь runnig "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 мастер
А теперь о "рабочем процессе"; работать над проектом А:
git checkout master_project_A # переключиться на проект A git svn rebase #check для любых обновлений репозитория SVN git checkout -b work_on_A master_project_A # создать ветку, начиная с мастера проекта A работа работа работа на work_on_A; совершать и т. д. git checkout master_project_A # вернуться назад к мастеру проекта A git svn rebase #check снова для любого обновления репозитория SVN git checkout work_on_A # вернуться в рабочую ветку git rebase master_project_A #update ветка с любыми изменениями из мастера проекта A git checkout master_project_A # вернуться к мастеру проекта A git merge work_on_A #merge к мастеру проекта A изменения из рабочей ветки git svn dcommit #commit изменения в репозитории SVN в транке, потому что master_project_A указывал на его транк
Если я хочу извлечь существующую ветку из SVN, я могу сделать это с:
git checkout -b work_on_branch projA / branch_name работа Работа работа git svn rebase #update любые изменения от projA/branch_name git svn dcommit #commit обновляет обратно в ветку в репозитории SVN
Для проекта B I можно делать точно такие же вещи. В конце концов, я могу иметь содержимое проекта 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 не поддерживает параллельные проверки нескольких веток в одном репо. Возможно, вы захотите заглянуть в подмодули для интеграции нескольких репо.