我通过 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
以执行本地 rebase(使用最后一次 fetch 操作中的更改)。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>
不幸的是,这些答案中的大多数链接都不起作用,所以我将从git wiki复制一些信息以供将来参考。
这个解决方案对我有用:
编辑svn-remote
url
(或fetch
路径).git/config
以指向新的域/url/路径
运行 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
作为一种解决方法,将svn-remote
url
(或fetch
路径)更改回原始域/url/路径
现在git svn rebase -l
再次运行以使用最后一次 fetch 操作中的更改进行本地 rebase。这一次它会起作用,显然是因为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
该脚本取自博客条目,对我有用。提供新旧 repo URL 作为参数,就像 for 一样svn switch --relocate
。
该脚本调用git filter-branch
以替换git-svn-id
提交消息中的 Subversion URL,更新.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
的 repo创建一个新的repo 。假设指向最后的 SVN 提交。master
git_fast_filter
从 Gitorious 仓库克隆。git_fast_filter
根据此 Gist在克隆的同一目录中创建一个 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
、 咨询.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 存储库中new
old
_new
cd new
git fetch ../old
git tag old FETCH_HEAD
new
在顶部old
(应该成功,因为根部new
和尖端的树old
是相同的)
git checkout master
(假设master
分支指向 SVN 头部。干净的克隆就是这种情况;否则在开始之前 dcommit。)git rebase --root --onto old
new
以考虑变基
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 答案(用于主要逻辑)和关于将分支从一个 repo 实例复制到另一个实例的答案(用于复制具有未推送更改的分支)中的内容。
我一直在使用它来重新定位我工作的一堆 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。