Git svn gatekeeper репозиторий
Я использую git в течение некоторого времени, главным образом git -svn. Теперь я хочу убедить своих коллег переключиться с svn на git. Но, к сожалению, предварительным условием является то, что хранилище svn продолжает жить довольно долго. Поэтому я искал решение и придумал книгу:
Jon Loeliger "Управление версиями с помощью Git". Я купил его, и это действительно хорошо, но я не совсем понимаю руководство по настройке git svn gatekeeper repo.
В главе 16 он описывает ситуации, в которой есть Репозиторий Subversion и, по крайней мере, которые хотят использовать git. Он предлагает один Хранилище "gatekeeper" git, которое единственный интерфейс для подрывной деятельности. После git svn клонирование подрывной операции repo (с --prefix = svn/), все ветки затем подталкиваются к голой репозиторий (git push../svn-bare.git 'Ссылки/пультов ДУ/СВН/: ссылки/главы/СВН/', и другим пользователям git говорят клонировать это репо, которое теперь содержит локальные ветвей всех svn пультов.
Эта часть работает, и я думаю, что полностью ее понимаю. Но я не получаю следующую часть:
Если разработчик, который клонирует голый репозиторий, отбрасывает изменения обратно из своего репо в голый репозиторий, а затем я dcommit это в голое репо, чтобы svn, фиксации, которые пользователь нажал, потеряны по уважительной причине из-за замененных коммитов git -svn создает. Или я ошибаюсь? Как это работает?
В книге говорится:
Затем, чтобы слить обратно в подрывную деятельность, в репозиторий привратника, вы делаете
git checkout svn/trunk (или другое ветки - это проверка отсоединенная головка, поскольку svn/trunk - это дистанционный пульт) git merge --no-ff new-feature git svn dcommit
Как я могу проверить ветку в открытом репозитории? Я не думаю, что это работает
Это приводит к фиксации слияния на отсоединенную головку, а затем измененную commit (после строки git -svn-id добавлено) помещается в реальный svn/trunk филиал.
Что подразумевается под реальным svn/trunk?
Фиксирование на отдельном голова "хуже, чем избыточная". это для чего-то еще в конечном итоге приводит к конфликтам. Итак, просто забудьте об этом. Если вы не поставили это на ветке, в первую очередь, это намного легче забыть "(Джон Loeliger).
Я немного смущен. Есть ли у кого-то лучшее объяснение для создания репозитария git svn gatekeeper? Я искал в Интернете и на этом сайте, но я не нашел ничего подходящего для меня.
Я так устал тратить столько времени на ветвление и слияние svn, когда сотрудничаю с моими коллегами.
Ответы
Ответ 1
Как я могу проверить ветку в открытом репозитории? Я не думаю, что это работает
Да, это так: вы просто клонируете голый репо локально, создавая не-обнаженное репо в этом процессе, где вы можете проверить/создать (снова локально), как как вы хотите.
Голый репо необходим как восходящий репо, куда нужно нажать. (см. git push
только для голых репозиториев?")
Но для того, чтобы подталкивать к нему что-либо, то есть для других разработчиков, чтобы отменить свои изменения в ветвях не-SVN обратно в репозиторий-гейткипер, сказал, что другой разработчик сначала должен клонировать это голый репо, внести все соответствующие изменения в локальный экземпляр и вернуться к общему репо.
Кроме того, вы можете настроить какой-то крючок на этом голом репо, чтобы проверить ваш push: см. "Крючки для git -svn".
Затем, чтобы dcommit
, гейткипер также клонировал репозиторий гейткипера, из которого он/она будет:
- проверка удаленной ветки, связанной с svn ('
svn
', являющейся именем удаленного репо), например, < svn/trunk
'
- объединить соответствующие изменения в этой неназванной ветке
-
git-svn dcommit
Итак, чтобы повторить:
- клон разработчика, который репозиторий-гейткипер записывает свои изменения в свою ветвь (чтобы они могли отступить, поскольку репозиторий-гейткипер является голым)
- человек, отвечающий за возврат к фактическому репо SVN, также клонирует репозиторий-гейткипер, чтобы выбрать то, что нужно объединить, с ветвью Git, специально связанной с SVN (см., например, "Преодолеть Git svn caveats" ).
Ответ 2
Я попытался автоматизировать установку gatekeeper, описанную Джоном Лолигером, и заставил ее работать. Он очень подробно рассказывает о том, какие шаги следует выполнить, но часть "Слияние с Subversion" довольно короткая. Я пробовал разные настройки с помощью git -svn, также после отличных презентаций/примеров, предоставленных Томасом Феррисом Николаисом, и использовал его примеры проектов ( с модификациями) для тестирования "установки гейткипера":
@echo 1. Clone Subversion repo
cd %WDIR%\devs\adm
call git svn clone -s --prefix=svn/ http://localhost/svn-repos/company-repo/websites -- username adm
cd %WDIR%\devs\adm\websites
call git reset --hard svn/trunk
@echo ----------------------------------
@echo 2. Create bare repo
cd %WDIR%\devs\adm
mkdir websites.git
cd websites.git
call git init --bare
@echo ----------------------------------
@echo 3. Populate bare with content from gatekeeper
cd %WDIR%\devs\adm\websites
call git push --all ../websites.git
call git push ../websites.git "refs/remotes/svn/*:refs/heads/svn/*"
@echo ----------------------------------
@echo 4. Setup bare as a remote in gatekeeper and fetch branches
call git remote add bare_repo ../websites.git
call git fetch bare_repo
Шаг 4 не описывается Джоном Лолигером, но я думаю, что он это говорит.
Когда это время для слияния обратно с подрывной деятельностью:
C:\tmp\devs\adm\websites>git fetch bare_repo
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From ../websites
e53fba9..2ac281c svn/trunk -> bare_repo/svn/trunk
Теперь мы можем выполнить шаги из книги:
C:\tmp\devs\adm\websites>git checkout svn/trunk
Note: checking out 'svn/trunk'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b new_branch_name
HEAD is now at e53fba9... [maven-release-plugin] prepare release kaksi
C:\tmp\devs\adm\websites>git merge --no-ff remotes/bare_repo/svn/trunk
Merge made by the 'recursive' strategy.
0 files changed
create mode 100644 web/howto.txt
create mode 100644 web/readme.txt
C:\tmp\devs\adm\websites>git svn dcommit
Committing to http://localhost/svn-repos/company-repo/websites/trunk ...
A web/howto.txt
A web/readme.txt
Committed r8
A web/readme.txt
A web/howto.txt
r8 = 28da267255ae56022bd4ed3c0f4886da1ac04944 (refs/remotes/svn/trunk)
No changes between current HEAD and refs/remotes/svn/trunk
Resetting to the latest refs/remotes/svn/trunk
Моя проблема с этой настройкой (и мы ранее были предупреждены в этой книге) состоит в том, что история раздавлена:
C:\tmp\devs\adm\svn\websites>svn log
------------------------------------------------------------------------
r8 | adm | 2012-05-12 23:21:11 +0200 (lø, 12 mai 2012) | 1 line
Merge remote-tracking branch 'remotes/bare_repo/svn/trunk' into HEAD
------------------------------------------------------------------------
Теперь рассмотрим эту альтернативу для слияния обратно в подрывную деятельность:
C:\tmp\devs\adm\websites>git checkout -t svn/trunk
Branch trunk set up to track local ref refs/remotes/svn/trunk.
Switched to a new branch 'trunk'
C:\tmp\devs\adm\websites>git fetch bare_repo
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From ../websites
c188a72..b1b4237 svn/trunk -> bare_repo/svn/trunk
C:\tmp\devs\adm\websites>git rebase remotes/bare_repo/svn/trunk
First, rewinding head to replay your work on top of it...
Fast-forwarded trunk to remotes/bare_repo/svn/trunk.
C:\tmp\devs\adm\websites>git svn reset 2147483647
r7 = c188a72da6df2966e563e9e575b626d5b449400f (refs/remotes/svn/trunk)
C:\tmp\devs\adm\websites>git svn rebase
Current branch trunk is up to date.
C:\tmp\devs\adm\websites>git svn dcommit
Committing to http://localhost/svn-repos/company-repo/websites/trunk ...
A web/howto.txt
A web/readme.txt
Committed r8
A web/readme.txt
A web/howto.txt
r8 = 18b7c7b4693cc8e55098bd716c9259ed5570acf0 (refs/remotes/svn/trunk)
No changes between current HEAD and refs/remotes/svn/trunk
Resetting to the latest refs/remotes/svn/trunk
Теперь история фиксации неповреждена:
C:\tmp\devs\adm\svn\websites>svn log
------------------------------------------------------------------------
r8 | adm | 2012-05-12 23:51:48 +0200 (lø, 12 mai 2012) | 1 line
'ola added [readme.txt, howto.txt] on svn/trunk'
Для того, чтобы эта настройка работала, нам нужно использовать команду git svn reset ", иначе dcommit будет терпеть неудачу во второй раз, потому что git -svn запутался в текущей версии и (до того же пересмотра, что и при создании bare-repo). Вероятно, это связано с тем, что мы использовали rebase, что, в свою очередь, необходимо для получения хорошей линейной истории в подрывной деятельности.
Большой вопрос: что делает "git svn reset"?
Является ли "пересылка вперед" законным использованием "git svn reset" в этом случае?
Ответ 3
Я не думаю, что вы должны когда-либо подталкивать изменения к голой репо. У меня есть пример настройки здесь, чтобы вы могли попробовать:
http://blog.tfnico.com/2010/10/gitsvn-5-centralized-git-svn-mirror.html
В моей настройке (которую я использую в течение 3-4 месяцев без каких-либо проблем), изменения должны всегда "течь" через репозиторий SVN. Я действительно не понимаю эту методику привратника.