Junio C Hamano [off-list ref] writes:
Jeff King [off-list ref] writes:
quoted
I wonder if the right solution is for us to be more picky about what can
be found in $GIT_DIR. Maybe matching all-uppercase, or starting with
"refs/", which I think would match existing convention?
I think we've discussed tightening it a few years ago already.
HEAD, MERGE_HEAD, FETCH_HEAD, etc. all are "^[_A-Z]*$" and it may even be
a good idea to insist "^[_A-Z]*HEAD$" or even "^([A-Z][A-Z]*_)?HEAD$".
Perhaps like this? Only compile tested...
sha1_name.c | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/sha1_name.c b/sha1_name.c
index ba976b4..5effb1a 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -261,6 +261,23 @@ static char *substitute_branch_name(const char **string, int *len)
return NULL;
}
+static int is_kind_of_head(const char *str)
+{
+ int len = strlen(str) - 4;
+ if (len < 0 || strcmp(str + len, "HEAD"))
+ return 0;
+ if (!len)
+ return 1;
+ if (str[--len] != '_' || !len)
+ return 0;
+ while (len) {
+ char ch = str[--len];
+ if (ch < 'A' || 'Z' < ch)
+ return 0;
+ }
+ return 1;
+}
+
int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
{
char *last_branch = substitute_branch_name(&str, &len);@@ -274,6 +291,8 @@ int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
unsigned char *this_result;
int flag;
+ if (p == ref_rev_parse_rules && !is_kind_of_head(str))
+ continue;
this_result = refs_found ? sha1_from_ref : sha1;
mksnpath(fullref, sizeof(fullref), *p, len, str);
r = resolve_ref(fullref, this_result, 1, &flag);
@@ -302,6 +321,8 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
char path[PATH_MAX];
const char *ref, *it;
+ if (p == ref_rev_parse_rules && !is_kind_of_head(str))
+ continue;
mksnpath(path, sizeof(path), *p, len, str);
ref = resolve_ref(path, hash, 1, NULL);
if (!ref)