From: Junio C Hamano Date: Sat, 23 May 2009 08:39:45 +0000 (-0700) Subject: Merge branch 'rr/forbid-bs-in-ref' X-Git-Tag: v1.6.4-rc0~139 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/e05aae684d453695bc5bd1e66aa96bc7d42e186a?hp=-c Merge branch 'rr/forbid-bs-in-ref' * rr/forbid-bs-in-ref: Disallow '\' in ref names --- e05aae684d453695bc5bd1e66aa96bc7d42e186a diff --combined Documentation/git-check-ref-format.txt index 0873e60f7f,bf43454415..0b7982ea76 --- a/Documentation/git-check-ref-format.txt +++ b/Documentation/git-check-ref-format.txt @@@ -25,10 -25,6 +25,10 @@@ imposes the following rules on how refe grouping, but no slash-separated component can begin with a dot `.`. +. They must contain at least one `/`. This enforces the presence of a + category like `heads/`, `tags/` etc. but the actual names are not + restricted. + . They cannot have two consecutive dots `..` anywhere. . They cannot have ASCII control characters (i.e. bytes whose @@@ -42,6 -38,8 +42,8 @@@ . They cannot contain a sequence `@{`. + - They cannot contain a `\\`. + 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 avoids ambiguities in certain diff --combined refs.c index 2b1f0f0e6e,fc33bc6ac4..bb4bdc9eac --- a/refs.c +++ b/refs.c @@@ -682,12 -682,13 +682,13 @@@ int for_each_rawref(each_ref_fn fn, voi * - it has ASCII control character, "~", "^", ":" or SP, anywhere, or * - it ends with a "/". * - it ends with ".lock" + * - it contains a "\" (backslash) */ static inline int bad_ref_char(int ch) { if (((unsigned) ch) <= ' ' || - ch == '~' || ch == '^' || ch == ':') + ch == '~' || ch == '^' || ch == ':' || ch == '\\') return 1; /* 2.13 Pattern Matching Notation */ if (ch == '?' || ch == '[') /* Unsupported */ @@@ -1002,10 -1003,12 +1003,10 @@@ int delete_ref(const char *refname, con } else { path = git_path("%s", refname); } - err = unlink(path); - if (err && errno != ENOENT) { + err = unlink_or_warn(path); + if (err && errno != ENOENT) ret = 1; - error("unlink(%s) failed: %s", - path, strerror(errno)); - } + if (!(delopt & REF_NODEREF)) lock->lk->filename[i] = '.'; } @@@ -1015,7 -1018,10 +1016,7 @@@ */ ret |= repack_without_ref(refname); - err = unlink(git_path("logs/%s", lock->ref_name)); - if (err && errno != ENOENT) - warning("unlink(%s) failed: %s", - git_path("logs/%s", lock->ref_name), strerror(errno)); + unlink_or_warn(git_path("logs/%s", lock->ref_name)); invalidate_cached_refs(); unlock_ref(lock); return ret; @@@ -1376,7 -1382,7 +1377,7 @@@ int create_symref(const char *ref_targe if (adjust_shared_perm(git_HEAD)) { error("Unable to fix permissions on %s", lockpath); error_unlink_return: - unlink(lockpath); + unlink_or_warn(lockpath); error_free_return: free(git_HEAD); return -1;