From: Junio C Hamano Date: Tue, 10 Nov 2009 20:30:43 +0000 (-0800) Subject: Merge branch 'jp/dirty-describe' X-Git-Tag: v1.6.6-rc0~66 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/48cbf915a4738097f291de06e23d293f79ff3f9e?ds=inline;hp=-c Merge branch 'jp/dirty-describe' * jp/dirty-describe: Teach "git describe" --dirty option --- 48cbf915a4738097f291de06e23d293f79ff3f9e diff --combined Documentation/git-describe.txt index 2f97916781,5253d86118..d7329eb4c0 --- a/Documentation/git-describe.txt +++ b/Documentation/git-describe.txt @@@ -9,6 -9,7 +9,7 @@@ git-describe - Show the most recent ta SYNOPSIS -------- 'git describe' [--all] [--tags] [--contains] [--abbrev=] ... + 'git describe' [--all] [--tags] [--contains] [--abbrev=] --dirty[=] DESCRIPTION ----------- @@@ -27,6 -28,11 +28,11 @@@ OPTION ...:: Committish object names to describe. + --dirty[=]:: + Describe the working tree. + It means describe HEAD and appends (`-dirty` by + default) if the working tree is dirty. + --all:: Instead of using only the annotated tags, use any ref found in `.git/refs/`. This option enables matching @@@ -44,9 -50,7 +50,9 @@@ --abbrev=:: Instead of using the default 7 hexadecimal digits as the - abbreviated object name, use digits. + abbreviated object name, use digits, or as many digits + as needed to form a unique object name. An of 0 + will suppress long format, only showing the closest tag. --candidates=:: Instead of considering only the 10 most recent tags as @@@ -70,8 -74,8 +76,8 @@@ This is useful when you want to see parts of the commit object name in "describe" output, even when the commit in question happens to be a tagged version. Instead of just emitting the tag name, it will - describe such a commit as v1.2-0-deadbeef (0th commit since tag v1.2 - that points at object deadbeef....). + describe such a commit as v1.2-0-gdeadbee (0th commit since tag v1.2 + that points at object deadbee....). --match :: Only consider tags matching the given pattern (can be used to avoid @@@ -110,7 -114,7 +116,7 @@@ the output shows the reference path as [torvalds@g5 git]$ git describe --all --abbrev=4 v1.0.5^2 tags/v1.0.0-21-g975b - [torvalds@g5 git]$ git describe --all HEAD^ + [torvalds@g5 git]$ git describe --all --abbrev=4 HEAD^ heads/lt/describe-7-g975b With --abbrev set to 0, the command can be used to find the @@@ -119,13 -123,6 +125,13 @@@ closest tagname without any suffix [torvalds@g5 git]$ git describe --abbrev=0 v1.0.5^2 tags/v1.0.0 +Note that the suffix you get if you type these commands today may be +longer than what Linus saw above when he ran these commands, as your +git repository may have new commits whose object names begin with +975b that did not exist back then, and "-g975b" suffix alone may not +be sufficient to disambiguate these commits. + + SEARCH STRATEGY --------------- diff --combined builtin-describe.c index eaa8a9d229,7dbbee36ac..390c14ec59 --- a/builtin-describe.c +++ b/builtin-describe.c @@@ -5,12 -5,14 +5,14 @@@ #include "builtin.h" #include "exec_cmd.h" #include "parse-options.h" + #include "diff.h" #define SEEN (1u<<0) #define MAX_TAGS (FLAG_BITS - 1) static const char * const describe_usage[] = { "git describe [options] *", + "git describe [options] --dirty", NULL }; @@@ -23,6 -25,13 +25,13 @@@ static int max_candidates = 10 static int found_names; static const char *pattern; static int always; + static const char *dirty; + + /* diff-index command arguments to check if working tree is dirty. */ + static const char *diff_index_args[] = { + "diff-index", "--quiet", "HEAD", "--", NULL + }; + struct commit_name { struct tag *tag; @@@ -180,6 -189,7 +189,6 @@@ static void describe(const char *arg, i unsigned char sha1[20]; struct commit *cmit, *gave_up_on = NULL; struct commit_list *list; - static int initialized = 0; struct commit_name *n; struct possible_tag all_matches[MAX_TAGS]; unsigned int match_cnt = 0, annotated_cnt = 0, cur_match; @@@ -191,6 -201,14 +200,6 @@@ if (!cmit) die("%s is not a valid '%s' object", arg, commit_type); - if (!initialized) { - initialized = 1; - for_each_ref(get_name, NULL); - } - - if (!found_names) - die("cannot describe '%s'", sha1_to_hex(sha1)); - n = cmit->util; if (n) { /* @@@ -199,6 -217,8 +208,8 @@@ display_name(n); if (longformat) show_suffix(0, n->tag ? n->tag->tagged->sha1 : sha1); + if (dirty) + printf("%s", dirty); printf("\n"); return; } @@@ -256,7 -276,10 +267,10 @@@ if (!match_cnt) { const unsigned char *sha1 = cmit->object.sha1; if (always) { - printf("%s\n", find_unique_abbrev(sha1, abbrev)); + printf("%s", find_unique_abbrev(sha1, abbrev)); + if (dirty) + printf("%s", dirty); + printf("\n"); return; } die("cannot describe '%s'", sha1_to_hex(sha1)); @@@ -291,6 -314,8 +305,8 @@@ display_name(all_matches[0].name); if (abbrev) show_suffix(all_matches[0].depth, cmit->object.sha1); + if (dirty) + printf("%s", dirty); printf("\n"); if (!last_one) @@@ -315,6 -340,9 +331,9 @@@ int cmd_describe(int argc, const char * "only consider tags matching "), OPT_BOOLEAN(0, "always", &always, "show abbreviated commit object as fallback"), + {OPTION_STRING, 0, "dirty", &dirty, "mark", + "append on dirty working tree (default: \"-dirty\")", + PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"}, OPT_END(), }; @@@ -350,12 -378,12 +369,16 @@@ return cmd_name_rev(i + argc, args, prefix); } + for_each_ref(get_name, NULL); + if (!found_names && !always) + die("No names found, cannot describe anything."); + if (argc == 0) { + if (dirty && !cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1, diff_index_args, prefix)) + dirty = NULL; describe("HEAD", 1); + } else if (dirty) { + die("--dirty is incompatible with committishes"); } else { while (argc-- > 0) { describe(*argv++, argc == 0); diff --combined t/t6120-describe.sh index f5a1b615f6,100c4d99fb..c050f94bc6 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@@ -34,8 -34,6 +34,8 @@@ test_expect_success setup echo one >file && git add file && git commit -m initial && one=$(git rev-parse HEAD) && + git describe --always HEAD && + test_tick && echo two >file && git add file && git commit -m second && two=$(git rev-parse HEAD) && @@@ -125,6 -123,20 +125,20 @@@ test_expect_success 'rename tag Q back test_expect_success 'pack tag refs' 'git pack-refs' check_describe A-* HEAD + check_describe "A-*[0-9a-f]" --dirty + + test_expect_success 'set-up dirty work tree' ' + echo >>file + ' + + check_describe "A-*[0-9a-f]-dirty" --dirty + + check_describe "A-*[0-9a-f].mod" --dirty=.mod + + test_expect_success 'describe --dirty HEAD' ' + test_must_fail git describe --dirty HEAD + ' + test_expect_success 'set-up matching pattern tests' ' git tag -a -m test-annotated test-annotated && echo >>file &&