etc./StackOverFlow

히스토리가 있는 SVN 리포지토리를 새 Git 리포지토리로 마이그레이션하려면 어떻게 해야 합니까?

청렴결백한 만능 재주꾼 2022. 1. 25. 11:40
반응형

질문자 :Community Wiki


나는 Git 매뉴얼, FAQ, Git - SVN 단기집중과정 등을 읽었고 그들은 모두 이것 저것 설명하지만 어디에서도 다음과 같은 간단한 지침을 찾을 수 없습니다.

SVN 저장소: svn://myserver/path/to/svn/repos

Git 저장소: git://myserver/path/to/git/repos

 git-do-the-magic-svn-import-with-history \ svn://myserver/path/to/svn/repos \ git://myserver/path/to/git/repos

나는 그것이 그렇게 간단하지 않을 것이라고 기대하지 않으며 단일 명령이 될 것이라고 기대하지 않습니다. 그러나 나는 그것이 어떤 것도 설명하려고 하지 않을 것으로 기대합니다. 단지 이 예에서 어떤 조치를 취해야 하는지를 말하는 것뿐입니다.



SVN 사용자를 Git에 매핑하기 위한 사용자 파일(예: users.txt

 user1 = First Last Name <email@address.com> user2 = First Last Name <email@address.com> ...

이 한 줄짜리를 사용하여 기존 SVN 저장소에서 템플릿을 빌드할 수 있습니다.

 svn log -q | awk -F '|' '/^r/ {gsub(/ /, "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt

파일이 아닌 누락된 SVN 사용자를 찾으면 SVN이 중지됩니다. 그러나 그 후에 파일을 업데이트하고 중단한 부분부터 다시 시작할 수 있습니다.

이제 저장소에서 SVN 데이터를 가져옵니다.

 git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp

dest_dir-tmp 에 새 Git 리포지토리를 만들고 SVN 리포지토리를 가져오기 시작합니다. "--stdlayout" 플래그는 공통 "trunk/, branch/, tags/" SVN 레이아웃이 있음을 의미합니다. 레이아웃 다릅니다은, 익숙해 경우 --tags , --branches , --trunk (일반적으로 옵션 git svn help ).

모든 일반 프로토콜이 허용됩니다: svn:// , http:// , https:// . URL은 http://svn.mycompany.com/myrepo/repository 와 같은 기본 저장소를 대상으로 해야 합니다. URL 문자열은 /trunk , /tag 또는 /branches 포함하지 않아야 합니다.

이 명령을 실행한 후 작업이 "중단/정지"된 것처럼 보이는 경우가 매우 많으며 새 저장소를 초기화한 후 오랜 시간 동안 중단될 수 있는 것은 지극히 정상입니다. 결국 마이그레이션 중임을 나타내는 로그 메시지가 표시됩니다.

--no-metadata 플래그를 생략하면 Git은 해당 SVN 개정에 대한 정보를 커밋 메시지에 추가합니다(예: git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID> )

사용자 이름을 찾을 수 없으면 users.txt 파일을 업데이트한 다음 다음을 수행합니다.

 cd dest_dir-tmp git svn fetch

모든 Subversion 커밋을 가져올 때까지 큰 프로젝트가 있는 경우 마지막 명령을 여러 번 반복해야 할 수도 있습니다.

 git svn fetch

완료되면 Git은 SVN trunk 를 새 분기로 체크아웃합니다. 다른 모든 분기는 원격으로 설정됩니다. 다음을 사용하여 다른 SVN 분기를 볼 수 있습니다.

 git branch -r

리포지토리에 다른 원격 분기를 유지하려면 각 분기에 대해 수동으로 로컬 분기를 만들고 싶습니다. (트렁크/마스터 건너뛰기) 이렇게 하지 않으면 최종 단계에서 분기가 복제되지 않습니다.

 git checkout -b local_branch remote_branch # It's OK if local_branch and remote_branch are the same names

태그는 분기로 가져옵니다. 로컬 브랜치를 생성하고, 태그를 만들고, 브랜치를 삭제해야 Git에서 태그로 사용할 수 있습니다. "v1" 태그로 수행하려면:

 git checkout -b tag_v1 remotes/tags/v1 git checkout master git tag v1 tag_v1 git branch -D tag_v1

GIT-SVN 저장소를 깨끗한 Git 저장소로 복제합니다.

 git clone dest_dir-tmp dest_dir rm -rf dest_dir-tmp cd dest_dir

이전에 원격 분기에서 생성한 로컬 분기는 새로 복제된 저장소에 원격 분기로만 복사됩니다. (트렁크/마스터를 건너뜁니다.) 유지하려는 각 분기에 대해 다음을 수행합니다.

 git checkout -b local_branch origin/remote_branch

마지막으로, 지금 삭제된 임시 저장소를 가리키는 깨끗한 Git 저장소에서 리모컨을 제거합니다.

 git remote rm origin

Community Wiki

마법:

 $ git svn clone http://svn/repo/here/trunk

Git과 SVN은 매우 다르게 작동합니다. Git을 배워야 하고 SVN 업스트림에서 변경 사항을 추적하려면 git-svn 을 배워야 합니다. git-svn 메인 페이지에는 좋은 예제 섹션이 있습니다 .

 $ git svn --help

jfm3

Subversion 저장소를 Git 저장소로 깔끔하게 마이그레이션하십시오 . 먼저 Subversion 커밋 작성자 이름을 Git 커미터에 매핑하는 파일을 만들어야 합니다(예: ~/authors.txt

 jmaddox = Jon Maddox <jon@gmail.com> bigpappa = Brian Biggs <bigpappa@gmail.com>

그런 다음 Subversion 데이터를 Git 리포지토리로 다운로드할 수 있습니다.

 mkdir repo && cd repo git svn init http://subversion/repo --no-metadata git config svn.authorsfile ~/authors.txt git svn fetch

Mac을 사용하는 경우 git-core +svn 을 설치하여 MacPorts에서 git-svn 을 얻을 수 있습니다.

Subversion 저장소가 원하는 git 저장소와 동일한 시스템에 있는 경우 init 단계에 이 구문을 사용할 수 있습니다. 그렇지 않으면 모두 동일합니다.

 git svn init file:///home/user/repoName --no-metadata

Community Wiki

나는 svn2git 스크립트를 사용했고 매력처럼 작동합니다.


Community Wiki

git-svn을 지속적으로 사용하기 전에 Git에 익숙해지는 것이 좋습니다. 즉, SVN을 중앙 집중식 저장소로 유지하고 로컬에서 Git을 사용하는 것입니다.

그러나 모든 기록이 있는 단순 마이그레이션의 경우 다음과 같은 몇 가지 간단한 단계가 있습니다.

로컬 리포지토리를 초기화합니다.

 mkdir project cd project git svn init http://svn.url

버전 가져오기를 시작하려는 시점을 표시하세요.

 git svn fetch -r42

(또는 모든 버전에 대해 "git svn fetch"만)

실제로 그 이후로 모든 것을 가져옵니다.

 git svn rebase

가져오기 결과는 Gitk로 확인할 수 있습니다. 이것이 Windows에서 작동하는지 확실하지 않지만 OSX 및 Linux에서 작동합니다.

 gitk

SVN 리포지토리가 로컬로 복제되면 더 쉬운 공동 작업을 위해 중앙 집중식 Git 리포지토리로 푸시할 수 있습니다.

먼저 빈 원격 리포지토리를 만듭니다( GitHub에 있을 수 있습니까?):

 git remote add origin git@github.com:user/project-name.git

그런 다음 선택적으로 메인 브랜치를 동기화하여 풀 작업이 원격 마스터와 로컬 마스터 모두에 새 항목이 포함되어 있을 때 자동으로 로컬 마스터와 병합하도록 합니다.

 git config branch.master.remote origin git config branch.master.merge refs/heads/master

그런 다음 원격 분기를 처리하는 데 도움이 되는 git_remote_branch 도구를 사용해 보는 데 관심이 있을 수 있습니다.

첫 번째 설명 게시물: " Git 원격 분기 "

최신 버전에 대한 후속 조치: " git_remote_branch와 협업할 시간 "


webmat

Subversion에서 Git으로의 원활한 마이그레이션(또는 둘 다 동시에 사용)을 위한 새로운 솔루션인 SubGit 가 있습니다.

이 프로젝트를 직접 진행하고 있습니다. 우리는 저장소에서 SubGit을 사용합니다. 팀원 중 일부는 Git과 일부 Subversion을 사용하며 지금까지는 매우 잘 작동합니다.

SubGit을 사용하여 Subversion에서 Git으로 마이그레이션하려면 다음을 실행해야 합니다.

 $ subgit install svn_repos ... TRANSLATION SUCCESSFUL

그 후에 svn_repos/.git에 Git 리포지토리를 가져와서 복제하거나 Subversion과 이 새로운 Git 리포지토리를 함께 계속 사용할 수 있습니다. SubGit은 둘 다 항상 동기화 상태로 유지되도록 합니다.

Subversion 저장소에 여러 프로젝트가 포함된 경우 svn_repos/git 디렉토리에 여러 Git 저장소가 생성됩니다. 실행하기 전에 번역을 사용자 정의하려면 다음을 수행하십시오.

 $ subgit configure svn_repos $ edit svn_repos/conf/subgit.conf (change mapping, add authors mapping, etc) $ subgit install svn_repos

SubGit 을 사용하면 순수 Git(git-svn이 아님)으로 마이그레이션하고 필요한 만큼 Subversion을 유지하면서 사용을 시작할 수 있습니다(예: 이미 구성된 빌드 도구의 경우).

도움이 되었기를 바랍니다!


Community Wiki

공식 git-svn 맨페이지를 참조하십시오. 특히 "기본 예"를 살펴보십시오.

전체 Subversion 관리 프로젝트 추적 및 기여(트렁크, 태그 및 분기 포함):

 # Clone a repo (like git clone): git svn clone http://svn.foo.org/project -T trunk -b branches -t tags

EfForEffort

Pro Git 8.2에서 설명합니다. http://git-scm.com/book/en/Git-and-Other-Systems-Migrating-to-Git


Community Wiki

SubGit (죽음의 블루 스크린 대)

 subgit import --svn-url url://svn.serv/Bla/Bla directory/path/Local.git.Repo

그게 다야

+ SVN에서 업데이트하기 위해 첫 번째 명령으로 Git 저장소를 생성합니다.

 subgit import directory/path/Local.git.Repo

거대한 저장소를 위해 즉시 Git으로 마이그레이션하는 방법을 사용했습니다.
물론 약간의 준비가 필요합니다.
그러나 개발 프로세스를 전혀 중단할 수는 없습니다.

여기 내 방법이 있습니다.

내 솔루션은 다음과 같습니다.

  • SVN을 Git 저장소로 마이그레이션
  • 팀이 로 전환하기 직전에 Git 리포지토리를 업데이트합니다 .

대규모 SVN 저장소의 경우 마이그레이션에 많은 시간이 걸립니다.
그러나 완료된 마이그레이션을 업데이트하는 데 몇 초밖에 걸리지 않습니다.

물론 저는 SubGit을 사용하고 있습니다. 엄마. git-svn은 죽음의 블루 스크린을 만듭니다. 그냥 끊임없이. 그리고 git-svn은 Git의 " filename too long " 치명적인 오류로 지루합니다.

단계

1. 서브깃 다운로드

2. 마이그레이션 및 업데이트 명령을 준비합니다.

Windows용으로 수행한다고 가정해 보겠습니다(Linux로 이식하는 것은 간단합니다).
SubGit의 설치 bin 디렉토리(subgit-2.XX\bin)에서 두 개의 .bat 파일을 만듭니다.

마이그레이션을 위한 파일/명령의 내용:

 start subgit import --svn-url url://svn.serv/Bla/Bla directory/path/Local.git.Repo

"시작" 명령은 여기에서 선택 사항입니다(Windows). 시작 시 오류를 볼 수 있고 SubGit 완료 후 열린 셸을 남길 수 있습니다.

여기에 git-svn 과 유사한 추가 매개변수를 추가할 수 있습니다. SVN 작성자의 이메일 주소 도메인을 수정하기 위해 --default-domain myCompanyDomain.com 만 사용하고 있습니다.
나는 표준 SVN 저장소의 구조(트렁크/분기/태그)를 가지고 있으며 "저자 매핑"에 문제가 없었습니다. 그래서 나는 더 이상 아무것도 하지 않는다.

(분기와 같은 태그를 마이그레이션하거나 SVN에 여러 분기/태그 폴더가 있는 경우 더 자세한 SubGit 접근 방식 사용을 고려할 수 있습니다)

팁 1 : --minimal-revision YourSvnRevNumber를 사용하여 상황이 어떻게 종료되는지 빠르게 확인합니다(일종의 디버깅). 특히 확인된 작성자 이름 또는 이메일을 확인하는 데 유용합니다.
또는 마이그레이션 기록 깊이를 제한합니다.

팁 2 : 마이그레이션이 중단되고( Ctrl + C ) 다음 업데이트 명령/파일을 실행하여 복원할 수 있습니다.
큰 리포지토리에 대해서는 이 작업을 수행하지 않는 것이 좋습니다. "메모리 부족 Java+Windows 예외"를 받았습니다.

팁 3 : 결과 베어 리포지토리의 복사본을 만드는 것이 좋습니다.

업데이트를 위한 파일/명령의 내용:

 start subgit import directory/path/Local.git.Repo

Git 리포지토리에 대한 마지막 팀의 커밋을 얻고 싶을 때 언제든지 실행할 수 있습니다.

경고! 베어 저장소를 만지지 마십시오(예: 분기 생성).
다음 치명적인 오류가 발생합니다.

복구할 수 없는 오류: 동기화되지 않아 동기화할 수 없습니다... Subversion 버전을 Git 커밋으로 변환하는 중...

3. 첫 번째 명령/파일을 실행합니다. 큰 리포지토리의 경우 시간이 많이 걸립니다. 내 겸손한 저장소에 30시간.

그게 다야
두 번째 파일/명령을 실행하여 언제든지 SVN에서 Git 리포지토리를 업데이트할 수 있습니다. 개발 팀을 Git으로 전환하기 전에.
몇 초밖에 걸리지 않습니다.



유용한 작업이 하나 더 있습니다.

로컬 Git 리포지토리를 원격 Git 리포지토리로 푸시

당신의 경우입니까? 진행합시다.

  1. 리모컨 구성

운영:

 $ git remote add origin url://your/repo.git
  1. 거대한 로컬 Git 리포지토리를 원격 리포지토리로 초기 보내기 준비

기본적으로 Git은 큰 청크를 보낼 수 없습니다. 치명적: 원격 끝이 예기치 않게 끊겼습니다.

그것을 위해 실행하자:

 git config --global http.postBuffer 1073741824

524288000 - 500MB 1073741824 - 1GB 등

로컬 인증서 문제를 해결하십시오 . git-server가 깨진 인증서를 사용하는 경우.

인증서를 비활성화했습니다.

또한 Git 서버에 수정해야 할 요청 양 제한이 있을 수 있습니다 .

  1. 모든 마이그레이션 을 팀의 원격 Git 리포지토리로 푸시합니다.

로컬 Git으로 실행:

 git push origin --mirror

(이전 Git 버전의 경우 git push origin '*:*')

다음이 표시되는 경우: error: cannot spawn git: No such file or directory ... 저에게 저장소를 완전히 재생하면 이 오류(30시간)가 해결됩니다. 다음 명령을 시도할 수 있습니다.

 git push origin --all git push origin --tags

또는 Git을 다시 설치해 보십시오( 나에게 쓸모 없음 ). 또는 모든 태그에서 분기를 만들고 푸시할 수 있습니다. 또는, 또는, 또는...


Community Wiki

재생 외과 의사

복잡한 경우에는 Eric S. Raymond의 재수술이 선택되는 도구입니다. fast-export 형식과 CVS 를 통해 다른 많은 버전 제어 시스템을 지원합니다. 저자는 EmacsFreeBSD 와 같은 고대 저장소의 성공적인 변환을 보고합니다.

이 도구는 역사가 긴 어려운 저장소 레이아웃의 경우에도 거의 완벽한 변환 svn:ignore 속성을 .gitignore 파일으로 변환)을 목표로 합니다. 대부분의 경우 다른 도구를 사용하는 것이 더 쉬울 수 있습니다.

reposurgeon 명령줄의 문서를 reposurgeon 전에 변환 프로세스를 단계별로 설명 하는 우수한 DVCS 마이그레이션 가이드 를 읽으십시오.


Community Wiki

atlassian 웹사이트에 있는 이 가이드는 내가 찾은 최고의 가이드 중 하나입니다.

https://www.atlassian.com/git/migration

이 도구( https://bitbucket.org/atlassian/svn-migration-scripts) 는 또한 무엇보다도 Authors.txt를 생성하는 데 정말 유용합니다.


Community Wiki

당신은 설치해야

 git git-svn

이 링크에서 복사했습니다 http://john.albin.net/git/convert-subversion-to-git .

1. 모든 Subversion 커미터 목록 검색

Subversion은 단순히 각 커밋에 대한 사용자 이름을 나열합니다. Git의 커밋에는 훨씬 더 풍부한 데이터가 있지만 가장 간단하게 커밋 작성자는 이름과 이메일을 나열해야 합니다. 기본적으로 git-svn 도구는 작성자 및 이메일 필드 모두에 SVN 사용자 이름을 나열합니다. 그러나 약간의 작업을 통해 모든 SVN 사용자 목록과 해당 Git 이름 및 이메일을 만들 수 있습니다. 이 목록은 git-svn에서 일반 svn 사용자 이름을 적절한 Git 커미터로 변환하는 데 사용할 수 있습니다.

로컬 Subversion 체크아웃의 루트에서 다음 명령을 실행합니다.

 svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors-transform.txt

그러면 모든 로그 메시지를 가져오고, 사용자 이름을 뽑아내고, 중복 사용자 이름을 제거하고, 사용자 이름을 정렬하여 "authors-transform.txt" 파일에 넣습니다. 이제 파일의 각 줄을 편집합니다. 예를 들어 다음을 변환합니다.

 jwilkins = jwilkins <jwilkins>

이것으로:

 jwilkins = John Albin Wilkins <johnalbin@example.com>

2. git-svn을 사용하여 Subversion 저장소를 복제합니다.

 git svn clone [SVN repo URL] --no-metadata -A authors-transform.txt --stdlayout ~/temp

이것은 표준 git-svn 변환을 수행하고(1단계에서 생성한 author-transform.txt 파일 사용) git 저장소를 홈 디렉토리 내의 "~/temp" 폴더에 배치합니다.

3. svn:ignore 속성을 .gitignore로 변환

svn repo가 svn:ignore 속성을 사용하고 있었다면 다음을 사용하여 이것을 .gitignore 파일로 쉽게 변환할 수 있습니다.

 cd ~/temp git svn show-ignore > .gitignore git add .gitignore git commit -m 'Convert svn:ignore properties to .gitignore.'

4. 저장소를 베어 git 저장소로 푸시

먼저 베어 저장소를 만들고 기본 분기가 svn의 "trunk" 분기 이름과 일치하도록 합니다.

 git init --bare ~/new-bare.git cd ~/new-bare.git git symbolic-ref HEAD refs/heads/trunk

그런 다음 임시 저장소를 새 베어 저장소로 푸시합니다.

 cd ~/temp git remote add bare ~/new-bare.git git config remote.bare.push 'refs/remotes/*:refs/heads/*' git push bare

이제 ~/temp 저장소를 안전하게 삭제할 수 있습니다.

5. "trunk" 브랜치의 이름을 "master"로 바꿉니다.

기본 개발 분기의 이름은 Subversion에 있던 이름과 일치하는 "trunk"로 지정됩니다. 다음을 사용하여 Git의 표준 "마스터" 브랜치로 이름을 바꾸고 싶을 것입니다.

 cd ~/new-bare.git git branch -m trunk master

6. 브랜치 및 태그 정리

git-svn은 모든 Subversions 태그를 "tags/name" 형식의 Git에서 매우 짧은 분기로 만듭니다. 다음을 사용하여 모든 분기를 실제 Git 태그로 변환하고 싶을 것입니다.

 cd ~/new-bare.git git for-each-ref --format='%(refname)' refs/heads/tags | cut -d / -f 4 | while read ref do git tag "$ref" "refs/heads/tags/$ref"; git branch -D "tags/$ref"; done

이 단계는 약간의 입력이 필요합니다. :-) 하지만 걱정하지 마세요. 유닉스 셸은 git for-each-ref로 시작하는 매우 긴 명령에 대한 > 보조 프롬프트를 제공합니다.


Community Wiki

이제 GitHub에는 SVN 저장소에서 가져올 수 있는 기능이 있습니다. 나는 그것을 시도한 적이 없습니다.


webmat

git, SVN 및 bash만 사용하는 다소 확장된 답변입니다. 여기에는 trunk/branches/tags 디렉토리 레이아웃과 함께 기존 레이아웃을 사용하지 않는 SVN 리포지토리에 대한 단계가 포함됩니다(SVN은 이러한 종류의 레이아웃을 적용하기 위해 절대적으로 아무 것도 하지 않음).

먼저 이 bash 스크립트를 사용하여 SVN 저장소에서 기여한 다른 사람들을 스캔하고 매핑 파일에 대한 템플릿을 생성합니다.

 #!/usr/bin/env bash authors=$(svn log -q | grep -e '^r' | awk 'BEGIN { FS = "|" } ; { print $2 }' | sort | uniq) for author in ${authors}; do echo "${author} = NAME <USER@DOMAIN>"; done

git config 속성 user.nameuser.email 사용하여 개발자가 설정한 대로 svn 사용자 이름을 사용자 이름과 이메일에 매핑 authors 파일을 만듭니다(GitHub과 같은 서비스의 경우 일치하는 이메일만 있으면 충분합니다).

그런 다음 git svn 이 svn 저장소를 git 저장소에 복제하도록 하여 매핑에 대해 알려줍니다.

git svn clone --authors-file=authors --stdlayout svn://example.org/Folder/projectroot

git svn은 존재하는 모든 태그 또는 분기에 대한 모든 개정을 개별적으로 확인하기 때문에 이 작업은 엄청나게 오래 걸릴 수 있습니다. (SVN의 태그는 실제로 분기일 뿐이므로 Git에서 태그와 같이 끝납니다.) 필요하지 않은 SVN의 오래된 태그와 분기를 제거하여 속도를 높일 수 있습니다.

동일한 네트워크의 서버 또는 동일한 서버에서 이것을 실행하면 속도가 실제로 빨라질 수도 있습니다. 또한 어떤 이유로 이 프로세스가 중단되면 다음을 사용하여 다시 시작할 수 있습니다.

git svn rebase --continue

많은 경우 여기에서 완료됩니다. 그러나 SVN 리포지토리에 SVN에 디렉터리가 있고 git 분기에 넣고 싶은 독특한 레이아웃이 있는 경우 몇 가지 추가 단계를 수행할 수 있습니다.

가장 간단한 방법은 규칙을 따르는 서버에 새 SVN 저장소를 만들고 svn copy 를 사용하여 디렉토리를 트렁크 또는 분기에 넣는 것입니다. git svn 시도했을 때 디렉토리가 저장소의 루트에 있는 경우 이것이 유일한 방법일 수 있습니다. 단순히 체크아웃을 거부했습니다.

git을 사용하여 이 작업을 수행할 수도 있습니다. git svn clone 경우 git 브랜치에 넣고 싶은 디렉토리를 사용하기만 하면 됩니다.

실행 후

 git branch --set-upstream master git-svn git svn rebase

이를 위해서는 Git 1.7 이상이 필요합니다.


Community Wiki

svn 태그를 git 태그로 변환하고 svn 분기를 git 분기로 변환하는 것을 포함하여 svn을 git으로 변환하는 단계별 가이드( here )를 게시했습니다.

짧은 버전:

1) 특정 개정 번호에서 svn을 복제합니다. (리비전 번호는 마이그레이션하려는 가장 오래된 것이어야 함)

 git svn clone --username=yourSvnUsername -T trunk_subdir -t tags_subdir -b branches_subdir -r aRevisionNumber svn_url gitreponame

2) svn 데이터를 가져옵니다. 이 단계는 가장 시간이 많이 걸리는 단계입니다.

 cd gitreponame git svn fetch

오류 없이 완료될 때까지 git svn fetch를 반복합니다.

3) 마스터 브랜치 업데이트 받기

 git svn rebase

4) 참조를 복사하여 svn 브랜치에서 로컬 브랜치 생성

 cp .git/refs/remotes/origin/* .git/refs/heads/

5) svn 태그를 git 태그로 변환

 git for-each-ref refs/remotes/origin/tags | sed 's#^.*\([[:xdigit:]]\{40\}\).*refs/remotes/origin/tags/\(.*\)$#\2 \1#g' | while read p; do git tag -m "tag from svn" $p; done

6) github와 같은 더 나은 장소에 저장소를 두십시오.

 git remotes add newrepo git@github.com:aUser/aProjectName.git git push newrepo refs/heads/* git push --tags newrepo

더 자세한 내용을 원하시면 제 글을 읽거나 저에게 물어보세요.


Community Wiki

아래와 같이 git svn clone 명령을 사용할 수 있습니다.

  • svn log -q <SVN_URL> | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors.txt

위의 명령은 SVN 커밋에서 작성자 파일을 생성합니다.

  • svn log --stop-on-copy <SVN_URL>

위의 명령은 SVN 프로젝트가 생성될 때 첫 번째 개정 번호를 제공합니다.

  • git svn clone -r<SVN_REV_NO>:HEAD --no-minimize-url --stdlayout --no-metadata --authors-file authors.txt <SVN_URL>

위의 명령은 로컬에 Git 저장소를 생성합니다.

문제는 분기와 태그를 푸시로 변환하지 않는다는 것입니다. 수동으로 수행해야 합니다. 지점에 대한 예를 들면 다음과 같습니다.

 $ git remote add origin https://github.com/pankaj0323/JDProjects.git $ git branch -a * master remotes/origin/MyDevBranch remotes/origin/tags/MyDevBranch-1.0 remotes/origin/trunk $$ git checkout -b MyDevBranch origin/MyDevBranch Branch MyDevBranch set up to track remote branch MyDevBranch from origin. Switched to a new branch 'MyDevBranch' $ git branch -a * MyDevBranch master remotes/origin/MyDevBranch remotes/origin/tags/MyDevBranch-1.0 remotes/origin/trunk $

태그의 경우:

 $git checkout origin/tags/MyDevBranch-1.0 Note: checking out 'origin/tags/MyDevBranch-1.0'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b new_branch_name HEAD is now at 3041d81... Creating a tag $ git branch -a * (detached from origin/tags/MyDevBranch-1.0) MyDevBranch master remotes/origin/MyDevBranch remotes/origin/tags/MyDevBranch-1.0 remotes/origin/trunk $ git tag -a MyDevBranch-1.0 -m "creating tag" $git tag MyDevBranch-1.0 $

이제 마스터, 분기 및 태그를 원격 git 저장소로 푸시합니다.

 $ git push origin master MyDevBranch MyDevBranch-1.0 Counting objects: 14, done. Delta compression using up to 8 threads. Compressing objects: 100% (11/11), done. Writing objects: 100% (14/14), 2.28 KiB | 0 bytes/s, done. Total 14 (delta 3), reused 0 (delta 0) To https://github.com/pankaj0323/JDProjects.git * [new branch] master -> master * [new branch] MyDevBranch -> MyDevBranch * [new tag] MyDevBranch-1.0 -> MyDevBranch-1.0 $

svn2git 유틸리티

svn2git 유틸리티는 분기 및 태그를 사용하여 수동 작업을 제거합니다.

sudo gem install svn2git 명령을 사용하여 설치합니다. 그 후 아래 명령을 실행하십시오.

  • $ svn2git <SVN_URL> --authors authors.txt --revision <SVN_REV_NO>

이제 브랜치, 태그를 나열하고 쉽게 푸시할 수 있습니다.

 $ git remote add origin https://github.com/pankaj0323/JDProjects.git $ git branch -a MyDevBranch * master remotes/svn/MyDevBranch remotes/svn/trunk $ git tag MyDevBranch-1.0 $ git push origin master MyDevBranch MyDevBranch-1.0

20개의 브랜치와 태그가 있다고 상상해 보세요. 분명히 svn2git이 많은 시간을 절약할 수 있기 때문에 기본 명령보다 더 좋아합니다. git svn clone 명령을 둘러싼 멋진 래퍼입니다.

전체 예를 보려면 내 블로그 항목 을 참조하십시오.


Community Wiki

TortoiseGit이 이 작업을 수행합니다. 이 블로그 게시물 참조: http://jimmykeen.net/articles/03-nov-2012/how-migrate-from-svn-to-git-windows-using-tortoise-clients

예, 링크로 응답하는 것이 훌륭하지 않다는 것을 알고 있지만 그것은 해결책입니다. 응?


Community Wiki

GitLab 사용자의 경우 여기에 SVN에서 마이그레이션한 방법에 대한 요지를 올렸습니다.

https://gist.github.com/leftclickben/322b7a3042cbe97ed2af

SVN에서 GitLab으로 마이그레이션하는 단계

설정

  • svn.domain.com.au 에서 호스팅됩니다.
  • http 를 통해 액세스할 수 있습니다(다른 프로토콜이 작동해야 함).
  • GitLab은에서 호스팅 git.domain.com.au 과 :
    • dev-team 네임스페이스로 그룹이 생성됩니다.
    • 하나 이상의 사용자 계정이 생성되어 그룹에 추가되고 마이그레이션에 사용되는 계정에 대한 SSH 키가 있습니다( ssh git@git.domain.com.au 사용하여 테스트).
    • 프로젝트 favourite-project dev-team 네임스페이스에 생성됩니다.
  • users.txt 파일 username = First Last <address@domain.com.au> 의 관련 사용자 세부 정보가 한 줄에 하나씩 포함되어 있습니다. 여기서 username 은 SVN 로그에 제공된 username (자세한 내용은 참조 섹션의 첫 번째 링크, 특히 사용자 Casey의 답변을 참조하십시오).

버전

  • Subversion 버전 1.6.17(r1128011)
  • 자식 버전 1.9.1
  • GitLab 버전 7.2.1 ff1633f
  • 우분투 서버 14.04

명령

 bash git svn clone --stdlayout --no-metadata -A users.txt http://svn.domain.com.au/svn/repository/favourite-project cd favourite-project git remote add gitlab git@git.domain.com.au:dev-team/favourite-project.git git push --set-upstream gitlab master

그게 다야! GitLab 웹 UI에서 프로젝트 페이지를 다시 로드하면 모든 커밋과 파일이 나열되는 것을 볼 수 있습니다.

노트

  • 알 수 없는 사용자가 있는 경우 git svn clone 명령이 중지되고, 이 경우 중지된 위치에서 update users.txt , cd favourite-projectgit svn fetch 가 계속됩니다.
  • SVN 저장소에 대한 표준 trunk - tags - branches 레이아웃이 필요합니다.
  • git svn clone 명령에 제공된 SVN URL은 trunk/ , tags/branches/ 바로 위의 수준에서 멈춥니다.
  • git svn clone 명령은 상단에 몇 가지 경고를 포함하여 많은 출력을 생성합니다. 나는 경고를 무시했다.

Community Wiki

방금 발견한 이 짧은 스크린캐스트 시리즈를 적극 추천합니다. 저자는 기본 작업을 안내하고 몇 가지 고급 사용법을 보여줍니다.


Community Wiki

SourceTree를 사용하는 경우 앱에서 직접 이 작업을 수행할 수 있습니다. 파일 -> 새로 만들기/복제로 이동한 다음 다음을 수행합니다.

  1. 원격 SVN URL을 "소스 경로/URL"로 입력합니다.
  2. 메시지가 표시되면 자격 증명을 입력합니다.
  3. 로컬 폴더 위치를 "대상 경로"로 입력합니다.
  4. 이름을 지정합니다.
  5. 고급 옵션에서 "Create local repository of type"의 드롭다운에서 "Git"을 선택합니다.
  6. 선택적으로 복제할 개정판을 지정할 수 있습니다.
  7. 클론을 누르십시오.

SourceTree에서 저장소를 열면 커밋 메시지도 마이그레이션된 것을 볼 수 있습니다.

이제 리포지토리 -> 리포지토리 설정으로 이동하여 새 원격 리포지토리 세부 정보를 추가합니다. 원하는 경우 SVN 원격을 삭제합니다("구성 파일 편집" 옵션을 통해 이 작업을 수행했습니다.

준비가 되면 코드를 새 원격 리포지토리로 푸시하고 자유롭게 코딩하세요.


Community Wiki

다른 한편으로, git-stash 명령은 git-svn dcommits로 git을 시도할 때 신의 선물입니다.

일반적인 프로세스:

  1. git repo 설정
  2. 다른 파일에 대한 작업을 수행
  3. git을 사용하여 일부 작업을 확인하기로 결정
  4. svn-dcommit 결정
  5. 두려운 "더티 인덱스로 커밋할 수 없습니다" 오류가 발생합니다.

솔루션(git 1.5.3+ 필요):

 git stash; git svn dcommit ; git stash apply

Gregg Lind

저는 Git 커뮤니티에 제 기여를 추가하고 싶었습니다. 전체 가져오기를 자동화하는 간단한 bash 스크립트를 작성했습니다. 다른 마이그레이션 도구와 달리 이 도구는 jGit 대신 기본 git에 의존합니다. 이 도구는 큰 수정 기록 및/또는 큰 Blob이 있는 리포지토리도 지원합니다. github를 통해 사용할 수 있습니다.

https://github.com/onepremise/SGMS

이 스크립트는 SVN에 저장된 프로젝트를 다음 형식으로 변환합니다.

 /trunk /Project1 /Project2 /branches /Project1 /Project2 /tags /Project1 /Project2

이 구성표도 널리 사용되며 지원됩니다.

 /Project1 /trunk /branches /tags /Project2 /trunk /branches /tags

각 프로젝트는 프로젝트 이름별로 동기화됩니다.

 Ex: ./migration https://svnurl.com/basepath project1

전체 리포지토리를 변환하려면 다음 구문을 사용하세요.

 Ex: ./migration https://svnurl.com/basepath .

Community Wiki

다음은 하나 이상의 SVN 저장소를 git으로 변환하고 GitHub에 푸시하는 종속성이 없는 간단한 셸 스크립트입니다.

https://gist.github.com/NathanSweet/7327535

약 30줄의 스크립트에서 git SVN을 사용하여 복제하고 SVN::ignore 속성에서 .gitignore 파일을 생성하고 베어 git 저장소로 푸시하고 SVN 트렁크의 이름을 마스터로 변경하고 SVN 태그를 git 태그로 변환하고 GitHub에 푸시합니다. 태그를 유지하면서.

수십 개의 SVN 저장소를 Google 코드에서 GitHub로 옮기는 데 많은 어려움을 겪었습니다. Windows를 사용하는 것은 도움이 되지 않았습니다. Ruby는 내 오래된 Debian 상자에서 모든 종류의 손상을 입었고 Windows에서 작동하는 것은 농담이었습니다. 다른 솔루션은 Cygwin 경로에서 작동하지 않았습니다. 작동하는 것을 얻었음에도 GitHub에 태그를 표시하는 방법을 알 수 없었습니다(비밀은 --follow-tags입니다).

결국 위에 링크된 두 개의 짧고 간단한 스크립트를 함께 만들었으며 훌륭하게 작동합니다. 솔루션은 그보다 더 복잡할 필요가 없습니다!


Community Wiki

나는 Windows 시스템에 있고 히스토리가 있는 SVN repo(분기 없음)를 GIT repo로 전송하기 위해 작은 배치를 만들었습니다.

transfer.bat http://svn.my.address/svn/myrepo/trunk https://git.my.address/orga/myrepo

아마 누구나 사용할 수 있습니다. TMP 폴더를 생성하고 거기에 SVN 저장소를 git으로 체크아웃하고 새 원본을 추가하고 밀어넣고... 폴더를 다시 삭제합니다.

 @echo off SET FROM=%1 SET TO=%2 SET TMP=tmp_%random% echo from: %FROM% echo to: %TO% echo tmp: %TMP% pause git svn clone --no-metadata --authors-file=users.txt %FROM% %TMP% cd %TMP% git remote add origin %TO% git push --set-upstream origin master cd .. echo delete %TMP% ... pause rmdir /s /q %TMP%

다음과 같은 사용자 매핑이 있는 users.txt가 여전히 필요합니다.

 User1 = User One <u.1@xxx.com>

Community Wiki

먼저 @cmcginty의 답변을 참조하십시오. 그것은 저에게 훌륭한 출발점이 되었고, 여기에 포스팅할 내용의 대부분은 그것에서 크게 차용되었습니다. 그러나 내가 옮기고 있던 repos는 수년 간의 역사를 가지고 있어 그 편지에 대한 답변에 따라 몇 가지 문제가 발생했습니다.

그래서 몇 시간의 검색과 시행착오 끝에 여러 프로젝트를 SVN에서 GIT로 쉽게 이동할 수 있는 스크립트를 작성할 수 있었고 다른 사람이 내 입장에 있는 경우를 대비하여 여기에서 내 발견을 공유하기로 결정했습니다.

<tl;dr> 시작하자


먼저 기본 svn 사용자를 더 복잡한 git 사용자로 변환할 'Authors' 파일을 만듭니다. 이를 수행하는 가장 쉬운 방법은 명령을 사용하여 이동할 svn 저장소에서 모든 사용자를 추출하는 것입니다.

 svn log -q | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > authors-transform.txt

이것은 실행된 svn 리포지토리에서 변경을 수행한 각 사용자에 대한 행이 있는authors-transform.txt라는 파일을 생성합니다.

 someuser = someuser <someuser>

git의 전체 이름과 이메일을 포함하도록 업데이트

 someuser = Some User <someuser@somewhere.com>

이제 작성자 파일을 사용하여 복제를 시작하십시오.

 git svn clone --stdlayout --no-metadata -r854:HEAD --authors-file=authors-transform.txt https://somesvnserver/somerepo/ temp
  • --stdlayout은 svn repo가 표준 /trunk /branches /tags 레이아웃을 따른다는 것을 나타냅니다.
  • --no-metadata는 각 git 커밋에서 svn 커밋과 관련된 메타데이터를 스탬프하지 않도록 git에 지시합니다. 단방향 전환이 아닌 경우 이 태그를 제거하세요.
  • -r854:HEAD는 개정판 854부터 기록만 가져옵니다. 이것은 내가 첫 번째 걸림돌을 치는 곳입니다. 내가 변환하고 있던 리포지토리에는 개정판 853에서 '손상된' 커밋이 있으므로 복제되지 않습니다. 이 매개변수를 사용하면 기록의 일부만 복제할 수 있습니다.
  • temp는 새로운 git repo를 초기화하기 위해 생성될 디렉토리의 이름입니다.

이 단계는 특히 크거나 오래된 리포지토리에서 시간이 걸릴 수 있습니다(당사 중 하나의 경우 약 18시간). -r 스위치를 사용하여 클론을 보기 위해 작은 기록만 가져오고 나머지는 나중에 가져올 수 있습니다.

새 디렉토리로 이동

 cd temp

클론에서 부분적으로만 가져온 경우 누락된 기록을 가져옵니다.

 git svn fetch

태그는 복제 중에 분기로 생성됩니다. 몇 개만 있으면 한 번에 하나씩 변환할 수 있습니다.

 git 1.0.0 origin/tags/1.0.0

그러나 수백 개의 태그가 있으면 지루하므로 다음 스크립트가 저에게 효과적이었습니다.

 for brname in `git branch -r | grep tags | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do echo $brname; tname=${brname:5}; echo $tname; git tag $tname origin/tags/$tname; done

또한 유지하려는 모든 지점을 체크아웃해야 합니다.

 git checkout -b branchname origin/branches/branchname

또한 많은 지점이 있는 경우 이 스크립트가 도움이 될 수 있습니다.

 for brname in `git branch -r | grep -v master | grep -v HEAD | grep -v trunk | grep -v tags | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do echo $brname; git checkout -b $brname origin/$brname; done

이것은 이미 마스터로 체크 아웃된 트렁크 분기를 무시하고 중복 분기를 삭제하고 이미 변환한 /tag를 무시하는 단계를 저장합니다.

지금은 새로운 리포지토리를 살펴보고 원격 브랜치가 잠시 후 삭제될 것이기 때문에 유지하려는 모든 것에 대한 로컬 브랜치 또는 태그가 있는지 확인하기에 좋은 시간입니다.

자, 이제 체크아웃한 모든 항목을 깨끗한 저장소(여기서는 temp2)에 복제하겠습니다.

 cd .. git clone temp temp2 cd temp2

이제 모든 브랜치를 최종 리모컨으로 푸시하기 전에 한 번 더 체크아웃해야 하므로 위에서 선호하는 방법을 따르십시오.

gitflow를 따르는 경우 개발할 작업 분기의 이름을 바꿀 수 있습니다.

 git checkout -b WORKING git branch -m develop git push origin --delete WORKING git push origin -u develop

이제 모든 것이 좋아 보인다면 git 저장소로 푸시할 준비가 된 것입니다.

 git remote set-url origin https://somebitbucketserver/somerepo.git git push -u origin --all git push origin --tags

Control Freak이 내가 생성하지 않은 태그를 푸시하는 것을 처음에 차단했다는 마지막 문제에 부딪쳤습니다. 따라서 팀에서 Control Freak을 사용하는 경우 초기 푸시에 대해 해당 설정을 비활성화하거나 조정해야 할 수 있습니다.


Community Wiki

Subversion과 함께 Git을 효과적으로 사용 하는 것은 git-svn에 대한 간단한 소개입니다. 기존 SVN 저장소의 경우 git-svn을 사용하면 매우 쉽습니다. 새 리포지토리를 시작하는 경우 먼저 빈 SVN 리포지토리를 만든 다음 git-svn을 사용하여 가져오는 것이 반대 방향으로 가는 것보다 훨씬 쉽습니다. 새 Git 리포지토리를 만든 다음 SVN으로 가져올 수 있지만 특히 Git을 처음 사용하고 커밋 기록을 보존하려는 경우 약간 고통스럽습니다.


Community Wiki

Windows용 Ruby 설치 프로그램을 다운로드하고 최신 버전을 설치하십시오. 경로에 Ruby 실행 파일을 추가합니다.

  • svn2git 설치
  • 시작 메뉴 -> 모든 프로그램 -> Ruby -> Ruby로 명령 프롬프트 시작
  • 그런 다음 "gem install svn2git"을 입력하고 입력하십시오.

    Subversion 저장소 마이그레이션

  • Ruby 명령 프롬프트를 열고 파일을 마이그레이션할 디렉터리로 이동합니다.

    그런 다음 svn2git http://[도메인 이름]/svn/ [저장소 루트]

  • 프로젝트 코드 크기에 따라 프로젝트를 Git으로 마이그레이션하는 데 몇 시간이 걸릴 수 있습니다.

  • 이 주요 단계는 아래에 언급된 Git 리포지토리 구조를 만드는 데 도움이 됩니다.

    SVN(/Project_components) 트렁크 --> Git 마스터 SVN(/Project_components) 분기 --> Git 분기 SVN(/Project_components) 태그 --> Git 태그

원격 저장소를 만들고 변경 사항을 푸시합니다.


Community Wiki

GitHub에는 수입업자가 있습니다. 저장소를 만든 후에는 URL을 통해 기존 저장소에서 가져올 수 있습니다. 해당되는 경우 자격 증명을 요청하고 거기에서 이동합니다.

실행 중이면 작성자를 찾을 수 있으며 GitHub의 사용자에게 간단히 매핑할 수 있습니다.

나는 지금 몇 개의 리포지토리에 그것을 사용했고, 그것은 꽤 정확하고 훨씬 빠릅니다! ~4000개의 커밋이 있는 저장소에는 10분이 걸렸고 내 친구는 4일이 걸렸습니다!


Community Wiki

여기에서 몇 가지 답변은 https://github.com/nirvdrum/svn2git 을 참조하지만 큰 리포지토리의 경우 느릴 수 있습니다. 나는 정확히 같은 이름을 가진 도구이지만 SVN에서 Git으로 KDE를 마이그레이션하는 데 사용되는 https://github.com/svn-all-fast-export/svn2git을 대신 사용해 보았습니다.

설정하는 데 약간 더 많은 작업이 필요하지만 완료되면 다른 스크립트가 몇 시간을 소비하는 변환 자체에 몇 분이 걸렸습니다.


Community Wiki

이 목표를 달성하기 위한 다양한 방법이 있습니다. 나는 그들 중 일부를 시도했고 Windows OS에 설치된 git 및 svn만으로 실제로 작동하는 것을 발견했습니다.

전제 조건:

  1. git on windows (저는 이것을 사용했습니다) https://git-scm.com/
  2. 콘솔 도구가 설치된 svn(저는 tortoise svn을 사용했습니다)
  3. SVN 저장소의 덤프 파일입니다. svnadmin dump /path/to/repository > repo_name.svn_dump

최종 목표를 달성하기 위한 단계(히스토리가 있는 모든 저장소를 git, 먼저 로컬 git, 그 다음 원격으로 이동)

  1. cd REPO_NAME_PARENT_FOLDER 디렉토리에 빈 저장소(콘솔 도구 또는 tortoiseSVN 사용)를 만들고 dumpfile.dump를 REPO_NAME_PARENT_FOLDER에 넣습니다.

  2. svnadmin load REPO_NAME_FOLDER < dumpfile.dump 이 작업을 기다리십시오. 시간이 오래 걸릴 수 있습니다.

  3. 이 명령은 자동이므로 두 번째 cmd 창을 엽니다. svnserve -d -R --root REPO_NAME_FOLDER 왜 file:///......을 사용하지 않습니까? https://stackoverflow.com/a/6300968/4953065 답변 덕분에 다음 명령이 실패하고 Unable to open ... to URL:

  4. 새 폴더 SOURCE_GIT_FOLDER 만들기

  5. cd SOURCE_GIT_FOLDER
  6. git svn clone svn://localhost/ 이 작업을 기다립니다.

마지막으로 무엇을 얻었습니까?

로컬 저장소를 확인할 수 있습니다.

 git log

이전 커밋이 보이나요? 그렇다면 - 알았어

이제 소스와 이전 svn 기록이 포함된 완전히 작동하는 로컬 git 저장소가 있습니다. 이제 일부 서버로 이동하려면 다음 명령을 사용하십시오.

 git remote add origin https://fullurlpathtoyourrepo/reponame.git git push -u origin --all # pushes up the repo and its refs for the first time git push -u origin --tags # pushes up any tags

제 경우에는 내 저장소에 태그가 없기 때문에 태그 명령이 필요하지 않습니다.

행운을 빕니다!


Community Wiki

출처 : http:www.stackoverflow.com/questions/79165/how-do-i-migrate-an-svn-repository-with-history-to-a-new-git-repository

반응형