如何在分支中重命名文件,合并并在Git中有两个具有历史记录的文件?

时间:2014-06-04 17:26:54

标签: git git-branch

我有一个包含以下分支的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)

1 个答案:

答案 0 :(得分:0)

这是使用git rebase更改文件名的强大而安全的方法。这将完全适用于您的分支newer和/或older与master(或其他分支)分歧,并且之后未从父分支合并新的更改的简单情况 - 删除旧文件名完全来自您的历史记录。

(如果确实发生了这样的合并,那么命令仍然是安全的 - 最终结果是相同的 - 但它可能不会像你想的那样清理你的历史。)

  1. 选择要更改文件名的分支。检查该分支。我假设您选择了older

    $ git checkout older
    
  2. 现在,我们需要找到older及其父级的合并基础。这是older与其父级不同的地方,创建了一个新的独立历史。您通常可以通过浏览git loggitk轻松找到它,但我们可以通过简单的命令找到它。 (我假设masterolder的父级。)

    $ git merge-base older master
    914b05d90e1de0ff9f89370810888c7f192d65cc
    $ git tag base 914b05d
    

    在我的存储库中,git merge-base输出提交ID 914b05d。我们使用标记base标记提交,以便于参考。

  3. 现在,在base

    上进行交互式变基
    $ git rebase --interactive base
    
  4. 在显示的编辑器窗口中,验证它是否列出了旧版本中的每个提交,从它从父版本转移到最近一次提交。

    • 转到第一次提交。
    • 将单词pick更改为edit。我们很快就会编辑此提交以重命名该文件。
    • 现在,向下看其他提交。在提交消息中提及名称file的任何内容都需要重新编写。将pick更改为reword,让自己有机会重写相应的提交消息。
    • 保存文件并退出。
  5. 现在,你的rebase将开始! git将检出第一次提交并停止,等待您修改提交。在这里,我们可以移动文件,然后重新开始rebase。

     $ git mv file file-from-older
     $ git rebase --continue
    

    git将使用您的更改修改提交,然后打开您的编辑器以允许您重新提交提交。将任何对file的引用更改为file-from-older。保存文件并退出。

  6. 您为reword标记的任何提交也会出现在您的编辑器中。以相同的方式编辑它们。 (如果您错过标记重新提交的提交,则可以再次进行重新定位)

  7. 一旦rebase完成,请使用git loggitk检查结果。观察

    • 工作树中不存在原始文件名
    • 或在您的历史记录中,
    • older仍在其父级位于同一位置,即base

    如果这些事情中的任何一个是不真实的,那么就会出现问题(可能是拼写错误),我们需要撤消提交。我们可以使用git reset --hard older@{1}轻松完成此操作,这会在rebase发生之前将其重置为旧状态。然后,您可以重复rebase操作,并找出出错的地方。

  8. 现在您已验证了rebase的成功,您可以将更改合并到master或任何地方。如果您想在两个分支中重命名file,只需重复newer分支的过程。

  9. 最后,您可以将分支合并到master

    $ git checkout master
    $ git merge older newer
    

    任何(不相关的)冲突都应该顺利进行。