programing tip

svn 브랜치와 태그를 git-svn으로 가져 오는 방법은 무엇입니까?

itbloger 2020. 11. 11. 08:11
반응형

svn 브랜치와 태그를 git-svn으로 가져 오는 방법은 무엇입니까?


커밋해야 할 중앙 SVN 저장소가 있지만 git에 대한 열정이 있습니다 (내가 아는 다른 개발자처럼). 그 사건은 잘 알려져 있습니다.

그런 다음 git-svn에 대해 읽고 사용해 보았습니다. 2 개월 정도의 전체 이력이 필요하지 않기 때문에 다음과 같이했습니다.

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 repo에서 브랜치를 가져 오려면 어떻게해야합니까?

git-svn, 내가 그것에 대해 읽은 곳마다 브랜치와 태그를 현명하게 다루었지만 행동은 내가 예상했던 것과 다릅니다. 감사!

편집 : 나는 git svn fetch그것을 것임을 알았 습니다. 그러나 그것은 내가 좋아하지 않는 모든 수정을 얻을 것입니다.


몇 가지 단계가 필요합니다.

  1. 적절한 트렁크, 분기 및 태그 폴더 이름을 제공하고 svn 저장소를 가져옵니다.

    git svn init -t tags -b branches -T trunk https://mysvn.com/svnrepo
    git svn fetch
    
  2. svn의 태그는 실제 브랜치이므로 태그 브랜치에서 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. 이전 단계에서 표시된 태그가 커밋 "태그 생성"을 가리 키기 때문에 "실제"태그, 즉 "태그 생성"커밋의 부모를 파생해야합니다.

    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. 지금해야 할 일은 이전 태그를 제거하는 것입니다.


이것은 위의 Vanuan의 대답을 기반으로하지만 태그 에서 원래 태그 메시지유지합니다 .svngit

$ 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

이것은 위의 nicolai.rostov의 대답과 동일하지만 터미널에 git 버전 사용하여 교체 refs/remotes/tagsrefs 경로를 변경합니다 .refs/remotes/origin/tags2.1.1cygwin

$ 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

계산대에서 지점을 얻지 못했다고 말합니다.

이것은 svn repo의 레이아웃에 문제가있을 수 있습니다.

'표준 레이아웃'은 다음과 같습니다.

branches/

tags/

trunk/

다음과 같은 레이아웃이있는 경우 :

branches/user1/

branches/user2/

그런 다음 git svn fetch / clone을 수행하면 브랜치를 잃게됩니다.

이 문제를 해결하려면 다음과 같이 주장해야합니다.

--branches=branches/*/* git clone에.


svn에서 가져온 후 git 브랜치를 수행 할 때 브랜치를 보려면 ruby ​​스크립트 svn2git (및 git2svn)을 사용해야합니다.

svn에이 코드가 있으면 git svn clone보다 낫습니다.

  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 repo를 빌드합니다.
모든 분기와 태그를 원격 SVN 분기로 가져 오지만 실제로 원하는 것은 git 네이티브 로컬 분기와 git 태그 객체입니다. 따라서이 프로젝트를 가져 오면 다음을 얻을 수 있습니다.

  $ 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

원하는대로 마이그레이션하는 데 도움이되는 스크립트를 작성했습니다. 스크립트가 완벽하지는 않지만 도움이 되었기를 바랍니다.

자세한 내용은 https://github.com/MPDFT/svn-to-git를 방문하십시오.

#!/bin/bash

####### Project name 
PROJECT_NAME="myproject"
EMAIL="mycompany.com"

###########################
####### SVN 
# SVN repository to be migrated
BASE_SVN="http://svn.mycompany.com/svn/repo/sistemas/myproject"

# Organization inside BASE_SVN
BRANCHES="branches"
TAGS="tags"
TRUNK="trunk"

###########################
####### GIT 
# Git repository to migrate
GIT_URL="https://git.mycompany.com/git/repo/sistemas/myproject.git"

###########################
#### Don't need to change from here
###########################

# Geral Configuration
ABSOLUTE_PATH=$(pwd)
TMP=$ABSOLUTE_PATH/"migration-"$PROJECT_NAME

# Branchs Configuration
SVN_BRANCHES=$BASE_SVN/$BRANCHES
SVN_TAGS=$BASE_SVN/$TAGS
SVN_TRUNK=$BASE_SVN/$TRUNK

AUTHORS=$PROJECT_NAME"-authors.txt"

echo '[LOG] Starting migration of '$SVN_TRUNK
echo '[LOG] Using: '$(git --version)
echo '[LOG] Using: '$(svn --version | grep svn,)

mkdir $TMP
cd $TMP

echo
echo '[LOG] Getting authors'
svn log -q $BASE_SVN | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2"@"$EMAIL">"}' | sort -u >> $AUTHORS

echo
echo '[RUN] git svn clone --authors-file='$AUTHORS' --trunk='$TRUNK' --branches='$BRANCHES' --tags='$TAGS $BASE_SVN $TMP
git svn clone --authors-file=$AUTHORS --trunk=$TRUNK --branches=$BRANCHES --tags=$TAGS $BASE_SVN $TMP

echo
echo '[LOG] Getting first revision'
FIRST_REVISION=$( svn log -r 1:HEAD --limit 1 $BASE_SVN | awk -F '|' '/^r/ {sub("^ ", "", $1); sub(" $", "", $1); print $1}' )

echo
echo '[RUN] git svn fetch -'$FIRST_REVISION':HEAD'
git svn fetch -$FIRST_REVISION:HEAD

echo
echo '[RUN] git remote add origin '$GIT_URL
git remote add origin $GIT_URL

echo
echo '[RUN] svn ls '$SVN_BRANCHES
for BRANCH in $(svn ls $SVN_BRANCHES); do
    echo git branch ${BRANCH%/} remotes/svn/${BRANCH%/}
    git branch ${BRANCH%/} remotes/svn/${BRANCH%/}
done

git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/origin/tags | grep -v "@" | cut -d / -f 3- |
while read ref
do
  echo git tag -a $ref -m 'import tag from svn'
  git tag -a $ref -m 'import tag from svn'
done

git for-each-ref --format="%(refname:short)" refs/remotes/origin/tags | cut -d / -f 1- |
while read ref
do
  git branch -rd $ref
done

echo
echo '[RUN] git push'
git push origin --all --force
git push origin --tags

echo 'Sucessufull.'

직장에서 Windws에서 작업해야하는 사람들을 위해 여기에 git 버전 2.17.0의 최신 솔루션이 있습니다 (이론적으로 이전 버전에서도 작동 함).

git svn init -t tags -b branches -T trunk https://mysvn.com/svnrepo

git svn fetch

for /f "tokens=1-2 delims= " %a in ('git for-each-ref --format="%(refname:lstrip=-1) %(objectname)" refs/remotes/origin/tags') do git tag -a %a %b -m "import tag from svn"

나는 같은 문제가 있었다-내가 개정판을 지정할 때 태그와 분기가 누락되었다.

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

수정 사항은 수정 범위를 지정하는 것이 었습니다 -r 34000:HEAD.

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

The git mailing list gave me the hint.

참고URL : https://stackoverflow.com/questions/2244252/how-to-import-svn-branches-and-tags-into-git-svn

반응형