Как мне сообщить git-svn об удаленной ветке, созданной после того, как я получил репо? - PullRequest
187 голосов
/ 18 ноября 2008

Я использую git-svn для работы с центральным репозиторием svn моей компании. Недавно мы создали новую ветку функций в центральном репо. Как мне рассказать git об этом? Когда я запускаю git branch -r, я вижу только те ветви, которые существовали, когда я запускал fetch против репо svn, чтобы инициализировать мое git репо?

Ответы [ 9 ]

284 голосов
/ 16 сентября 2009

Вы можете вручную добавить удаленную ветку,

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
90 голосов
/ 16 апреля 2012

Если вы хотите отслеживать ВСЕ удаленные ветви 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.

Если вы хотите получать только определенные ветви вместо ВСЕХ, есть хороший пример в 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.

53 голосов
/ 18 ноября 2008

Кажется, мне просто нужно было git svn fetch; каким-то образом я убедил себя, что получит весь репо вместо просто изменений.

14 голосов
/ 11 декабря 2010

Может быть, я как-то все испортил, но следовал инструкциям в ответе Вьянгуса, и это почти сработало. Единственная проблема состояла в том, что newbranch, казалось, не был отделен от ствола. В gitk это было своего рода «плавающее» все само по себе; у него не было общего предка со стволом.

Решение этого было:

  1. Найдите SHA1 последнего коммита, который произошел в транке перед созданием ветви.
  2. Найти SHA1 первого коммита в новой ветви (возможно, сообщение "Создана новая ветка, скопировано из транка @ 12345" или что-то в этом роде)
  3. git diff-tree <sha1 from step 1> <sha1 from step 2> - выход не должен быть. Если вывод есть, возможно, вы выбрали неправильные коммиты.
  4. git checkout local-newbranch, затем git rebase <sha1 from step 1>. Это переместит local-newbranch на новое дерево, но remotes/newbranch все равно будет отключено.
  5. Перейдите к файлу .git/refs/remotes/newbranch и отредактируйте его так, чтобы он содержал полный SHA1 нового коммита (на перебазированном newbranch), который соответствует старому коммиту, на который он в данный момент указывает. (Или, может быть, используйте git-update-ref refs/remotes/newbranch <new-SHA>. Спасибо, Пингер.)
  6. В следующий раз, когда вы наберете git svn dcommit до newbranch, вы получите кучу сообщений об этом, обновляющих некоторый журнал. Я думаю, это нормально.

Я рекомендую держать gitk --all открытым все время и часто обновлять его, чтобы отслеживать, что вы делаете. Я все еще новичок в git и git svn, поэтому, пожалуйста, предложите усовершенствования этого метода.

7 голосов
/ 02 апреля 2014

Упрощение ответа Вьянгуса:

Если вы используете стандартную компоновку в SVN и выполнили обычный svn init, git-svn сделает все за вас Просто:

  1. Найти редакцию ветки-копии в SVN
  2. Получить эту ревизию с помощью git-svn
  3. Создание нового локального удаленного отслеживания филиала

Пример. URL SVN svn+ssh://gil@svn.myplace.com/repo. Я ищу ветку SVN newbranch. Локальная ветка git (отслеживающая удаленный newbranch) будет git-newbranch.

Шаг 1: найти редакцию ветки-копии

    # <strong>svn log --stop-on-copy svn+ssh://gil@svn.myplace.com/repo/branches/newbranch | tail -4</strong>
    r7802 | someone | 2014-03-21 18:54:58 +0000 (Fri, 21 Mar 2014) | 1 line

    branching HEAD to newbranch
    ------------------------------------------------------------------------

Таким образом, точка ветвления в SVN - это версия 7802.

Шаг 2: получить ревизию

    # <strong>git svn fetch -r 7802</strong>
    Found possible branch point: svn+ssh://gil@svn.myplace.com/repo/trunk => svn+ssh://gil@svn.myplace.com/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. Создайте новый локальный филиал, отслеживающий удаленный:

    # <strong>git checkout -b git-newbranch -t newbranch</strong>
    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'
5 голосов
/ 11 февраля 2012

Я не нашел никакой документации об этой функции, но похоже, что конфигурация 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

[Редактировать] Иногда кажется необходимым запустить fetch с параметром --all для извлечения вновь добавленных веток:

git svn fetch --all -r 10000:HEAD
4 голосов
/ 25 июня 2012

Вместо того, чтобы иметь дело с причудами git-svn, вы можете попробовать SubGit .

Нужно установить SubGit в хранилище Subversion. После этого можно использовать стандартный рабочий процесс git вместо специальных команд git-svn:

  1. Нажатие новых коммитов:

    ГИТ-SVN:

    $ git commit
    $ git svn rebase
    $ git svn dcommit
    

    SubGit:

    $ git commit
    $ git push
    
  2. Получение входящих изменений

    ГИТ-SVN:

    $ git svn rebase
    

    SubGit:

    $ git pull [--rebase]
    
  3. Создание новой ветки:

    ГИТ-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 .

2 голосов
/ 17 февраля 2014

Чтобы добавить к ответу vjangus, который мне помог, я также счел полезным добавить использование git-графтов для привязки веток к стволу в соответствующей точке - что позволяет git видеть историю и правильно выполнять слияния.

Это просто случай добавления строки в .git/info/grafts с хешами:

<initial branch commit> <parent commit in trunk>

например.

378b0ae0902f5c2d2ba230c429a47698810532e5 6c7144991381ce347d4e563e9912465700be0638

Кредит http://evan -tech.livejournal.com / 255341.html

(Я бы добавил это как комментарий, но у меня недостаточно репутации.)

0 голосов
/ 15 ноября 2011

Если вы не подтвердите правильность макета, вы не сможете оформить удаленный филиал.

Вот что я делаю:

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

Тогда вы автоматически переключитесь на свою ветку.

...