1
0
mirror of https://github.com/git/git.git synced 2024-10-22 12:28:32 +02:00

Merge branch 'sb/describe-broken'

"git describe --dirty" dies when it cannot be determined if the
state in the working tree matches that of HEAD (e.g. broken
repository or broken submodule).  The command learned a new option
"git describe --broken" to give "$name-broken" (where $name is the
description of HEAD) in such a case.

* sb/describe-broken:
  builtin/describe: introduce --broken flag
This commit is contained in:
Junio C Hamano 2017-03-27 10:59:27 -07:00
commit 844768a298
3 changed files with 66 additions and 12 deletions

@ -30,9 +30,14 @@ OPTIONS
Commit-ish object names to describe. Defaults to HEAD if omitted. Commit-ish object names to describe. Defaults to HEAD if omitted.
--dirty[=<mark>]:: --dirty[=<mark>]::
Describe the working tree. --broken[=<mark>]::
It means describe HEAD and appends <mark> (`-dirty` by Describe the state of the working tree. When the working
default) if the working tree is dirty. tree matches HEAD, the output is the same as "git describe
HEAD". If the working tree has local modification "-dirty"
is appended to it. If a repository is corrupt and Git
cannot determine if there is local modification, Git will
error out, unless `--broken' is given, which appends
the suffix "-broken" instead.
--all:: --all::
Instead of using only the annotated tags, use any ref Instead of using only the annotated tags, use any ref

@ -9,6 +9,7 @@
#include "diff.h" #include "diff.h"
#include "hashmap.h" #include "hashmap.h"
#include "argv-array.h" #include "argv-array.h"
#include "run-command.h"
#define SEEN (1u << 0) #define SEEN (1u << 0)
#define MAX_TAGS (FLAG_BITS - 1) #define MAX_TAGS (FLAG_BITS - 1)
@ -31,7 +32,7 @@ static int have_util;
static struct string_list patterns = STRING_LIST_INIT_NODUP; static struct string_list patterns = STRING_LIST_INIT_NODUP;
static struct string_list exclude_patterns = STRING_LIST_INIT_NODUP; static struct string_list exclude_patterns = STRING_LIST_INIT_NODUP;
static int always; static int always;
static const char *dirty; static const char *suffix, *dirty, *broken;
/* diff-index command arguments to check if working tree is dirty. */ /* diff-index command arguments to check if working tree is dirty. */
static const char *diff_index_args[] = { static const char *diff_index_args[] = {
@ -292,8 +293,8 @@ static void describe(const char *arg, int last_one)
display_name(n); display_name(n);
if (longformat) if (longformat)
show_suffix(0, n->tag ? &n->tag->tagged->oid : &oid); show_suffix(0, n->tag ? &n->tag->tagged->oid : &oid);
if (dirty) if (suffix)
printf("%s", dirty); printf("%s", suffix);
printf("\n"); printf("\n");
return; return;
} }
@ -369,8 +370,8 @@ static void describe(const char *arg, int last_one)
struct object_id *oid = &cmit->object.oid; struct object_id *oid = &cmit->object.oid;
if (always) { if (always) {
printf("%s", find_unique_abbrev(oid->hash, abbrev)); printf("%s", find_unique_abbrev(oid->hash, abbrev));
if (dirty) if (suffix)
printf("%s", dirty); printf("%s", suffix);
printf("\n"); printf("\n");
return; return;
} }
@ -413,8 +414,8 @@ static void describe(const char *arg, int last_one)
display_name(all_matches[0].name); display_name(all_matches[0].name);
if (abbrev) if (abbrev)
show_suffix(all_matches[0].depth, &cmit->object.oid); show_suffix(all_matches[0].depth, &cmit->object.oid);
if (dirty) if (suffix)
printf("%s", dirty); printf("%s", suffix);
printf("\n"); printf("\n");
if (!last_one) if (!last_one)
@ -445,6 +446,9 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
{OPTION_STRING, 0, "dirty", &dirty, N_("mark"), {OPTION_STRING, 0, "dirty", &dirty, N_("mark"),
N_("append <mark> on dirty working tree (default: \"-dirty\")"), N_("append <mark> on dirty working tree (default: \"-dirty\")"),
PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"}, PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"},
{OPTION_STRING, 0, "broken", &broken, N_("mark"),
N_("append <mark> on broken working tree (default: \"-broken\")"),
PARSE_OPT_OPTARG, NULL, (intptr_t) "-broken"},
OPT_END(), OPT_END(),
}; };
@ -493,7 +497,28 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
die(_("No names found, cannot describe anything.")); die(_("No names found, cannot describe anything."));
if (argc == 0) { if (argc == 0) {
if (dirty) { if (broken) {
struct child_process cp = CHILD_PROCESS_INIT;
argv_array_pushv(&cp.args, diff_index_args);
cp.git_cmd = 1;
cp.no_stdin = 1;
cp.no_stdout = 1;
if (!dirty)
dirty = "-dirty";
switch (run_command(&cp)) {
case 0:
suffix = NULL;
break;
case 1:
suffix = dirty;
break;
default:
/* diff-index aborted abnormally */
suffix = broken;
}
} else if (dirty) {
static struct lock_file index_lock; static struct lock_file index_lock;
int fd; int fd;
@ -506,11 +531,15 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
if (!cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1, if (!cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1,
diff_index_args, prefix)) diff_index_args, prefix))
dirty = NULL; suffix = NULL;
else
suffix = dirty;
} }
describe("HEAD", 1); describe("HEAD", 1);
} else if (dirty) { } else if (dirty) {
die(_("--dirty is incompatible with commit-ishes")); die(_("--dirty is incompatible with commit-ishes"));
} else if (broken) {
die(_("--broken is incompatible with commit-ishes"));
} else { } else {
while (argc-- > 0) while (argc-- > 0)
describe(*argv++, argc == 0); describe(*argv++, argc == 0);

@ -233,4 +233,24 @@ test_expect_success 'describe --contains and --no-match' '
test_cmp expect actual test_cmp expect actual
' '
test_expect_success 'setup and absorb a submodule' '
test_create_repo sub1 &&
test_commit -C sub1 initial &&
git submodule add ./sub1 &&
git submodule absorbgitdirs &&
git commit -a -m "add submodule" &&
git describe --dirty >expect &&
git describe --broken >out &&
test_cmp expect out
'
test_expect_success 'describe chokes on severly broken submodules' '
mv .git/modules/sub1/ .git/modules/sub_moved &&
test_must_fail git describe --dirty
'
test_expect_success 'describe ignoring a borken submodule' '
git describe --broken >out &&
grep broken out
'
test_done test_done