将两个不同的git存储库组合在一起而不丢失任何一个历史记录

将两个不同的git存储库组合在一起而不丢失任何一个历史记录,git,Git,在我当前的项目中,我在git方面面临一个有趣的问题: 自项目开始以来,更改存储在我的客户端的远程服务器上的SVN存储库中。在开发过程中,我开始并行使用本地git存储库,以便在不破坏当前版本的情况下更轻松地测试新功能。不幸的是,git svn无法工作,这会让我的生活更轻松 现在,我的客户机切换到另一台服务器,在此过程中,他们将SVN repo移动到git(使用git2svn) 虽然总体上我对此感到高兴,但我现在有两个问题: 因为我开发了一个更大的功能,所以我有7天没有向SVN承诺。我在本地功能分支

在我当前的项目中,我在git方面面临一个有趣的问题:

自项目开始以来,更改存储在我的客户端的远程服务器上的SVN存储库中。在开发过程中,我开始并行使用本地git存储库,以便在不破坏当前版本的情况下更轻松地测试新功能。不幸的是,git svn无法工作,这会让我的生活更轻松

现在,我的客户机切换到另一台服务器,在此过程中,他们将SVN repo移动到git(使用git2svn)

虽然总体上我对此感到高兴,但我现在有两个问题

  • 因为我开发了一个更大的功能,所以我有7天没有向SVN承诺。我在本地功能分支工作,并将其备份到本地服务器,但SVN副本(现在是远程git repo)与本地版本相比已经过时

  • 由于远程repo是由git2svn创建的,因此它与我自己的repo完全不同(消息:警告:repo没有公共提交)-这使得标准合并不可能

  • 现在,我的期望目标是:

  • 合并两个回购协议,使我的当前版本成为签入版本,并再次推送到原始版本

  • 保留两次回购的历史记录(SVN的旧回购以及git最近7天的回购)

  • 我到目前为止所做的尝试

    我试图克隆远程git(来自svn)并将本地回购合并到其中。我得到了153个与“在两个版本中都更改”的冲突。接受“他们的”(即我的最新开发)会丢失文件的历史记录(它只是从我的并行git repo初始化开始)

    我的想法是,我可以为过去7天的每次提交创建一个补丁,并使用相应的提交消息(即“手动合并”)将其提交到新的repo中。在编写脚本之前,我想问一下是否有一种内置的方法来实现这一点

    提前谢谢

    更新:我尝试了许多解决方案,但都失败了。基本问题是,我现在有两个分支,它们不是单一的公共提交,而是相同的树结构。这会导致合并冲突,如“在两个分支中添加”,因为git不知道
    myFile.txt“和
    myFile.txt”是相同的,可以合并。取而代之的是,我必须手动合并我在那个星期更改的150个文件——我不能也不会这样做

    到目前为止,我最好的方法是为这些变化创建一个补丁,并将其应用于“新”回购协议。但我并没有抽出时间来创建一个不会因为树不匹配而失败的补丁。我还没有找到正确的提交开始补丁信息

    决议 TL;医生:没有。你可以在较小的邪恶之间做出选择

  • 您可以使用,但它会将SVN中的单个文件历史记录替换为您的git中的文件历史记录(即,如果您的另一个回购协议只有2个月,您无法查找此文件在3个月前更改的原因)。但从积极的一面来看,您仍然可以通过git日志将您的更改合并到全球历史中

  • 我最后的另一个选择是复制“新”(又名SVN)repo中的所有文件,并将其替换为我的git repo的当前状态(通过
    cp-vru
    ,但省略
    .git
    -文件夹和所有生成的文件)。这让我失去了一周的历史价值,但仍然让我回顾过去,直到我喜欢的项目开始。 为了减轻这一损失带来的痛苦,我在提交消息中使用
    git log--date=short--pretty=“format:%cd-%s”--name status
    编制了一份我所做工作的详细摘要,这至少让我有机会返回到此条目并查看带有说明的消息。 但是,这当然不适用于文件删除,并且您无法知道哪个更改实际上属于biiiig提交消息的哪个部分


  • 如果我理解正确,你会遇到这样的情况:

    remote repo:
    A - B
    
    your repo
    C - D - E - F
    
    其中,commit A实际上与C相同,commit B与D相同(关于包含的文件)。我相信,可能有效的方法是通过执行以下操作,在最新的远程提交上对您的工作进行重定

    git rebase --onto B D
    
    这会将您的提交从D带到头部(例如F),并将它们作为补丁应用到B,从而导致:

    A - B - E' - F'
    

    这应该与您的本地更改相同,并且可以方便地推送到远程存储库。

    我刚刚用我的存储库测试了这一点。我创建了一个新的克隆,它代表您客户的新存储库。然后我将旧版本的内容复制到一个新文件夹中,并在其中初始化了一个存储库。我添加了内容,并做出了一些承诺

    这样,我有两个没有公共提交的存储库

    现在,在新的存储库中,我添加了我的副本(在下面:
    mine
    )作为远程文件,并获取了它的内容。然后我向我的主人借了一个新的分支:

    git checkout -b new mine/master
    
    因此,我可以从这个分支访问我的单独存储库的所有历史记录。接下来,我使用递归合并策略将更新后的主机合并到我的分支中,但倾向于对冲突进行(新)更改:

    git merge master -s recursive -Xours
    
    这将自动合并所有内容,如果发生冲突,它将通过使用我们的版本自动解决这些问题,从而有效地丢弃master中的更改


    因此,您应该得到一个合并的分支,并且两个存储库中的所有历史记录仍然存在。

    Hmmm,感谢您的快速回答,但这不起作用。我确实
    git-rebase——在newgitrepo/master myfeaturebranch上
    ,但是现在featurebranch的历史在这个分支中不再可见了。我是从错误的方向做的吗?尝试将最新的特性更改引入newgitrepo不是更好吗?因为这将与push兼容。
    rebase
    的参数应该是第一个com