Programing

git-svn :`svn switch --relocate`와 동등한 것은 무엇입니까?

lottogame 2020. 9. 14. 21:35
반응형

git-svn :`svn switch --relocate`와 동등한 것은 무엇입니까?


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싶지만 그 자체로는 작동하지 않습니다. 일반적으로 다음 절차를 따라야합니다.

  1. svn-remote url설정을 새 이름으로 전환하십시오 .
  2. 을 실행 git svn fetch합니다. 이것은 svn에서 적어도 하나의 새 개정판을 가져와야합니다!
  3. svn-remote url설정을 원래 URL로 다시 변경하십시오 .
  4. 실행 git svn rebase -l하여 로컬 리베이스를 수행합니다 (마지막 페치 작업에서 변경된 사항 포함).
  5. svn-remote url설정을 다시 새 URL로 변경하십시오 .
  6. 이제 git svn rebase다시 작동해야합니다.

모험심이 강한 영혼은 시도해 볼 수 --rewrite-root있습니다.


다음이 제대로 작동하는지 확인할 수 있습니다.

  1. svn-remote.svn.rewriteRoot구성 파일 ( .git/config) 에이없는 경우 :

    git config svn-remote.svn.rewriteRoot <currentRepositoryURL>
    
  2. svn-remote.svn.rewriteUUID구성 파일에없는 경우 :

    git config svn-remote.svn.rewriteUUID <currentRepositoryUUID>
    

    currentRepositoryUUID로부터 얻을 수있다 .git/svn/.metadata.

  3. git config svn-remote.svn.url <newRepositoryURL>


불행히도이 답변의 대부분의 링크가 작동하지 않으므로 향후 참조를 위해 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

This script, taken from a blog entry, has worked for me. Supply old and new repo URL as parameter, just like for svn switch --relocate.

The script calls git filter-branch to replace Subversion URLs in the git-svn-id in the commit messages, updates .git/config, and also updates git-svn metadata by recreating it using git svn rebase. While git svn clone might be the more robust solution, the filter-branch approach works much faster for huge repositories (hours vs. days).

#!/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

Yet faster than git-filter-branch (i.e., minutes instead of hours), but similar in spirit, is to use git_fast_filter. However, this requires a bit more coding, and no neat ready-packed solution exists. In contrast to git-filter-branch, this will create a new repo from an old one. It is assumed that master points to the last SVN commit.

  1. Clone git_fast_filter from the Gitorious repo.
  2. Create a Python script in the same directory where you cloned git_fast_filter based on this Gist, set the executable bit using chmod +x. Adapt old and new repository paths. (Contents of the script are pasted below, too.)
  3. Initialize a new target repository using git init, change working directory to this new repo.
  4. Execute the following pipe:

    (cd path/to/old/repo && git-fast-export --branches --tags --progress=100) | \
        path/to/git_fast_filter/commit_filter.py | git-fast-import
    
  5. Copy .git/config, and perhaps other relevant files in .git/info from the old repo to the new repo.

  6. Remove .git/svn.
  7. Make git-svn aware of the new revision number mapping

    1. Execute git branch refs/remotes/git-svn master

      • Your git-svn remotes might be called different than refs/remotes/git-svn, consult .git/config, svn-remote sections
    2. Execute git svn info. If this command freezes, something's wrong. It should rebuild the revision number mapping.

    3. Remove the fake branch refs/remotes/git-svn, it will be recreated by git-svn

  8. Synchronize by calling git svn rebase.

Below are the contents of commit_filter.py, replace the values of IN_REPO and OUT_REPO as appropriate:

#!/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()

The above git svn rebase -l solution didn't work for me. I decided to go about it a different way:

  1. Clone old SVN repo into git repo old and new SVN into git repo new
  2. Fetch old into new
    • cd new
    • git fetch ../old
    • git tag old FETCH_HEAD
  3. Rebase new on top of old (should succeed because the trees in the root of new and the tip of old are identical)
    • git checkout master (Assumes that the master branch is pointing at the SVN head. This will be the case with a clean clone; otherwise dcommit before you start.)
    • git rebase --root --onto old
  4. Rebuild the git-svn metadata of new to account for the rebase
    • git update-ref --no-deref refs/remotes/git-svn master (adjust the remote ref depending on how you cloned, e.g. it could be refs/remotes/svn/trunk)
    • rm -r .git/svn
    • git svn info

Based off of some of the other responses to this question, I have come up with a Ruby script that handles the git-svn relocating. You can find it at https://gist.github.com/henderea/6e779b66be3580c9a584.

It handles the relocate without checking out another copy, and it even handles the case where there are un-pushed changes in one or more branches (since that breaks the regular logic). It uses stuff from the git filter-branch answer (for the main logic) and the answer about copying branches from one instance of the repo to another (for copying branches with un-pushed changes).

I've been using this to relocate a bunch of git-svn repos that I have for work, and this version of the script (I've been through countless iterations) seems to work for me. It isn't super-fast, but it does seem to handle all of the cases I've encountered and result in a fully-relocated repo.

The script gives you the option to create a copy of the repo before making any changes, so you can use this option to create a backup. Creating a copy is required if you have un-pushed changes in any branches.

The script does not use any gems or other libraries not included in the normal MRI Ruby installation. It does use the readline and fileutils libraries included in MRI.

Hopefully my script will prove useful to someone else. Feel free to make changes to the script.

NOTE: I've only tested this script with git 2.3.0/2.3.1 and Ruby 2.2.0 on OS X 10.10 Yosemite (since that's the environment I use), but I would expect it to work on other environments as well. No guarantees about Windows, though.

참고URL : https://stackoverflow.com/questions/268736/git-svn-whats-the-equivalent-to-svn-switch-relocate

반응형