git-svn을 통해 미러링하는 svn 저장소가 URL을 변경했습니다.
바닐라 svn에서는 그냥 할 것 svn switch --relocate old_url_base new_url_base
입니다.
git-svn을 사용하여 어떻게 할 수 있습니까?
구성 파일에서 svn url을 변경하는 것만으로는 실패합니다.
git-svn을 통해 미러링하는 svn 저장소가 URL을 변경했습니다.
바닐라 svn에서는 그냥 할 것 svn switch --relocate old_url_base new_url_base
입니다.
git-svn을 사용하여 어떻게 할 수 있습니까?
구성 파일에서 svn url을 변경하는 것만으로는 실패합니다.
답변:
이것은 내 상황을 아주 잘 처리합니다.
https://git.wiki.kernel.org/index.php/GitSvnSwitch
file://
프로토콜을 사용하여 복제했고 프로토콜로 전환하고 싶었습니다 http://
.
url
의 [svn-remote "svn"]
섹션 에서 설정 을 편집하고 .git/config
싶지만 그 자체로는 작동하지 않습니다. 일반적으로 다음 절차를 따라야합니다.
url
설정을 새 이름으로 전환하십시오 .git svn fetch
합니다. 이것은 svn에서 적어도 하나의 새 개정판을 가져와야합니다!url
설정을 원래 URL로 다시 변경하십시오 .git svn rebase -l
하여 로컬 리베이스를 수행합니다 (마지막 가져 오기 작업에서 발생한 변경 사항 포함).url
설정을 다시 새 URL로 변경하십시오 .git svn rebase
다시 작동해야합니다.모험심이 강한 영혼은 시도해 볼 수 --rewrite-root
있습니다.
다음이 정상적으로 작동하는지 확인할 수 있습니다.
svn-remote.svn.rewriteRoot
구성 파일 ( .git/config
) 에이없는 경우 :
git config svn-remote.svn.rewriteRoot <currentRepositoryURL>
svn-remote.svn.rewriteUUID
구성 파일에없는 경우 :
git config svn-remote.svn.rewriteUUID <currentRepositoryUUID>
currentRepositoryUUID
로부터 얻을 수있다 .git/svn/.metadata
.
git config svn-remote.svn.url <newRepositoryURL>
file://
,로 전환 svn+ssh
). 주의 할 점 :이 절차는 "svn에서 적어도 하나의 새 개정판을 가져올"필요가 없습니다. 또한 ./.git/svn/.metadata
after first svn rebase
는 <newRepository>
as를 포함 reposRoot
하지만 이것은 rewrite*
키 를 제거하기에 충분하지 않습니다 .git/config
. 따라서 해당 키는 내가 이해하는 한 영구적으로 보관되어야합니다.
svn+ssh://
하고 있으며 svn-server가 내부 이름을 삭제 .se
하기 .com
위해 도메인을에서 로 변경했습니다 .
불행히도이 답변의 대부분의 링크가 작동하지 않으므로 향후 참조를 위해 git wiki 에서 약간의 정보를 복제 할 것입니다.
이 솔루션은 저에게 효과적이었습니다.
새 도메인 / URL / 경로를 가리 키도록 svn-remote
url
(또는 fetch
경로)를 편집합니다..git/config
실행 git git svn fetch
. 이것은 svn에서 적어도 하나의 새 개정판을 가져와야합니다!
git svn rebase
지금 시도하면 다음 과 같은 오류 메시지가 표시됩니다.
Unable to determine upstream SVN information from working tree history
git svn
가져 오기 전에 최신 커밋이에서 git-svn-id
찾은 경로와 일치하지 않는 이전 경로를 가리키는 사실 로 인해 혼란 스럽기 때문이라고 생각합니다 .git/config
.
해결 방법으로 원래 도메인 / URL / 경로로 다시 변경 svn-remote
url
(또는 fetch
경로)
이제 git svn rebase -l
다시 실행 하여 마지막 가져 오기 작업에서 발생한 변경 사항으로 로컬 리베이스를 수행합니다. 이번에는 것 분명히 있기 때문에, 작업 git svn
사실에 의해 혼동되지 않습니다 git-svn-id
새로운 머리가있는 것을 발견과 일치하지 않습니다 .git/config
.
마지막으로 svn-remote
url
(또는 fetch
경로)를 새 도메인 / URL / 경로로 다시 변경하십시오.
이 시점에서 git svn rebase
다시 작동합니다!
Git svn은 svn URL에 크게 의존합니다. svn에서 가져온 모든 커밋에는git-svn-id
에는 svn URL을 포함하는가 있습니다.
유효한 재배치 전략은 다음을 호출하는 것입니다. git-svn clone
새 저장소 하고 변경 사항을 새 닫기에 병합하는 것입니다. 자세한 절차는 다음 문서를 참조하십시오.
http://www.sanityinc.com/articles/relocating-git-svn-repositories
git filter-branch
블로그 항목 에서 가져온 이 스크립트 는 저에게 효과적이었습니다. 다음과 같이 이전 및 새 저장소 URL을 매개 변수로 제공하십시오.svn switch --relocate
.
스크립트 는 커밋 메시지에서 git filter-branch
Subversion URL을 교체하기 위해 호출 하고 업데이트 하며을 사용하여 메타 데이터를 다시 생성하여 업데이트합니다 . 더 강력한 솔루션 일 수 있지만 이 접근 방식은 대규모 리포지토리의 경우 훨씬 더 빠르게 작동합니다 (시간 대 며칠).git-svn-id
.git/config
git-svn
git svn rebase
git svn clone
filter-branch
#!/bin/sh
# Must be called with two command-line args.
# Example: git-svn-relocate.sh http://old.server https://new.server
if [ $# -ne 2 ]
then
echo "Please invoke this script with two command-line arguments (old and new SVN URLs)."
exit $E_NO_ARGS
fi
# Prepare URLs for regex search and replace.
oldUrl=`echo $1 | awk '{gsub("[\\\.]", "\\\\\\\&");print}'`
newUrl=`echo $2 | awk '{gsub("[\\\&]", "\\\\\\\&");print}'`
filter="sed \"s|^git-svn-id: $oldUrl|git-svn-id: $newUrl|g\""
git filter-branch --msg-filter "$filter" -- --all
sed -i.backup -e "s|$oldUrl|$newUrl|g" .git/config
rm -rf .git/svn
git svn rebase
git_fast_filter
그러나 더 빠르지 만 git-filter-branch
(즉, 몇 시간이 아닌 몇 분) 정신적으로 비슷하게 git_fast_filter
. 그러나 이것은 약간 더 많은 코딩이 필요하며 깔끔한 준비된 솔루션이 없습니다. 과는 대조적으로 이전 저장소에서 새 저장소를 git-filter-branch
만듭니다 . 마지막 SVN 커밋 을 가리키는 것으로 가정합니다 .master
git_fast_filter
Gitorious 저장소에서 합니다.git_fast_filter
기반으로 복제 한 동일한 디렉토리에 Python 스크립트를 만들고 다음을 사용하여 실행 가능한 비트를 설정합니다.chmod +x
. 이전 및 새 저장소 경로를 조정합니다. (대본의 내용도 아래에 붙여 넣습니다.)git init
작업 디렉토리를이 새 저장소로 변경하십시오.다음 파이프를 실행하십시오.
(cd path/to/old/repo && git-fast-export --branches --tags --progress=100) | \
path/to/git_fast_filter/commit_filter.py | git-fast-import
복사 .git/config
및 기타 관련 파일을.git/info
이전 저장소에서 새 저장소로 하십시오.
.git/svn
.확인 git-svn
새로운 버전 번호 매핑 인식
실행 git branch refs/remotes/git-svn master
refs/remotes/git-svn
, consult .git/config
, svn-remote
섹션 과 다르게 호출 될 수 있습니다.을 실행합니다 git svn info
. 이 명령이 중지되면 문제가있는 것입니다. 개정 번호 매핑을 다시 작성해야합니다.
가짜 분기를 제거하면 다음에 refs/remotes/git-svn
의해 다시 생성됩니다.git-svn
git svn rebase
.다음은의 내용입니다 commit_filter.py
. IN_REPO
및 의 값을 OUT_REPO
적절하게 바꿉니다.
#!/usr/bin/python
from git_fast_filter import Commit, FastExportFilter
import re
import sys
IN_REPO = "https://svn.code.sf.net/p/matsim/code"
OUT_REPO = "https://svn.code.sf.net/p/matsim/source"
IN_REPO_RE = re.compile("^git-svn-id: %s" % re.escape(IN_REPO), re.M)
OUT_REPO_RE = "git-svn-id: %s" % OUT_REPO
def my_commit_callback(commit):
commit.message = IN_REPO_RE.sub(OUT_REPO_RE, commit.message)
sys.stderr.write(".")
filter = FastExportFilter(commit_callback = my_commit_callback)
filter.run()
위의 git svn rebase -l
솔루션은 저에게 효과적이지 않았습니다. 나는 그것에 대해 다른 방식으로 가기로 결정했습니다.
old
하고 새 SVN을 git repo에 복제new
old
에new
cd new
git fetch ../old
git tag old FETCH_HEAD
new
위에 Rebase old
(의 뿌리 new
와 끝의 나무가 성공해야old
가 동일 함)
git checkout master
( master
분기가 SVN 헤드를 가리키고 있다고 가정합니다 . 이것은 깨끗한 클론의 경우입니다. 그렇지 않으면 시작하기 전에 dcommit합니다.)git rebase --root --onto old
new
rebase를 고려
git update-ref --no-deref refs/remotes/git-svn master
(복제 방법에 따라 원격 참조를 조정하십시오. 예를 들어 refs/remotes/svn/trunk
)rm -r .git/svn
git svn info
이 질문에 대한 다른 응답을 바탕으로 git-svn 재배치를 처리하는 Ruby 스크립트를 작성했습니다. https://gist.github.com/henderea/6e779b66be3580c9a584 에서 찾을 수 있습니다. .
다른 복사본을 확인하지 않고 재배치를 처리하며, 하나 이상의 분기에 푸시되지 않은 변경 사항이있는 경우 (일반 논리를 위반하기 때문에)도 처리합니다. git filter-branch 답변 (주 논리 용)과 저장소의 한 인스턴스에서 다른 인스턴스로 분기를 복사하는 것에 대한 답변 (푸시되지 않은 변경 사항이있는 분기 복사 용)의 내용을 사용합니다.
나는 이것을 사용하여 작업을 위해 가지고있는 git-svn 저장소를 재배치 했으며이 버전의 스크립트 (수없이 반복되었습니다)가 나를 위해 작동하는 것 같습니다. 초고속은 아니지만 내가 만난 모든 경우를 처리하고 완전히 재배치 된 저장소를 생성하는 것 같습니다.
스크립트는 변경하기 전에 리포지토리의 복사본을 생성하는 옵션을 제공하므로이 옵션을 사용하여 백업을 생성 할 수 있습니다. 분기에 푸시되지 않은 변경 사항이있는 경우 사본을 작성해야합니다.
이 스크립트는 일반적인 MRI Ruby 설치에 포함되지 않은 gem이나 기타 라이브러리를 사용하지 않습니다. MRI에 포함 된 readline 및 fileutils 라이브러리를 사용합니다.
내 스크립트가 다른 사람에게 유용하다는 것이 증명되기를 바랍니다. 스크립트를 자유롭게 변경하십시오.
참고 : 이 스크립트는 OS X 10.10 Yosemite에서 git 2.3.0 / 2.3.1 및 Ruby 2.2.0으로 만 테스트했지만 (내가 사용하는 환경이기 때문에) 다른 환경에서도 작동 할 것으로 예상합니다. 그러나 Windows에 대한 보장은 없습니다.