Skip to content

Commit b0176ce

Browse files
stefanbellergitster
authored andcommitted
builtin/describe: introduce --broken flag
git-describe tells you the version number you're at, or errors out, e.g. when you run it outside of a repository, which may happen when downloading a tar ball instead of using git to obtain the source code. To keep this property of only erroring out, when not in a repository, severe (submodule) errors must be downgraded to reporting them gently instead of having git-describe error out completely. To achieve that a flag '--broken' is introduced, which is in the same vein as '--dirty' but uses an actual child process to check for dirtiness. When that child dies unexpectedly, we'll append '-broken' instead of '-dirty'. Signed-off-by: Stefan Beller <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c0f9c70 commit b0176ce

File tree

3 files changed

+66
-12
lines changed

3 files changed

+66
-12
lines changed

Documentation/git-describe.txt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,14 @@ OPTIONS
3030
Commit-ish object names to describe. Defaults to HEAD if omitted.
3131

3232
--dirty[=<mark>]::
33-
Describe the working tree.
34-
It means describe HEAD and appends <mark> (`-dirty` by
35-
default) if the working tree is dirty.
33+
--broken[=<mark>]::
34+
Describe the state of the working tree. When the working
35+
tree matches HEAD, the output is the same as "git describe
36+
HEAD". If the working tree has local modification "-dirty"
37+
is appended to it. If a repository is corrupt and Git
38+
cannot determine if there is local modification, Git will
39+
error out, unless `--broken' is given, which appends
40+
the suffix "-broken" instead.
3641

3742
--all::
3843
Instead of using only the annotated tags, use any ref

builtin/describe.c

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "diff.h"
1010
#include "hashmap.h"
1111
#include "argv-array.h"
12+
#include "run-command.h"
1213

1314
#define SEEN (1u << 0)
1415
#define MAX_TAGS (FLAG_BITS - 1)
@@ -31,7 +32,7 @@ static int have_util;
3132
static struct string_list patterns = STRING_LIST_INIT_NODUP;
3233
static struct string_list exclude_patterns = STRING_LIST_INIT_NODUP;
3334
static int always;
34-
static const char *dirty;
35+
static const char *suffix, *dirty, *broken;
3536

3637
/* diff-index command arguments to check if working tree is dirty. */
3738
static const char *diff_index_args[] = {
@@ -292,8 +293,8 @@ static void describe(const char *arg, int last_one)
292293
display_name(n);
293294
if (longformat)
294295
show_suffix(0, n->tag ? &n->tag->tagged->oid : &oid);
295-
if (dirty)
296-
printf("%s", dirty);
296+
if (suffix)
297+
printf("%s", suffix);
297298
printf("\n");
298299
return;
299300
}
@@ -369,8 +370,8 @@ static void describe(const char *arg, int last_one)
369370
struct object_id *oid = &cmit->object.oid;
370371
if (always) {
371372
printf("%s", find_unique_abbrev(oid->hash, abbrev));
372-
if (dirty)
373-
printf("%s", dirty);
373+
if (suffix)
374+
printf("%s", suffix);
374375
printf("\n");
375376
return;
376377
}
@@ -413,8 +414,8 @@ static void describe(const char *arg, int last_one)
413414
display_name(all_matches[0].name);
414415
if (abbrev)
415416
show_suffix(all_matches[0].depth, &cmit->object.oid);
416-
if (dirty)
417-
printf("%s", dirty);
417+
if (suffix)
418+
printf("%s", suffix);
418419
printf("\n");
419420

420421
if (!last_one)
@@ -445,6 +446,9 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
445446
{OPTION_STRING, 0, "dirty", &dirty, N_("mark"),
446447
N_("append <mark> on dirty working tree (default: \"-dirty\")"),
447448
PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"},
449+
{OPTION_STRING, 0, "broken", &broken, N_("mark"),
450+
N_("append <mark> on broken working tree (default: \"-broken\")"),
451+
PARSE_OPT_OPTARG, NULL, (intptr_t) "-broken"},
448452
OPT_END(),
449453
};
450454

@@ -493,7 +497,28 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
493497
die(_("No names found, cannot describe anything."));
494498

495499
if (argc == 0) {
496-
if (dirty) {
500+
if (broken) {
501+
struct child_process cp = CHILD_PROCESS_INIT;
502+
argv_array_pushv(&cp.args, diff_index_args);
503+
cp.git_cmd = 1;
504+
cp.no_stdin = 1;
505+
cp.no_stdout = 1;
506+
507+
if (!dirty)
508+
dirty = "-dirty";
509+
510+
switch (run_command(&cp)) {
511+
case 0:
512+
suffix = NULL;
513+
break;
514+
case 1:
515+
suffix = dirty;
516+
break;
517+
default:
518+
/* diff-index aborted abnormally */
519+
suffix = broken;
520+
}
521+
} else if (dirty) {
497522
static struct lock_file index_lock;
498523
int fd;
499524

@@ -506,11 +531,15 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
506531

507532
if (!cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1,
508533
diff_index_args, prefix))
509-
dirty = NULL;
534+
suffix = NULL;
535+
else
536+
suffix = dirty;
510537
}
511538
describe("HEAD", 1);
512539
} else if (dirty) {
513540
die(_("--dirty is incompatible with commit-ishes"));
541+
} else if (broken) {
542+
die(_("--broken is incompatible with commit-ishes"));
514543
} else {
515544
while (argc-- > 0)
516545
describe(*argv++, argc == 0);

t/t6120-describe.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,4 +233,24 @@ test_expect_success 'describe --contains and --no-match' '
233233
test_cmp expect actual
234234
'
235235

236+
test_expect_success 'setup and absorb a submodule' '
237+
test_create_repo sub1 &&
238+
test_commit -C sub1 initial &&
239+
git submodule add ./sub1 &&
240+
git submodule absorbgitdirs &&
241+
git commit -a -m "add submodule" &&
242+
git describe --dirty >expect &&
243+
git describe --broken >out &&
244+
test_cmp expect out
245+
'
246+
247+
test_expect_success 'describe chokes on severly broken submodules' '
248+
mv .git/modules/sub1/ .git/modules/sub_moved &&
249+
test_must_fail git describe --dirty
250+
'
251+
test_expect_success 'describe ignoring a borken submodule' '
252+
git describe --broken >out &&
253+
grep broken out
254+
'
255+
236256
test_done

0 commit comments

Comments
 (0)