Skip to content

Commit 7ecf193

Browse files
vdyegitster
authored andcommitted
builtin/diagnose.c: add '--mode' option
Create '--mode=<mode>' option in 'git diagnose' to allow users to optionally select non-default diagnostic information to include in the output archive. Additionally, document the currently-available modes, emphasizing the importance of not sharing a '--mode=all' archive publicly due to the presence of sensitive information. Note that the option parsing callback - 'option_parse_diagnose()' - is added to 'diagnose.c' rather than 'builtin/diagnose.c' so that it may be reused in future callers configuring a diagnostics archive. Helped-by: Derrick Stolee <[email protected]> Signed-off-by: Victoria Dye <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6783fd3 commit 7ecf193

File tree

5 files changed

+84
-4
lines changed

5 files changed

+84
-4
lines changed

Documentation/git-diagnose.txt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ SYNOPSIS
99
--------
1010
[verse]
1111
'git diagnose' [(-o | --output-directory) <path>] [(-s | --suffix) <format>]
12+
[--mode=<mode>]
1213

1314
DESCRIPTION
1415
-----------
@@ -17,7 +18,7 @@ repository state and packages that information into a zip archive. The
1718
generated archive can then, for example, be shared with the Git mailing list to
1819
help debug an issue or serve as a reference for independent debugging.
1920

20-
The following information is captured in the archive:
21+
By default, the following information is captured in the archive:
2122

2223
* 'git version --build-options'
2324
* The path to the repository root
@@ -27,6 +28,9 @@ The following information is captured in the archive:
2728
* The total count of loose objects, as well as counts broken down by
2829
`.git/objects` subdirectory
2930

31+
Additional information can be collected by selecting a different diagnostic mode
32+
using the `--mode` option.
33+
3034
This tool differs from linkgit:git-bugreport[1] in that it collects much more
3135
detailed information with a greater focus on reporting the size and data shape
3236
of repository contents.
@@ -45,6 +49,17 @@ OPTIONS
4549
form of a strftime(3) format string; the current local time will be
4650
used.
4751

52+
--mode=(stats|all)::
53+
Specify the type of diagnostics that should be collected. The default behavior
54+
of 'git diagnose' is equivalent to `--mode=stats`.
55+
+
56+
The `--mode=all` option collects everything included in `--mode=stats`, as well
57+
as copies of `.git`, `.git/hooks`, `.git/info`, `.git/logs`, and
58+
`.git/objects/info` directories. This additional information may be sensitive,
59+
as it can be used to reconstruct the full contents of the diagnosed repository.
60+
Users should exercise caution when sharing an archive generated with
61+
`--mode=all`.
62+
4863
GIT
4964
---
5065
Part of the linkgit:git[1] suite

builtin/diagnose.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include "diagnose.h"
44

55
static const char * const diagnose_usage[] = {
6-
N_("git diagnose [-o|--output-directory <path>] [-s|--suffix <format>]"),
6+
N_("git diagnose [-o|--output-directory <path>] [-s|--suffix <format>] [--mode=<mode>]"),
77
NULL
88
};
99

@@ -12,6 +12,7 @@ int cmd_diagnose(int argc, const char **argv, const char *prefix)
1212
struct strbuf zip_path = STRBUF_INIT;
1313
time_t now = time(NULL);
1414
struct tm tm;
15+
enum diagnose_mode mode = DIAGNOSE_STATS;
1516
char *option_output = NULL;
1617
char *option_suffix = "%Y-%m-%d-%H%M";
1718
char *prefixed_filename;
@@ -21,6 +22,9 @@ int cmd_diagnose(int argc, const char **argv, const char *prefix)
2122
N_("specify a destination for the diagnostics archive")),
2223
OPT_STRING('s', "suffix", &option_suffix, N_("format"),
2324
N_("specify a strftime format suffix for the filename")),
25+
OPT_CALLBACK_F(0, "mode", &mode, N_("(stats|all)"),
26+
N_("specify the content of the diagnostic archive"),
27+
PARSE_OPT_NONEG, option_parse_diagnose),
2428
OPT_END()
2529
};
2630

@@ -47,7 +51,7 @@ int cmd_diagnose(int argc, const char **argv, const char *prefix)
4751
}
4852

4953
/* Prepare diagnostics */
50-
if (create_diagnostics_archive(&zip_path, DIAGNOSE_STATS))
54+
if (create_diagnostics_archive(&zip_path, mode))
5155
die_errno(_("unable to create diagnostics archive %s"),
5256
zip_path.buf);
5357

diagnose.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,36 @@ struct archive_dir {
1313
int recursive;
1414
};
1515

16+
struct diagnose_option {
17+
enum diagnose_mode mode;
18+
const char *option_name;
19+
};
20+
21+
static struct diagnose_option diagnose_options[] = {
22+
{ DIAGNOSE_STATS, "stats" },
23+
{ DIAGNOSE_ALL, "all" },
24+
};
25+
26+
int option_parse_diagnose(const struct option *opt, const char *arg, int unset)
27+
{
28+
int i;
29+
enum diagnose_mode *diagnose = opt->value;
30+
31+
if (!arg) {
32+
*diagnose = unset ? DIAGNOSE_NONE : DIAGNOSE_STATS;
33+
return 0;
34+
}
35+
36+
for (i = 0; i < ARRAY_SIZE(diagnose_options); i++) {
37+
if (!strcmp(arg, diagnose_options[i].option_name)) {
38+
*diagnose = diagnose_options[i].mode;
39+
return 0;
40+
}
41+
}
42+
43+
return error(_("invalid --%s value '%s'"), opt->long_name, arg);
44+
}
45+
1646
static void dir_file_stats_objects(const char *full_path, size_t full_path_len,
1747
const char *file_name, void *data)
1848
{

diagnose.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
#define DIAGNOSE_H
33

44
#include "strbuf.h"
5+
#include "parse-options.h"
56

67
enum diagnose_mode {
78
DIAGNOSE_NONE,
89
DIAGNOSE_STATS,
910
DIAGNOSE_ALL
1011
};
1112

13+
int option_parse_diagnose(const struct option *opt, const char *arg, int unset);
14+
1215
int create_diagnostics_archive(struct strbuf *zip_path, enum diagnose_mode mode);
1316

1417
#endif /* DIAGNOSE_H */

t/t0092-diagnose.sh

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,35 @@ test_expect_success UNZIP 'creates diagnostics zip archive' '
2626
2727
# Should not include .git directory contents by default
2828
! "$GIT_UNZIP" -l "$zip_path" | grep ".git/"
29-
grep "^Total: [0-9][0-9]*" out
29+
'
30+
31+
test_expect_success UNZIP '--mode=stats excludes .git dir contents' '
32+
test_when_finished rm -rf report &&
33+
34+
git diagnose -o report -s test --mode=stats >out &&
35+
36+
# Includes pack quantity/size info
37+
"$GIT_UNZIP" -p "$zip_path" packs-local.txt >out &&
38+
grep ".git/objects" out &&
39+
40+
# Does not include .git directory contents
41+
! "$GIT_UNZIP" -l "$zip_path" | grep ".git/"
42+
'
43+
44+
test_expect_success UNZIP '--mode=all includes .git dir contents' '
45+
test_when_finished rm -rf report &&
46+
47+
git diagnose -o report -s test --mode=all >out &&
48+
49+
# Includes pack quantity/size info
50+
"$GIT_UNZIP" -p "$zip_path" packs-local.txt >out &&
51+
grep ".git/objects" out &&
52+
53+
# Includes .git directory contents
54+
"$GIT_UNZIP" -l "$zip_path" | grep ".git/" &&
55+
56+
"$GIT_UNZIP" -p "$zip_path" .git/HEAD >out &&
57+
test_file_not_empty out
3058
'
3159

3260
test_done

0 commit comments

Comments
 (0)