Browse Source
Create a 'git diagnose' builtin to generate a standalone zip archive of
repository diagnostics.
The "diagnose" functionality was originally implemented for Scalar in
aa5c79a331
(scalar: implement `scalar diagnose`, 2022-05-28). However, the
diagnostics gathered are not specific to Scalar-cloned repositories and
can be useful when diagnosing issues in any Git repository.
Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Helped-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
![vdye@github.com](/assets/img/avatar_default.png)
![Junio C Hamano](/assets/img/avatar_default.png)
7 changed files with 143 additions and 0 deletions
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
git-diagnose(1) |
||||
================ |
||||
|
||||
NAME |
||||
---- |
||||
git-diagnose - Generate a zip archive of diagnostic information |
||||
|
||||
SYNOPSIS |
||||
-------- |
||||
[verse] |
||||
'git diagnose' [(-o | --output-directory) <path>] [(-s | --suffix) <format>] |
||||
|
||||
DESCRIPTION |
||||
----------- |
||||
Collects detailed information about the user's machine, Git client, and |
||||
repository state and packages that information into a zip archive. The |
||||
generated archive can then, for example, be shared with the Git mailing list to |
||||
help debug an issue or serve as a reference for independent debugging. |
||||
|
||||
The following information is captured in the archive: |
||||
|
||||
* 'git version --build-options' |
||||
* The path to the repository root |
||||
* The available disk space on the filesystem |
||||
* The name and size of each packfile, including those in alternate object |
||||
stores |
||||
* The total count of loose objects, as well as counts broken down by |
||||
`.git/objects` subdirectory |
||||
|
||||
This tool differs from linkgit:git-bugreport[1] in that it collects much more |
||||
detailed information with a greater focus on reporting the size and data shape |
||||
of repository contents. |
||||
|
||||
OPTIONS |
||||
------- |
||||
-o <path>:: |
||||
--output-directory <path>:: |
||||
Place the resulting diagnostics archive in `<path>` instead of the |
||||
current directory. |
||||
|
||||
-s <format>:: |
||||
--suffix <format>:: |
||||
Specify an alternate suffix for the diagnostics archive name, to create |
||||
a file named 'git-diagnostics-<formatted suffix>'. This should take the |
||||
form of a strftime(3) format string; the current local time will be |
||||
used. |
||||
|
||||
GIT |
||||
--- |
||||
Part of the linkgit:git[1] suite |
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
#include "builtin.h" |
||||
#include "parse-options.h" |
||||
#include "diagnose.h" |
||||
|
||||
static const char * const diagnose_usage[] = { |
||||
N_("git diagnose [-o|--output-directory <path>] [-s|--suffix <format>]"), |
||||
NULL |
||||
}; |
||||
|
||||
int cmd_diagnose(int argc, const char **argv, const char *prefix) |
||||
{ |
||||
struct strbuf zip_path = STRBUF_INIT; |
||||
time_t now = time(NULL); |
||||
struct tm tm; |
||||
char *option_output = NULL; |
||||
char *option_suffix = "%Y-%m-%d-%H%M"; |
||||
char *prefixed_filename; |
||||
|
||||
const struct option diagnose_options[] = { |
||||
OPT_STRING('o', "output-directory", &option_output, N_("path"), |
||||
N_("specify a destination for the diagnostics archive")), |
||||
OPT_STRING('s', "suffix", &option_suffix, N_("format"), |
||||
N_("specify a strftime format suffix for the filename")), |
||||
OPT_END() |
||||
}; |
||||
|
||||
argc = parse_options(argc, argv, prefix, diagnose_options, |
||||
diagnose_usage, 0); |
||||
|
||||
/* Prepare the path to put the result */ |
||||
prefixed_filename = prefix_filename(prefix, |
||||
option_output ? option_output : ""); |
||||
strbuf_addstr(&zip_path, prefixed_filename); |
||||
strbuf_complete(&zip_path, '/'); |
||||
|
||||
strbuf_addstr(&zip_path, "git-diagnostics-"); |
||||
strbuf_addftime(&zip_path, option_suffix, localtime_r(&now, &tm), 0, 0); |
||||
strbuf_addstr(&zip_path, ".zip"); |
||||
|
||||
switch (safe_create_leading_directories(zip_path.buf)) { |
||||
case SCLD_OK: |
||||
case SCLD_EXISTS: |
||||
break; |
||||
default: |
||||
die_errno(_("could not create leading directories for '%s'"), |
||||
zip_path.buf); |
||||
} |
||||
|
||||
/* Prepare diagnostics */ |
||||
if (create_diagnostics_archive(&zip_path, DIAGNOSE_STATS)) |
||||
die_errno(_("unable to create diagnostics archive %s"), |
||||
zip_path.buf); |
||||
|
||||
free(prefixed_filename); |
||||
strbuf_release(&zip_path); |
||||
return 0; |
||||
} |
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh |
||||
|
||||
test_description='git diagnose' |
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true |
||||
. ./test-lib.sh |
||||
|
||||
test_expect_success UNZIP 'creates diagnostics zip archive' ' |
||||
test_when_finished rm -rf report && |
||||
|
||||
git diagnose -o report -s test >out && |
||||
grep "Available space" out && |
||||
|
||||
zip_path=report/git-diagnostics-test.zip && |
||||
test_path_is_file "$zip_path" && |
||||
|
||||
# Check zipped archive content |
||||
"$GIT_UNZIP" -p "$zip_path" diagnostics.log >out && |
||||
test_file_not_empty out && |
||||
|
||||
"$GIT_UNZIP" -p "$zip_path" packs-local.txt >out && |
||||
grep ".git/objects" out && |
||||
|
||||
"$GIT_UNZIP" -p "$zip_path" objects-local.txt >out && |
||||
grep "^Total: [0-9][0-9]*" out && |
||||
|
||||
# Should not include .git directory contents by default |
||||
! "$GIT_UNZIP" -l "$zip_path" | grep ".git/" |
||||
grep "^Total: [0-9][0-9]*" out |
||||
' |
||||
|
||||
test_done |
Loading…
Reference in new issue