[git] 기존 Git 저장소를 SVN으로 푸시

나는 Git에서 모든 작업을 수행하고 GitHub로 추진했다. 소프트웨어와 사이트 모두에 매우 만족했으며이 시점에서 작업 방식을 바꾸고 싶지 않습니다.

저의 PhD 고문은 모든 학생들에게 대학에서 주최하는 SVN 저장소에서 작업을 유지하도록 요청하고 있습니다. 기존 SVN 저장소를 Git으로 가져 오는 것에 대한 수많은 문서와 자습서를 찾았지만 Git 저장소를 새로운 SVN 저장소로 푸시하는 것에 대해서는 아무것도 없습니다. 나는 git-svn과 신선한 브랜치 및 rebasing 및 모든 훌륭한 용어를 조합 하여이 작업을 수행 할 수있는 방법이 있어야한다고 생각하지만, Git 초보자이며 그 중 어느 것에도 자신감이 없습니다.

그런 다음 선택할 때 SVN 저장소에 커밋을 푸시하는 몇 가지 명령을 실행하고 싶습니다. Git을 계속 사용하고 SVN 저장소에 Git의 내용을 반영하고 싶습니다.

이것이 SVN에 헌신하는 유일한 사람이 될 것입니다.



답변

나는 이것도 필요했고 Bombe의 대답과 주변의 도움으로 도움이되었습니다. 레시피는 다음과 같습니다.

가져 오기 힘내-> Subversion

1. cd /path/to/git/localrepo
2. svn mkdir --parents protocol:///path/to/repo/PROJECT/trunk -m "Importing git repo"
3. git svn init protocol:///path/to/repo/PROJECT -s
4. git svn fetch
5. git rebase origin/trunk
5.1.  git status
5.2.  git add (conflicted-files)
5.3.  git rebase --continue
5.4.  (repeat 5.1.)
6. git svn dcommit

# 3 후에 다음과 같은 암호 메시지가 나타납니다.

더 높은 수준의 URL 사용 : protocol:///path/to/repo/PROJECT => protocol:///path/to/repo

그냥 무시해

# 5를 실행 하면 충돌 이 발생할 수 있습니다. 상태가 “병합되지 않음”인 파일을 추가하고 rebase를 다시 시작하여이를 해결하십시오. 결국, 당신은 끝날 것입니다; 을 사용하여 SVN 저장소로 다시 동기화하십시오 dcommit. 그게 다야.

리포지토리 동기화

다음 명령을 사용하여 SVN에서 Git으로 동기화 할 수 있습니다.

git svn fetch
git rebase trunk

Git에서 SVN으로 동기화하려면 다음을 사용하십시오.

git svn dcommit

최종 메모

라이브 저장소에 적용하기 전에 로컬 사본에서이를 시도 할 수 있습니다. Git 저장소의 사본을 임시 위치에 만들 수 있습니다. cp -r모든 데이터가 저장소 자체에 있으므로 간단히 사용 하십시오. 그런 다음 다음을 사용하여 파일 기반 테스트 저장소를 설정할 수 있습니다.

svnadmin create /home/name/tmp/test-repo

다음을 사용하여 작업 복사본을 확인하십시오.

svn co file:///home/name/tmp/test-repo svn-working-copy

그것은 당신이 지속적인 변화를하기 전에 사물을 가지고 놀 수있게 해줍니다.

부록 : 엉망인 경우 git svn init

실수로 git svn init잘못된 URL 로 실행 하고 작업을 백업 할만큼 똑똑하지 않은 경우 (요청하지 않음) 동일한 명령을 다시 실행할 수 없습니다. 그러나 다음을 발행하여 변경 사항을 취소 할 수 있습니다.

rm -rf .git/svn
edit .git/config

섹션 [svn-remote "svn"]섹션을 제거 하십시오.

그런 다음 git svn init새로 실행할 수 있습니다 .


답변

작동 방식은 다음과 같습니다.

머신의 어딘가에 Git 저장소를 복제하십시오.

.git / config를 열고 Git 저장소의 읽기 전용 SVN 미러 유지 보수 에서 다음을 추가하십시오 .

[svn-remote "svn"]
    url = https://your.svn.repo
    fetch = :refs/remotes/git-svn

이제 콘솔 창에서 다음을 입력하십시오.

git svn fetch svn
git checkout -b svn git-svn
git merge master

어떤 이유로 든 여기에서 끊어지면 다음 세 줄을 입력하십시오.

git checkout --theirs .
git add .
git commit -m "some message"

그리고 마지막으로 SVN에 커밋 할 수 있습니다.

git svn dcommit

참고 : 나는 항상 그 폴더를 스크랩합니다.


답변

git rebase직접 사용 하면 첫 번째 커밋이 손실됩니다. 힘내는 그것을 다르게 취급하고 rebase 할 수 없습니다.

전체 기록을 보존하는 절차가 있습니다 : http://kerneltrap.org/mailarchive/git/2008/10/26/3815034

여기에 해결책을 제시하지만 Björn의 크레딧입니다.

git-svn을 초기화하십시오 :

git svn init -s --prefix=svn/ https://svn/svn/SANDBOX/warren/test2

–prefix는 “svn / trunk”와 같은 원격 추적 분기를 제공합니다. 로컬 분기를 “trunk”라고 부르면 모호한 이름을 얻지 못하기 때문에 좋습니다. 과-s 표준 트렁크 / 태그 / 지점 레이아웃에 대한 바로 가기입니다.

SVN에서 초기 내용을 가져옵니다.

git svn fetch

이제 루트 커밋의 해시를 찾으십시오 (단일 커밋을 표시해야 함).

git rev-list --parents master | grep '^.\{40\}$'

그런 다음 빈 트렁크 커밋의 해시를 가져옵니다.

git rev-parse svn/trunk

이식편을 만듭니다.

echo <root-commit-hash> <svn-trunk-commit-hash> >> .git/info/grafts

이제 “gitk”는 svn/trunk마스터 브랜치를 기반으로하는 첫 번째 커밋으로 표시되어야합니다 .

이식편을 영구적으로 만듭니다.

git filter-branch -- ^svn/trunk --all

이식편을 삭제하십시오 :

rm .git/info/grafts

gitk는 여전히 svn/trunk마스터의 조상에 보여 져야합니다 .

트렁크 위에서 역사를 선형화하십시오.

git svn rebase

이제 “git svn dcommit -n”은 트렁크에 커밋 할 것임을 알려줍니다.

git svn dcommit


답변

프로젝트의 Subversion 저장소에 새 디렉토리를 작성하십시오.

# svn mkdir --parents svn://ip/path/project/trunk

Git 관리 프로젝트로 변경하고 git-svn을 초기화하십시오.

# git svn init svn://ip/path/project -s
# git svn fetch

SVN 프로젝트 디렉토리가 여전히 비어 있기 때문에 단일 커밋이 생성됩니다. 이제 커밋의 모든 것을 리베이스 git svn dcommit하고 완료해야합니다. 그러나 커밋 날짜를 심각하게 망칠 것입니다.


답변

완전한 커밋 히스토리를 가진 Git-> SVN

나는 Git 프로젝트를 가지고 있었고 SVN으로 옮겨야했다. 이것이 내가 저지른 전체 커밋 기록을 유지하는 방법입니다. libSVN이 우리가 할 때 로컬 시간을 설정하므로 원래 커밋 시간이 유실됩니다 git svn dcommit.

어떻게:

  1. SVN 저장소에 물건을 가져오고 git-svn으로 복제하십시오.

    git svn clone https://path.to/svn/repository repo.git-svn`
    
  2. 저기로가:

    cd repo.git-svn
    
  3. Git 저장소의 원격을 추가하십시오 (이 예에서는 C : /Projects/repo.git 사용하고 있습니다 ). SVN으로 푸시하고 old-git 이름을 지정하려고합니다.

    git remote add old-git file:///C/Projects/repo.git/
    
  4. 이전 분기 저장소에서 현재 저장소로 마스터 브랜치에서 정보를 가져옵니다.

    git fetch old-git master
    
  5. old-git remote의 master 브랜치를 현재 저장소에서 old라는 새로운 브랜치로 체크 아웃하십시오.

    git checkout -b old old-git/master`
    
  6. HEAD를 낡은 git / master 위에 놓도록 리베이스하십시오. 이것은 모든 커밋을 유지합니다. 이것이 기본적으로하는 일은 Git에서 수행 한 모든 작업을 SVN에서 액세스하는 작업 위에 두는 것입니다.

    git rebase master
    
  7. 이제 마스터 지점으로 돌아갑니다.

    git checkout master
    

    그리고 커밋 기록이 깨끗하다는 것을 알 수 있습니다. 이것이 SVN으로 푸시하려는 것입니다.

  8. 작업을 SVN으로 푸시하십시오.

    git svn dcommit
    

그게 다야. 매우 깨끗하고 해킹이 없으며 모든 것이 완벽하게 작동합니다. 즐겨.


답변

SubGit을 사용하는 4 개의 명령으로 매우 짧은 명령을 제안합니다 . 자세한 내용은이 게시물 을 참조하십시오.


답변

기존 Git 리포지토리를 빈 SVN 리포지토리에 커밋해야했습니다.

이것이 내가 관리하는 방법입니다.

$ git checkout master
$ git branch svn
$ git svn init -s --prefix=svn/ --username <user> https://path.to.repo.com/svn/project/
$ git checkout svn
$ git svn fetch
$ git reset --hard remotes/svn/trunk
$ git merge master
$ git svn dcommit

문제없이 작동했습니다. 나는 이것이 누군가를 돕기를 바랍니다.

SVN 저장소와 다른 사용자 이름으로 내 권한을 부여해야했기 때문에 ( origin개인 / 공개 키 인증을 사용합니다) --username속성 을 사용해야 했습니다.