我正在处理一个包含多个子模块的足够大的仓库。为确保我们在CI过程中处于正确状态,我们启动子模块
$ git submodule init
$ git submodule sync
$ git submodule update --force
打印出类似的内容,
Synchronizing submodule url for 'android/public'
Synchronizing submodule url for 'ios/public'
...
Submodule path 'android/public': checked out 'asdf1234'
Submodule path 'ios/public': checked out 'bsdf2345'
如果我们然后检查几个不同的分支,如果我们再运行
$ for platform in android ios
$ do
$ (cd $platform/public; git fetch --all; git checkout origin/master)
$ done
并使用git branch
检查这些文件夹,他们都说(HEAD detached at origin/master)
。
但是,如果我们重做顶部的子模块初始化,并运行
$ for platform in android ios
$ do
$ (cd $platform/public; git fetch --all; git reset --hard origin/master; git checkout origin/master)
$ done
然后使用git branch
再次检查这些内容,它们会显示为(HEAD detached at <some SHA>)
。
这是我们的CI中的遗留程序,因此可以更改,但我仍然想知道为什么运行git checkout origin/master
不会始终导致git branch
显示在origin/master
分离的HEAD。
答案 0 :(得分:3)
“detached at”字符串仅仅是为了提供信息。较旧版本的Git仅使用 哈希ID,您只会看到“在&lt; hash&gt;处分离”。
较新版本的Git尝试记住执行分离的git checkout
命令中的项目,如果可以的话,会说“在something_more_informative处分离”。在这里,您有时会看到detached at origin/master
。在各种情况下,它们将丢失详细信息,包括移动当前提交(通过将新提交ID写入HEAD
,例如,再次使用git checkout
或进行新提交)。在这种情况下,一些较新版本的Git将开始说“分离从”而不是“分离”,并挂起一些额外的信息,无论是哈希ID还是名称。虽然所有较新的Git版本都试图这样做,但有些版本会有一些小错误,并且无法正确区分“分离”和“分离”。
在这个特殊情况下 - 尽管它是依赖于Git版本的 - 很可能是你的上一个示例进程导致“ hash 分离”的原因是你的{ {1}}通过ID移动到给定的提交,破坏旧的保留信息,然后您的git reset --hard origin/master
发现这不是移动,即您已经在该ID,因此它不会更新保留的哈希或名称。
如果是这种情况,只需将git checkout origin/master
替换为git reset --hard origin/master
,以便随后的git reset --hard
(通常)移动,就会更改保留的信息回到这个名字。