对在git中创建嵌套分支感到困惑 [英] confused about creating nested branches in git

查看:129
本文介绍了对在git中创建嵌套分支感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始使用git,并开始与其他开发人员在同一代码上进行协作.我之前在SVN上工作了一段时间,但从未与我的代码库上的其他人合作. 现在,在协作者使用相同代码的情况下,我需要高效的工作流程.在搜索此类内容时,我发现了,它看起来像一个满足我们要求的良好工作流程.

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

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

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

这样,当协作者键入git branch -a时,他/她将立即知道"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(您需要 not 名为develop的分支可以使它正常工作!).


分支并没有真正地嵌套",原因很简单:分支名称(如newFeature)仅代表某些commit-ID,即某些commit的某些SHA-1真实名称". /p>

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

使(本地)分支名称特别(使它们与任何其他引用均不同)的原因是,通过在git的HEAD中写入分支名称,"git checkout"将使您在分支上"文件,一旦完成,进行新的提交将自动更新分支名称,使其指向您刚刚进行的新提交.

(不能以这种方式打开"远程分支名称,但是还会根据需要更改其目标SHA-1.我之所以提及这一点,仅是因为下一段提到了远程分支"或远程跟踪分支" ,您将在git branch -r输出中看到.)

但是,

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

这里的问题是git最初将这些分支名称放置在包含文件的目录中,从而实现了 1 .在支持git的系统上,您不能同时有一个名为develop 的目录和一个名为develop的文件. 2 因此,如果您有一个分支名为develop,git可能已经创建了一个文件(特别是.git/refs/heads/develop),然后阻止该文件创建包含文件(newFeature)的目录(再次是.git/refs/heads/develop),该文件包含具有SHA-1的SHA-1.分支当前标识的提交.


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

2 就个人而言,我认为将文件系统名称实体同时用作目录文件是有意义的:例如,这是一种存储所有文件的方式将可执行文件的ELF部分作为可执行程序目录中的文件存储,或处理MacOS对应用程序捆绑包所做的事情.但这违反了POSIX中所有事物工作方式的各种规则,因此将需要对文件系统名称空间进行重大重新设计,并且更适合作为Plan 9的后续版本(例如)而不是像Unix一样的变体.

I just started using git and started collaborating with other developers on same code. I have worked a little with SVN before but never had to collaborate with other people on my codebase. Now with collaborators working on same code, I need an efficient workflow. While searching for such, I found this, and it seems like a good workflow for our requirement.

My repository resides in a local machine. I created the repository with git init --bare. I added the initial codes to master and pushed it. Then I added a "develop" branch using git branch develop; git push -u origin develop.

Now I want to create feature branches from "develop", and I want these feature branches to be accessible by all collaborators. I wish to have a nested structure, something like this

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

so that when a collaborator types in git branch -a he/she will immediately know the "newFeature" is in the "develop" line, and decides what to do.

So after some trial and error, this is what I did:

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

Now this "newFeature" is available for all collaborator to clone. git branch -a gives me

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

So is the "newFeature" really part of the "develop" branch? Or is it now branch by itself? Once I clone the "newFeature", how do I check whether it is the develop line? This may potentially be confusing as I may end up having a branch named "newFeature" in master in due time!

My understanding of how git works is definitely inadequate. Therefore, if anyone can point me to right direction, that will be great!

TIA,

解决方案

TL;DR version: just git checkout -b develop/feature initially (you'll need to not have a branch named develop for this to work though!).


Branches don't really "nest" for a ridiculously simple reason: a branch name (like newFeature) merely stands in for some commit-ID, i.e., some SHA-1 "true name" of some commit.

(In this respect, a branch name is the same as a tag, like "v2.3".)

The thing that makes (local) branch names special—what makes them different from any other reference—is that "git checkout" will let you get "on a branch" by writing the name of the branch in git's HEAD file, and, once you have done that, making a new commit will automatically update the branch-name so that it points to the new commit you just made.

(Remote branch names can't be gotten "on" this way, but will also change their target SHA-1 as needed. I mention this only because the next paragraph mentions "remote branches" or "remote-tracking branches", which you'll see in git branch -r output.)

Branch names are, however, sorted by git branch --list (after sorting by "kind", i.e., grouping all local branches together first, then all remote branches). This means you can have the names grouped together: just create the names as develop/anotherFeature and develop/newFeature originally. The slash is, in this case, merely a part of the name.

The problem here is that git originally implemented1 these branch names by putting them in directories containing files. On the systems that support git, you can't have a directory named develop and a file named develop at the same time.2 So if you have a branch named develop, git may have created a file (.git/refs/heads/develop, specifically), which then prevents it from creating a directory (.git/refs/heads/develop, again) containing the file (newFeature) containing the SHA-1 of the commit that the branch currently identifies.


1While git now also uses a flat file (.git/packed-refs) to store branch-to-SHA-1 mappings, it still also uses directories of files, and must make sure that you don't create a name that must serve as both directory and file.

2Personally I think it makes sense for a file system name entity to work as both directory and file: this would be a way to, for instance, store all the ELF sections of an executable as files within the directory that is the executable program, or handle the things that MacOS does for app bundles. But this violates all kinds of rules for the way things must work in POSIX, so it would require a major redesign of the file system name space(s), and would be more suitable as a follow-on to Plan 9 (for instance) than as a Unix-ish variant.

这篇关于对在git中创建嵌套分支感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆