在我的当前项目中,我遇到了一个有趣的 git 问题:
自项目开始以来,更改一直存储在客户端远程服务器上的 SVN 存储库中。在开发进展中,我开始并行使用本地 git 存储库,以便更轻松地测试新功能而不破坏当前版本。可惜的是,git-svn 无法工作,这会让我的生活更加轻松。
现在我的客户转移到了另一个服务器,并在此过程中将 SVN 存储库移动到 git(使用 git2svn)。
虽然我总体上对此感到高兴,但是我现在有两个问题:
1.由于我正在处理一个较大的功能,因此我已经七天没有提交到 SVN。我在本地功能分支上工作并将其备份到本地服务器,但现在是远程 git 存储库的 SVN 副本与我的本地版本相比已经过时了。
2.由于远程 repo 是由 git2svn 创建的,它与我的 repo 完全不同(消息:警告:Repo 没有共同的提交),这使得标准合并变得不可能。
现在我的期望目标是:
1.合并两个存储库,使我的当前版本成为检查的版本,并再次推送到 origin。
2.保留两个存储库的历史记录(来自 SVN 的旧记录以及来自我的 git 的最近 7 天的记录)。
我尝试过的方法:
我尝试克隆远程 git(从 svn),并将我的本地 repo 合并到其中。我有 153 个冲突,"changed in both versions"。接受 "theirs"(即我最新的开发)会丢失文件的历史记录(它只是从我的平行 git repo 初始化开始)。
我的想法是,我可以为最近 7 天的每个提交创建一个补丁,并使用相应的提交消息(即 "手动合并")将其提交到新存储库中。在编写脚本之前,我想询问是否有内置的方法来执行此操作。
先感谢您!
更新:我尝试了许多解决方案,但每个解决方案都让我失望。基本问题是我现在有两个分支,没有一个共同的提交,但具有相同的树结构。这导致合并冲突,例如 "added in both branches",因为 git 不知道“myFile.txt”和“myFile.txt”是相同的并且可以合并。相反,我必须手动合并那一周中更改的 150 个文件,这是我无法也不会做的。
到目前为止,我最好的方法是为更改创建一个补丁,并将其应用于 "new" 存储库。但由于树不匹配,我还没有找到一个不会失败的补丁。我还需要找到正确的提交来开始补丁信息。
解决方案:
TL;DR:没有完美的解决方案,只能在两种选择中取其一。
1. 你可以使用这里描述的合并方法,但它会用你的side-git(即你的其他repo)替换SVN的单个文件历史记录(如果你的其他repo只有2个月,你就无法查找为什么这个文件3个月前被更改)。但是积极的一面是,你仍然可以通过git log在全局历史记录中合并你的更改。
2. 我最终采用的另一种选择是将“新”(即SVN)repo中的所有文件复制并替换为我的git repo的当前状态(通过
自项目开始以来,更改一直存储在客户端远程服务器上的 SVN 存储库中。在开发进展中,我开始并行使用本地 git 存储库,以便更轻松地测试新功能而不破坏当前版本。可惜的是,git-svn 无法工作,这会让我的生活更加轻松。
现在我的客户转移到了另一个服务器,并在此过程中将 SVN 存储库移动到 git(使用 git2svn)。
虽然我总体上对此感到高兴,但是我现在有两个问题:
1.由于我正在处理一个较大的功能,因此我已经七天没有提交到 SVN。我在本地功能分支上工作并将其备份到本地服务器,但现在是远程 git 存储库的 SVN 副本与我的本地版本相比已经过时了。
2.由于远程 repo 是由 git2svn 创建的,它与我的 repo 完全不同(消息:警告:Repo 没有共同的提交),这使得标准合并变得不可能。
现在我的期望目标是:
1.合并两个存储库,使我的当前版本成为检查的版本,并再次推送到 origin。
2.保留两个存储库的历史记录(来自 SVN 的旧记录以及来自我的 git 的最近 7 天的记录)。
我尝试过的方法:
我尝试克隆远程 git(从 svn),并将我的本地 repo 合并到其中。我有 153 个冲突,"changed in both versions"。接受 "theirs"(即我最新的开发)会丢失文件的历史记录(它只是从我的平行 git repo 初始化开始)。
我的想法是,我可以为最近 7 天的每个提交创建一个补丁,并使用相应的提交消息(即 "手动合并")将其提交到新存储库中。在编写脚本之前,我想询问是否有内置的方法来执行此操作。
先感谢您!
更新:我尝试了许多解决方案,但每个解决方案都让我失望。基本问题是我现在有两个分支,没有一个共同的提交,但具有相同的树结构。这导致合并冲突,例如 "added in both branches",因为 git 不知道“myFile.txt”和“myFile.txt”是相同的并且可以合并。相反,我必须手动合并那一周中更改的 150 个文件,这是我无法也不会做的。
到目前为止,我最好的方法是为更改创建一个补丁,并将其应用于 "new" 存储库。但由于树不匹配,我还没有找到一个不会失败的补丁。我还需要找到正确的提交来开始补丁信息。
解决方案:
TL;DR:没有完美的解决方案,只能在两种选择中取其一。
1. 你可以使用这里描述的合并方法,但它会用你的side-git(即你的其他repo)替换SVN的单个文件历史记录(如果你的其他repo只有2个月,你就无法查找为什么这个文件3个月前被更改)。但是积极的一面是,你仍然可以通过git log在全局历史记录中合并你的更改。
2. 我最终采用的另一种选择是将“新”(即SVN)repo中的所有文件复制并替换为我的git repo的当前状态(通过
cp -vru
,但省略.git
文件夹和所有生成的文件)。这让我失去了一周的历史记录,但仍然让我回溯到项目开始之前的过去,这是我喜欢的。
为了减轻这种损失的痛苦,我使用git log --date=short --pretty="format:%cd - %s" --name-status
创建了一个详细的提交消息摘要,这至少给了我一个机会返回到这个条目并查看带有描述的消息。
但是,这对于文件删除是不起作用的,而且你也不知道哪个更改实际上属于巨大的提交消息的哪个部分。
mine
存储库的分支mine-master
,然后(2)运行git rebase master mine-master
将mine
的工作重放在master
中保留的工作之上。 - JJD