{"thread":{"id":"30834","subject":"[PATCH 0/9] Extending the shelf life of \"git describe\" output","startedAt":"2012-06-18T22:05:29Z","lastAt":"2012-06-20T07:40:00Z","messageCount":14,"participants":["Junio C Hamano","Thomas Rast"],"isPatch":true,"patchVersion":1,"patchTotal":9},"messages":[{"id":"193803","messageId":"1340057139-8311-1-git-send-email-gitster@pobox.com","threadId":"30834","inReplyTo":null,"subject":"[PATCH 0/9] Extending the shelf life of \"git describe\" output","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-18T22:05:29Z","receivedAt":"2012-06-18T22:05:29Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The output from \"git describe\" is a tagname, dash, number, dash, and\n'g' followed by an abbreviated commit object name, and it can be\nused anywhere we expect an object name.  This is so that people can\nuse it to name an exact commit in the inter-human communication. The\nrecipients are expected to be able to cut & paste it to their\ncommand line.\n\nBecause it uses an abbreviated commit object name, it is possible\nthat a \"git describe\" name taken earlier can become ambiguous over\ntime, even though \"git describe\" ensures the uniqueness of its\noutput in the repository when it runs.\n\nThis series teaches the sha1_name machinery to only look for\nunambigous commit object names when the caller knows that the name\nmust refer to a commit object.  By taking advantage of the fact that\nthere are more trees and blobs in a project's history than commits\nby definition, this reduces the potential of collisions, extending\nthe shelf life of \"git describe\" output by a little bit.\n\nBuilding on the foundation this series lays, I can see two separate\navenues to further extend this work:\n\n - You will further be able to extend the lifetime of uniqueness of\n   \"git describe\" output if you take advantage of the \"tagname\" or\n   \"number\". The current parser does not do this.\n\n   There are a number of ways to do this, but probably the cleanest\n   would be to (you only can do this when you have \"tagname\" tag\n   locally; you may not have it) pass the tag and the number down to\n   the find_short_*() routines with commit_only set, and when they\n   find a commit that match the prefix, inside is_commit_object()\n   test, check also that the commit reaches the given tag object in\n   the given number steps (otherwise discard it as it is not the one\n   you are looking for).\n\n - Some callers that are involved in the get_sha1_1() callpath know\n   that the name they have must be referring to commit objects (e.g.\n   get_parent() and get_nth_ancestor()).  It might be worthwhile to\n   let get_sha1_1() know that the caller knows the name it is\n   feeding must refer to a commit object, and have the uniqueness\n   logic take advantage of it.\n\n   I think that most of these callers are expecting to parse a\n   committish and the user may have given them the name of a a tag\n   object that peels to a commit, so you would need to add a new\n   GET_SHORT_COMMITTISH that allows any committish, in addition to\n   the GET_SHORT_COMMIT_ONLY this series adds, if you want to do\n   this.\n\nI do not claim the ownership rights on either of the above ideas;\npeople who find them interesting are welcome to pursue them (hint,\nhint).\n\nJunio C Hamano (9):\n  sha1_name.c: indentation fix\n  sha1_name.c: clarify what \"fake\" is for in find_short_object_filename()\n  sha1_name.c: rename \"now\" to \"current\"\n  sha1_name.c: refactor find_short_packed_object()\n  sha1_name.c: teach find_short_object_filename() a commit-only option\n  sha1_name.c: teach find_short_packed_object() a commit-only option\n  sha1_name.c: allow get_short_sha1() to take other flags\n  sha1_name.c: teach get_short_sha1() a commit-only option\n  sha1_name.c: get_describe_name() by definition groks only commits\n\n sha1_name.c | 157 ++++++++++++++++++++++++++++++++++++++----------------------\n 1 file changed, 101 insertions(+), 56 deletions(-)\n\n-- \n1.7.11\n"},{"id":"193804","messageId":"1340057139-8311-2-git-send-email-gitster@pobox.com","threadId":"30834","inReplyTo":"1340057139-8311-1-git-send-email-gitster@pobox.com","subject":"[PATCH 1/9] sha1_name.c: indentation fix","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-18T22:05:30Z","receivedAt":"2012-06-18T22:05:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Signed-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sha1_name.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 03ffc2c..5b0c845 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -103,10 +103,10 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne\n \t\t}\n \t\tif (first < num) {\n \t\t\tconst unsigned char *now, *next;\n-\t\t       now = nth_packed_object_sha1(p, first);\n+\t\t\tnow = nth_packed_object_sha1(p, first);\n \t\t\tif (match_sha(len, match, now)) {\n \t\t\t\tnext = nth_packed_object_sha1(p, first+1);\n-\t\t\t       if (!next|| !match_sha(len, match, next)) {\n+\t\t\t\tif (!next|| !match_sha(len, match, next)) {\n \t\t\t\t\t/* unique within this pack */\n \t\t\t\t\tif (!found) {\n \t\t\t\t\t\tfound_sha1 = now;\n-- \n1.7.11\n"},{"id":"193813","messageId":"1340057139-8311-3-git-send-email-gitster@pobox.com","threadId":"30834","inReplyTo":"1340057139-8311-1-git-send-email-gitster@pobox.com","subject":"[PATCH 2/9] sha1_name.c: clarify what \"fake\" is for in find_short_object_filename()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-18T22:05:31Z","receivedAt":"2012-06-18T22:05:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Signed-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sha1_name.c | 7 +++++++\n 1 file changed, 7 insertions(+)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 5b0c845..4cbca34 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -17,6 +17,13 @@ static int find_short_object_filename(int len, const char *name, unsigned char *\n \tstatic struct alternate_object_database *fakeent;\n \n \tif (!fakeent) {\n+\t\t/*\n+\t\t * Create a \"fake\" alternate object database that\n+\t\t * points to our own object database, to make it\n+\t\t * easier to get a temporary working space in\n+\t\t * alt->name/alt->base while iterating over the\n+\t\t * object databases including our own.\n+\t\t */\n \t\tconst char *objdir = get_object_directory();\n \t\tint objdir_len = strlen(objdir);\n \t\tint entlen = objdir_len + 43;\n-- \n1.7.11\n"},{"id":"193812","messageId":"1340057139-8311-4-git-send-email-gitster@pobox.com","threadId":"30834","inReplyTo":"1340057139-8311-1-git-send-email-gitster@pobox.com","subject":"[PATCH 3/9] sha1_name.c: rename \"now\" to \"current\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-18T22:05:32Z","receivedAt":"2012-06-18T22:05:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This variable points at the element we are currently looking at, and\ndoes not have anything to do with the current time which the name\n\"now\" implies.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sha1_name.c | 16 ++++++++--------\n 1 file changed, 8 insertions(+), 8 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 4cbca34..5224f39 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -93,11 +93,11 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne\n \t\tlast = num;\n \t\twhile (first < last) {\n \t\t\tuint32_t mid = (first + last) / 2;\n-\t\t\tconst unsigned char *now;\n+\t\t\tconst unsigned char *current;\n \t\t\tint cmp;\n \n-\t\t\tnow = nth_packed_object_sha1(p, mid);\n-\t\t\tcmp = hashcmp(match, now);\n+\t\t\tcurrent = nth_packed_object_sha1(p, mid);\n+\t\t\tcmp = hashcmp(match, current);\n \t\t\tif (!cmp) {\n \t\t\t\tfirst = mid;\n \t\t\t\tbreak;\n@@ -109,17 +109,17 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne\n \t\t\tlast = mid;\n \t\t}\n \t\tif (first < num) {\n-\t\t\tconst unsigned char *now, *next;\n-\t\t\tnow = nth_packed_object_sha1(p, first);\n-\t\t\tif (match_sha(len, match, now)) {\n+\t\t\tconst unsigned char *current, *next;\n+\t\t\tcurrent = nth_packed_object_sha1(p, first);\n+\t\t\tif (match_sha(len, match, current)) {\n \t\t\t\tnext = nth_packed_object_sha1(p, first+1);\n \t\t\t\tif (!next|| !match_sha(len, match, next)) {\n \t\t\t\t\t/* unique within this pack */\n \t\t\t\t\tif (!found) {\n-\t\t\t\t\t\tfound_sha1 = now;\n+\t\t\t\t\t\tfound_sha1 = current;\n \t\t\t\t\t\tfound++;\n \t\t\t\t\t}\n-\t\t\t\t\telse if (hashcmp(found_sha1, now)) {\n+\t\t\t\t\telse if (hashcmp(found_sha1, current)) {\n \t\t\t\t\t\tfound = 2;\n \t\t\t\t\t\tbreak;\n \t\t\t\t\t}\n-- \n1.7.11\n"},{"id":"193806","messageId":"1340057139-8311-5-git-send-email-gitster@pobox.com","threadId":"30834","inReplyTo":"1340057139-8311-1-git-send-email-gitster@pobox.com","subject":"[PATCH 4/9] sha1_name.c: refactor find_short_packed_object()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-18T22:05:33Z","receivedAt":"2012-06-18T22:05:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Extract the logic to find object(s) that match a given prefix inside\na single pack into a separate helper function, and give it a bit more\ncomment.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sha1_name.c | 103 +++++++++++++++++++++++++++++++++---------------------------\n 1 file changed, 56 insertions(+), 47 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 5224f39..e03992c 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -78,6 +78,59 @@ static int match_sha(unsigned len, const unsigned char *a, const unsigned char *\n \treturn 1;\n }\n \n+static int unique_in_pack(int len,\n+\t\t\t  const unsigned char *match,\n+\t\t\t  struct packed_git *p,\n+\t\t\t  const unsigned char **found_sha1,\n+\t\t\t  int seen_so_far)\n+{\n+\tuint32_t num, last, i, first = 0;\n+\tconst unsigned char *current = NULL;\n+\n+\topen_pack_index(p);\n+\tnum = p->num_objects;\n+\tlast = num;\n+\twhile (first < last) {\n+\t\tuint32_t mid = (first + last) / 2;\n+\t\tconst unsigned char *current;\n+\t\tint cmp;\n+\n+\t\tcurrent = nth_packed_object_sha1(p, mid);\n+\t\tcmp = hashcmp(match, current);\n+\t\tif (!cmp) {\n+\t\t\tfirst = mid;\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (cmp > 0) {\n+\t\t\tfirst = mid+1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tlast = mid;\n+\t}\n+\n+\t/*\n+\t * At this point, \"first\" is the location of the lowest object\n+\t * with an object name that could match \"match\".  See if we have\n+\t * 0, 1 or more objects that actually match(es).\n+\t */\n+\tfor (i = first; i < num; i++) {\n+\t\tcurrent = nth_packed_object_sha1(p, first);\n+\t\tif (!match_sha(len, match, current))\n+\t\t\tbreak;\n+\n+\t\t/* current matches */\n+\t\tif (!seen_so_far) {\n+\t\t\t*found_sha1 = current;\n+\t\t\tseen_so_far++;\n+\t\t} else if (seen_so_far) {\n+\t\t\t/* is it the same as the one previously found elsewhere? */\n+\t\t\tif (hashcmp(*found_sha1, current))\n+\t\t\t\treturn 2; /* definitely not unique */\n+\t\t}\n+\t}\n+\treturn seen_so_far;\n+}\n+\n static int find_short_packed_object(int len, const unsigned char *match, unsigned char *sha1)\n {\n \tstruct packed_git *p;\n@@ -85,53 +138,9 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne\n \tint found = 0;\n \n \tprepare_packed_git();\n-\tfor (p = packed_git; p && found < 2; p = p->next) {\n-\t\tuint32_t num, last;\n-\t\tuint32_t first = 0;\n-\t\topen_pack_index(p);\n-\t\tnum = p->num_objects;\n-\t\tlast = num;\n-\t\twhile (first < last) {\n-\t\t\tuint32_t mid = (first + last) / 2;\n-\t\t\tconst unsigned char *current;\n-\t\t\tint cmp;\n-\n-\t\t\tcurrent = nth_packed_object_sha1(p, mid);\n-\t\t\tcmp = hashcmp(match, current);\n-\t\t\tif (!cmp) {\n-\t\t\t\tfirst = mid;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t\tif (cmp > 0) {\n-\t\t\t\tfirst = mid+1;\n-\t\t\t\tcontinue;\n-\t\t\t}\n-\t\t\tlast = mid;\n-\t\t}\n-\t\tif (first < num) {\n-\t\t\tconst unsigned char *current, *next;\n-\t\t\tcurrent = nth_packed_object_sha1(p, first);\n-\t\t\tif (match_sha(len, match, current)) {\n-\t\t\t\tnext = nth_packed_object_sha1(p, first+1);\n-\t\t\t\tif (!next|| !match_sha(len, match, next)) {\n-\t\t\t\t\t/* unique within this pack */\n-\t\t\t\t\tif (!found) {\n-\t\t\t\t\t\tfound_sha1 = current;\n-\t\t\t\t\t\tfound++;\n-\t\t\t\t\t}\n-\t\t\t\t\telse if (hashcmp(found_sha1, current)) {\n-\t\t\t\t\t\tfound = 2;\n-\t\t\t\t\t\tbreak;\n-\t\t\t\t\t}\n-\t\t\t\t}\n-\t\t\t\telse {\n-\t\t\t\t\t/* not even unique within this pack */\n-\t\t\t\t\tfound = 2;\n-\t\t\t\t\tbreak;\n-\t\t\t\t}\n-\t\t\t}\n-\t\t}\n-\t}\n+\tfor (p = packed_git; p && found < 2; p = p->next)\n+\t\tfound = unique_in_pack(len, match, p, &found_sha1, found);\n+\n \tif (found == 1)\n \t\thashcpy(sha1, found_sha1);\n \treturn found;\n-- \n1.7.11\n"},{"id":"193809","messageId":"1340057139-8311-6-git-send-email-gitster@pobox.com","threadId":"30834","inReplyTo":"1340057139-8311-1-git-send-email-gitster@pobox.com","subject":"[PATCH 5/9] sha1_name.c: teach find_short_object_filename() a commit-only option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-18T22:05:34Z","receivedAt":"2012-06-18T22:05:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Signed-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sha1_name.c | 19 +++++++++++++++++--\n 1 file changed, 17 insertions(+), 2 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex e03992c..a283c85 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -9,7 +9,14 @@\n \n static int get_sha1_oneline(const char *, unsigned char *, struct commit_list *);\n \n-static int find_short_object_filename(int len, const char *name, unsigned char *sha1)\n+static int is_commit_object(const unsigned char *sha1)\n+{\n+\tint kind = sha1_object_info(sha1, NULL);\n+\treturn (kind == OBJ_COMMIT);\n+}\n+\n+static int find_short_object_filename(int len, const char *name, unsigned char *sha1,\n+\t\t\t\t      int commit_only)\n {\n \tstruct alternate_object_database *alt;\n \tchar hex[40];\n@@ -47,6 +54,14 @@ static int find_short_object_filename(int len, const char *name, unsigned char *\n \t\t\t\tcontinue;\n \t\t\tif (memcmp(de->d_name, name + 2, len - 2))\n \t\t\t\tcontinue;\n+\t\t\tif (commit_only) {\n+\t\t\t\tchar found_name[40];\n+\t\t\t\tunsigned char found_bin[20];\n+\t\t\t\tsprintf(found_name, \"%.2s%s\", name, de->d_name);\n+\t\t\t\tif (get_sha1_hex(found_name, found_bin) ||\n+\t\t\t\t    !is_commit_object(found_bin))\n+\t\t\t\t\tcontinue; /* not a commit object name */\n+\t\t\t}\n \t\t\tif (!found) {\n \t\t\t\tmemcpy(hex + 2, de->d_name, 38);\n \t\t\t\tfound++;\n@@ -156,7 +171,7 @@ static int find_unique_short_object(int len, char *canonical,\n \tunsigned char unpacked_sha1[20], packed_sha1[20];\n \n \tprepare_alt_odb();\n-\thas_unpacked = find_short_object_filename(len, canonical, unpacked_sha1);\n+\thas_unpacked = find_short_object_filename(len, canonical, unpacked_sha1, 0);\n \thas_packed = find_short_packed_object(len, res, packed_sha1);\n \tif (!has_unpacked && !has_packed)\n \t\treturn SHORT_NAME_NOT_FOUND;\n-- \n1.7.11\n"},{"id":"193811","messageId":"1340057139-8311-7-git-send-email-gitster@pobox.com","threadId":"30834","inReplyTo":"1340057139-8311-1-git-send-email-gitster@pobox.com","subject":"[PATCH 5/9] sha1_name.c: teach find_short_object_filename() a commit-only option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-18T22:05:35Z","receivedAt":"2012-06-18T22:05:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Signed-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sha1_name.c | 19 +++++++++++++++++--\n 1 file changed, 17 insertions(+), 2 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex e03992c..a283c85 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -9,7 +9,14 @@\n \n static int get_sha1_oneline(const char *, unsigned char *, struct commit_list *);\n \n-static int find_short_object_filename(int len, const char *name, unsigned char *sha1)\n+static int is_commit_object(const unsigned char *sha1)\n+{\n+\tint kind = sha1_object_info(sha1, NULL);\n+\treturn (kind == OBJ_COMMIT);\n+}\n+\n+static int find_short_object_filename(int len, const char *name, unsigned char *sha1,\n+\t\t\t\t      int commit_only)\n {\n \tstruct alternate_object_database *alt;\n \tchar hex[40];\n@@ -47,6 +54,14 @@ static int find_short_object_filename(int len, const char *name, unsigned char *\n \t\t\t\tcontinue;\n \t\t\tif (memcmp(de->d_name, name + 2, len - 2))\n \t\t\t\tcontinue;\n+\t\t\tif (commit_only) {\n+\t\t\t\tchar found_name[40];\n+\t\t\t\tunsigned char found_bin[20];\n+\t\t\t\tsprintf(found_name, \"%.2s%s\", name, de->d_name);\n+\t\t\t\tif (get_sha1_hex(found_name, found_bin) ||\n+\t\t\t\t    !is_commit_object(found_bin))\n+\t\t\t\t\tcontinue; /* not a commit object name */\n+\t\t\t}\n \t\t\tif (!found) {\n \t\t\t\tmemcpy(hex + 2, de->d_name, 38);\n \t\t\t\tfound++;\n@@ -156,7 +171,7 @@ static int find_unique_short_object(int len, char *canonical,\n \tunsigned char unpacked_sha1[20], packed_sha1[20];\n \n \tprepare_alt_odb();\n-\thas_unpacked = find_short_object_filename(len, canonical, unpacked_sha1);\n+\thas_unpacked = find_short_object_filename(len, canonical, unpacked_sha1, 0);\n \thas_packed = find_short_packed_object(len, res, packed_sha1);\n \tif (!has_unpacked && !has_packed)\n \t\treturn SHORT_NAME_NOT_FOUND;\n-- \n1.7.11\n"},{"id":"193808","messageId":"1340057139-8311-8-git-send-email-gitster@pobox.com","threadId":"30834","inReplyTo":"1340057139-8311-1-git-send-email-gitster@pobox.com","subject":"[PATCH 6/9] sha1_name.c: teach find_short_packed_object() a commit-only option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-18T22:05:36Z","receivedAt":"2012-06-18T22:05:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Signed-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sha1_name.c | 11 ++++++++---\n 1 file changed, 8 insertions(+), 3 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex a283c85..262d7e1 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -97,6 +97,7 @@ static int unique_in_pack(int len,\n \t\t\t  const unsigned char *match,\n \t\t\t  struct packed_git *p,\n \t\t\t  const unsigned char **found_sha1,\n+\t\t\t  int commit_only,\n \t\t\t  int seen_so_far)\n {\n \tuint32_t num, last, i, first = 0;\n@@ -134,6 +135,8 @@ static int unique_in_pack(int len,\n \t\t\tbreak;\n \n \t\t/* current matches */\n+\t\tif (commit_only && !is_commit_object(current))\n+\t\t\tcontinue;\n \t\tif (!seen_so_far) {\n \t\t\t*found_sha1 = current;\n \t\t\tseen_so_far++;\n@@ -146,7 +149,8 @@ static int unique_in_pack(int len,\n \treturn seen_so_far;\n }\n \n-static int find_short_packed_object(int len, const unsigned char *match, unsigned char *sha1)\n+static int find_short_packed_object(int len, const unsigned char *match,\n+\t\t\t\t    unsigned char *sha1, int commit_only)\n {\n \tstruct packed_git *p;\n \tconst unsigned char *found_sha1 = NULL;\n@@ -154,7 +158,8 @@ static int find_short_packed_object(int len, const unsigned char *match, unsigne\n \n \tprepare_packed_git();\n \tfor (p = packed_git; p && found < 2; p = p->next)\n-\t\tfound = unique_in_pack(len, match, p, &found_sha1, found);\n+\t\tfound = unique_in_pack(len, match, p, &found_sha1,\n+\t\t\t\t       commit_only, found);\n \n \tif (found == 1)\n \t\thashcpy(sha1, found_sha1);\n@@ -172,7 +177,7 @@ static int find_unique_short_object(int len, char *canonical,\n \n \tprepare_alt_odb();\n \thas_unpacked = find_short_object_filename(len, canonical, unpacked_sha1, 0);\n-\thas_packed = find_short_packed_object(len, res, packed_sha1);\n+\thas_packed = find_short_packed_object(len, res, packed_sha1, 0);\n \tif (!has_unpacked && !has_packed)\n \t\treturn SHORT_NAME_NOT_FOUND;\n \tif (1 < has_unpacked || 1 < has_packed)\n-- \n1.7.11\n"},{"id":"193810","messageId":"1340057139-8311-9-git-send-email-gitster@pobox.com","threadId":"30834","inReplyTo":"1340057139-8311-1-git-send-email-gitster@pobox.com","subject":"[PATCH 7/9] sha1_name.c: allow get_short_sha1() to take other flags","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-18T22:05:37Z","receivedAt":"2012-06-18T22:05:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Instead of a separate \"int quietly\" argument, make it take \"unsigned flags\"\nso that we can pass other options to it.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sha1_name.c | 9 ++++++---\n 1 file changed, 6 insertions(+), 3 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 262d7e1..df11ded 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -193,12 +193,15 @@ static int find_unique_short_object(int len, char *canonical,\n \treturn 0;\n }\n \n+#define GET_SHORT_QUIETLY 01\n+\n static int get_short_sha1(const char *name, int len, unsigned char *sha1,\n-\t\t\t  int quietly)\n+\t\t\t  unsigned flags)\n {\n \tint i, status;\n \tchar canonical[40];\n \tunsigned char res[20];\n+\tint quietly = !!(flags & GET_SHORT_QUIETLY);\n \n \tif (len < MINIMUM_ABBREV || len > 40)\n \t\treturn -1;\n@@ -240,7 +243,7 @@ const char *find_unique_abbrev(const unsigned char *sha1, int len)\n \t\treturn hex;\n \twhile (len < 40) {\n \t\tunsigned char sha1_ret[20];\n-\t\tstatus = get_short_sha1(hex, len, sha1_ret, 1);\n+\t\tstatus = get_short_sha1(hex, len, sha1_ret, GET_SHORT_QUIETLY);\n \t\tif (exists\n \t\t    ? !status\n \t\t    : status == SHORT_NAME_NOT_FOUND) {\n@@ -571,7 +574,7 @@ static int get_describe_name(const char *name, int len, unsigned char *sha1)\n \t\t\tif (ch == 'g' && cp[-1] == '-') {\n \t\t\t\tcp++;\n \t\t\t\tlen -= cp - name;\n-\t\t\t\treturn get_short_sha1(cp, len, sha1, 1);\n+\t\t\t\treturn get_short_sha1(cp, len, sha1, GET_SHORT_QUIETLY);\n \t\t\t}\n \t\t}\n \t}\n-- \n1.7.11\n"},{"id":"193805","messageId":"1340057139-8311-10-git-send-email-gitster@pobox.com","threadId":"30834","inReplyTo":"1340057139-8311-1-git-send-email-gitster@pobox.com","subject":"[PATCH 8/9] sha1_name.c: teach get_short_sha1() a commit-only option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-18T22:05:38Z","receivedAt":"2012-06-18T22:05:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Signed-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sha1_name.c | 13 +++++++++----\n 1 file changed, 9 insertions(+), 4 deletions(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex df11ded..4a0fefd 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -170,14 +170,17 @@ static int find_short_packed_object(int len, const unsigned char *match,\n #define SHORT_NAME_AMBIGUOUS (-2)\n \n static int find_unique_short_object(int len, char *canonical,\n-\t\t\t\t    unsigned char *res, unsigned char *sha1)\n+\t\t\t\t    unsigned char *res, unsigned char *sha1,\n+\t\t\t\t    int commit_only)\n {\n \tint has_unpacked, has_packed;\n \tunsigned char unpacked_sha1[20], packed_sha1[20];\n \n \tprepare_alt_odb();\n-\thas_unpacked = find_short_object_filename(len, canonical, unpacked_sha1, 0);\n-\thas_packed = find_short_packed_object(len, res, packed_sha1, 0);\n+\thas_unpacked = find_short_object_filename(len, canonical, unpacked_sha1,\n+\t\t\t\t\t\t  commit_only);\n+\thas_packed = find_short_packed_object(len, res, packed_sha1,\n+\t\t\t\t\t      commit_only);\n \tif (!has_unpacked && !has_packed)\n \t\treturn SHORT_NAME_NOT_FOUND;\n \tif (1 < has_unpacked || 1 < has_packed)\n@@ -194,6 +197,7 @@ static int find_unique_short_object(int len, char *canonical,\n }\n \n #define GET_SHORT_QUIETLY 01\n+#define GET_SHORT_COMMIT_ONLY 02\n \n static int get_short_sha1(const char *name, int len, unsigned char *sha1,\n \t\t\t  unsigned flags)\n@@ -226,7 +230,8 @@ static int get_short_sha1(const char *name, int len, unsigned char *sha1,\n \t\tres[i >> 1] |= val;\n \t}\n \n-\tstatus = find_unique_short_object(i, canonical, res, sha1);\n+\tstatus = find_unique_short_object(i, canonical, res, sha1,\n+\t\t\t\t\t  !!(flags & GET_SHORT_COMMIT_ONLY));\n \tif (!quietly && (status == SHORT_NAME_AMBIGUOUS))\n \t\treturn error(\"short SHA1 %.*s is ambiguous.\", len, canonical);\n \treturn status;\n-- \n1.7.11\n"},{"id":"193807","messageId":"1340057139-8311-11-git-send-email-gitster@pobox.com","threadId":"30834","inReplyTo":"1340057139-8311-1-git-send-email-gitster@pobox.com","subject":"[PATCH 9/9] sha1_name.c: get_describe_name() by definition groks only commits","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-18T22:05:39Z","receivedAt":"2012-06-18T22:05:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Signed-off-by: Junio C Hamano <gitster@pobox.com>\n---\n sha1_name.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/sha1_name.c b/sha1_name.c\nindex 4a0fefd..b09a23e 100644\n--- a/sha1_name.c\n+++ b/sha1_name.c\n@@ -569,6 +569,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1)\n static int get_describe_name(const char *name, int len, unsigned char *sha1)\n {\n \tconst char *cp;\n+\tunsigned flags = GET_SHORT_QUIETLY | GET_SHORT_COMMIT_ONLY;\n \n \tfor (cp = name + len - 1; name + 2 <= cp; cp--) {\n \t\tchar ch = *cp;\n@@ -579,7 +580,7 @@ static int get_describe_name(const char *name, int len, unsigned char *sha1)\n \t\t\tif (ch == 'g' && cp[-1] == '-') {\n \t\t\t\tcp++;\n \t\t\t\tlen -= cp - name;\n-\t\t\t\treturn get_short_sha1(cp, len, sha1, GET_SHORT_QUIETLY);\n+\t\t\t\treturn get_short_sha1(cp, len, sha1, flags);\n \t\t\t}\n \t\t}\n \t}\n-- \n1.7.11\n"},{"id":"193820","messageId":"877gv34vtg.fsf@thomas.inf.ethz.ch","threadId":"30834","inReplyTo":"1340057139-8311-1-git-send-email-gitster@pobox.com","subject":"Re: [PATCH 0/9] Extending the shelf life of \"git describe\" output","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2012-06-19T07:14:51Z","receivedAt":"2012-06-19T07:14:51Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> This series teaches the sha1_name machinery to only look for\n> unambigous commit object names when the caller knows that the name\n> must refer to a commit object.\n[...]\n>  - You will further be able to extend the lifetime of uniqueness of\n>    \"git describe\" output if you take advantage of the \"tagname\" or\n>    \"number\". The current parser does not do this.\n>\n>    There are a number of ways to do this, but probably the cleanest\n>    would be to (you only can do this when you have \"tagname\" tag\n>    locally; you may not have it) pass the tag and the number down to\n>    the find_short_*() routines with commit_only set, and when they\n>    find a commit that match the prefix, inside is_commit_object()\n>    test, check also that the commit reaches the given tag object in\n>    the given number steps (otherwise discard it as it is not the one\n>    you are looking for).\n>\n>  - Some callers that are involved in the get_sha1_1() callpath know\n>    that the name they have must be referring to commit objects (e.g.\n>    get_parent() and get_nth_ancestor()).  It might be worthwhile to\n>    let get_sha1_1() know that the caller knows the name it is\n>    feeding must refer to a commit object, and have the uniqueness\n>    logic take advantage of it.\n>\n>    I think that most of these callers are expecting to parse a\n>    committish and the user may have given them the name of a a tag\n>    object that peels to a commit, so you would need to add a new\n>    GET_SHORT_COMMITTISH that allows any committish, in addition to\n>    the GET_SHORT_COMMIT_ONLY this series adds, if you want to do\n>    this.\n\nTwo random thoughts:\n\n* The commit_only flag is only one thing you may \"know\" about the\n  parsing, as you state above.  E.g., we may know the distance from a\n  certain tag.  Given this, wouldn't it be cleaner to patch a struct\n  things_we_know into the call chain instead of only a flag?\n\n* The treeish:path syntax also \"knows\" that the left side must be or\n  peel to a tree, so it makes no sense to go looking for a blob.\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"193898","messageId":"7vfw9qyk6m.fsf@alter.siamese.dyndns.org","threadId":"30834","inReplyTo":"877gv34vtg.fsf@thomas.inf.ethz.ch","subject":"Re: [PATCH 0/9] Extending the shelf life of \"git describe\" output","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-19T23:08:01Z","receivedAt":"2012-06-19T23:08:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@student.ethz.ch> writes:\n\n> Two random thoughts:\n>\n> * The commit_only flag is only one thing you may \"know\" about the\n>   parsing, as you state above.  E.g., we may know the distance from a\n>   certain tag.  Given this, wouldn't it be cleaner to patch a struct\n>   things_we_know into the call chain instead of only a flag?\n>\n> * The treeish:path syntax also \"knows\" that the left side must be or\n>   peel to a tree, so it makes no sense to go looking for a blob.\n\nBoth good.  I take it to mean that we found a volunteer to take the\nownership of the second idea to build on top of the series ;-)\n\nThanks.\n"},{"id":"193923","messageId":"877gv2xwhb.fsf@thomas.inf.ethz.ch","threadId":"30834","inReplyTo":"7vfw9qyk6m.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 0/9] Extending the shelf life of \"git describe\" output","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2012-06-20T07:40:00Z","receivedAt":"2012-06-20T07:40:00Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Thomas Rast <trast@student.ethz.ch> writes:\n>\n>> Two random thoughts:\n>>\n>> * The commit_only flag is only one thing you may \"know\" about the\n>>   parsing, as you state above.  E.g., we may know the distance from a\n>>   certain tag.  Given this, wouldn't it be cleaner to patch a struct\n>>   things_we_know into the call chain instead of only a flag?\n>>\n>> * The treeish:path syntax also \"knows\" that the left side must be or\n>>   peel to a tree, so it makes no sense to go looking for a blob.\n>\n> Both good.  I take it to mean that we found a volunteer to take the\n> ownership of the second idea to build on top of the series ;-)\n\nDoes the idea come with round tuits included? :-)\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"}]}