Как сообщить git -svn о удаленной ветке, созданной после того, как я взял репо?

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

Ответ 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 нового коммита (на rebased newbranch), который соответствует старой фиксации, которую он сейчас указывает. (Или, может быть, используйте 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

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