8

我们已将大部分代码库从单一svn存储库移至一组git存储库。由于各种原因,一些工作(在现场部署的旧版本项目上)必须在旧svn分支中继续,在它们被移动到git并从 subversion 中删除之后trunk

我刚刚在一个svn分支上做了一些这样的工作,并通过执行以下操作将存储库中的更改重新应用到svn存储git库中:

cd <common_svn_commit_root>
svn diff -r 12344:12345 > ~/r12345.diff
gedit ~/r12345.diff
cd <common_git_commit_root>
git apply ~/r12345.diff

但是对于每次svn提交都执行此操作相当麻烦,尤其是在gedit步骤中,我必须手动将svn路径转换为git路径(通常通过在顶级目录名称前加上前缀)。

尝试到目前为止提出的一些选项的一个问题是旧svn回购和新git回购的结构不同。这是我必须编辑补丁文件的原因之一。

旧的目录结构是

svn
    configurations
        blah
        mine
        blam
    plugins
        foo
        core
        mine
        bar

鉴于新结构是

svn
    plugins
        bar
git
    my_git
        my_config
        plugins
            mine
    core_git
        plugins
            core
    foo_git
        plugins
            foo

我真的很想知道是否有更简单的方法来做到这一点,并了解这种情况下的最佳做法是什么。

4

3 回答 3

2

您可以使用 git svn 将您的 git repo 与 svn 的更改同步。

git svn --authors-file=authors.txt clone https://repo/svn/reponame/trunk reponame-git-svn

# if something aborts:
cd reponame-git-svn
git svn fetch

# create a new branch
git checkout -b dvcs

git remote add dvcs-svn https://repo/git/reponame.git

这将使您在 git 分支中获得 svn 源代码。从 svn 同步到 git:

git checkout master
# get the changes from svn
git svn rebase
git checkout dvcs

# apply the changes from svn
git rebase master

# fetch the changes from git repo to the local repo
git fetch dvcs-svn

# apply the changes from git repo to the branch dvcs
git rebase dvcs-svn/master

# push all changes back to git repo
git push dvcs-svn dvcs:master

与合并相比,我们在变基方面有更好的经验。希望这对你也有用。

于 2012-07-13T09:51:19.710 回答
1

没有什么可以禁止您在源代码树中拥有gitsvn共存。这使得提交的选择比在不同的源树之间打补丁和复制要容易得多。

  1. svn checkout您已经在 git 中的分支和修订。
  2. git clone以及git checkout与步骤 1 中相同的源树状态(如果存储库非常庞大,则此处可能存在涉及裸存储库的捷径 - 您只需要.git/存储库数据)。
  3. .git/目录复制到您的 svn checkout 根目录中。
  4. 通过添加到您的文件中来告诉git忽略颠覆元数据。.svn.gitignore
  5. 如果可以的话,你也可以跑去svn propset svn:ignore dirname .git告诉svn忽略 .git 导演。

现在有很多方法可以导出提交。如果您想选择提交,这是一种方法r12345(假设如上所述,svn 和 git 都是最新的):

  1. 创建并签出临时 git 分支(git checkout -b throway-branch);
  2. 在所需的 svn 提交下获得一个svn co -r12344
  3. 将这些更改(将被忽略)提交到您的git存储库中,如下git add -A所示git commit -m "SVN -r12344 (uninteresting stuff)"
  4. 签出有趣的 svn commit by svn co -r12345and
  5. 将其保存到您的 git 存储库:(git add -A && git commit --date <svn commit date> 使用此处--date <svn commit date>假设您要保留 svn 提交日期)。
  6. 现在,您可以git cherry-pick对您计划向世界发布的实际分支进行最后一次有意义的提交。

当我曾经在git本地使用时必须处理上游颠覆存储库时,这种双存储库设置对我来说非常有效。我最终制作了一些脚本来简化这一切。例如,对您而言,脚本可以获取 svn 提交日期和消息,并为您创建一个具有相同日期和消息的 git 提交(将 svn 修订号添加到消息中以与 svn 提交匹配)。

或者,您可以像您在帖子中提到的那样使用svn diff --gitgit am,这更方便,因为您不需要在不同目录之间移动补丁,并且您可以随时将您的单个工作目录与您的svn checkout当前目录进行比较git commit

我不git svn知道这是否对您有用。

于 2012-07-10T09:44:06.750 回答
1

假设您的源的目录结构保持不变,我建议您将远程添加到旧的 SVN 分支:

$ git config --add svn-remote.svn-branch.url http://my.svn.server/project/branches/my-branch
$ git config --add svn-remote.svn-branch.fetch :refs/remotes/old-svn-branch

这样,您将能够跟踪旧 SVN 分支和本地分支中全新 Git 服务器上的更改,并使用git-cherry-pick在 Git 服务器分支上应用包含修复的提交。

编辑

Git 会跟踪文件移动。

我自己没有尝试过,但是如果您克隆 SVN 存储库,然后在本地移动目录以匹配您的新 Git 服务器结构,cherry-pick 合并可以将其应用于移动的文件。

它已经为我工作了一些文件,但也许有一些限制。这绝对值得一试。

于 2012-07-13T14:40:05.437 回答