我正在创建一个模块,将第三方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。我听说过变调和樱桃采摘,但我对它们中的任何一个都不太了解。接受的答案将提供解决方案以及解释。
答案 0 :(得分:4)
问题有点不寻常/不清楚,主要是因为它似乎没有设置在“The Git Way”/查看源代码控制的背景中。 Git中的“Heads”有多个含义......例如,它与SVN中的含义不同。这是我稍后会回到的一点,但是现在,我将尝试解决将以前版本的代码库添加到Git仓库的问题。
您至少有两个选择:
checkout
操作无法访问共同的祖先和类似的东西。v10
/ master
分支,并添加新标记。我建议您使用选项#2,因为它之前已经在Stack Overflow上解决了问题,并且更多的是“The Git Way”来解决这个问题:
特别是,我建议您按照这些基本步骤详细解释in this answer:
创建回购的备份克隆:
git clone original-repo backup-repo
创建一个孤儿分支(这将是您的新根)。
git checkout --orphan new-master firstCommitOfOldMaster
从孤立分支中删除工作目录文件。
git rm -rf .
将较早的作品重新投入new-master
。
将旧版master
重新投放到new-master
。
git rebase --onto new-master --root master
验证最终提交是否仍然相同。
git diff master@{1}
在您将旧主服务器重新绑定到新主服务器之前,或之后,您可以使用lightweight tag或annotated tag标记v9
分支:
# Lightweight
$ git tag "v9"
# Annotated
$ git tag -a "v9" -m "Tag version 9"
因此Git中的“头”具有多种含义,具体取决于具体情况。在您使用它的上下文中 - 作为提交参考 - HEAD
仅表示 您当前已签入工作副本的提交 。它与SVN中的含义不同,即HEAD
不代表存储库中最新的全局提交 。
当您在分支机构之间签出或沿着这些分支机构提交时,HEAD
将指向您的历史记录中的不同提交(有时是之前的提交),因为您要检查不同的提交到您的工作副本中。参见
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
。期。我认为它是Git中最基本,最基本,最强大的工具,如果你不使用它,那么你就不会有效地使用Git。因此,要学会以交互方式和非交互方式进行变基。
除此之外,我不会详细介绍git rebase
如何工作,因为有很多在线资源可以解释它(我会列出它们),这个答案已经是非常长。
但简而言之,rebase允许您以您可能想要的任何方式重写您的历史记录。它需要一组提交,并且 将这些提交的副本重新应用 副本到历史记录中的任何位置。这就是我上面建议的解决方案所做的,它会使用旧的v10
历史记录,并在新的v9
历史记录之上重新创建它,就像创建历史记录的方式一样。
以下是了解更多关于rebase的优秀资源。请记住,你总是可以创建一个充满.txt
文件或任何你想要的Git repo,然后练习分支,变基和合并: