如何追溯性地将提交添加到Git存储库?

时间:2013-08-11 20:05:01

标签: git git-rebase git-cherry-pick

我正在创建一个模块,将第三方lib移植到另一个平台。我的模块版本与它包装的lib的版本相匹配。

出于这个问题的目的,让我们说lib是版本10,因此我的模块也是版本10.

Git refs看起来像这样:

master === HEAD === v10 (tag)

但是,出于兼容性原因,我还希望创建包装器的版本8和9。

如果我提交v9,它将成为新的HEAD,但我希望HEAD留在v10。我只想通过

选择v9选项
// switch to version 9
git checkout v9

有没有这样做?

注意,我是一个git noob。我听说过变调和樱桃采摘,但我对它们中的任何一个都不太了解。接受的答案将提供解决方案以及解释。

1 个答案:

答案 0 :(得分:4)

问题有点不寻常/不清楚,主要是因为它似乎没有设置在“The Git Way”/查看源代码控制的背景中。 Git中的“Heads”有多个含义......例如,它与SVN中的含义不同。这是我稍后会回到的一点,但是现在,我将尝试解决将以前版本的代码库添加到Git仓库的问题。

如何在Git

中追溯添加提交

您至少有两个选择:

  1. 将以前版本的代码库添加为孤立的单独分支。这不是我推荐的,因为在我的经验中,孤立的分支在您的工作副本之间切换是低效的,可能是因为checkout操作无法访问共同的祖先和类似的东西。
  2. 您可以将以前的版本添加为孤立的分支,但随后在它们之上重新定义最新的v10 / master分支,并添加新标记。
  3. 我建议您使用选项#2,因为它之前已经在Stack Overflow上解决了问题,并且更多的是“The Git Way”来解决这个问题:

    1. git: how to insert a commit as the first, shifting all the others?
    2. Git: how to add commits before first/initial/root commit?
    3. 特别是,我建议您按照这些基本步骤详细解释in this answer

      1. 创建回购的备份克隆:

        git clone original-repo backup-repo
        
      2. 创建一个孤儿分支(这将是您的新根)。

        git checkout --orphan new-master firstCommitOfOldMaster
        
      3. 从孤立分支中删除工作目录文件。

        git rm -rf .
        
      4. 将较早的作品重新投入new-master

      5. 将旧版master重新投放到new-master

        git rebase --onto new-master --root master
        
      6. 验证最终提交是否仍然相同。

        git diff master@{1}
        
      7. 在您将旧主服务器重新绑定到新主服务器之前,或之后,您可以使用lightweight tagannotated tag标记v9分支:

        # Lightweight
        $ git tag "v9"
        
        # Annotated
        $ git tag -a "v9" -m "Tag version 9"
        

        HEAD的说明

        因此Git中的“头”具有多种含义,具体取决于具体情况。在您使用它的上下文中 - 作为提交参考 - HEAD仅表示 您当前已签入工作副本的提交 。它与SVN中的含义不同,即HEAD 不代表存储库中最新的全局提交

        当您在分支机构之间签出或沿着这些分支机构提交时,HEAD将指向您的历史记录中的不同提交(有时是之前的提交),因为您要检查不同的提交到您的工作副本中。参见

        1. What is git HEAD, exactly?
        2. HEAD and ORIG_HEAD in Git
        3. Git中还有另一个使用“head”的上下文:存储库本地的分支通常存储在.git/refs/heads/目录下。在此上下文中,“头”仅表示分支指针/引用,并且是分支的“提示”/最近提交。您可以通过运行git show-ref

          来查看当地回购的分支头/提示
          git show-ref
          35ec88f1c5b319b7ca08f5d3dca3cafdebddecd4 refs/heads/awesome-feature
          ea112e91953e02f9c6dcc7b9470b8bdf0a69a3eb refs/heads/epic-feature
          a9874fd23f67c245fadd23bef449971fa7338755 refs/heads/master
          

          在这里,您可以看到我有3个分支头/提示/引用:master分支,awesome-feature分支和epic-feature分支。在每个分支的左侧,您将看到分支当前指向的完整提交sha,即该分支的最新提交。

          rebase

          的说明

          首先,让我先说你应该学会rebase 。期。我认为它是Git中最基本,最基本,最强大的工具,如果你不使用它,那么你就不会有效地使用Git。因此,要学会以交互方式和非交互方式进行变基。

          除此之外,我不会详细介绍git rebase如何工作,因为有很多在线资源可以解释它(我会列出它们),这个答案已经是非常长。

          但简而言之,rebase允许您以您可能想要的任何方式重写您的历史记录。它需要一组提交,并且 将这些提交的副本重新应用 副本到历史记录中的任何位置。这就是我上面建议的解决方案所做的,它会使用旧的v10历史记录,并在新的v9历史记录之上重新创建它,就像创建历史记录的方式一样。

          Rebase资源

          以下是了解更多关于rebase的优秀资源。请记住,你总是可以创建一个充满.txt文件或任何你想要的Git repo,然后练习分支,变基和合并:

          1. Git Tools - Rewriting History
          2. git-rebase(1) Manual Page
          3. Learn Git Branching,请参阅Interactive Rebase演示。
          4. Code School course Git Real, lesson 6