0

我正在创建一个将第三方库移植到另一个平台的模块。我的模块的版本与它包装的 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。我听说过变基和樱桃采摘,但我对它们中的任何一个都不太了解。接受的答案将提供解决方案和解释。

4

1 回答 1

4

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

如何在 Git 中追溯添加提交

你至少有两个选择:

  1. 将以前版本的代码库添加为孤立的独立分支。这不是我推荐的,因为根据我的经验,孤立的分支在你的工作副本中切换的效率很低,可能是因为该checkout操作无法访问共同的祖先和类似的东西。
  2. 您可以将以前的版本添加为孤立的分支,然后在它们之上重新设置最新的v10/分支,并添加新标签。master

我建议你使用选项#2,因为这是一个在 Stack Overflow 上已经解决过的问题,而且它更像是“The Git Way”来解决这个问题:

  1. git:如何插入一个提交作为第一个,转移所有其他的?
  2. Git:如何在第一次/初始/根提交之前添加提交?)

特别是,我建议您遵循我在此答案中详细解释的这些基本步骤:

  1. 创建您的存储库的备份克隆:

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

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

    git rm -rf .
    
  4. 将较早的工作重新提交到new-master.

  5. 将旧变基masternew-master.

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

    git diff master@{1}
    

在将旧的 master 重新定位到新的 master 之前,或者之后,您可以使用轻量级标签或带注释的标签v9来标记您的分支:

# Lightweight
$ git tag "v9"

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

HEAD的解释

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

当您在分支之间签出或沿这些分支提交时,HEAD将指向您历史记录中的不同提交(有时是以前的提交),因为您正在将不同的提交签出到您的工作副本中。看

  1. git HEAD 到底是什么?.
  2. Git 中的 HEAD 和 ORIG_HEAD

在 Git 中还有另一个使用“heads”的上下文:存储库本地的分支通常存储在.git/refs/heads/目录下。在这种情况下,“heads”仅表示分支指针/引用,并且是分支的“提示”/最近提交。您可以通过运行查看本地 repo 的分支头/提示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. 时期。我认为它是 Git 中最基本、最重要和最强大的工具,如果你不使用它,那么你就没有有效地使用 Git。因此,学会以交互方式和非交互方式进行变基。

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

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

变基资源

这里是了解更多关于 rebase 的优秀资源。请记住,您始终可以创建一个包含文件或任何您想要的东西的练习 Git存储库.txt,然后练习分支、变基和合并:

  1. Git 工具 - 重写历史
  2. git-rebase(1) 手册页
  3. 学习 Git 分支,请参阅 Interactive Rebase 演示。
  4. Code School 课程 Git Real,第 6 课
于 2013-08-11T20:47:16.627 回答