From d0f810f0bc0d6b51722b400f70c2590713f168e8 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Wed, 3 Sep 2014 11:45:43 -0700 Subject: refs.c: allow listing and deleting badly named refs We currently do not handle badly named refs well: $ cp .git/refs/heads/master .git/refs/heads/master.....@\*@\\. $ git branch fatal: Reference has invalid format: 'refs/heads/master.....@*@\.' $ git branch -D master.....@\*@\\. error: branch 'master.....@*@\.' not found. Users cannot recover from a badly named ref without manually finding and deleting the loose ref file or appropriate line in packed-refs. Making that easier will make it easier to tweak the ref naming rules in the future, for example to forbid shell metacharacters like '`' and '"', without putting people in a state that is hard to get out of. So allow "branch --list" to show these refs and allow "branch -d/-D" and "update-ref -d" to delete them. Other commands (for example to rename refs) will continue to not handle these refs but can be changed in later patches. Details: In resolving functions, refuse to resolve refs that don't pass the git-check-ref-format(1) check unless the new RESOLVE_REF_ALLOW_BAD_NAME flag is passed. Even with RESOLVE_REF_ALLOW_BAD_NAME, refuse to resolve refs that escape the refs/ directory and do not match the pattern [A-Z_]* (think "HEAD" and "MERGE_HEAD"). In locking functions, refuse to act on badly named refs unless they are being deleted and either are in the refs/ directory or match [A-Z_]*. Just like other invalid refs, flag resolved, badly named refs with the REF_ISBROKEN flag, treat them as resolving to null_sha1, and skip them in all iteration functions except for for_each_rawref. Flag badly named refs (but not symrefs pointing to badly named refs) with a REF_BAD_NAME flag to make it easier for future callers to notice and handle them specially. For example, in a later patch for-each-ref will use this flag to detect refs whose names can confuse callers parsing for-each-ref output. In the transaction API, refuse to create or update badly named refs, but allow deleting them (unless they try to escape refs/ and don't match [A-Z_]*). Signed-off-by: Ronnie Sahlberg Signed-off-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- refs.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'refs.h') diff --git a/refs.h b/refs.h index c61b8f442..2bc355687 100644 --- a/refs.h +++ b/refs.h @@ -56,11 +56,19 @@ struct ref_transaction; /* * Reference cannot be resolved to an object name: dangling symbolic - * reference (directly or indirectly), corrupt reference file, or - * symbolic reference refers to ill-formatted reference name. + * reference (directly or indirectly), corrupt reference file, + * reference exists but name is bad, or symbolic reference refers to + * ill-formatted reference name. */ #define REF_ISBROKEN 0x04 +/* + * Reference name is not well formed. + * + * See git-check-ref-format(1) for the definition of well formed ref names. + */ +#define REF_BAD_NAME 0x08 + /* * The signature for the callback function for the for_each_*() * functions below. The memory pointed to by the refname and sha1 -- cgit v1.2.1