开发者

Why can't a branch name contain the 'space' char?

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, b开发者_开发技巧ut Git?)

What could be valid technical reasons for that?


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.


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.)


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...


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.


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)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜