我有一个包含以下分支的git存储库:
older:
file (with, say, 10 commits)
newer:
file (10 commits from "older" plus 5 new commits)
分支“较新”从分支“较旧”分支为某些点。
我想将两个分支合并为master,将两个版本的“file”作为两个不同的文件,我想保留两者的历史记录:
master:
file-as-seen-in-older (10 commits)
file-as-seen-in-newer (15 commits)
答案 0 :(得分:0)
这是使用git rebase
更改文件名的强大而安全的方法。这将完全适用于您的分支newer
和/或older
与master(或其他分支)分歧,并且之后未从父分支合并新的更改的简单情况 - 删除旧文件名完全来自您的历史记录。
(如果确实发生了这样的合并,那么命令仍然是安全的 - 最终结果是相同的 - 但它可能不会像你想的那样清理你的历史。)
选择要更改文件名的分支。检查该分支。我假设您选择了older
。
$ git checkout older
现在,我们需要找到older
及其父级的合并基础。这是older
与其父级不同的地方,创建了一个新的独立历史。您通常可以通过浏览git log
或gitk
轻松找到它,但我们可以通过简单的命令找到它。 (我假设master
是older
的父级。)
$ git merge-base older master
914b05d90e1de0ff9f89370810888c7f192d65cc
$ git tag base 914b05d
在我的存储库中,git merge-base
输出提交ID 914b05d
。我们使用标记base
标记提交,以便于参考。
现在,在base
$ git rebase --interactive base
在显示的编辑器窗口中,验证它是否列出了旧版本中的每个提交,从它从父版本转移到最近一次提交。
pick
更改为edit
。我们很快就会编辑此提交以重命名该文件。file
的任何内容都需要重新编写。将pick
更改为reword
,让自己有机会重写相应的提交消息。现在,你的rebase将开始! git将检出第一次提交并停止,等待您修改提交。在这里,我们可以移动文件,然后重新开始rebase。
$ git mv file file-from-older
$ git rebase --continue
git将使用您的更改修改提交,然后打开您的编辑器以允许您重新提交提交。将任何对file
的引用更改为file-from-older
。保存文件并退出。
您为reword
标记的任何提交也会出现在您的编辑器中。以相同的方式编辑它们。 (如果您错过标记重新提交的提交,则可以再次进行重新定位)
一旦rebase完成,请使用git log
或gitk
检查结果。观察
older
仍在其父级位于同一位置,即base
。 如果这些事情中的任何一个是不真实的,那么就会出现问题(可能是拼写错误),我们需要撤消提交。我们可以使用git reset --hard older@{1}
轻松完成此操作,这会在rebase发生之前将其重置为旧状态。然后,您可以重复rebase操作,并找出出错的地方。
现在您已验证了rebase的成功,您可以将更改合并到master
或任何地方。如果您想在两个分支中重命名file
,只需重复newer
分支的过程。
最后,您可以将分支合并到master
:
$ git checkout master
$ git merge older newer
任何(不相关的)冲突都应该顺利进行。