2010-02-11 4 views
56

У меня есть центральный репозиторий SVN, который я должен совершить, но у меня есть страсть к git (как и любой другой разработчик, которого я знаю). Случай хорошо известен.Как импортировать ветви svn и теги в git-svn?

Затем я прочитал о git-svn и дал ему попробовать. Так как я не нужна полная история, только от двух месяцев или около того, я сделал так:

git svn clone -r 34000 -s https://svn.ourdomain.com/svn/repos/Project/SubProject

подпроекта был, как обычно, подкаталоги trunk, tags и branches. Отлично.

Тогда для того, чтобы получить последнюю версию, я

git svn rebase

Некоторые загрузки позже, большой. Последняя ревизия, журналы и т. Д. Хорошо, теперь я переключусь на свою ветвь.

$ git branch
* master

$ git branch -r
trunk

$ git branch -a
* master
remotes/trunk

На вопросы: Где мои ветви? Я сделал что-то не так? Как мне сделать, чтобы получить мои филиалы в новом git-репо?

git-svn, где бы я ни читал об этом, разумно раздал ветви и метки, но поведение не то, что я ожидал. Благодаря!

EDIT: Я только что узнал, что git svn fetch сделает это. Но он получит все изменения, что мне не понравится.

+2

Ну, это не ответит на ваш вопрос, следовательно, комментарий: при использовании git-s vn вы нарушите функции отслеживания слияния subversion, так как git-svn не поддерживает их. IMHO эта проблема сама по себе дисквалифицирует git-svn для серьезного использования с хранилищем подрывной деятельности. Я не нашел никакой информации о том, будет ли эта функция когда-либо разрабатываться - возможно, нет, поскольку людям нравится переключаться на DVCS вместо использования таких хаков. – gimpf

+0

Я где-то читал, что преобразование git слияния в коммитах с использованием --squash не нарушит отслеживание слияния подрывных операций. –

+4

Для стандартного макета «багажника/веток/тегов», который вы, кажется, используете, вы можете попробовать ['--stdlayout'] (http://www.kernel.org/pub/software/scm/git/docs /git-svn.html), как в 'git svn clone --stdlayout svn: // ...' - см. http://stackoverflow.com/questions/5361559/what-does-the-stdlayout-do-in -git-svn-clone –

ответ

5

Если вы хотите, чтобы ваши филиалы, делая GIT ветвь после импорта из SVN, вы должны использовать рубиновый скрипт svn2git (and git2svn)

Это лучше, чем мерзавец Svn клон, потому что если у вас есть этот код в SVN :

trunk 
    ... 
    branches 
    1.x 
    2.x 
    tags 
    1.0.0 
    1.0.1 
    1.0.2 
    1.1.0 
    2.0.0 

git-svn будет проходить через всю историю совершить, чтобы построить новый Git репо.
Он будет импортировать все ветви и теги в виде удаленных ветвей SVN, тогда как то, что вы действительно хотите, это git-native local branch и git tag objects. Таким образом, после импорта этого проекта, вы получите:

$ git branch 
    * master 
    $ git branch -a 
    * master 
    1.x 
    2.x 
    tags/1.0.0 
    tags/1.0.1 
    tags/1.0.2 
    tags/1.1.0 
    tags/2.0.0 
    trunk 
    $ git tag -l 
    [ empty ] 

После svn2git делается с вашим проектом, вы получите вместо этого:

$ git branch 
    * master 
    1.x 
    2.x 
    $ git tag -l 
    1.0.0 
    1.0.1 
    1.0.2 
    1.1.0 
    2.0.0 
+0

Но, делая это, я не убиваю каждую возможность совершать репозиторий svn? Кроме того, мой вопрос был не таким. У меня нет моих филиалов. Так что дело не в организации кода. –

+0

Я использовал svn2git, и он обрабатывал все мои ветви и метки как теги ... Так что, другими словами, когда я делаю git branch, это просто показывает мне * master. И когда я делаю git tag -l, он показывает мне все ветки и теги из SVN ... Не имеет смысла. Я что-то пропустил ? –

+0

@ShariqueAbdullah не уверен. Я использую SubGit в эти дни: http://stackoverflow.com/a/18693798/6309 – VonC

7

Вы говорите, что вы не получили ваши филиалы в вашем оформлении.

Возможно, это проблема с расположением вашего репозитория svn.

'стандартной компоновки' является:

branches/

tags/

trunk/

Если у Вас есть свой макет, как это:

branches/user1/

branches/user2/

Затем вы потеряете свои ветки, когда будете делать git svn fetch/clone.

Чтобы исправить это, вы должны дать этот аргумент

--branches=branches/*/* мерзавцу клон.

+0

Но что, если ветви расположены в корне, как здесь http://svn.code.sf.net/p/azconvert/code/ ? Папки 'phpport' и' otherfiles' кажутся ветвями. – thorn

63

Вам понадобится несколько шагов.

  1. питания собственно ствол, ветви и теги имен папок и получать СВН репо:

    git svn init -t tags -b branches -T trunk https://mysvn.com/svnrepo 
    git svn fetch 
    
  2. Поскольку теги в СВН реальные ветви, создавать GIT теги из ветвей тегов:

    git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/tags | cut -d/-f 3- | 
    while read ref 
    do 
        echo git tag -a $ref -m 'import tag from svn' 
    done 
    
  3. Удалить тег филиалы

    git for-each-ref --format="%(refname:short)" refs/remotes/tags | cut -d/-f 2- | 
    while read ref 
    do 
        echo git branch -rd $ref 
    done 
    
  4. Поскольку теги, отмеченные на предыдущем шаге, указывают на фиксацию «создать тег», нам нужно получить «реальные» теги, т. Е. Совершить фиксацию родителей «create tag».

    git for-each-ref --format="%(refname:short)" refs/tags | 
    while read ref 
    do 
        tag=`echo $ref | sed 's/_/./g'` # give tags a new name 
        echo $ref -\> $tag 
        git tag -a $tag `git rev-list -2 $ref | tail -1` -m "proper svn tag" 
    done 
    
  5. Все, что нам нужно сделать, это удалить старые теги.

+3

Команда «cut» не работала для меня для миграции тегов, возможно, из-за другого выхода команды «git». Эта измененная командная строка работала для меня: 'git for-each-ref -format ="% (refname: short)% (objectname) "refs/remotes/tags | при чтении тега ref; do echo git tag -a $ tag -m \ "Импортировать $ тег из svn \" $ ref; done' –

+6

То же самое здесь. Также обратите внимание, что вам нужно удалить «эхо» в командах, когда вы довольны тем, что он сделает, и хотите включить фактическую команду. Я закончил со следующей строкой, которая напрямую привязывает родителя и использует сообщение SVN: 'git for-each-ref -format ="% (refname: short)% (objectname) "refs/remotes/tags | cut -d/-f 2- | при чтении тега ref; do msg = $ (git log --pretty = format: '% s' -1 $ {ref}); git tag -f -a $ tag -m "$ msg" $ {ref} ^; done' – Florian

+0

Каков результат 'git for-each-ref -format ="% (refname: short) «refs/remotes/tags» в вашем случае? – Vanuan

19

Это опирается на ответ Vanuan в выше, но он сохраняет сообщение оригинального svn тега в новом git тега.

$ git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/tags \ 
| while read BRANCH REF 
    do 
     TAG_NAME=${BRANCH#*/} 
     BODY="$(git log -1 --format=format:%B $REF)" 

     echo "ref=$REF parent=$(git rev-parse $REF^) tagname=$TAG_NAME body=$BODY" >&2 

     git tag -a -m "$BODY" $TAG_NAME $REF^ &&\ 
     git branch -r -d $BRANCH 
    done 
8

Это то же самое, как ответ nicolai.rostov в выше, но я просто изменить путь REFS я заменил refs/remotes/tags на refs/remotes/origin/tags Я использую Git версии 2.1.1 в cygwin терминал.

$ git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/origin/tags \ 
| while read BRANCH REF 
    do 
     TAG_NAME=${BRANCH#*/} 
     BODY="$(git log -1 --format=format:%B $REF)" 

     echo "ref=$REF parent=$(git rev-parse $REF^) tagname=$TAG_NAME body=$BODY" >&2 

     git tag -a -m "$BODY" $TAG_NAME $REF^ &&\ 
     git branch -r -d $BRANCH 
    done 
0

У меня была такая же проблема - теги и ветви отсутствует, когда я указал ревизии:

$ git svn clone -r 34000 -s https://... 

Исправление было specifiy диапазон ревизий, -r 34000:HEAD:

$ git svn clone -r 34000:HEAD -s https://... 

git mailing list gave me the hint.

Смежные вопросы