confused about creating nested branches in git

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.

  • git - Tags with the same name with a branch
  • Dealing with Jekyll and Git
  • git fetch doesn't fetch all branches
  • git bug or misuse of branching?
  • Git merge doesn't merge a file the second time
  • Remove commits from a single branch in Git
  • 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,

  • GitPython nothing appears in working copy after pull
  • How to clean the branch list?
  • Is there a generic git “undo” command?
  • Linphone Android Import and Build
  • Mercurial - what is “future auditing”?
  • Git: how to roll back to last push/commit
  • One Solution collect form web for “confused about creating nested branches in git”

    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 Baby is a git and github fan, let's start git clone.