74

I tried:

git branch "MyProj/bin/ ignored"

and received:

fatal: 'MyProj/bin/ ignored' is not a valid branch name.

The git-branch man page points to the git-check-ref-format man page to get the actual rules for a valid branch name.

Sure enough, the reason for the above fatal error appears to be the inclusion of a space character.

Any idea why, in this day and age, spaces are still excluded from a branch name (I would have expected it in ancient CVS, for example, but Git?)

What could be valid technical reasons for that?

nulltoken
  • 64,429
  • 20
  • 138
  • 130
WinWin
  • 7,493
  • 10
  • 44
  • 53
  • 14
    There are no *valid* technical reasons for this. It's somewhere between "I'm too lazy to support this" and "I strongly believe for some arbitrary reasons that spaces should never be part of branch names". – Roman Starkov Sep 09 '13 at 19:02
  • 1
    http://stackoverflow.com/questions/3651860/which-characters-are-illegal-within-a-branch-name – Ciro Santilli OurBigBook.com Aug 26 '16 at 22:41
  • For the sake of sanity, brevity, predictability (and portability: for scripts regex'ing on branch names), I _only_ use dash ("`-`"), lowercase (`[a-z]`) & numbers (`[0-9]`) in branch names. No underscores ("`_`"), nor uppercase. Why make it more complicated than necessary? I also never use slash ("`/`"), because it's a useful indication the branch is "special". And basically there's no reason to use a "`/`" instead of a "`-`", except to aid dumb gui tools that automatically fold them close (eg a tree), which a smart gui could/should just as easily do on dashes "`-`". – michael Nov 01 '16 at 10:03

5 Answers5

77

I do not know if you are going to find a pure, technical reason down at the bottom of this. However, I can offer that spaces tend to throw wrenches in all sorts of *nix utilities and filename processing, so it may have been to avoid accidentally doing anything wrong further down the line. After all, a git branch boils down to a file in the repo and this avoids dealing with spaces in that file's name (specifically, a branch is a file in .git/refs/heads/, as mentioned in the comment).

Mostly I would guess the reason is philosophical, and meant to keep things simple. Branch names are human-readable names that have no real reason to be complicated (and require typing two extra chars each time haha, to invoke the ghost of the sysadmin who has aliased every command to an indecipherable three letter combination). Otherwise known as the "why cd is not chdir" argument.

shelhamer
  • 29,752
  • 2
  • 30
  • 33
  • 17
    Under the hood, a Git branch is a simple file in `.git/refs/heads/`, containing just the SHA-1 of the commit it points to. Spaces in filenames are moderately awkward in *nix, as @Shelhamer said, so Git just sidesteps that. – dunedain289 Jul 08 '11 at 01:50
11

On a Mac, I use Alt+Space to insert an invisible character that does the trick. This character is known as a non-breaking space. (  in the HTML encoding; otherwise known as U+00A0. For other platforms, you can copy the character from the code snippet below.)

It's not the same as a normal space. It's an invisible character that looks like a space, and behaves like a space in many contexts, but is a completely distinct character. Git only disallows the normal space character, so it will allow this.

Using this is 100% likely going to confuse the hell out of anyone else and definitely going to bring chaos everywhere, but you can do it if you really want to.

git checkout -b US24024 Automated Tests - Profile A
Switched to a new branch 'US24024 Automated Tests - Profile A'

Note that you cannot copy the character from the above code block (due to a limitation in Stack Overflow). To copy it, run the code snippet below and copy from the text box:

<input type="text" size="1" value="&nbsp;" style="text-align: center;" readonly>
(Select and copy the contents of this text box.)
ADTC
  • 8,999
  • 5
  • 68
  • 93
joe
  • 1,359
  • 14
  • 19
  • 3
    btw, it has been pointed out that atlasian sourcetree fails to read a branch named with 'space' in some occasions. it's obvious, but use at your own risk (or to annoy your colleagues). – joe Jul 07 '17 at 21:43
5

There is a possible workaround if you are desparate enough. There are a lot of space-like characters in the unicode set. But only U+0020 is the space that is disallowed. Take e.g. a non-breaking space and you can have a branch name with spaces. The main issue is that your keyboard likely has no key for that code point. I use the following script to work around that issue:

#!/bin/zsh
git co -b "${@// / }"

It simply replaces all spaces in the arguments with non-breaking spaces...

Vir
  • 449
  • 5
  • 5
  • 1
    It is probably better to just accept the git way than to complicate your setup like this. – binki Jan 05 '22 at 00:53
3

Because using path names correctly in shell scripts is hard. From the linked git check-ref-format man page itself:

These rules make it easy for shell script based tools to parse reference names, pathname expansion by the shell when a reference name is used unquoted (by mistake), and also avoid ambiguities in certain reference name expressions (see gitrevisions(7)):

See also Filenames and Pathnames in Shell: How to do it Correctly:

The basic problem is that today most Unix-likes allow filenames to include almost any bytes. That includes newlines, tabs, the escape character (including escape sequences that can execute commands when displayed), other control characters, spaces (anywhere!), leading dashes (-), shell metacharacters, and byte sequences that aren’t legal UTF-8 strings.

...

However, this flaw in Unix-like kernels (allowing dangerous filenames) combines with additional weaknesses in the Bourne shell language, making it even more difficult in shell to correctly handle filenames and pathnames. I think shell is a reasonable language for short scripts, when properly used, but the excessive permissiveness of filenames turns easy tasks into easily-done-wrong tasks.

kelvin
  • 1,421
  • 13
  • 28
  • 1
    There have been myriad critical elevation exploits in Windows based on the stupendously incomprehensible early-2000s decision to install all executables below “C:\Program Files\…” by default. Most dangerously, consider a malicious **program.exe** when dropped into the root directory, or accessible via such an alias. – Glenn Slayden Aug 15 '21 at 21:04
  • …The Windows registry is a key enabler for bad actors here, owing to its prolific use of `%ProgramFiles%` expansion, since that token duly—but perhaps not so obviously—expands into a space-containing sequence. – Glenn Slayden Aug 15 '21 at 21:12
  • 2
    I've always hated that windows allows spaces in directory names and ESPECAILLY that the built in OS uses a folder with such a name One of the few things used to be better for developers. – ggb667 Jun 20 '22 at 13:47
0

It's not allowed because it would complicate the functionality of the "git checkout" command.

Ex: Consider you currently have a branch called "fix", although you are currently in the master. If you would run the command

(master): git checkout -b my fix

git would not know if you want to make a new branch called "my fix" or if you want to make a new branch called "my" that is linked to your original "fix", rather than the "master" branch.

Source: https://git-scm.com/docs/git-checkout (Git Documentation)

Abdul Aziz Barkat
  • 19,475
  • 3
  • 20
  • 33