对在 git 中创建嵌套分支感到困惑

confused about creating nested branches in git

我刚开始使用 git 并开始与其他开发人员协作编写相同的代码。我之前使用过 SVN,但从未在我的代码库上与其他人协作过。 现在有合作者处理相同的代码,我需要一个高效的工作流程。在搜索此类内容时,我发现 this,这似乎是满足我们要求的良好工作流程。

我的存储库位于本地计算机中。我使用 git init --bare 创建了存储库。我将初始代码添加到 master 并推送它。然后我使用 git branch develop; git push -u origin develop 添加了一个 "develop" 分支。

现在我想从 "develop" 创建功能分支,并且我希望所有协作者都可以访问这些功能分支。我希望有一个嵌套结构,像这样

origin/master
origin/develop
origin/develop/newFeature
origin/develop/anotherFeature
etc.

这样,当合作者输入 git branch -a 时,he/she 会立即知道 "newFeature" 在 "develop" 行中,并决定要做什么。

所以经过反复试验,这就是我所做的:

git clone file:///path/to/repo --branch develop
git checkout -b newFeature develop
EDIT some files
git add .
git commit
git push origin newFeature

现在这个 "newFeature" 可供所有协作者克隆。 git branch -a 给我

  develop
* newFeature
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/master
  remotes/origin/newFeature

那么 "newFeature" 真的是 "develop" 分支的一部分吗?或者它现在自己分支?一旦我克隆了 "newFeature",我如何检查它是否是开发线?这可能会造成混淆,因为我最终可能会在适当的时候在 master 中有一个名为 "newFeature" 的分支!

我对git如何工作的理解肯定是不够的。因此,如果有人能指出我正确的方向,那就太好了!

TIA,

TL;DR 版本: 最初只是 git checkout -b develop/feature(你需要 而不是 有一个名为 develop 让它工作!)。


分支并不是真正的 "nest" 原因非常简单:分支名称(如 newFeature)仅代表某些提交 ID,即某些 SHA-1 "true name" 一些提交。

(在这方面,分支名称与标签相同,如"v2.3"。)

(本地)分支名称的特殊之处——它们与任何其他引用的不同之处——是 "git checkout" 让你通过在 [ 中写入分支名称来获得 "on a branch" =78=] 的 HEAD 文件,,完成后,进行新提交将 自动更新 分支-name 以便它指向您刚刚进行的新提交。

(无法通过这种方式获取 "on" 远程分支名称,但也会根据需要更改其目标 SHA-1。我提到这一点只是因为下一段提到 "remote branches" 或 "remote-tracking branches",您将在 git branch -r 输出中看到。)

然而,分支名称按 git branch --list 排序(在按 "kind" 排序之后,即首先将所有本地分支组合在一起,然后是所有远程分支)。这意味着您 可以 将名称组合在一起:只需最初将名称创建为 develop/anotherFeaturedevelop/newFeature。在这种情况下,斜杠只是名称的一部分。

这里的问题是 git 最初通过将这些分支名称放在包含文件的目录中来实现 1 这些分支名称。在支持 git 的系统上,您不能同时拥有名为 develop 的目录和 名为 develop 的文件。2 所以如果你有一个名为 develop 的分支,git 可能已经创建了一个文件(具体来说是 .git/refs/heads/develop),这会阻止它创建一个目录(.git/refs/heads/develop,再次)包含文件 (newFeature),其中包含分支当前标识的提交的 SHA-1。


1虽然 git 现在也使用平面文件 (.git/packed-refs) 来存储分支到 SHA-1 的映射,但它仍然使用文件目录,并且必须确保您没有创建必须同时用作目录 文件的名称。

2我个人认为文件系统名称实体同时作为目录 文件是有意义的:这将是例如,将可执行文件的所有 ELF 部分存储为可执行程序目录中的文件,或者处理 MacOS 为应用程序包所做的事情。但这违反了事物在 POSIX 中必须工作的各种规则,因此需要对文件系统名称进行重大重新设计 space(s),并且更适合作为后续 -到 Plan 9(例如)而不是作为 Unix-ish 变体。