Я использую git-svn
для работы с центральным репозиторием svn
моей компании. Недавно мы создали новую функциональную ветвь в центральном репо. Как мне сказать git
об этом? Когда я запускаю git branch -r
, я могу видеть ветки, которые существовали, когда я запускал fetch
против репозитория svn
, чтобы инициализировать репозиторий git
Как сообщить git -svn о удаленной ветке, созданной после того, как я взял репо?
Ответ 1
Вы можете вручную добавить удаленную ветку,
git config --add svn-remote.newbranch.url https://svn/path_to_newbranch/
git config --add svn-remote.newbranch.fetch :refs/remotes/newbranch
git svn fetch newbranch [-r<rev>]
git checkout -b local-newbranch -t newbranch
git svn rebase newbranch
Ответ 2
Если вы хотите отследить ВСЕ удаленные ветки svn, то решение будет таким же простым, как:
git svn fetch
Это приведет к удалению всех удаленных ветвей, которые еще не были извлечены.
Дополнительный совет: если вы сначала проверили только ствол, а затем вы хотите отследить все ветки, а затем отредактируйте .git/config
, чтобы выглядеть так, и заново запустите git svn fetch
:
[svn-remote "svn"]
url = https://svn/path_to_repo_root/
fetch = path_to_trunk:refs/remotes/git-svn
branches = path_to_branches/*:refs/remotes/*
Ключевые моменты url
должны указывать на корень репозитория, а пути, определенные в fetch
и branches
, должны относиться к url
.
Если вы хотите извлечь только определенные ветки вместо ALL, в git svn --help
есть хороший пример:
[svn-remote "huge-project"]
url = http://server.org/svn
fetch = trunk/src:refs/remotes/trunk
branches = branches/{red,green}/src:refs/remotes/branches/*
tags = tags/{1.0,2.0}/src:refs/remotes/tags/*
В более старых версиях git-svn
, как только вы указали такие ветки, вы не сможете получить новые ветки с помощью git svn fetch
. В одном обходном пути добавляется больше строк fetch
, например:
[svn-remote "huge-project"]
url = http://server.org/svn
fetch = trunk/src:refs/remotes/trunk
fetch = branches/blue:refs/remotes/branches/blue
fetch = branches/yellow:refs/remotes/branches/yellow
branches = branches/{red,green}/src:refs/remotes/branches/*
Еще одно обходное решение @AndyEstes: отредактируйте .git/svn/.metadata
и измените значение branches-maxRev
или tags-maxRev
на ревизию до того, как будут созданы какие-либо новые ветки или теги. Как только вы это сделаете, запустите git svn fetch
, чтобы отслеживать новую ветвь svn remote.
Ответ 3
Кажется, мне просто нужно git svn fetch
; почему-то я убедил себя, что вы получите всего репо вместо изменений.
Ответ 4
Может, я как-то испортил это, но я выполнил инструкции в ответе vjangus, и это почти сработало. Единственная проблема заключалась в том, что newbranch, похоже, не был отделен от ствола. В gitk это было своего рода "плавание" само по себе; у него не было общего предка с сундуком.
Решением было следующее:
- Найдите SHA1 последнего коммита, который произошел на соединительной линии до того, как была создана ветка.
- Найти SHA1 первой фиксации на новой ветке (возможно, сообщение "Создана новая ветка, скопирована из trunk @12345" или что-то еще)
-
git diff-tree <sha1 from step 1> <sha1 from step 2>
- не должно быть выхода. Если есть выход, возможно, вы выбрали неверные коммиты. -
git checkout local-newbranch
, затемgit rebase <sha1 from step 1>
. Это приведет к заменеlocal-newbranch
на новое дерево, ноremotes/newbranch
все равно будет отключено. - Перейдите в файл
.git/refs/remotes/newbranch
и отредактируйте его, чтобы он содержал полный SHA1 нового коммита (на rebasednewbranch
), который соответствует старой фиксации, которую он сейчас указывает. (Или, может быть, используйтеgit-update-ref refs/remotes/newbranch <new-SHA>
. Спасибо, inger.) - В следующий раз, когда вы
git svn dcommit
доnewbranch
, вы получите кучу сообщений об этом, обновив некоторые журналы. Это нормально, я думаю.
Я рекомендую держать gitk --all
открытым все время и регулярно обновлять его, чтобы отслеживать, что вы делаете. Я по-прежнему новичок в git и git svn, поэтому, пожалуйста, предложите улучшения этого метода.
Ответ 5
Я не нашел никакой документации об этой функции, но выглядит как git Конфигурация svn поддерживает несколько записей извлечения. Таким образом, вы также можете добавлять ветки отдельно, не добавляя в свою конфигурацию другую запись удаленного хранилища SVN или не используя подстановочные знаки для получения всех ветвей определенного каталога.
Предположим, что ваше дерево SVN действительно противно имеет множество ветвей без какой-либо логики, как они расположены, например. имеющих ветки и подкаталоги, содержащие более разветвленные.
то есть.
trunk
branches
-> branch1
-> sub-dir1
-> branch2
-> branch3
-> sub-dir2
-> branch4
-> sub-dir3
-> branchX
<... hundreds more ...>
и вы просто хотите перенести некоторые ветки, которые будут включены в ваш репозиторий git.
Вы можете сначала создать свой репозиторий только с помощью соединительной линии без каких-либо дополнительных ветвей:
git svn clone -r 10000:HEAD https://svn.com/MyRepo myrepo --prefix=svn/ --trunk=trunk
После этого вы увидите следующую конфигурацию:
localhost: elhigu$ git config --get-regexp "svn-remote."
svn-remote.svn.url https://svn.com/MyRepo
svn-remote.svn.fetch trunk:refs/remotes/svn/trunk
когда вы хотите получить новую ветку из MyRepo, вы можете просто добавить новые записи извлечения в конфигурацию:
git config --add svn-remote.svn.fetch branches/sub-dir2/branch4:refs/remotes/svn/branches/sub-dir2/branch4
Или вы можете отредактировать одну и ту же конфигурацию в .git/config
Чтобы получить новые ветки после добавления их в конфигурацию, просто запустите:
git svn fetch -r 10000:HEAD
[Edit] Иногда кажется, что нужно запустить fetch с параметром --all для извлечения вновь добавленных ветвей:
git svn fetch --all -r 10000:HEAD
Ответ 6
Вместо того, чтобы иметь дело с git -svn quirks, вы можете попробовать SubGit.
Нужно установить SubGit в репозиторий Subversion. После этого можно использовать стандартный рабочий процесс git вместо использования специальных команд git -svn:
-
Нажатие новых коммитов:
git -svn:
$ git commit $ git svn rebase $ git svn dcommit
SubGit:
$ git commit $ git push
-
Получение входящих изменений
git -svn:
$ git svn rebase
SubGit:
$ git pull [--rebase]
-
Создание новой ветки:
git -svn:
$ git svn branch foo $ git checkout -b foo -t remotes/foo $ git commit $ git svn dcommit
SubGit:
$ git checkout -b foo $ git commit $ git push
Подробнее см. Документацию SubGit.
Ответ 7
Упрощение ответа vjangus:
Если вы используете стандартную компоновку в SVN и выполнили обычную инициализацию svn, git -svn выполнит настройку для вас. Просто:
- Найти ревизию ветвящейся копии в SVN
- Получить эту версию с помощью git -svn
- Создание нового удаленного отслеживания ветвей ветки
Пример. SVN url svn+ssh://[email protected]/repo
. SVN-ветвь, которую я ищу, это newbranch
. Локальный ветвь git (удаленный трекинг newbranch
) будет git-newbranch
.
Шаг 1: найдите ревизию ветвей-копий
# svn log --stop-on-copy svn+ssh://[email protected]/repo/branches/newbranch | tail -4 r7802 | someone | 2014-03-21 18:54:58 +0000 (Fri, 21 Mar 2014) | 1 line branching HEAD to newbranch ------------------------------------------------------------------------
Таким образом, точкой ветвления в SVN является версия 7802.
Шаг 2: выберите версию
# git svn fetch -r 7802 Found possible branch point: svn+ssh://[email protected]/repo/trunk => svn+ssh://[email protected]/repo/branches/newbranch, 7801 Found branch parent: (refs/remotes/trunk) 8dcf3c5793ff1a8a79dc94d268c91c2bf388894a Following parent with do_switch Successfully followed parent r7802 = 9bbd4194041675ca5c9c6f3917e05ca5654a8a1e (refs/remotes/newbranch)
git -svn выполнил всю работу и теперь знает о пульте дистанционного управления:
# git show-ref | grep newbranch 2df23af4733f36f5ad3c14cc1fa582ceeb3edb5c refs/remotes/newbranch
Шаг 3. Создайте новую локальную ветвь, отслеживающую удаленный:
# git checkout -b git-newbranch -t newbranch Checking out files: 100% (413/413), done. Branch git-newbranch set up to track local ref refs/remotes/newbranch. Switched to a new branch 'git-newbranch'
Ответ 8
Чтобы добавить к ответу vjangus, который мне помог, я также счел полезным добавить граф git для привязки ветвей к магистрали в соответствующей точке - позволяя git видеть историю и выполнять слиты правильно.
Это просто случай добавления строки к .git/info/grafts
с помощью хэшей:
<initial branch commit> <parent commit in trunk>
например.
378b0ae0902f5c2d2ba230c429a47698810532e5 6c7144991381ce347d4e563e9912465700be0638
Кредит http://evan-tech.livejournal.com/255341.html
(Я бы добавил это как комментарий, но у меня недостаточно репутации.)
Ответ 9
Если вы не проверите с допустимым макетом, вы не сможете проверить удаленную ветку.
Это то, что я делаю:
git svn init -s <svn path with no trunk> local_repo
cd local_repo
git svn fetch
## wait
После этого вы можете переключиться на удаленную ветвь:
git checkout --track -b branch_name branch_name
Затем вы автоматически переключитесь на свою ветку.