{"thread":{"id":"6652","subject":"[PATCH 1/2] enable HEAD@{...} and make it independent from the current branch","startedAt":"2007-02-04T02:49:16Z","lastAt":"2007-02-04T02:49:16Z","messageCount":1,"participants":["Nicolas Pitre"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"33519","messageId":"Pine.LNX.4.64.0702032144010.3021@xanadu.home","threadId":"6652","inReplyTo":null,"subject":"[PATCH 1/2] enable HEAD@{...} and make it independent from the current branch","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2007-02-04T02:49:16Z","receivedAt":"2007-02-04T02:49:16Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"\nSigned-off-by: Nicolas Pitre <nico@cam.org>\n---\n\n sha1_name.c |   60 +++++++++++++++++++++++++++++++++-------------------------\n 1 files changed, 34 insertions(+), 26 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex de8caf8..9841b05 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -235,22 +235,23 @@ static int ambiguous_path(const char *path, int len)\n \treturn slash;\n }\n \n+static const char *ref_fmt[] = {\n+\t\"%.*s\",\n+\t\"refs/%.*s\",\n+\t\"refs/tags/%.*s\",\n+\t\"refs/heads/%.*s\",\n+\t\"refs/remotes/%.*s\",\n+\t\"refs/remotes/%.*s/HEAD\",\n+\tNULL\n+};\n+\n int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)\n {\n-\tstatic const char *fmt[] = {\n-\t\t\"%.*s\",\n-\t\t\"refs/%.*s\",\n-\t\t\"refs/tags/%.*s\",\n-\t\t\"refs/heads/%.*s\",\n-\t\t\"refs/remotes/%.*s\",\n-\t\t\"refs/remotes/%.*s/HEAD\",\n-\t\tNULL\n-\t};\n \tconst char **p, *r;\n \tint refs_found = 0;\n \n \t*ref = NULL;\n-\tfor (p = fmt; *p; p++) {\n+\tfor (p = ref_fmt; *p; p++) {\n \t\tunsigned char sha1_from_ref[20];\n \t\tunsigned char *this_result;\n \n@@ -266,6 +267,26 @@ int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)\n \treturn refs_found;\n }\n \n+static int dwim_log(const char *str, int len, char **log)\n+{\n+\tconst char **p;\n+\tint logs_found = 0;\n+\n+\t*log = NULL;\n+\tfor (p = ref_fmt; *p; p++) {\n+\t\tstruct stat st;\n+\t\tchar *path = mkpath(*p, len, str);\n+\t\tif (!stat(git_path(\"logs/%s\", path), &st) &&\n+\t\t    S_ISREG(st.st_mode)) {\n+\t\t\tif (!logs_found++)\n+\t\t\t\t*log = xstrdup(path);\n+\t\t\tif (!warn_ambiguous_refs)\n+\t\t\t\tbreak;\n+\t\t}\n+\t}\n+\treturn logs_found;\n+}\n+\n static int get_sha1_basic(const char *str, int len, unsigned char *sha1)\n {\n \tstatic const char *warning = \"warning: refname '%.*s' is ambiguous.\\n\";\n@@ -295,7 +316,9 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)\n \tif (!len && reflog_len) {\n \t\t/* allow \"@{...}\" to mean the current branch reflog */\n \t\trefs_found = dwim_ref(\"HEAD\", 4, sha1, &real_ref);\n-\t} else\n+\t} else if (reflog_len)\n+\t\trefs_found = dwim_log(str, len, &real_ref);\n+\telse\n \t\trefs_found = dwim_ref(str, len, sha1, &real_ref);\n \n \tif (!refs_found)\n@@ -310,21 +333,6 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)\n \t\tunsigned long co_time;\n \t\tint co_tz, co_cnt;\n \n-\t\t/*\n-\t\t * We'll have an independent reflog for \"HEAD\" eventually\n-\t\t * which won't be a synonym for the current branch reflog.\n-\t\t * In the mean time prevent people from getting used to\n-\t\t * such a synonym until the work is completed.\n-\t\t */\n-\t\tif (len && !strncmp(\"HEAD\", str, len) &&\n-\t\t    !strncmp(real_ref, \"refs/\", 5)) {\n-\t\t\terror(\"reflog for HEAD has not been implemented yet\\n\"\n-\t\t\t      \"Maybe you could try %s%s instead, \"\n-\t\t\t      \"or just %s for current branch..\",\n-\t\t\t      strchr(real_ref+5, '/')+1, str+len, str+len);\n-\t\t\texit(-1);\n-\t\t}\n-\n \t\t/* Is it asking for N-th entry, or approxidate? */\n \t\tfor (i = nth = 0; 0 <= nth && i < reflog_len; i++) {\n \t\t\tchar ch = str[at+2+i];\n-- \n1.5.0.rc2.651.g3924-dirty\n"}]}