{"thread":{"id":"21295","subject":"Re: [PATCH v2] new --dirty option for git describe","startedAt":"2009-10-20T14:27:11Z","lastAt":"2009-10-20T16:30:38Z","messageCount":3,"participants":["Jean Privat","Junio C Hamano"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"125478","messageId":"dffdbd190910200727r30e161ffka0b3cf764be26cd8@mail.gmail.com","threadId":"21295","inReplyTo":"1255800990-7806-1-git-send-email-jean@pryen.org","subject":"[PATCH v2] new --dirty option for git describe","fromName":"Jean Privat","fromEmail":"jean@pryen.org","sentAt":"2009-10-20T14:27:11Z","receivedAt":"2009-10-20T14:27:11Z","isPatch":true,"sender":{"key":"jean@pryen.org","avatar":"https://avatars.githubusercontent.com/u/135828?v=4"},"body":"With the --dirty option, git describe works on HEAD but append \"-dirty\"\nif the working tree is dirty. If the working tree is clean, nothing\nis appended.\n\n$ git describe --dirty\nv1.6.5-15-gc274db7\n$ echo >> Makefile\n$ git describe --dirty\nv1.6.5-15-gc274db7-dirty\n\n--dirty can also be used to specify what is append if the working\ntree is dirty.\n\n$ git describe --dirty=.mod\nv1.6.5-15-gc274db7.mod\n\nMany build scripts use `git describe` to produce a version number based\non the description of HEAD (on which is based the working tree) + saying\nthat if the working tree is dirty or no.\nThis patch helps the writing of such scripts since `git describe --dirty`\ndo directly the intended thing.\n\nAlternatives specifications:\n\n1 Describe the working tree by default and describe HEAD only if \"HEAD\"\n  is explicitly specified\nPro: does the right thing by default (both for users and for scripts)\nPro: is coherent with other git commands that works on the working tree\n     by default\nCon: breaks existing scripts (since the world is not ideal)\n\n2 Use --worktree instead of --dirty\nPro: does what it says: \"git describe --worktree\" will describe the\n     working three\nCon: is incoherent with other commands that do not require a --worktree\n     option to work on the working tree\nCon: unusable with an optional value: \"git describe --worktree=.mod\"\n     is quite unintuitive.\n\n3 Use --dirty as in this patch\nPro: make sense to specify an optional value (what the dirty mark is)\nPro: do not have any of the big cons of previous alternatives\n     * does not break scripts\n     * is not inconsistent with other git commands\nPro: has an easy fallback to alternative 1 if the world become suddenly\n     ideal, or at least allows some kind of future transition plan if\n     people *really* bother:\n     1- ask that scripts use either \"git describe HEAD\" or\n        \"git describe --dirty\" (no more \"git describe\")\n     2- change default\n     Once the transition is done, the role of the --dirty option will\n     just be the way to specify an alternative mark (and a noop if alone)\n\nSigned-off-by: Jean Privat <jean@pryen.org>\n\n---\n\nI tried to integrate the points of view of both Junio and Shawn.\nHowever, I am not sure that what I propose is the right solution.\n\n-J-\n---\n Documentation/git-describe.txt |    6 ++++++\n builtin-describe.c             |   25 ++++++++++++++++++++++++-\n t/t6120-describe.sh            |   15 +++++++++++++++\n 3 files changed, 45 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt\nindex b231dbb..5253d86 100644\n--- a/Documentation/git-describe.txt\n+++ b/Documentation/git-describe.txt\n@@ -9,6 +9,7 @@ git-describe - Show the most recent tag that is\nreachable from a commit\n SYNOPSIS\n --------\n 'git describe' [--all] [--tags] [--contains] [--abbrev=<n>] <committish>...\n+'git describe' [--all] [--tags] [--contains] [--abbrev=<n>] --dirty[=<mark>]\n\n DESCRIPTION\n -----------\n@@ -27,6 +28,11 @@ OPTIONS\n <committish>...::\n \tCommittish object names to describe.\n\n+--dirty[=<mark>]::\n+\tDescribe the working tree.\n+\tIt means describe HEAD and appends <mark> (`-dirty` by\n+\tdefault) if the working tree is dirty.\n+\n --all::\n \tInstead of using only the annotated tags, use any ref\n \tfound in `.git/refs/`.  This option enables matching\ndiff --git a/builtin-describe.c b/builtin-describe.c\nindex df67a73..84af981 100644\n--- a/builtin-describe.c\n+++ b/builtin-describe.c\n@@ -5,12 +5,14 @@\n #include \"builtin.h\"\n #include \"exec_cmd.h\"\n #include \"parse-options.h\"\n+#include \"diff.h\"\n\n #define SEEN\t\t(1u<<0)\n #define MAX_TAGS\t(FLAG_BITS - 1)\n\n static const char * const describe_usage[] = {\n \t\"git describe [options] <committish>*\",\n+\t\"git describe [options] --dirty\",\n \tNULL\n };\n\n@@ -23,6 +25,13 @@ static int max_candidates = 10;\n static int found_names;\n static const char *pattern;\n static int always;\n+static const char *dirty;\n+\n+/* diff-index command arguments to check if working tree is dirty. */\n+static const char *diff_index_args[] = {\n+\t\"diff-index\", \"--quiet\", \"HEAD\", \"--\", NULL\n+};\n+\n\n struct commit_name {\n \tstruct tag *tag;\n@@ -208,6 +217,8 @@ static void describe(const char *arg, int last_one)\n \t\tdisplay_name(n);\n \t\tif (longformat)\n \t\t\tshow_suffix(0, n->tag ? n->tag->tagged->sha1 : sha1);\n+\t\tif (dirty)\n+\t\t\tprintf(\"%s\", dirty);\n \t\tprintf(\"\\n\");\n \t\treturn;\n \t}\n@@ -265,7 +276,10 @@ static void describe(const char *arg, int last_one)\n \tif (!match_cnt) {\n \t\tconst unsigned char *sha1 = cmit->object.sha1;\n \t\tif (always) {\n-\t\t\tprintf(\"%s\\n\", find_unique_abbrev(sha1, abbrev));\n+\t\t\tprintf(\"%s\", find_unique_abbrev(sha1, abbrev));\n+\t\t\tif (dirty)\n+\t\t\t\tprintf(\"%s\", dirty);\n+\t\t\tprintf(\"\\n\");\n \t\t\treturn;\n \t\t}\n \t\tdie(\"cannot describe '%s'\", sha1_to_hex(sha1));\n@@ -300,6 +314,8 @@ static void describe(const char *arg, int last_one)\n \tdisplay_name(all_matches[0].name);\n \tif (abbrev)\n \t\tshow_suffix(all_matches[0].depth, cmit->object.sha1);\n+\tif (dirty)\n+\t\tprintf(\"%s\", dirty);\n \tprintf(\"\\n\");\n\n \tif (!last_one)\n@@ -324,6 +340,9 @@ int cmd_describe(int argc, const char **argv,\nconst char *prefix)\n \t\t\t   \"only consider tags matching <pattern>\"),\n \t\tOPT_BOOLEAN(0, \"always\",     &always,\n \t\t\t   \"show abbreviated commit object as fallback\"),\n+\t\t{OPTION_STRING, 0, \"dirty\",       &dirty, \"mark\",\n+\t\t\t   \"append <mark> on dirty working tree (default: \\\"-dirty\\\")\",\n+\t\t\t   PARSE_OPT_OPTARG, NULL, \"-dirty\"},\n \t\tOPT_END(),\n \t};\n\n@@ -360,7 +379,11 @@ int cmd_describe(int argc, const char **argv,\nconst char *prefix)\n \t}\n\n \tif (argc == 0) {\n+\t\tif (dirty && !cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1,\ndiff_index_args, prefix))\n+\t\t\tdirty = NULL;\n \t\tdescribe(\"HEAD\", 1);\n+\t} else if (dirty) {\n+\t\tdie(\"--dirty is incompatible with committishes\");\n \t} else {\n \t\twhile (argc-- > 0) {\n \t\t\tdescribe(*argv++, argc == 0);\ndiff --git a/t/t6120-describe.sh b/t/t6120-describe.sh\nindex 8c7e081..ee38f34 100755\n--- a/t/t6120-describe.sh\n+++ b/t/t6120-describe.sh\n@@ -123,6 +123,21 @@ test_expect_success 'rename tag Q back to A' '\n test_expect_success 'pack tag refs' 'git pack-refs'\n check_describe A-* HEAD\n\n+check_describe \"A-*[0-9a-f]\" --dirty\n+\n+test_expect_success 'set-up dirty working tree' '\n+\techo >>file\n+'\n+\n+check_describe \"A-*[0-9a-f]-dirty\" --dirty\n+\n+check_describe \"A-*[0-9a-f].mod\" --dirty=.mod\n+\n+test_expect_success 'describe --dirty HEAD' '\n+\tgit describe --dirty HEAD\n+\ttest $? != 0\n+'\n+\n test_expect_success 'set-up matching pattern tests' '\n \tgit tag -a -m test-annotated test-annotated &&\n \techo >>file &&\n-- \n1.6.5\n"},{"id":"125477","messageId":"dffdbd190910200731w5b49f329g5005539f875901e1@mail.gmail.com","threadId":"21295","inReplyTo":"dffdbd190910200727r30e161ffka0b3cf764be26cd8@mail.gmail.com","subject":"Re: [PATCH v2] new --dirty option for git describe","fromName":"Jean Privat","fromEmail":"jean@pryen.org","sentAt":"2009-10-20T14:31:45Z","receivedAt":"2009-10-20T14:31:45Z","isPatch":true,"sender":{"key":"jean@pryen.org","avatar":"https://avatars.githubusercontent.com/u/135828?v=4"},"body":"> --- a/Documentation/git-describe.txt\n> +++ b/Documentation/git-describe.txt\n> @@ -9,6 +9,7 @@ git-describe - Show the most recent tag that is\n> reachable from a commit\n\n%#$@!&&@ !!!\n\nI followed instructions from Documentation/SubmittingPatches about\nsending patches trought gmail imap, it did not seem to work.\nI will resend with git-send-email (and try on something else that\ngit@vger.kernel.org)\n\nSorry for that.\n\n-J\n"},{"id":"125488","messageId":"7vmy3mownl.fsf@alter.siamese.dyndns.org","threadId":"21295","inReplyTo":"dffdbd190910200727r30e161ffka0b3cf764be26cd8@mail.gmail.com","subject":"Re: [PATCH v2] new --dirty option for git describe","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-20T16:30:38Z","receivedAt":"2009-10-20T16:30:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jean Privat <jean@pryen.org> writes:\n\n> +test_expect_success 'describe --dirty HEAD' '\n> +\tgit describe --dirty HEAD\n> +\ttest $? != 0\n> +'\n\nWe tend to write this as\n\n\ttest_expect_success '...' '\n        \ttest_must_fail git describe --dirty HEAD\n\t'\n\nThe difference is when the tested command segfaults or dies in an\nuncontrolled fashion; test_must_fail diagnoses it as a failure,\nwhile \"test $? != 0\" at the end will say \"ok, the command correctly\nfailed\".\n"}]}