{"thread":{"id":"29764","subject":"[PATCH 1/2] builtin/symbolic-ref.c: add option to fall back to normal ref","startedAt":"2012-02-27T22:08:56Z","lastAt":"2012-02-27T22:40:37Z","messageCount":3,"participants":["Jan Krüger","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"185573","messageId":"1330380536-9647-1-git-send-email-jk@jk.gs","threadId":"29764","inReplyTo":null,"subject":"[PATCH 1/2] builtin/symbolic-ref.c: add option to fall back to normal ref","fromName":"Jan Krüger","fromEmail":"jk@jk.gs","sentAt":"2012-02-27T22:08:56Z","receivedAt":"2012-02-27T22:08:56Z","isPatch":true,"sender":{"key":"jk@jk.gs","avatar":"https://avatars.githubusercontent.com/u/1774?v=4"},"body":"Frequently, people want to determine the current value of HEAD in\nscripts. However, there is no tool that can always output it, since \"git\nsymbolic-ref\" will fail if HEAD isn't currently a symref, and other\ntools (e.g. \"git rev-parse --symbolic-full-name\") will also fail in\none of HEAD's possible modes.\n\nTo resolve this situation, add the new -f option to symbolic-ref that\nfalls back to outputting the value of HEAD as a normal ref if necessary.\n\nSigned-off-by: Jan Krüger <jk@jk.gs>\n---\n Documentation/git-symbolic-ref.txt |    7 ++++++-\n builtin/symbolic-ref.c             |   16 ++++++++++++++--\n 2 files changed, 20 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-symbolic-ref.txt b/Documentation/git-symbolic-ref.txt\nindex a45d4c4..a05819b 100644\n--- a/Documentation/git-symbolic-ref.txt\n+++ b/Documentation/git-symbolic-ref.txt\n@@ -8,7 +8,7 @@ git-symbolic-ref - Read and modify symbolic refs\n SYNOPSIS\n --------\n [verse]\n-'git symbolic-ref' [-q] [-m <reason>] <name> [<ref>]\n+'git symbolic-ref' [-q] [-f] [-m <reason>] <name> [<ref>]\n \n DESCRIPTION\n -----------\n@@ -33,6 +33,11 @@ OPTIONS\n \tsymbolic ref but a detached HEAD; instead exit with\n \tnon-zero status silently.\n \n+-f::\n+\tWhen showing the current value of <name>, do not fail if it is\n+\tnot a symbolic ref; instead output the SHA1 value referenced by\n+\t<name>.\n+\n -m::\n \tUpdate the reflog for <name> with <reason>.  This is valid only\n \twhen creating or updating a symbolic ref.\ndiff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c\nindex 2ef5962..2e0a86f 100644\n--- a/builtin/symbolic-ref.c\n+++ b/builtin/symbolic-ref.c\n@@ -8,6 +8,8 @@ static const char * const git_symbolic_ref_usage[] = {\n \tNULL\n };\n \n+static int fallback_regular_ref;\n+\n static void check_symref(const char *HEAD, int quiet)\n {\n \tunsigned char sha1[20];\n@@ -17,10 +19,18 @@ static void check_symref(const char *HEAD, int quiet)\n \tif (!refs_heads_master)\n \t\tdie(\"No such ref: %s\", HEAD);\n \telse if (!(flag & REF_ISSYMREF)) {\n-\t\tif (!quiet)\n+\t\tif (fallback_regular_ref) {\n+\t\t\tchar sha1[20];\n+\t\t\tif (!get_sha1(HEAD, sha1))\n+\t\t\t\tputs(sha1_to_hex(sha1));\n+\t\t\telse\n+\t\t\t\tdie(\"failed to resolve ref %s\", HEAD);\n+\t\t\treturn;\n+\t\t} else if (!quiet) {\n \t\t\tdie(\"ref %s is not a symbolic ref\", HEAD);\n-\t\telse\n+\t\t} else {\n \t\t\texit(1);\n+\t\t}\n \t}\n \tputs(refs_heads_master);\n }\n@@ -32,6 +42,8 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)\n \tstruct option options[] = {\n \t\tOPT__QUIET(&quiet,\n \t\t\t\"suppress error message for non-symbolic (detached) refs\"),\n+\t\tOPT_BOOLEAN('f', NULL, &fallback_regular_ref,\n+\t\t\t\t\t\"fall back to showing as a regular ref\"),\n \t\tOPT_STRING('m', NULL, &msg, \"reason\", \"reason of the update\"),\n \t\tOPT_END(),\n \t};\n-- \n1.7.9.2.302.g3724c.dirty\n\n\nFrom 1fffb746a65aac88d3af9bae785b1cfa58cbf31c Mon Sep 17 00:00:00 2001\nFrom: =?UTF-8?q?Jan=20Kr=C3=BCger?= <jk@jk.gs>\nDate: Mon, 27 Feb 2012 22:40:13 +0100\nSubject: [PATCH 2/2] builtin/symbolic-ref.c: add option to output shortened\n ref\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\n\nIn scripts meant to generate user-consumable output, it can be helpful\nto resolve a symbolic ref and output the result in a shortened form,\nsuch as for use in shell prompts. Add a new -s option to allow this.\n\nSigned-off-by: Jan Krüger <jk@jk.gs>\n---\n Documentation/git-symbolic-ref.txt |    6 +++++-\n builtin/symbolic-ref.c             |    5 +++++\n 2 files changed, 10 insertions(+), 1 deletion(-)\n\ndiff --git a/Documentation/git-symbolic-ref.txt b/Documentation/git-symbolic-ref.txt\nindex a05819b..7f108ce 100644\n--- a/Documentation/git-symbolic-ref.txt\n+++ b/Documentation/git-symbolic-ref.txt\n@@ -8,7 +8,7 @@ git-symbolic-ref - Read and modify symbolic refs\n SYNOPSIS\n --------\n [verse]\n-'git symbolic-ref' [-q] [-f] [-m <reason>] <name> [<ref>]\n+'git symbolic-ref' [-q] [-f] [-s] [-m <reason>] <name> [<ref>]\n \n DESCRIPTION\n -----------\n@@ -38,6 +38,10 @@ OPTIONS\n \tnot a symbolic ref; instead output the SHA1 value referenced by\n \t<name>.\n \n+-s::\n+\tWhen showing the value of <name> as a symbolic ref, try to shorten the\n+\tvalue, e.g. from `refs/heads/master` to `master`.\n+\n -m::\n \tUpdate the reflog for <name> with <reason>.  This is valid only\n \twhen creating or updating a symbolic ref.\ndiff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c\nindex 2e0a86f..df8da11 100644\n--- a/builtin/symbolic-ref.c\n+++ b/builtin/symbolic-ref.c\n@@ -9,6 +9,7 @@ static const char * const git_symbolic_ref_usage[] = {\n };\n \n static int fallback_regular_ref;\n+static int shorten;\n \n static void check_symref(const char *HEAD, int quiet)\n {\n@@ -32,6 +33,9 @@ static void check_symref(const char *HEAD, int quiet)\n \t\t\texit(1);\n \t\t}\n \t}\n+\tif (shorten)\n+\t\trefs_heads_master = shorten_unambiguous_ref(\n+\t\t\trefs_heads_master, 0);\n \tputs(refs_heads_master);\n }\n \n@@ -44,6 +48,7 @@ int cmd_symbolic_ref(int argc, const char **argv, const char *prefix)\n \t\t\t\"suppress error message for non-symbolic (detached) refs\"),\n \t\tOPT_BOOLEAN('f', NULL, &fallback_regular_ref,\n \t\t\t\t\t\"fall back to showing as a regular ref\"),\n+\t\tOPT_BOOLEAN('s', NULL, &shorten, \"shorten ref output\"),\n \t\tOPT_STRING('m', NULL, &msg, \"reason\", \"reason of the update\"),\n \t\tOPT_END(),\n \t};\n-- \n1.7.9.2.302.g3724c.dirty\n"},{"id":"185575","messageId":"7v1upf6hp5.fsf@alter.siamese.dyndns.org","threadId":"29764","inReplyTo":"1330380536-9647-1-git-send-email-jk@jk.gs","subject":"Re: [PATCH 1/2] builtin/symbolic-ref.c: add option to fall back to normal ref","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-02-27T22:21:26Z","receivedAt":"2012-02-27T22:21:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jan Krüger <jk@jk.gs> writes:\n\n> Frequently, people want to determine the current value of HEAD in\n> scripts. However, there is no tool that can always output it, since \"git\n> symbolic-ref\" will fail if HEAD isn't currently a symref, and other\n> tools (e.g. \"git rev-parse --symbolic-full-name\") will also fail in\n> one of HEAD's possible modes.\n\nWhat is \"the current value of HEAD\"?\n\nThe symbolic-ref command is there for people who _care_ about the\ndistinction between a HEAD that points at a branch and a HEAD that points\ndirectly at a commit.  There is no room for the command to \"fall back\"\nanywhere, as that will only introduce an unnecessary ambiguity to the\ncommand whose sole purpose is to be able to tell them apart.\n\nIf the caller does not need to know if the HEAD is detached or not, and\nwants to know what commit it points at, why is it insufficient to just use\nrev-parse, e.g. \"git rev-parse --verify HEAD\"?\n"},{"id":"185579","messageId":"4F4C0665.6000103@jk.gs","threadId":"29764","inReplyTo":"7v1upf6hp5.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 1/2] builtin/symbolic-ref.c: add option to fall back to normal ref","fromName":"Jan Krüger","fromEmail":"jk@jk.gs","sentAt":"2012-02-27T22:40:37Z","receivedAt":"2012-02-27T22:40:37Z","isPatch":true,"sender":{"key":"jk@jk.gs","avatar":"https://avatars.githubusercontent.com/u/1774?v=4"},"body":"On 02/27/2012 11:21 PM, Junio C Hamano wrote:\n> What is \"the current value of HEAD\"?\n\nWell, essentially it contains a \"type\" and a \"value\". The type is either\n\"symbolic\" or \"not symbolic\" and the value is a ref if HEAD is currently\nsymbolic or a SHA1 otherwise.\n\nThese definitions don't come from the glossary, obviously. It's just the\nway I interpret HEAD. If you think the patch would be better off with a\ndifferent wording, I'd be happy for suggestions.\n\nIn any case, if you have the \"value\" without the \"type\", you can\nactually derive the \"type\" from the \"value\": if it has the shape of a\nSHA1, it was a direct ref; otherwise it was a symbolic ref (unless the\nuser has a ref that looks like a SHA1 but in that case some other tools\ndo funny things, too).\n\n> The symbolic-ref command is there for people who _care_ about the\n> distinction between a HEAD that points at a branch and a HEAD that points\n> directly at a commit.  There is no room for the command to \"fall back\"\n> anywhere, as that will only introduce an unnecessary ambiguity to the\n> command whose sole purpose is to be able to tell them apart.\n\nThat's why it's an optional thing.\n\n> If the caller does not need to know if the HEAD is detached or not, and\n> wants to know what commit it points at, why is it insufficient to just use\n> rev-parse, e.g. \"git rev-parse --verify HEAD\"?\n\nThe use case here is having one convenient command to remember what is\ncurrently checked out, and being able to go back to that later. \"git\ncheckout\" will do the right thing if you just give it \"master\" or a\ncomplete SHA1, so all we need to remember is that.\n\n\"git rev-parse --verify HEAD\" will only give us the SHA1, even if HEAD\nisn't actually detached.\n\nIncidentally, the -s switch in the second patch makes this even easier:\n\n    OLDHEAD=`git symbolic-ref -s -f HEAD`\n    # do stuff here that involves switching branches or detaching or\n    # whatever\n    git checkout $OLDHEAD\n\nWithout these patches, the shortest way I can think of to do the same\nthing would be:\n\n    OLDHEAD=`git rev-parse --symbolic-full-name HEAD`\n    [ \"$OLDHEAD\" = \"HEAD\" ] && OLDHEAD=`git rev-parse HEAD`\n    # ...\n\n-Jan\n"}]}