Legal Git branch namesEdit

Overview

A Git branch name can not:

  • Have a path component that begins with .
  • Have a double dot ..
  • Have an ASCII control character, ~, ^, : or SP, anywhere
  • End with a /
  • End with .lock
  • Contain a \ (backslash)

Source: http://www.spinics.net/lists/git/msg133704.html

Source code

The definitive reference for what is a legal ref name (ie. applies to both tags and branches) is the implementation of the check_ref_format() function in refs.c, along with bad_ref_char() in the same file. At the current time of writing (19 September 2010) they read as follows:

static inline int bad_ref_char(int ch)
{
        if (((unsigned) ch) <= ' ' ||
            ch == '~' || ch == '^' || ch == ':' || ch == '\\')
                return 1;
        /* 2.13 Pattern Matching Notation */
        if (ch == '?' || ch == '[') /* Unsupported */
                return 1;
        if (ch == '*') /* Supported at the end */
                return 2;
        return 0;
}

int check_ref_format(const char *ref)
{
        int ch, level, bad_type, last;
        int ret = CHECK_REF_FORMAT_OK;
        const char *cp = ref;

        level = 0;
        while (1) {
                while ((ch = *cp++) == '/')
                        ; /* tolerate duplicated slashes */
                if (!ch)
                        /* should not end with slashes */
                        return CHECK_REF_FORMAT_ERROR;

                /* we are at the beginning of the path component */
                if (ch == '.')
                        return CHECK_REF_FORMAT_ERROR;
                bad_type = bad_ref_char(ch);
                if (bad_type) {
                        if (bad_type == 2 && (!*cp || *cp == '/') &&
                            ret == CHECK_REF_FORMAT_OK)
                                ret = CHECK_REF_FORMAT_WILDCARD;
                        else
                                return CHECK_REF_FORMAT_ERROR;
                }

                last = ch;
                /* scan the rest of the path component */
                while ((ch = *cp++) != 0) {
                        bad_type = bad_ref_char(ch);
                        if (bad_type)
                                return CHECK_REF_FORMAT_ERROR;
                        if (ch == '/')
                                break;
                        if (last == '.' && ch == '.')
                                return CHECK_REF_FORMAT_ERROR;
                        if (last == '@' && ch == '{')
                                return CHECK_REF_FORMAT_ERROR;
                        last = ch;
                }
                level++;
                if (!ch) {
                        if (ref <= cp - 2 && cp[-2] == '.')
                                return CHECK_REF_FORMAT_ERROR;
                        if (level < 2)
                                return CHECK_REF_FORMAT_ONELEVEL;
                        if (has_extension(ref, ".lock"))
                                return CHECK_REF_FORMAT_ERROR;
                        return ret;
                }
        }
}

So in addition to the summary posted above, we can also add that:

  • the sequence @{ is not allowed
  • ? and [ are not allowed
  • * is allowed only if it constitutes an entire path component (eg. foo/* or bar/*/baz), in which case it is interpreted as a wildcard and not as part of the actual ref name