Git branch name - case sensitive or insensitive?

30,911

Solution 1

So I went ahead and create new branch (git branch DEV)

You created a new branch DEV when you were on the branch dev. So DEV and dev are two branches that point to the same commit. After you renamed DEV to DV, now DV and dev are two branches that point to the same commit.

Everything is just fine. If you don't want DV to bother you, you could just run git branch -d DV to remove it. If you indeed want to make a new branch, better to follow some naming rule which cannot confuse you and others.

I never used git show-branch. git log --oneline --all --graph --decorate=full draws a clear log graph.

Solution 2

Answering just the question in the subject line, without addressing anything about git show-branch (like ElpieKay, I never actually use git show-branch; it seems mainly mis-informative):

Git branch names—and tag names, and all other reference names, as Git calls them—were originally intended to be case-sensitive.

This all works perfectly on Linux / Unix machines, where Git's code is case-sensitive to start with. When Git stores branch names in the file system as file names (which it only does sometimes), the file system is also case-sensitive.1

It sometimes fails on Windows and some MacOS systems. Specifically, it fails when Git stores references in individual files, whose names are derived from the reference name, and those file names are case-insensitive (e.g., case-preserving, but fold case during name-matching; or even converting everything to uppercase-only, as in the really old FAT 8.3 format, but we can hope no modern file system does this).

As noted above, Git does not always store reference names as file names. In fact, on initial clone, all the names are in a single file called .git/packed-refs,2 so at this point they are case sensitive. But they become "unpacked" over time,3 and then on some systems they become case-folding.

Because it sometimes fails on some systems, it's generally best to avoid using multiple reference names that differ only in case.


1Of course, on modern Unix/Linux systems, you can now get access to case-preserving-but-case-insensitive file systems, and Windows and MacOS can now be told not to do case-folding for some file systems. (But if you change from the defaults, expect software that is intended for your box to fail, because it will. Things like Photoshop internally try to use files named foo and FOO and expect this to refer to the same file!)

2This packed-references file has been around for quite a while, but not forever, and very early versions of Git may not use it. Internally, Git is acquiring a new "pluggable reference name interface" and future versions of Git might use neither this file, nor individual per-reference files.

3In general, creating or updating a reference causes an unpacked reference file to come into existence. Running git pack-refs --all will replace unpacked references with packed ones, restoring full case-sensitivity. Without --all, git pack-refs only packs already-packed references, which is largely a useless mode of operation (it was intended for a case that is no longer used).

Share:
30,911
jak
Author by

jak

Updated on July 11, 2020

Comments

  • jak
    jak almost 4 years

    I am a new git user and recently been handed with an out of date git repository to look after.

    This is the original state ( output by git show-branch):

    ! [cr232] CR 232 Release
            * [dev] Style Changes
    ---------------
            *   [dev] Style Changes
            *   [dev^] SMS 5.4
            *   [dev~2] Logo Change
            *   [dev~3] SMS 5.3
            *   [dev~4] SMS 5.2
            *   [dev~5] SIT R-0.3.3 EDW SMS Layers
            *   [dev~6] SIT Release R 0.3.0
           +*   [cr232] CR 232 Release
           +*   [cr232^] Dashboard Fix
           +*   [cr232~2] Release for system testing
    

    Note that there is a branch called ‘dev’ at this point. Note that highlighted there are several references to dev (i.e. dev, dev^, dev~2 etc).

    For my development purpose, I was trying to come up with a branch called ‘DEV’, all capital.

    So I went ahead and create new branch (git branch DEV) and now running git show-branch –date-order:

    ! [DEV] Style Changes
        ! [cr232] CR 232 Release
            * [dev] Style Changes
    ---------------
            *   [DEV] Style Changes
            *   [DEV^] SMS 5.4
            *   [DEV~2] Logo Change
            *   [DEV~3] SMS 5.3
            *   [DEV~4] SMS 5.2
            *   [DEV~5] SIT R-0.3.3 EDW SMS Layers
            *   [DEV~6] SIT Release R 0.3.0
           +*   [cr232] CR 232 Release
           +*   [cr232^] Dashboard Fix
           +*   [cr232~2] Release for system testing
    

    Note that both dev and DEV are listed as branch. Note also that on the 5th line the references to dev have now changed to DEV (i.e. DEV, DEV^, DEV~2 etc).

    What is the 5th line output referring to? I would expect it to remain “dev” instead of being changed to “DEV” as the descriptions next to it refers to the description of old work during “dev” branch.

    I am trying to return back to how it was by modifying the DEV branch name to DV (running git branch –m DEV DV) and showing the branch now look like:

    ! [DV] Style Changes
        ! [cr232] CR 232 Release
            * [dev] Style Changes
    ---------------
            *   [DV] Style Changes
            *   [DV^] SMS 5.4
            *   [DV~2] Logo Change
            *   [DV~3] SMS 5.3
            *   [DV~4] SMS 5.2
            *   [DV~5] SIT R-0.3.3 EDW SMS Layers
            *   [DV~6] SIT Release R 0.3.0
           +*   [cr232] CR 232 Release
           +*   [cr232^] Dashboard Fix
           +*   [cr232~2] Release for system testing
    

    Note that the branch is now including DV and dev. Note also that the 5th line references to dev have now changed to DV (i.e. DV, DV^, DV~2 etc).

    Is there any way to get back to how it was during original state in term of the DV references? Did the git got confused and renamed my historic information with a branch that is similar and only differs by capital case?

    Please assist on how I can fix this. Thanks heaps

  • jak
    jak almost 8 years
    I hope this is the case. But just to clarify, after I created DEV, I also created two other branches called TST and PRD while I am on dev branch. So these two would be pointing to the same commit as well. But why is the reference only changes when I create DEV branch?
  • ElpieKay
    ElpieKay almost 8 years
    @Nora I made some tests and found the rule. The part above the --------, the branches are sorted by some order. If git show-branch without any option, it's the alphabetic order. The part below the ---------, if some branches point to the same commit, the first one of them is listed as the delegate. DEV comes before TST and PRD, so it's the delegate of them.
  • ElpieKay
    ElpieKay almost 8 years
    @Nora and I found more info. I guess the positions of the mark + in your show-branch output are wrong. They are supposed to be right below the first ! mark. And the !s have different colors, if the below commit is reachable from the above branch, there is a + right below the ! which represents that branch. The checked-out branch is prefixed by a * instead.
  • jak
    jak almost 8 years
    thanks for your clarification, if I go ahead and delete DV, will it also remove the references? and also, your second comment, it doesn't look right because I only take a portion of the whole thing to post here. The original marking looks like + + + * [DV] Style Changes + + + * [DV^] SMS 5.4 + + + * [DV~2] Logo Change + + + * [DV~3] SMS 5.3 + + + * [DV~4] SMS 5.2
  • ElpieKay
    ElpieKay almost 8 years
    @Nora DV is one of the references. It's a variable that stores the commit sha1 or another ref which it points to. Deleting it will not lose any commit history.
  • ElpieKay
    ElpieKay almost 8 years
    @Nora so you omitted some of the + marks, which made the output unreasonable.
  • jak
    jak almost 8 years
    Yes, I omitted. Thanks for your answer, it solved my question. I have deleted DV and now it's referencing PRD.
  • Chris Quenelle
    Chris Quenelle over 4 years
    Someone needs to create a fresh question so that we can attach torek's answer to the new question and make it the accepted answer. This answer is in dire need of more wide exposure. Especially the part about packed-refs and branch names beinginconsistently treated by git over the lifetime of a repo.