리포지토리를 가져온 후 생성 된 원격 브랜치에 대해 git-svn에 알리려면 어떻게해야합니까?


193

git-svn회사의 중앙 Subversion 저장소에 대해 작업 하는 데 사용 하고 있습니다. 우리는 최근에 중앙 저장소에 새로운 기능 분기를 만들었습니다.

Git에게 어떻게 말합니까? 실행할 git branch -rfetchSubversion 저장소에 대해 실행 하여 Git 저장소를 초기화 할 때 존재했던 분기 만 볼 수 있습니까?


여기에 대한 답변 : stackoverflow.com/questions/13376917/… 도 유용 할 수 있습니다.
Tomasz Gandor 2016 년

답변:


294

원격 지점을 수동으로 추가 할 수 있습니다.

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

3
이 링크를 문서에 참조 kernel.org/pub/software/scm/git/docs/git-svn.html
slf

1
.git / config에서 단일 / 여러 리포지토리에서 원격 브랜치를 구성하는 방법을 이해하는 것은 매우 쉽습니다.
Mikael Lepistö

6
내가 이것을 8 번처럼 공표 할 수 있다면 나는 할 것이다. 마지막으로 비표준 위치에 추가 된 svn 분기를 추가하는 방법!
Tim Keating

7
fatal: Cannot setup tracking information; starting point 'newbranch' is not a branch.git checkout 단계에 도달 했습니다.
phpguru

17
@phpguru -t 옵션 플래그를 제거하여 'git checkout -b local-newbranch newbranch'가되도록하십시오. newbranch에 원격 접두사를 포함시키는 것을 잊지 마십시오 (예 : origin / newbranch).
mj1531

96

모든 원격 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리포지토리 루트를 가리켜 야하며에 정의 된 경로 fetchbranches상대 경로 여야합니다 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 원격 분기를 추적하도록 실행 하십시오.


1
해당 설정을 설정하기 전에 svn 분기를 수행 한 개정판을 이미 가져온 경우 git svn reset을 수행 할 수 있습니다.
kcm1700

3
편집 .git/svn/.metadata이 매우 도움이되었습니다! 내에서 별도의 지점 추가 된 .git/config, git svn fetch메타 데이터 버전 번호는 "너무 멀리 앞서"때문에 -에 선택하지 않았다입니다. 어떤 경우에는 지점에서 마지막 커밋 만 가져 왔습니다. 내가 수동으로 (이름 결함이있는 지점의 없앴다고 .git/svn/refs/remotes/svn/qa/XYZ.git/svn/refs/remotes/svn/qa/XYZ~, 그것의 존재를 떨어 .git/packed-refs등) ... 메타 데이터에 대한 "이전"개정 번호를 포착 ... 실행 된 git svn fetch마지막 w / 수정, 연결된 그래프 전체 역사를 얻을 수 있습니다.
starlocke

8
이것은 승인 된 답변이어야합니다! @ janos, 당신은 방금 두통의 시간을 절약했습니다! 인도에 오면 맥주 마시 러 갈 게요!
Roopesh Shenoy

1
또는 : git svn fetch --all.
kenorb

1
이 답변은 답을 찾을 수없는 약 7 개의 질문에 대한 답변이므로 6 페이지의 설명을 쓰지 않아도됩니다.
Droj

53

방금 필요한 것 같습니다 git svn fetch. 어떻게 든 변경 사항 대신 전체 저장소를 가져올 것이라고 스스로 확신했습니다.


7
@mitjak 왜 해결책이 맞습니까? 응답의 미묘함을 이해하지 못합니다.
rholmes

'솔루션'은 '솔루션'이 아닐 수도 있습니다
slf

1
@ rholmes : mitjak은 그것이 당신의 문제에 대한 해결책이지만 당신이 묻는 질문에 대한 대답은 아니라는 것을 확신합니다. (당신이 틀린 질문을했기 때문에, 당시 문제를 잘못 해석했을 때.)
Mike Nelson

이것은 svn 저장소를 git에 복제 한 순간에 분기가 존재할 때 작동합니다. svn 저장소의 분기가 나중에 작성된 경우 작동하지 않습니다.
Petr Gladkikh

3
복제 후 브랜치가 생성되면 정상적으로 작동합니다.
Tim Gautier

15

어쩌면 나는 어쨌든 그것을 엉망으로 만들었지 만 vjangus의 답변에있는 지침을 따르고 거의 효과가있었습니다. 유일한 문제는 뉴 브랜치가 트렁크에서 분기되지 않은 것입니다. gitk에서, 그것은 스스로 "떠 다니는"종류였다. 트렁크와 공통 조상이 없었습니다.

이에 대한 해결책은 다음과 같습니다.

  1. 분기를 만들기 전에 트렁크에서 발생한 마지막 커밋의 SHA1을 찾습니다.
  2. 새 브랜치에서 첫 번째 커밋의 SHA1을 찾으십시오 (메시지는 아마도 "Created new branch, copy from trunk @ 12345"또는 다른 것입니다)
  3. git diff-tree <sha1 from step 1> <sha1 from step 2>-출력이 없어야합니다. 출력이 있으면 잘못된 커밋을 선택했을 수 있습니다.
  4. git checkout local-newbranch그때 git rebase <sha1 from step 1>. local-newbranch새 트리로 리베이스 되지만 remotes/newbranch여전히 연결이 끊어집니다.
  5. 파일로 이동하여 현재 가리키는 이전 커밋에 해당하는 새로운 커밋 .git/refs/remotes/newbranch의 전체 SHA1 (rebased에 있음 ) 을 포함하도록 편집하십시오 . (또는 어쩌면 사용하십시오 . 감사합니다.)newbranchgit-update-ref refs/remotes/newbranch <new-SHA>
  6. 다음 번에 당신이 git svn dcommitnewbranch, 당신은 몇 가지 로그를 업데이트 그것에 대해 메시지의 무리를 얻을 수 있습니다. 이것은 정상적인 것입니다.

gitk --all하루 종일 열어 두고 자주 새로 고쳐서 수행중인 작업을 추적하는 것이 좋습니다. 나는 여전히 git 및 git svn을 처음 사용 하므로이 방법의 개선을 제안하십시오.


2
고마워, 이것은 유용하게 들린다. 아마도 'git-update-ref refs / remotes / newbranch <new-SHA>'가 더 안전한 옵션 일 것입니다.
inger

vjangus의 방법을 다시 시도하면 완벽하게 작동했습니다. 누군가에게 가치가 있기 때문에 여기에 남겨 두겠습니다.
MatrixFrog

1
vjangus 솔루션은 항상 트렁크에서 분리 된 새 분기를 만듭니다. 나는 이것이 SVN 자체가 실제 내용이 어떻게 복사되는지에 대한 단서가 없기 때문이라고 생각합니다.
bogdan.mustiata

큰 git-svn repo에 대한 나의 경험은 svn 브랜치가 항상 트렁크에서 분리 된 git으로 생성된다는 것입니다. 그것들을 연결하는 방법이 있어야하지만, 그것을 알아내는 데 시간이 걸리지 않았습니다. AFAIK, svn 브랜치에 연결된 git 브랜치를 리베이스 할 수 없습니다 .dcommit 로직을 망칠 수 있기 때문입니다. 우리는 방금 그것과 함께 사는 법을 배웠습니다.
Spencer

7

vjangus의 답변 단순화 :

SVN에서 표준 레이아웃을 사용하고 일반적인 svn init을 수행했다면 git-svn이 구성 작업을 수행합니다. 다만:

  1. SVN에서 분기 복사 수정본 찾기
  2. git-svn으로 그 개정판 가져 오기
  3. 새로운 로컬 지점 추적 원격 생성

예입니다. SVN URL은 svn+ssh://gil@svn.myplace.com/repo입니다. 내가 찾고있는 SVN 지점은 newbranch입니다. 로컬 자식 브랜치 (트래킹 원격 newbranch)가됩니다 git-newbranch.

1 단계 : 분기 복사 개정판 찾기

    # svn log --stop-on-copy svn + ssh : //gil@svn.myplace.com/repo/branches/newbranch | 꼬리 -4
    r7802 | 누군가 | 2014-03-21 18:54:58 +0000 (2014 년 3 월 21 일 금요일) | 1 줄

    HEAD를 새 가지로 분기
    -------------------------------------------------- ----------------------

SVN의 분기점은 개정 7802입니다.

2 단계 : 개정판 가져 오기

    # 자식 svn 가져 오기 -r 7802
    가능한 분기점을 찾았습니다. svn + ssh : //gil@svn.myplace.com/repo/trunk => svn + ssh : //gil@svn.myplace.com/repo/branches/newbranch, 7801
    찾은 분기 상위 : (참조 / 원격 / 트렁크) 8dcf3c5793ff1a8a79dc94d268c91c2bf388894a
    do_switch가있는 다음 부모
    부모님을 성공적으로 따름
    r7802 = 9bbd4194041675ca5c9c6f3917e05ca5654a8a1e (refs / remotes / newbranch)

git-svn은 모든 작업을 수행했으며 이제 원격에 대해 알고 있습니다.

    # git show-ref | Grep Newbranch
    2df23af4733f36f5ad3c14cc1fa582ceeb3edb5c refs / remotes / newbranch

3 단계 : 원격 지점을 추적하는 새 로컬 지점을 만듭니다.

    # git checkout -b git-newbranch -t newbranch
    파일 체크 아웃 : 100 % (413/413) 완료
    지점 git-newbranch는 로컬 심판 심판 / 원격 / newbranch를 추적하도록 설정되었습니다.
    새로운 분기 'git-newbranch'로 전환

이것에 따라 마침내 나를 이해할 수있었습니다 show-ref. 원격 지사를 잘못 참조하는 사람이라면 누구든지 삭제할 수 있습니다 (필자는 git branch -d newbranchref 디렉토리를 강제로 제거 한 다음 강제로 제거해야합니다 .git/svn/refs/remotes/newbranch).
tutuDajuju

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

[편집] 때때로 새로 추가 된 브랜치를 가져 오기 위해 --all 매개 변수와 함께 fetch를 실행해야 할 때가 있습니다.

git svn fetch --all -r 10000:HEAD

4

git-svn quirks 를 처리하는 대신 SubGit을 사용해보십시오 .

SubGit을 Subversion 저장소에 설치해야합니다. 그 후 특별한 git-svn 명령을 사용하는 대신 표준 git workflow를 사용할 수 있습니다.

  1. 새로운 커밋 추진 :

    git-svn :

    $ git commit
    $ git svn rebase
    $ git svn dcommit
    

    서브 깃 :

    $ git commit
    $ git push
    
  2. 수신 변경 사항 가져 오기

    git-svn :

    $ git svn rebase
    

    서브 깃 :

    $ git pull [--rebase]
    
  3. 새로운 지점 만들기 :

    git-svn :

    $ git svn branch foo
    $ git checkout -b foo -t remotes/foo
    $ git commit
    $ git svn dcommit
    

    서브 깃 :

    $ git checkout -b foo
    $ git commit
    $ git push
    

자세한 내용은 SubGit 설명서 를 참조하십시오.


1
SubGit은 하나의 svn과 하나의 "shadow"git 저장소라는 두 개의 저장소를 생성한다는 단점이 있습니다. 이것은 거대한 SVN 저장소에 문제가 될 수 있습니다 ...
Udo

SVN 저장소에 몇 개의 프로젝트가있는 경우 @Udo 프로젝트 중 하나만 지정하고 Git 저장소와 동기화 할 수 있습니다. 이 경우 전체 Subversion 저장소를 Git으로 변환 할 필요가 없습니다. 그러나이 저장소에 거대한 SVN 프로젝트가있는 경우이 저장소의 전체 히스토리가 아니라 최소 개정부터 시작하여 히스토리를 변환 할 수 있습니다. 이렇게하면 번역 된 Git 리포지토리의 크기를 줄일 수 있습니다.
vadishev

1
@Udo-저장소 서버를 구매하지 않으려는 회사는 우선 순위가 엉망입니다. 그러나 대규모 리포지토리가있는 대부분의 장소는 리포지토리를 매우 중요하게 생각하며 리포지토리의 디스크 공간 요구 사항은 일반적으로 수십 년의 역사와 수천만 줄의 코드 및 수십만 개의 개정이있는 회사의 경우 큰 문제가되지 않습니다. 회사의 가장 핵심적인 지적 자산 형태이며 디스크 공간이 매우 저렴합니다. 그것은 ..., 심지어 생산성의 이득을 RAID 컨트롤러를 업그레이드 할 필요를 트리거하지만, 수
밥 컨스

@Bob Kerns-요점은 "현명한 크기"SVN 및 Git이며 호환되지 않는다는 것입니다. 디스크 스토리지의 문제는 아닙니다. 그러나 일반적으로 몇 개의 파일 / 프로젝트 만 체크 아웃해야하므로 대규모 SVN 저장소로 작업 할 수 있습니다. 그러나 거대한 Git 저장소를 복제 할 수는 없습니다. 적어도 재미는 없습니다. ;-) "거대한"이란 몇 가지 Gigs를 의미합니다.
Udo

2

vjangus의 답변에 추가하기 위해 git grafts를 사용하여 분기를 트렁크에 적절한 지점에 묶는 것이 유용하다는 것을 알았습니다 .git이 역사를보고 병합을 올바르게 수행 할 수있게했습니다.

이것은 단순히 .git/info/grafts해시 로 라인을 추가하는 경우입니다 .

<initial branch commit> <parent commit in trunk>

예.

378b0ae0902f5c2d2ba230c429a47698810532e5 6c7144991381ce347d4e563e9912465700be0638

http://evan-tech.livejournal.com/255341.html에 크레딧

(이 의견을 의견으로 추가하지만 평판이 충분하지 않습니다.)


0

유효한 레이아웃으로 체크 아웃하지 않으면 원격 지점을 체크 아웃 할 수 없습니다.

이것이 제가하는 것입니다:

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

그러면 자동으로 지점으로 전환됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.