2016-09-30 20 views
12

我有一个Git repo,它是从另一个Git仓库中克隆出来的,它是一个巨型SVN仓库的克隆。我们可以从SVN更新其他Git仓库,并将其从SVN提交给SVN,但是与其他用户进行交易。如何告诉Git两个提交在一个不相交的历史中实际上是相同的?

我想用我自己的用户直接发布我的本地提交到SVN仓库。

这就是我想:我手动创建git-svn分支,加入这.git/config

[branch "master"] 
[svn-remote "svn"] 
     url = https://url/to/svn/trunk/repo_name 
     fetch = :refs/remotes/git-svn 

然后git svn fetch,下载32K的提交。

但我结束了两个不相交的历史:

  1. 一个从SVN:
    1. 在提交674c35a表示SVN回购协议的原始克隆点的状态开始。
    2. 分支master始终与SVN同步(通过其他Git仓库)。
    3. 分支dev有我们目前的进展,应该合并到master(通常是压扁),然后再回到SVN回购。
  2. 一个用于SVN回购的:
    1. 开始与适当的初始提交。
    2. 它有30k +提交。
    3. Git最初从SVN [fb1b9c7]克隆的提交(但只有前一个提交的差异,而不是整个回购作为开始提交)。
    4. 然后相同的承诺(100+)应该是共同的git/origin/master

我怎么能告诉混帐的起点提交(674c35a)实际上是相同的SVN提交(fb1b9c7)?所以Git可以以某种方式理解克隆之后master的提交实际上与git-svn相同吗?

我试图用--onto进行重定位,正如here所解释的那样,但那不是我真正想要的(提交不在分支的顶端)。

+3

Git + SVN ...有什么意义? – Hackerman

+0

SVN对于这个项目是强制性的,但我的团队想要使用git(分布式,代码审查,分支等) – RSFalcon7

回答

0

你的历史可能看起来是这样的:

*--*--*--fb1b9c7--*--*--* [git-svn] (version of master from SVN) 

     674c35a--*--*--* [master] (version of master from Git) 
         \ 
          *--*--*--* [dev] 

它看起来就像你有两个问题:你的提交历史不包含30K +从完整SVN历史承诺,并dev是基于关闭(不完整)Git历史,而不是SVN版本。

由于fb1b9c7 == 674c35a,你应该能够做到:

git rebase --onto git-svn master dev 

我的实验表明,git rebase不关心目标分支(git-svn)不具有相同的历史为基础分支(master)。 SVN只存储差异也没有关系,因为git-svn会在提取期间将这些差异转换为真正的Git提交。

由于历史包含相同的内容,你甚至应该能够做到:

git checkout dev 
git rebase git-svn 

之后,你可以删除master,让这棵树让垃圾收集后。 (如果您还需要一个单独master分支,然后删除原始master后做git checkout -b master git-svn

当你说:

(在提交不在分支的顶部)

我假设你指的是提交fb1b9c7674c35a。但是,这些提交埋在历史中并不重要,因为我们将选择一个(fb1b9c7)来使用,并让另一个被垃圾收集,如上所述。

0

如果您想用另一个提交来替换一个提交,只需使用git replace,如git replace 674c35a fb1b9c7
如果你想永久使用,请使用git rebase

1

我相信我有,应此在我的博客文章Grafting History with Git工作,这与网站遵守规则的目的,我会在这里总结的方法:

当前状态:

  • 两个混帐

      :具有散光的历史,但一个起源

    目标状态回购

  • 一个git仓库有两个分支表示这些分歧的历史

  • 双方历史转换成的Git分支(我想你已经有了这个)
  • 通过比较日志查找分歧点并看到当哈希改变
    • 获取树ID的列表,并使用git log --reverse --format="%T %H"提交的IDS上的每个分支并保存此到文件
    • 比较清单,看看那里的树哈希发散(我用的比较差异程序,可以做栏目,你可以只用awk和DIFF虽然)
  • 退房发散的点针对回购分支,并作出新的分支
  • 获取来自源中的所有对象到目标
  • 对于原始出处每个修订,目标创建一个新的修订版
    • 是的树的结账国外修改使用git read-tree -um $TREEID
    • 用途使用git commit --reuse-message $ORIGINAL_COMMIT

或者......猫你的树-ID列表+提交-ID到这个脚本的原始提交信息。

 
#!/bin/bash 
# graft script 
while read TREE COMMIT 
do 
git read-tree -um $TREE 
git commit --reuse-message $COMMIT 
done 
相关问题