{"thread":{"id":"52845","subject":"[PATCH v8 02/15] help: add shell-path to --build-options","startedAt":"2020-02-20T01:59:15Z","lastAt":"2020-03-23T21:28:01Z","messageCount":87,"participants":["Emily Shaffer","Danh Doan","Johannes Schindelin","Junio C Hamano","Jeff Hostetler"],"isPatch":true,"patchVersion":8,"patchTotal":15},"messages":[{"id":"392135","messageId":"20200220015858.181086-3-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 02/15] help: add shell-path to --build-options","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:45Z","receivedAt":"2020-02-20T01:59:15Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"It may be useful to know which shell Git was built to try to point to,\nin the event that shell-based Git commands are failing. $SHELL_PATH is\nset during the build and used to launch the manpage viewer, as well as\nby git-compat-util.h, and it's used during tests. 'git version\n--build-options' is encouraged for use in bug reports, so it makes sense\nto include this information there.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n help.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/help.c b/help.c\nindex a21487db77..190722fb0a 100644\n--- a/help.c\n+++ b/help.c\n@@ -654,6 +654,7 @@ int cmd_version(int argc, const char **argv, const char *prefix)\n \t\t\tprintf(\"no commit associated with this build\\n\");\n \t\tprintf(\"sizeof-long: %d\\n\", (int)sizeof(long));\n \t\tprintf(\"sizeof-size_t: %d\\n\", (int)sizeof(size_t));\n+\t\tprintf(\"shell-path: %s\\n\", SHELL_PATH);\n \t\t/* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */\n \t}\n \treturn 0;\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392136","messageId":"20200220015858.181086-1-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200214015343.201946-1-emilyshaffer@google.com","subject":"[PATCH v8 00/15] add git-bugreport tool","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:43Z","receivedAt":"2020-02-20T01:59:16Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"No longer relies on any topic branches, since mr/show-config-scope is\nmerged. Range-diff at the bottom of the cover letter.\n\nSince v7:\n - Dropped some POSIX regex magic in\n   generate-bugreport-config-safelist.sh.\n - Added some advice in doc for scenarios when git-bugreport may not run\n   nicely\n - Quit using unusual \"return -foo(bar)\" and start using \"return\n   !!foo(bar)\"\n - Add a test to ensure path creation works outside of a git dir\n - Add some GNUC and GNUC_MINOR reporting\n - Use git_cmd instead of hardcoding \"git\" as the first arg when\n   invoking another process\n - Fix some pesky whitespace\n\nThanks.\n - Emily\n\nEmily Shaffer (15):\n  help: move list_config_help to builtin/help\n  help: add shell-path to --build-options\n  bugreport: add tool to generate debugging info\n  bugreport: gather git version and build info\n  bugreport: add uname info\n  bugreport: add compiler info\n  bugreport: add git-remote-https version\n  bugreport: include user interactive shell\n  bugreport: generate config safelist based on docs\n  bugreport: add config values from safelist\n  bugreport: collect list of populated hooks\n  bugreport: count loose objects\n  bugreport: add packed object summary\n  bugreport: list contents of $OBJDIR/info\n  bugreport: summarize contents of alternates file\n\n .gitignore                              |   3 +\n Documentation/asciidoc.conf             |   9 +\n Documentation/asciidoctor-extensions.rb |   7 +\n Documentation/config/sendemail.txt      |  56 ++--\n Documentation/git-bugreport.txt         |  60 ++++\n Makefile                                |  27 +-\n bugreport.c                             | 418 ++++++++++++++++++++++++\n builtin/help.c                          |  86 +++++\n command-list.txt                        |   1 +\n compat/compiler.h                       |  27 ++\n generate-bugreport-config-safelist.sh   |  18 +\n generate-cmdlist.sh                     |  19 --\n generate-configlist.sh                  |  21 ++\n help.c                                  | 132 ++------\n help.h                                  |   2 +-\n object-store.h                          |   6 +\n packfile.c                              |   3 +-\n remote-curl.c                           |   8 +\n t/t0091-bugreport.sh                    |  61 ++++\n 19 files changed, 808 insertions(+), 156 deletions(-)\n create mode 100644 Documentation/git-bugreport.txt\n create mode 100644 bugreport.c\n create mode 100644 compat/compiler.h\n create mode 100755 generate-bugreport-config-safelist.sh\n create mode 100755 generate-configlist.sh\n create mode 100755 t/t0091-bugreport.sh\n\n\n 1:  429c7e093b =  1:  69f54afc6b help: move list_config_help to builtin/help\n 2:  0cfb24f878 =  2:  9ea1c3ab34 help: add shell-path to --build-options\n 3:  02bb151176 !  3:  8a290b5445 bugreport: add tool to generate debugging info\n    @@ Documentation/git-bugreport.txt (new)\n     + - Expected behavior\n     + - Actual behavior\n     +\n    ++This tool is invoked via the typical Git setup process, which means that in some\n    ++cases, it might not be able to launch - for example, if a relevant config file\n    ++is unreadable. In this kind of scenario, it may be helpful to manually gather\n    ++the kind of information listed above when manually asking for help.\n    ++\n     +OPTIONS\n     +-------\n     +-o <path>::\n    @@ bugreport.c (new)\n     +\n     +\tUNLEAK(buffer);\n     +\tUNLEAK(report_path);\n    -+\treturn -launch_editor(report_path.buf, NULL, NULL);\n    ++\treturn !!launch_editor(report_path.buf, NULL, NULL);\n     +}\n     \n      ## command-list.txt ##\n    @@ t/t0091-bugreport.sh (new)\n     +\ttest_when_finished rm non-repo/git-bugreport-*\n     +'\n     +\n    ++test_expect_success 'can create leading directories outside of a git dir' '\n    ++\tnongit git bugreport -o foo/bar/baz &&\n    ++\ttest_when_finished rm -fr foo/bar/baz\n    ++'\n    ++\n    ++\n     +test_done\n 4:  463612e409 !  4:  4eb4a7aef3 bugreport: gather git version and build info\n    @@ Documentation/git-bugreport.txt: The following information is requested from the\n     +\n     + - 'git version --build-options'\n     +\n    - OPTIONS\n    - -------\n    - -o <path>::\n    + This tool is invoked via the typical Git setup process, which means that in some\n    + cases, it might not be able to launch - for example, if a relevant config file\n    + is unreadable. In this kind of scenario, it may be helpful to manually gather\n     \n      ## bugreport.c ##\n     @@\n 5:  85e11ea125 !  5:  4e18b4678e bugreport: add uname info\n    @@ Documentation/git-bugreport.txt: The following information is requested from the\n       - 'git version --build-options'\n     + - uname sysname, release, version, and machine strings\n      \n    - OPTIONS\n    - -------\n    + This tool is invoked via the typical Git setup process, which means that in some\n    + cases, it might not be able to launch - for example, if a relevant config file\n     \n      ## bugreport.c ##\n     @@\n 6:  d9eafbaa48 !  6:  c18d17443d bugreport: add compiler info\n    @@ Documentation/git-bugreport.txt: The following information is captured automatic\n       - uname sysname, release, version, and machine strings\n     + - Compiler-specific info string\n      \n    - OPTIONS\n    - -------\n    + This tool is invoked via the typical Git setup process, which means that in some\n    + cases, it might not be able to launch - for example, if a relevant config file\n     \n      ## bugreport.c ##\n     @@\n    @@ compat/compiler.h (new)\n     +\n     +static inline void get_compiler_info(struct strbuf *info)\n     +{\n    -+\tstrbuf_addf(info, \"glibc: %s\", gnu_get_libc_version());\n    ++\tstrbuf_addf(info, \"glibc: %s\\n\", gnu_get_libc_version());\n    ++#ifdef __GNUC__\n    ++\tstrbuf_addf(info, \"gnuc: %d.%d\\n\", __GNUC__, __GNUC_MINOR__);\n    ++#endif\n     +}\n     +\n     +#else\n 7:  f5b6dd4174 !  7:  6d807cf857 bugreport: add git-remote-https version\n    @@ Documentation/git-bugreport.txt: The following information is captured automatic\n       - Compiler-specific info string\n     + - 'git remote-https --build-info'\n      \n    - OPTIONS\n    - -------\n    + This tool is invoked via the typical Git setup process, which means that in some\n    + cases, it might not be able to launch - for example, if a relevant config file\n     \n      ## bugreport.c ##\n     @@\n    @@ bugreport.c\n     +{\n     +\tstruct child_process cp = CHILD_PROCESS_INIT;\n     +\n    -+\targv_array_push(&cp.args, \"git\");\n    ++\tcp.git_cmd = 1;\n     +\targv_array_push(&cp.args, \"remote-https\");\n     +\targv_array_push(&cp.args, \"--build-info\");\n     +\tif (capture_command(&cp, version_info, 0))\n 8:  3119c9c1e3 !  8:  f85e1b69d0 bugreport: include user interactive shell\n    @@ Documentation/git-bugreport.txt: The following information is captured automatic\n       - 'git remote-https --build-info'\n     + - $SHELL\n      \n    - OPTIONS\n    - -------\n    + This tool is invoked via the typical Git setup process, which means that in some\n    + cases, it might not be able to launch - for example, if a relevant config file\n     \n      ## bugreport.c ##\n     @@ bugreport.c: static void get_git_remote_https_version_info(struct strbuf *version_info)\n 9:  c35bab2735 !  9:  9980728360 bugreport: generate config safelist based on docs\n    @@ generate-bugreport-config-safelist.sh (new)\n     +# cat all regular files in Documentation/config\n     +find Documentation/config -type f -exec cat {} \\; |\n     +# print the command name which matches the annotate-bugreport macro\n    -+sed -n 's/^\\([^[:blank:]]*\\)[[:blank:]]\\{1,\\}annotate:bugreport\\[include\\].* ::$/  \"\\1\",/p' \\\n    ++sed -n 's/^\\([^ ]*\\)  *annotate:bugreport\\[include\\].* ::$/  \"\\1\",/p' \\\n     +\t| sort\n     +\n     +cat <<EOF\n10:  8a54ebdbbb ! 10:  e9cd8ffec9 bugreport: add config values from safelist\n    @@ Documentation/git-bugreport.txt: The following information is captured automatic\n       - $SHELL\n     + - Selected config values\n      \n    - OPTIONS\n    - -------\n    + This tool is invoked via the typical Git setup process, which means that in some\n    + cases, it might not be able to launch - for example, if a relevant config file\n     \n      ## Makefile ##\n     @@ Makefile: git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)\n11:  8bb5bcd8b8 ! 11:  881b62369d bugreport: collect list of populated hooks\n    @@ Documentation/git-bugreport.txt: The following information is captured automatic\n       - Selected config values\n     + - A list of enabled hooks\n      \n    - OPTIONS\n    - -------\n    + This tool is invoked via the typical Git setup process, which means that in some\n    + cases, it might not be able to launch - for example, if a relevant config file\n     \n      ## bugreport.c ##\n     @@\n12:  744dd6aeee ! 12:  715e48e9a7 bugreport: count loose objects\n    @@ Documentation/git-bugreport.txt: The following information is captured automatic\n       - A list of enabled hooks\n     + - The number of loose objects in the repository\n      \n    - OPTIONS\n    - -------\n    + This tool is invoked via the typical Git setup process, which means that in some\n    + cases, it might not be able to launch - for example, if a relevant config file\n     \n      ## bugreport.c ##\n     @@\n13:  2f23e272bf ! 13:  c9e2f1f1d8 bugreport: add packed object summary\n    @@ Documentation/git-bugreport.txt: The following information is captured automatic\n       - The number of loose objects in the repository\n     + - The number of packs and packed objects in the repository\n      \n    - OPTIONS\n    - -------\n    + This tool is invoked via the typical Git setup process, which means that in some\n    + cases, it might not be able to launch - for example, if a relevant config file\n     \n      ## bugreport.c ##\n     @@ bugreport.c: static void get_loose_object_summary(struct strbuf *obj_info, int nongit) {\n    @@ bugreport.c: int cmd_main(int argc, const char **argv)\n     \n      ## object-store.h ##\n     @@\n    - #include \"list.h\"\n      #include \"sha1-array.h\"\n      #include \"strbuf.h\"\n    + #include \"thread-utils.h\"\n     +#include \"packfile.h\"\n      \n      struct object_directory {\n14:  7b5ae1aca1 ! 14:  89762a0de1 bugreport: list contents of $OBJDIR/info\n    @@ Documentation/git-bugreport.txt: The following information is captured automatic\n       - The number of packs and packed objects in the repository\n     + - A list of the contents of .git/objects/info (or equivalent)\n      \n    - OPTIONS\n    - -------\n    + This tool is invoked via the typical Git setup process, which means that in some\n    + cases, it might not be able to launch - for example, if a relevant config file\n     \n      ## bugreport.c ##\n     @@ bugreport.c: static void get_packed_object_summary(struct strbuf *obj_info, int nongit)\n    @@ bugreport.c: static void get_packed_object_summary(struct strbuf *obj_info, int\n      }\n      \n     +static void list_contents_of_dir_recursively(struct strbuf *contents,\n    -+\t\t\t\t      \t     struct strbuf *dirpath)\n    ++\t\t\t\t\t     struct strbuf *dirpath)\n     +{\n     +\tstruct dirent *d;\n     +\tDIR *dir;\n15:  315b00ed54 ! 15:  aa81e197aa bugreport: summarize contents of alternates file\n    @@ Documentation/git-bugreport.txt: The following information is captured automatic\n       - A list of the contents of .git/objects/info (or equivalent)\n     + - The number of valid and invalid alternates\n      \n    - OPTIONS\n    - -------\n    + This tool is invoked via the typical Git setup process, which means that in some\n    + cases, it might not be able to launch - for example, if a relevant config file\n     \n      ## bugreport.c ##\n     @@ bugreport.c: static void get_object_info_summary(struct strbuf *obj_info, int nongit)\n\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392137","messageId":"20200220015858.181086-2-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 01/15] help: move list_config_help to builtin/help","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:44Z","receivedAt":"2020-02-20T01:59:16Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"Starting in 3ac68a93fd2, help.o began to depend on builtin/branch.o,\nbuiltin/clean.o, and builtin/config.o. This meant that help.o was\nunusable outside of the context of the main Git executable.\n\nTo make help.o usable by other commands again, move list_config_help()\ninto builtin/help.c (where it makes sense to assume other builtin libraries\nare present).\n\nWhen command-list.h is included but a member is not used, we start to\nhear a compiler warning. Since the config list is generated in a fairly\ndifferent way than the command list, and since commands and config\noptions are semantically different, move the config list into its own\nheader and move the generator into its own script and build rule.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n .gitignore             |  1 +\n Makefile               | 13 +++++--\n builtin/help.c         | 86 ++++++++++++++++++++++++++++++++++++++++++\n generate-cmdlist.sh    | 19 ----------\n generate-configlist.sh | 21 +++++++++++\n help.c                 | 85 -----------------------------------------\n help.h                 |  1 -\n 7 files changed, 118 insertions(+), 108 deletions(-)\n create mode 100755 generate-configlist.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex aebe7c0908..ea97de83f3 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -189,6 +189,7 @@\n /gitweb/gitweb.cgi\n /gitweb/static/gitweb.js\n /gitweb/static/gitweb.min.*\n+/config-list.h\n /command-list.h\n *.tar.gz\n *.dsc\ndiff --git a/Makefile b/Makefile\nindex 6134104ae6..c552312d3f 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -815,6 +815,7 @@ LIB_FILE = libgit.a\n XDIFF_LIB = xdiff/lib.a\n VCSSVN_LIB = vcs-svn/lib.a\n \n+GENERATED_H += config-list.h\n GENERATED_H += command-list.h\n \n LIB_H := $(sort $(patsubst ./%,%,$(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \\\n@@ -2132,7 +2133,7 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)\n \n help.sp help.s help.o: command-list.h\n \n-builtin/help.sp builtin/help.s builtin/help.o: command-list.h GIT-PREFIX\n+builtin/help.sp builtin/help.s builtin/help.o: config-list.h GIT-PREFIX\n builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \\\n \t'-DGIT_HTML_PATH=\"$(htmldir_relative_SQ)\"' \\\n \t'-DGIT_MAN_PATH=\"$(mandir_relative_SQ)\"' \\\n@@ -2152,6 +2153,12 @@ $(BUILT_INS): git$X\n \tln -s $< $@ 2>/dev/null || \\\n \tcp $< $@\n \n+config-list.h: generate-configlist.sh\n+\n+config-list.h:\n+\t$(QUIET_GEN)$(SHELL_PATH) ./generate-configlist.sh \\\n+\t\t>$@+ && mv $@+ $@\n+\n command-list.h: generate-cmdlist.sh command-list.txt\n \n command-list.h: $(wildcard Documentation/git*.txt) Documentation/*config.txt Documentation/config/*.txt\n@@ -2785,7 +2792,7 @@ $(SP_OBJ): %.sp: %.c GIT-CFLAGS FORCE\n .PHONY: sparse $(SP_OBJ)\n sparse: $(SP_OBJ)\n \n-EXCEPT_HDRS := command-list.h unicode-width.h compat/% xdiff/%\n+EXCEPT_HDRS := command-list.h config-list.h unicode-width.h compat/% xdiff/%\n ifndef GCRYPT_SHA256\n \tEXCEPT_HDRS += sha256/gcrypt.h\n endif\n@@ -2807,7 +2814,7 @@ hdr-check: $(HCO)\n style:\n \tgit clang-format --style file --diff --extensions c,h\n \n-check: command-list.h\n+check: config-list.h command-list.h\n \t@if sparse; \\\n \tthen \\\n \t\techo >&2 \"Use 'make sparse' instead\"; \\\ndiff --git a/builtin/help.c b/builtin/help.c\nindex e5590d7787..1c5f2b9255 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -8,6 +8,7 @@\n #include \"parse-options.h\"\n #include \"run-command.h\"\n #include \"column.h\"\n+#include \"config-list.h\"\n #include \"help.h\"\n #include \"alias.h\"\n \n@@ -62,6 +63,91 @@ static const char * const builtin_help_usage[] = {\n \tNULL\n };\n \n+struct slot_expansion {\n+\tconst char *prefix;\n+\tconst char *placeholder;\n+\tvoid (*fn)(struct string_list *list, const char *prefix);\n+\tint found;\n+};\n+\n+static void list_config_help(int for_human)\n+{\n+\tstruct slot_expansion slot_expansions[] = {\n+\t\t{ \"advice\", \"*\", list_config_advices },\n+\t\t{ \"color.branch\", \"<slot>\", list_config_color_branch_slots },\n+\t\t{ \"color.decorate\", \"<slot>\", list_config_color_decorate_slots },\n+\t\t{ \"color.diff\", \"<slot>\", list_config_color_diff_slots },\n+\t\t{ \"color.grep\", \"<slot>\", list_config_color_grep_slots },\n+\t\t{ \"color.interactive\", \"<slot>\", list_config_color_interactive_slots },\n+\t\t{ \"color.remote\", \"<slot>\", list_config_color_sideband_slots },\n+\t\t{ \"color.status\", \"<slot>\", list_config_color_status_slots },\n+\t\t{ \"fsck\", \"<msg-id>\", list_config_fsck_msg_ids },\n+\t\t{ \"receive.fsck\", \"<msg-id>\", list_config_fsck_msg_ids },\n+\t\t{ NULL, NULL, NULL }\n+\t};\n+\tconst char **p;\n+\tstruct slot_expansion *e;\n+\tstruct string_list keys = STRING_LIST_INIT_DUP;\n+\tint i;\n+\n+\tfor (p = config_name_list; *p; p++) {\n+\t\tconst char *var = *p;\n+\t\tstruct strbuf sb = STRBUF_INIT;\n+\n+\t\tfor (e = slot_expansions; e->prefix; e++) {\n+\n+\t\t\tstrbuf_reset(&sb);\n+\t\t\tstrbuf_addf(&sb, \"%s.%s\", e->prefix, e->placeholder);\n+\t\t\tif (!strcasecmp(var, sb.buf)) {\n+\t\t\t\te->fn(&keys, e->prefix);\n+\t\t\t\te->found++;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\tstrbuf_release(&sb);\n+\t\tif (!e->prefix)\n+\t\t\tstring_list_append(&keys, var);\n+\t}\n+\n+\tfor (e = slot_expansions; e->prefix; e++)\n+\t\tif (!e->found)\n+\t\t\tBUG(\"slot_expansion %s.%s is not used\",\n+\t\t\t    e->prefix, e->placeholder);\n+\n+\tstring_list_sort(&keys);\n+\tfor (i = 0; i < keys.nr; i++) {\n+\t\tconst char *var = keys.items[i].string;\n+\t\tconst char *wildcard, *tag, *cut;\n+\n+\t\tif (for_human) {\n+\t\t\tputs(var);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\twildcard = strchr(var, '*');\n+\t\ttag = strchr(var, '<');\n+\n+\t\tif (!wildcard && !tag) {\n+\t\t\tputs(var);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (wildcard && !tag)\n+\t\t\tcut = wildcard;\n+\t\telse if (!wildcard && tag)\n+\t\t\tcut = tag;\n+\t\telse\n+\t\t\tcut = wildcard < tag ? wildcard : tag;\n+\n+\t\t/*\n+\t\t * We may produce duplicates, but that's up to\n+\t\t * git-completion.bash to handle\n+\t\t */\n+\t\tprintf(\"%.*s\\n\", (int)(cut - var), var);\n+\t}\n+\tstring_list_clear(&keys, 0);\n+}\n+\n static enum help_format parse_help_format(const char *format)\n {\n \tif (!strcmp(format, \"man\"))\ndiff --git a/generate-cmdlist.sh b/generate-cmdlist.sh\nindex 71158f7d8b..45fecf8bdf 100755\n--- a/generate-cmdlist.sh\n+++ b/generate-cmdlist.sh\n@@ -76,23 +76,6 @@ print_command_list () {\n \techo \"};\"\n }\n \n-print_config_list () {\n-\tcat <<EOF\n-static const char *config_name_list[] = {\n-EOF\n-\tgrep -h '^[a-zA-Z].*\\..*::$' Documentation/*config.txt Documentation/config/*.txt |\n-\tsed '/deprecated/d; s/::$//; s/,  */\\n/g' |\n-\tsort |\n-\twhile read line\n-\tdo\n-\t\techo \"\t\\\"$line\\\",\"\n-\tdone\n-\tcat <<EOF\n-\tNULL,\n-};\n-EOF\n-}\n-\n exclude_programs=\n while test \"--exclude-program\" = \"$1\"\n do\n@@ -113,5 +96,3 @@ echo\n define_category_names \"$1\"\n echo\n print_command_list \"$1\"\n-echo\n-print_config_list\ndiff --git a/generate-configlist.sh b/generate-configlist.sh\nnew file mode 100755\nindex 0000000000..8692fe5cf4\n--- /dev/null\n+++ b/generate-configlist.sh\n@@ -0,0 +1,21 @@\n+#!/bin/sh\n+\n+echo \"/* Automatically generated by generate-configlist.sh */\"\n+echo\n+\n+print_config_list () {\n+\tcat <<EOF\n+static const char *config_name_list[] = {\n+EOF\n+\tgrep -h '^[a-zA-Z].*\\..*::$' Documentation/*config.txt Documentation/config/*.txt |\n+\tsed '/deprecated/d; s/::$//; s/,  */\\n/g' |\n+\tsort |\n+\tsed 's/^.*$/\t\"&\",/'\n+\tcat <<EOF\n+\tNULL,\n+};\n+EOF\n+}\n+\n+echo\n+print_config_list\ndiff --git a/help.c b/help.c\nindex cf67624a94..a21487db77 100644\n--- a/help.c\n+++ b/help.c\n@@ -407,91 +407,6 @@ void list_common_guides_help(void)\n \tputchar('\\n');\n }\n \n-struct slot_expansion {\n-\tconst char *prefix;\n-\tconst char *placeholder;\n-\tvoid (*fn)(struct string_list *list, const char *prefix);\n-\tint found;\n-};\n-\n-void list_config_help(int for_human)\n-{\n-\tstruct slot_expansion slot_expansions[] = {\n-\t\t{ \"advice\", \"*\", list_config_advices },\n-\t\t{ \"color.branch\", \"<slot>\", list_config_color_branch_slots },\n-\t\t{ \"color.decorate\", \"<slot>\", list_config_color_decorate_slots },\n-\t\t{ \"color.diff\", \"<slot>\", list_config_color_diff_slots },\n-\t\t{ \"color.grep\", \"<slot>\", list_config_color_grep_slots },\n-\t\t{ \"color.interactive\", \"<slot>\", list_config_color_interactive_slots },\n-\t\t{ \"color.remote\", \"<slot>\", list_config_color_sideband_slots },\n-\t\t{ \"color.status\", \"<slot>\", list_config_color_status_slots },\n-\t\t{ \"fsck\", \"<msg-id>\", list_config_fsck_msg_ids },\n-\t\t{ \"receive.fsck\", \"<msg-id>\", list_config_fsck_msg_ids },\n-\t\t{ NULL, NULL, NULL }\n-\t};\n-\tconst char **p;\n-\tstruct slot_expansion *e;\n-\tstruct string_list keys = STRING_LIST_INIT_DUP;\n-\tint i;\n-\n-\tfor (p = config_name_list; *p; p++) {\n-\t\tconst char *var = *p;\n-\t\tstruct strbuf sb = STRBUF_INIT;\n-\n-\t\tfor (e = slot_expansions; e->prefix; e++) {\n-\n-\t\t\tstrbuf_reset(&sb);\n-\t\t\tstrbuf_addf(&sb, \"%s.%s\", e->prefix, e->placeholder);\n-\t\t\tif (!strcasecmp(var, sb.buf)) {\n-\t\t\t\te->fn(&keys, e->prefix);\n-\t\t\t\te->found++;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\t\tstrbuf_release(&sb);\n-\t\tif (!e->prefix)\n-\t\t\tstring_list_append(&keys, var);\n-\t}\n-\n-\tfor (e = slot_expansions; e->prefix; e++)\n-\t\tif (!e->found)\n-\t\t\tBUG(\"slot_expansion %s.%s is not used\",\n-\t\t\t    e->prefix, e->placeholder);\n-\n-\tstring_list_sort(&keys);\n-\tfor (i = 0; i < keys.nr; i++) {\n-\t\tconst char *var = keys.items[i].string;\n-\t\tconst char *wildcard, *tag, *cut;\n-\n-\t\tif (for_human) {\n-\t\t\tputs(var);\n-\t\t\tcontinue;\n-\t\t}\n-\n-\t\twildcard = strchr(var, '*');\n-\t\ttag = strchr(var, '<');\n-\n-\t\tif (!wildcard && !tag) {\n-\t\t\tputs(var);\n-\t\t\tcontinue;\n-\t\t}\n-\n-\t\tif (wildcard && !tag)\n-\t\t\tcut = wildcard;\n-\t\telse if (!wildcard && tag)\n-\t\t\tcut = tag;\n-\t\telse\n-\t\t\tcut = wildcard < tag ? wildcard : tag;\n-\n-\t\t/*\n-\t\t * We may produce duplicates, but that's up to\n-\t\t * git-completion.bash to handle\n-\t\t */\n-\t\tprintf(\"%.*s\\n\", (int)(cut - var), var);\n-\t}\n-\tstring_list_clear(&keys, 0);\n-}\n-\n static int get_alias(const char *var, const char *value, void *data)\n {\n \tstruct string_list *list = data;\ndiff --git a/help.h b/help.h\nindex 7a455beeb7..9071894e8c 100644\n--- a/help.h\n+++ b/help.h\n@@ -22,7 +22,6 @@ static inline void mput_char(char c, unsigned int num)\n void list_common_cmds_help(void);\n void list_all_cmds_help(void);\n void list_common_guides_help(void);\n-void list_config_help(int for_human);\n \n void list_all_main_cmds(struct string_list *list);\n void list_all_other_cmds(struct string_list *list);\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392138","messageId":"20200220015858.181086-4-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 03/15] bugreport: add tool to generate debugging info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:46Z","receivedAt":"2020-02-20T01:59:17Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"Teach Git how to prompt the user for a good bug report: reproduction\nsteps, expected behavior, and actual behavior. Later, Git can learn how\nto collect some diagnostic information from the repository.\n\nIf users can send us a well-written bug report which contains diagnostic\ninformation we would otherwise need to ask the user for, we can reduce\nthe number of question-and-answer round trips between the reporter and\nthe Git contributor.\n\nUsers may also wish to send a report like this to their local \"Git\nexpert\" if they have put their repository into a state they are confused\nby.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n .gitignore                      |  1 +\n Documentation/git-bugreport.txt | 46 ++++++++++++++++\n Makefile                        |  5 ++\n bugreport.c                     | 94 +++++++++++++++++++++++++++++++++\n command-list.txt                |  1 +\n t/t0091-bugreport.sh            | 61 +++++++++++++++++++++\n 6 files changed, 208 insertions(+)\n create mode 100644 Documentation/git-bugreport.txt\n create mode 100644 bugreport.c\n create mode 100755 t/t0091-bugreport.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex ea97de83f3..d89bf9e11e 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -25,6 +25,7 @@\n /git-bisect--helper\n /git-blame\n /git-branch\n+/git-bugreport\n /git-bundle\n /git-cat-file\n /git-check-attr\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nnew file mode 100644\nindex 0000000000..1f9fde5cde\n--- /dev/null\n+++ b/Documentation/git-bugreport.txt\n@@ -0,0 +1,46 @@\n+git-bugreport(1)\n+================\n+\n+NAME\n+----\n+git-bugreport - Collect information for user to file a bug report\n+\n+SYNOPSIS\n+--------\n+[verse]\n+'git bugreport' [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n+\n+DESCRIPTION\n+-----------\n+Captures information about the user's machine, Git client, and repository state,\n+as well as a form requesting information about the behavior the user observed,\n+into a single text file which the user can then share, for example to the Git\n+mailing list, in order to report an observed bug.\n+\n+The following information is requested from the user:\n+\n+ - Reproduction steps\n+ - Expected behavior\n+ - Actual behavior\n+\n+This tool is invoked via the typical Git setup process, which means that in some\n+cases, it might not be able to launch - for example, if a relevant config file\n+is unreadable. In this kind of scenario, it may be helpful to manually gather\n+the kind of information listed above when manually asking for help.\n+\n+OPTIONS\n+-------\n+-o <path>::\n+--output-directory <path>::\n+\tPlace the resulting bug report file in `<path>` instead of the root of\n+\tthe Git repository.\n+\n+-s <format>::\n+--suffix <format>::\n+\tSpecify an alternate suffix for the bugreport name, to create a file\n+\tnamed 'git-bugreport-<formatted suffix>'. This should take the form of a\n+\tlink:strftime[3] format string; the current local time will be used.\n+\n+GIT\n+---\n+Part of the linkgit:git[1] suite\ndiff --git a/Makefile b/Makefile\nindex c552312d3f..9e6705061d 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -681,6 +681,7 @@ EXTRA_PROGRAMS =\n # ... and all the rest that could be moved out of bindir to gitexecdir\n PROGRAMS += $(EXTRA_PROGRAMS)\n \n+PROGRAM_OBJS += bugreport.o\n PROGRAM_OBJS += credential-store.o\n PROGRAM_OBJS += daemon.o\n PROGRAM_OBJS += fast-import.o\n@@ -2461,6 +2462,10 @@ endif\n git-%$X: %.o GIT-LDFLAGS $(GITLIBS)\n \t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)\n \n+git-bugreport$X: bugreport.o GIT-LDFLAGS $(GITLIBS)\n+\t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \\\n+\t\t$(LIBS)\n+\n git-imap-send$X: imap-send.o $(IMAP_SEND_BUILDDEPS) GIT-LDFLAGS $(GITLIBS)\n \t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \\\n \t\t$(IMAP_SEND_LDFLAGS) $(LIBS)\ndiff --git a/bugreport.c b/bugreport.c\nnew file mode 100644\nindex 0000000000..8d4a76fdac\n--- /dev/null\n+++ b/bugreport.c\n@@ -0,0 +1,94 @@\n+#include \"builtin.h\"\n+#include \"parse-options.h\"\n+#include \"stdio.h\"\n+#include \"strbuf.h\"\n+#include \"time.h\"\n+\n+static const char * const bugreport_usage[] = {\n+\tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n+\tNULL\n+};\n+\n+static int get_bug_template(struct strbuf *template)\n+{\n+\tconst char template_text[] = N_(\n+\"Thank you for filling out a Git bug report!\\n\"\n+\"Please answer the following questions to help us understand your issue.\\n\"\n+\"\\n\"\n+\"What did you do before the bug happened? (Steps to reproduce your issue)\\n\"\n+\"\\n\"\n+\"What did you expect to happen? (Expected behavior)\\n\"\n+\"\\n\"\n+\"What happened instead? (Actual behavior)\\n\"\n+\"\\n\"\n+\"What's different between what you expected and what actually happened?\\n\"\n+\"\\n\"\n+\"Anything else you want to add:\\n\"\n+\"\\n\"\n+\"Please review the rest of the bug report below.\\n\"\n+\"You can delete any lines you don't wish to share.\\n\");\n+\n+\tstrbuf_addstr(template, template_text);\n+\treturn 0;\n+}\n+\n+int cmd_main(int argc, const char **argv)\n+{\n+\tstruct strbuf buffer = STRBUF_INIT;\n+\tstruct strbuf report_path = STRBUF_INIT;\n+\tFILE *report;\n+\ttime_t now = time(NULL);\n+\tchar *option_output = NULL;\n+\tchar *option_suffix = \"%F-%H%M\";\n+\tstruct stat statbuf;\n+\n+\tconst struct option bugreport_options[] = {\n+\t\tOPT_STRING('o', \"output-directory\", &option_output, N_(\"path\"),\n+\t\t\t   N_(\"specify a destination for the bugreport file\")),\n+\t\tOPT_STRING('s', \"suffix\", &option_suffix, N_(\"format\"),\n+\t\t\t   N_(\"specify a strftime format suffix for the filename\")),\n+\t\tOPT_END()\n+\t};\n+\targc = parse_options(argc, argv, \"\", bugreport_options,\n+\t\t\t     bugreport_usage, 0);\n+\n+\tif (option_output) {\n+\t\tstrbuf_addstr(&report_path, option_output);\n+\t\tstrbuf_complete(&report_path, '/');\n+\t}\n+\n+\n+\tstrbuf_addstr(&report_path, \"git-bugreport-\");\n+\tstrbuf_addftime(&report_path, option_suffix, localtime(&now), 0, 0);\n+\tstrbuf_addstr(&report_path, \".txt\");\n+\n+\tif (!stat(report_path.buf, &statbuf))\n+\t\tdie(\"'%s' already exists\", report_path.buf);\n+\n+\tswitch (safe_create_leading_directories(report_path.buf)) {\n+\tcase SCLD_OK:\n+\tcase SCLD_EXISTS:\n+\t\tbreak;\n+\tdefault:\n+\t\tdie(_(\"could not create leading directories for '%s'\"),\n+\t\t    report_path.buf);\n+\t}\n+\n+\tget_bug_template(&buffer);\n+\n+\treport = fopen_for_writing(report_path.buf);\n+\n+\tif (report == NULL) {\n+\t\tstrbuf_release(&report_path);\n+\t\tdie(\"couldn't open '%s' for writing\", report_path.buf);\n+\t}\n+\n+\tstrbuf_write(&buffer, report);\n+\tfclose(report);\n+\n+\tfprintf(stderr, _(\"Created new report at '%s'.\\n\"), report_path.buf);\n+\n+\tUNLEAK(buffer);\n+\tUNLEAK(report_path);\n+\treturn !!launch_editor(report_path.buf, NULL, NULL);\n+}\ndiff --git a/command-list.txt b/command-list.txt\nindex 2087894655..185e5e3f05 100644\n--- a/command-list.txt\n+++ b/command-list.txt\n@@ -54,6 +54,7 @@ git-archive                             mainporcelain\n git-bisect                              mainporcelain           info\n git-blame                               ancillaryinterrogators          complete\n git-branch                              mainporcelain           history\n+git-bugreport                           ancillaryinterrogators\n git-bundle                              mainporcelain\n git-cat-file                            plumbinginterrogators\n git-check-attr                          purehelpers\ndiff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh\nnew file mode 100755\nindex 0000000000..65f664fdac\n--- /dev/null\n+++ b/t/t0091-bugreport.sh\n@@ -0,0 +1,61 @@\n+#!/bin/sh\n+\n+test_description='git bugreport'\n+\n+. ./test-lib.sh\n+\n+# Headers \"[System Info]\" will be followed by a non-empty line if we put some\n+# information there; we can make sure all our headers were followed by some\n+# information to check if the command was successful.\n+HEADER_PATTERN=\"^\\[.*\\]$\"\n+\n+check_all_headers_populated () {\n+\twhile read -r line\n+\tdo\n+\t\tif test \"$(grep \"$HEADER_PATTERN\" \"$line\")\"\n+\t\tthen\n+\t\t\techo \"$line\"\n+\t\t\tread -r nextline\n+\t\t\tif test -z \"$nextline\"; then\n+\t\t\t\treturn 1;\n+\t\t\tfi\n+\t\tfi\n+\tdone\n+}\n+\n+test_expect_success 'creates a report with content in the right places' '\n+\tgit bugreport -s check-headers &&\n+\tcheck_all_headers_populated <git-bugreport-check-headers.txt &&\n+\ttest_when_finished rm git-bugreport-check-headers.txt\n+'\n+\n+test_expect_success 'dies if file with same name as report already exists' '\n+\t>>git-bugreport-duplicate.txt &&\n+\ttest_must_fail git bugreport --suffix duplicate &&\n+\ttest_when_finished rm git-bugreport-duplicate.txt\n+'\n+\n+test_expect_success '--output-directory puts the report in the provided dir' '\n+\tgit bugreport -o foo/ &&\n+\ttest_path_is_file foo/git-bugreport-* &&\n+\ttest_when_finished rm -fr foo/\n+'\n+\n+test_expect_success 'incorrect arguments abort with usage' '\n+\ttest_must_fail git bugreport --false 2>output &&\n+\ttest_i18ngrep usage output &&\n+\ttest_path_is_missing git-bugreport-*\n+'\n+\n+test_expect_success 'runs outside of a git dir' '\n+\tnongit git bugreport &&\n+\ttest_when_finished rm non-repo/git-bugreport-*\n+'\n+\n+test_expect_success 'can create leading directories outside of a git dir' '\n+\tnongit git bugreport -o foo/bar/baz &&\n+\ttest_when_finished rm -fr foo/bar/baz\n+'\n+\n+\n+test_done\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392139","messageId":"20200220015858.181086-5-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 04/15] bugreport: gather git version and build info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:47Z","receivedAt":"2020-02-20T01:59:20Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"Knowing which version of Git a user has and how it was built allows us\nto more precisely pin down the circumstances when a certain issue\noccurs, so teach bugreport how to tell us the same output as 'git\nversion --build-options'.\n\nIt's not ideal to directly call 'git version --build-options' because\nthat output goes to stdout. Instead, wrap the version string in a helper\nwithin help.[ch] library, and call that helper from within the bugreport\nlibrary.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt |  4 +++\n bugreport.c                     | 19 ++++++++++++-\n help.c                          | 48 ++++++++++++++++++++-------------\n help.h                          |  1 +\n 4 files changed, 52 insertions(+), 20 deletions(-)\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex 1f9fde5cde..f44ae8cbe7 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -23,6 +23,10 @@ The following information is requested from the user:\n  - Expected behavior\n  - Actual behavior\n \n+The following information is captured automatically:\n+\n+ - 'git version --build-options'\n+\n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\n is unreadable. In this kind of scenario, it may be helpful to manually gather\ndiff --git a/bugreport.c b/bugreport.c\nindex 8d4a76fdac..27f813643d 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -1,8 +1,17 @@\n-#include \"builtin.h\"\n+#include \"cache.h\"\n #include \"parse-options.h\"\n #include \"stdio.h\"\n #include \"strbuf.h\"\n #include \"time.h\"\n+#include \"help.h\"\n+\n+static void get_system_info(struct strbuf *sys_info)\n+{\n+\t/* get git version from native cmd */\n+\tstrbuf_addstr(sys_info, \"git version:\\n\");\n+\tget_version_info(sys_info, 1);\n+\tstrbuf_complete_line(sys_info);\n+}\n \n static const char * const bugreport_usage[] = {\n \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n@@ -32,6 +41,11 @@ static int get_bug_template(struct strbuf *template)\n \treturn 0;\n }\n \n+static void get_header(struct strbuf *buf, const char *title)\n+{\n+\tstrbuf_addf(buf, \"\\n\\n[%s]\\n\", title);\n+}\n+\n int cmd_main(int argc, const char **argv)\n {\n \tstruct strbuf buffer = STRBUF_INIT;\n@@ -76,6 +90,9 @@ int cmd_main(int argc, const char **argv)\n \n \tget_bug_template(&buffer);\n \n+\tget_header(&buffer, \"System Info\");\n+\tget_system_info(&buffer);\n+\n \treport = fopen_for_writing(report_path.buf);\n \n \tif (report == NULL) {\ndiff --git a/help.c b/help.c\nindex 190722fb0a..44cee69c11 100644\n--- a/help.c\n+++ b/help.c\n@@ -622,8 +622,33 @@ const char *help_unknown_cmd(const char *cmd)\n \texit(1);\n }\n \n+void get_version_info(struct strbuf *buf, int show_build_options)\n+{\n+\t/*\n+\t * The format of this string should be kept stable for compatibility\n+\t * with external projects that rely on the output of \"git version\".\n+\t *\n+\t * Always show the version, even if other options are given.\n+\t */\n+\tstrbuf_addf(buf, \"git version %s\\n\", git_version_string);\n+\n+\tif (show_build_options) {\n+\t\tstrbuf_addf(buf, \"cpu: %s\\n\", GIT_HOST_CPU);\n+\t\tif (git_built_from_commit_string[0])\n+\t\t\tstrbuf_addf(buf, \"built from commit: %s\\n\",\n+\t\t\t       git_built_from_commit_string);\n+\t\telse\n+\t\t\tstrbuf_addstr(buf, \"no commit associated with this build\\n\");\n+\t\tstrbuf_addf(buf, \"sizeof-long: %d\\n\", (int)sizeof(long));\n+\t\tstrbuf_addf(buf, \"sizeof-size_t: %d\\n\", (int)sizeof(size_t));\n+\t\tstrbuf_addf(buf, \"shell-path: %s\\n\", SHELL_PATH);\n+\t\t/* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */\n+\t}\n+}\n+\n int cmd_version(int argc, const char **argv, const char *prefix)\n {\n+\tstruct strbuf buf = STRBUF_INIT;\n \tint build_options = 0;\n \tconst char * const usage[] = {\n \t\tN_(\"git version [<options>]\"),\n@@ -637,26 +662,11 @@ int cmd_version(int argc, const char **argv, const char *prefix)\n \n \targc = parse_options(argc, argv, prefix, options, usage, 0);\n \n-\t/*\n-\t * The format of this string should be kept stable for compatibility\n-\t * with external projects that rely on the output of \"git version\".\n-\t *\n-\t * Always show the version, even if other options are given.\n-\t */\n-\tprintf(\"git version %s\\n\", git_version_string);\n+\tget_version_info(&buf, build_options);\n+\tprintf(\"%s\", buf.buf);\n+\n+\tstrbuf_release(&buf);\n \n-\tif (build_options) {\n-\t\tprintf(\"cpu: %s\\n\", GIT_HOST_CPU);\n-\t\tif (git_built_from_commit_string[0])\n-\t\t\tprintf(\"built from commit: %s\\n\",\n-\t\t\t       git_built_from_commit_string);\n-\t\telse\n-\t\t\tprintf(\"no commit associated with this build\\n\");\n-\t\tprintf(\"sizeof-long: %d\\n\", (int)sizeof(long));\n-\t\tprintf(\"sizeof-size_t: %d\\n\", (int)sizeof(size_t));\n-\t\tprintf(\"shell-path: %s\\n\", SHELL_PATH);\n-\t\t/* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */\n-\t}\n \treturn 0;\n }\n \ndiff --git a/help.h b/help.h\nindex 9071894e8c..500521b908 100644\n--- a/help.h\n+++ b/help.h\n@@ -37,6 +37,7 @@ void add_cmdname(struct cmdnames *cmds, const char *name, int len);\n void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes);\n int is_in_cmdlist(struct cmdnames *cmds, const char *name);\n void list_commands(unsigned int colopts, struct cmdnames *main_cmds, struct cmdnames *other_cmds);\n+void get_version_info(struct strbuf *buf, int show_build_options);\n \n /*\n  * call this to die(), when it is suspected that the user mistyped a\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392140","messageId":"20200220015858.181086-6-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 05/15] bugreport: add uname info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:48Z","receivedAt":"2020-02-20T01:59:21Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"The contents of uname() can give us some insight into what sort of\nsystem the user is running on, and help us replicate their setup if need\nbe. The domainname field is not guaranteed to be available, so don't\ncollect it.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt |  1 +\n bugreport.c                     | 13 +++++++++++++\n 2 files changed, 14 insertions(+)\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex f44ae8cbe7..17b0d14e8d 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -26,6 +26,7 @@ The following information is requested from the user:\n The following information is captured automatically:\n \n  - 'git version --build-options'\n+ - uname sysname, release, version, and machine strings\n \n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\ndiff --git a/bugreport.c b/bugreport.c\nindex 27f813643d..06a63cc283 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -7,10 +7,23 @@\n \n static void get_system_info(struct strbuf *sys_info)\n {\n+\tstruct utsname uname_info;\n+\n \t/* get git version from native cmd */\n \tstrbuf_addstr(sys_info, \"git version:\\n\");\n \tget_version_info(sys_info, 1);\n \tstrbuf_complete_line(sys_info);\n+\n+\t/* system call for other version info */\n+\tstrbuf_addstr(sys_info, \"uname -a: \");\n+\tif (uname(&uname_info))\n+\t\tstrbuf_addf(sys_info, \"uname() failed with code %d\\n\", errno);\n+\telse\n+\t\tstrbuf_addf(sys_info, \"%s %s %s %s\\n\",\n+\t\t\t    uname_info.sysname,\n+\t\t\t    uname_info.release,\n+\t\t\t    uname_info.version,\n+\t\t\t    uname_info.machine);\n }\n \n static const char * const bugreport_usage[] = {\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392141","messageId":"20200220015858.181086-7-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 06/15] bugreport: add compiler info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:49Z","receivedAt":"2020-02-20T01:59:22Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"To help pinpoint the source of a regression, it is useful to know some\ninfo about the compiler which the user's Git client was built with. By\nadding a generic get_compiler_info() in 'compat/' we can choose which\nrelevant information to share per compiler; to get started, let's\ndemonstrate the version of glibc if the user built with 'gcc'.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt |  1 +\n bugreport.c                     |  5 +++++\n compat/compiler.h               | 27 +++++++++++++++++++++++++++\n 3 files changed, 33 insertions(+)\n create mode 100644 compat/compiler.h\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex 17b0d14e8d..643d1b2884 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -27,6 +27,7 @@ The following information is captured automatically:\n \n  - 'git version --build-options'\n  - uname sysname, release, version, and machine strings\n+ - Compiler-specific info string\n \n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\ndiff --git a/bugreport.c b/bugreport.c\nindex 06a63cc283..9a470c5588 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -4,6 +4,7 @@\n #include \"strbuf.h\"\n #include \"time.h\"\n #include \"help.h\"\n+#include \"compat/compiler.h\"\n \n static void get_system_info(struct strbuf *sys_info)\n {\n@@ -24,6 +25,10 @@ static void get_system_info(struct strbuf *sys_info)\n \t\t\t    uname_info.release,\n \t\t\t    uname_info.version,\n \t\t\t    uname_info.machine);\n+\n+\tstrbuf_addstr(sys_info, \"compiler info: \");\n+\tget_compiler_info(sys_info);\n+\tstrbuf_complete_line(sys_info);\n }\n \n static const char * const bugreport_usage[] = {\ndiff --git a/compat/compiler.h b/compat/compiler.h\nnew file mode 100644\nindex 0000000000..ef41177233\n--- /dev/null\n+++ b/compat/compiler.h\n@@ -0,0 +1,27 @@\n+#ifndef COMPILER_H\n+#define COMPILER_H\n+\n+#include \"git-compat-util.h\"\n+#include \"strbuf.h\"\n+\n+#ifdef __GLIBC__\n+#include <gnu/libc-version.h>\n+\n+static inline void get_compiler_info(struct strbuf *info)\n+{\n+\tstrbuf_addf(info, \"glibc: %s\\n\", gnu_get_libc_version());\n+#ifdef __GNUC__\n+\tstrbuf_addf(info, \"gnuc: %d.%d\\n\", __GNUC__, __GNUC_MINOR__);\n+#endif\n+}\n+\n+#else\n+\n+static inline void get_compiler_info(struct strbuf *info)\n+{\n+\tstrbuf_addstr(info, \"get_compiler_info() not implemented\");\n+}\n+\n+#endif\n+\n+#endif /* COMPILER_H */\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392142","messageId":"20200220015858.181086-8-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 07/15] bugreport: add git-remote-https version","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:50Z","receivedAt":"2020-02-20T01:59:25Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"It's possible for git-remote-curl to be built separately from git; in that\ncase we want to know what version of cURL is used by git-remote-curl, not\nnecessarily which version was present at git-bugreport's build time.\nSo instead, ask git-remote-curl for the version information it knows\nabout.\n\nToday, \"git-remote-http\" and \"git-remote-https\" are aliased to\n\"git-remote-curl\"; but in case we rely on a different library than cURL\nin the future, let's not explicitly reference cURL from bugreport.\n\nFor longevity purposes, invoke the alias \"git-remote-https\" instead of\n\"git-remote-http\".\n\nSince it could have been built at a different time, also report the\nversion and built-from commit of git-remote-curl alongside the cURL info.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt |  1 +\n bugreport.c                     | 16 ++++++++++++++++\n remote-curl.c                   |  8 ++++++++\n 3 files changed, 25 insertions(+)\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex 643d1b2884..8c7cb9a5d4 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -28,6 +28,7 @@ The following information is captured automatically:\n  - 'git version --build-options'\n  - uname sysname, release, version, and machine strings\n  - Compiler-specific info string\n+ - 'git remote-https --build-info'\n \n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\ndiff --git a/bugreport.c b/bugreport.c\nindex 9a470c5588..fb2adfdf14 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -5,6 +5,18 @@\n #include \"time.h\"\n #include \"help.h\"\n #include \"compat/compiler.h\"\n+#include \"run-command.h\"\n+\n+static void get_git_remote_https_version_info(struct strbuf *version_info)\n+{\n+\tstruct child_process cp = CHILD_PROCESS_INIT;\n+\n+\tcp.git_cmd = 1;\n+\targv_array_push(&cp.args, \"remote-https\");\n+\targv_array_push(&cp.args, \"--build-info\");\n+\tif (capture_command(&cp, version_info, 0))\n+\t    strbuf_addstr(version_info, \"'git-remote-https --build-info' not supported\\n\");\n+}\n \n static void get_system_info(struct strbuf *sys_info)\n {\n@@ -29,6 +41,10 @@ static void get_system_info(struct strbuf *sys_info)\n \tstrbuf_addstr(sys_info, \"compiler info: \");\n \tget_compiler_info(sys_info);\n \tstrbuf_complete_line(sys_info);\n+\n+\tstrbuf_addstr(sys_info, \"git-remote-https --build-info:\\n\");\n+\tget_git_remote_https_version_info(sys_info);\n+\tstrbuf_complete_line(sys_info);\n }\n \n static const char * const bugreport_usage[] = {\ndiff --git a/remote-curl.c b/remote-curl.c\nindex 8eb96152f5..73e52175c0 100644\n--- a/remote-curl.c\n+++ b/remote-curl.c\n@@ -17,6 +17,7 @@\n #include \"protocol.h\"\n #include \"quote.h\"\n #include \"transport.h\"\n+#include \"version.h\"\n \n static struct remote *remote;\n /* always ends with a trailing slash */\n@@ -1375,6 +1376,13 @@ int cmd_main(int argc, const char **argv)\n \tstring_list_init(&options.deepen_not, 1);\n \tstring_list_init(&options.push_options, 1);\n \n+\tif (!strcmp(\"--build-info\", argv[1])) {\n+\t\tprintf(\"git-http-fetch version: %s\\n\", git_version_string);\n+\t\tprintf(\"built from commit: %s\\n\", git_built_from_commit_string);\n+\t\tprintf(\"curl version: %s\\n\", curl_version());\n+\t\treturn 0;\n+\t}\n+\n \t/*\n \t * Just report \"remote-curl\" here (folding all the various aliases\n \t * (\"git-remote-http\", \"git-remote-https\", and etc.) here since they\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392143","messageId":"20200220015858.181086-9-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 08/15] bugreport: include user interactive shell","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:51Z","receivedAt":"2020-02-20T01:59:27Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"It's possible a user may complain about the way that Git interacts with\ntheir interactive shell, e.g. autocompletion or shell prompt. In that\ncase, it's useful for us to know which shell they're using\ninteractively.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt | 1 +\n bugreport.c                     | 5 +++++\n 2 files changed, 6 insertions(+)\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex 8c7cb9a5d4..f7a13c0374 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -29,6 +29,7 @@ The following information is captured automatically:\n  - uname sysname, release, version, and machine strings\n  - Compiler-specific info string\n  - 'git remote-https --build-info'\n+ - $SHELL\n \n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\ndiff --git a/bugreport.c b/bugreport.c\nindex fb2adfdf14..f143b9a8f8 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -21,6 +21,7 @@ static void get_git_remote_https_version_info(struct strbuf *version_info)\n static void get_system_info(struct strbuf *sys_info)\n {\n \tstruct utsname uname_info;\n+\tchar *shell = NULL;\n \n \t/* get git version from native cmd */\n \tstrbuf_addstr(sys_info, \"git version:\\n\");\n@@ -42,6 +43,10 @@ static void get_system_info(struct strbuf *sys_info)\n \tget_compiler_info(sys_info);\n \tstrbuf_complete_line(sys_info);\n \n+\tshell = getenv(\"SHELL\");\n+\tstrbuf_addf(sys_info, \"$SHELL (typically, interactive shell): %s\\n\",\n+\t\t    shell ? shell : \"<unset>\");\n+\n \tstrbuf_addstr(sys_info, \"git-remote-https --build-info:\\n\");\n \tget_git_remote_https_version_info(sys_info);\n \tstrbuf_complete_line(sys_info);\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392144","messageId":"20200220015858.181086-10-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 09/15] bugreport: generate config safelist based on docs","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:52Z","receivedAt":"2020-02-20T01:59:31Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"Add a new step to the build to generate a safelist of git-config\nvariables which are appropriate to include in the output of\ngit-bugreport. New variables can be added to the safelist by annotating\ntheir documentation in Documentation/config with the \"annotate\" macro,\nwhich is a no-op in AsciiDoc and AsciiDoctor.\n\nSome configs are private in nature, and can contain remote URLs,\npasswords, or other sensitive information. In the event that a user\ndoesn't notice their information while reviewing a bugreport, that user\nmay leak their credentials to other individuals, mailing lists, or bug\ntracking tools inadvertently. Heuristic blocklisting of configuration\nkeys is imperfect and prone to false negatives; given the nature of the\ninformation which can be leaked, a safelist is more reliable.\n\nHowever, it's possible that in some situations, an organization may be\nless concerned with privacy of things like remote URLs and branch names,\nand more concerned with ease of diagnosis for their support staff. In\nthose cases, it may make more sense for that organization to modify the\ncode to use a blocklist. To that end, we should try to mark configs which\nare definitely safe, and configs which are definitely unsafe, and leave\nblank configs which are somewhere in between. To mark a config as safe,\nadd \"annotate:bugreport[include]\" to the corresponding line in the\nconfig documentation; to mark it as unsafe, add\n\"annotate:bugreport[exclude]\" instead.\n\nGenerating bugreport-config-safelist.h at build time by grepping the\ndocumentation for this new macro helps us prevent staleness. The macro\nitself is a no-op and should not alter the appearance of the\ndocumentation in either AsciiDoc or AsciiDoctor, confirmable by running:\n\n  cd Documentation\n  ./doc-diff --asciidoctor HEAD^ HEAD\n  ./doc-diff --asciidoc HEAD^ HEAD\n\nDiffing the rendered HTML shows that only inline comments were added,\nwhich shouldn't be a problem.\n\nAdditionally, add annotations to the sendemail config documentation in\norder to demonstrate a proof of concept.\n\nHelped-by: Martin Ågren <martin.agren@gmail.com>\nHelped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n .gitignore                              |  1 +\n Documentation/asciidoc.conf             |  9 ++++\n Documentation/asciidoctor-extensions.rb |  7 ++++\n Documentation/config/sendemail.txt      | 56 ++++++++++++-------------\n Makefile                                |  7 ++++\n generate-bugreport-config-safelist.sh   | 18 ++++++++\n 6 files changed, 70 insertions(+), 28 deletions(-)\n create mode 100755 generate-bugreport-config-safelist.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex d89bf9e11e..bd2f49b996 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -192,6 +192,7 @@\n /gitweb/static/gitweb.min.*\n /config-list.h\n /command-list.h\n+/bugreport-config-safelist.h\n *.tar.gz\n *.dsc\n *.deb\ndiff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf\nindex 8fc4b67081..663e06481f 100644\n--- a/Documentation/asciidoc.conf\n+++ b/Documentation/asciidoc.conf\n@@ -6,9 +6,14 @@\n #\n # Show Git link as: <command>(<section>); if section is defined, else just show\n # the command.\n+#\n+# The annotate macro does nothing as far as rendering is\n+# concerned -- we just grep for it in the sources to populate\n+# things like the bugreport safelist.\n \n [macros]\n (?su)[\\\\]?(?P<name>linkgit):(?P<target>\\S*?)\\[(?P<attrlist>.*?)\\]=\n+(?su)[\\\\]?(?P<name>annotate):(?P<target>\\S*?)\\[(?P<attrlist>.*?)\\]=\n \n [attributes]\n asterisk=&#42;\n@@ -28,6 +33,8 @@ ifdef::backend-docbook[]\n {0#<citerefentry>}\n {0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>}\n {0#</citerefentry>}\n+[annotate-inlinemacro]\n+{0#}\n endif::backend-docbook[]\n \n ifdef::backend-docbook[]\n@@ -94,4 +101,6 @@ ifdef::backend-xhtml11[]\n git-relative-html-prefix=\n [linkgit-inlinemacro]\n <a href=\"{git-relative-html-prefix}{target}.html\">{target}{0?({0})}</a>\n+[annotate-inlinemacro]\n+<!-- -->\n endif::backend-xhtml11[]\ndiff --git a/Documentation/asciidoctor-extensions.rb b/Documentation/asciidoctor-extensions.rb\nindex d906a00803..03c80af0e5 100644\n--- a/Documentation/asciidoctor-extensions.rb\n+++ b/Documentation/asciidoctor-extensions.rb\n@@ -39,10 +39,17 @@ module Git\n         output\n       end\n     end\n+\n+    class AnnotateProcessor < Asciidoctor::Extensions::InlineMacroProcessor\n+      def process(parent, target, attrs)\n+        \"\"\n+      end\n+    end\n   end\n end\n \n Asciidoctor::Extensions.register do\n   inline_macro Git::Documentation::LinkGitProcessor, :linkgit\n   postprocessor Git::Documentation::DocumentPostProcessor\n+  inline_macro Git::Documentation::AnnotateProcessor, :annotate\n end\ndiff --git a/Documentation/config/sendemail.txt b/Documentation/config/sendemail.txt\nindex 0006faf800..fe27473e44 100644\n--- a/Documentation/config/sendemail.txt\n+++ b/Documentation/config/sendemail.txt\n@@ -4,7 +4,7 @@ sendemail.identity::\n \tvalues in the 'sendemail' section. The default identity is\n \tthe value of `sendemail.identity`.\n \n-sendemail.smtpEncryption::\n+sendemail.smtpEncryption annotate:bugreport[include] ::\n \tSee linkgit:git-send-email[1] for description.  Note that this\n \tsetting is not subject to the 'identity' mechanism.\n \n@@ -15,7 +15,7 @@ sendemail.smtpsslcertpath::\n \tPath to ca-certificates (either a directory or a single file).\n \tSet it to an empty string to disable certificate verification.\n \n-sendemail.<identity>.*::\n+sendemail.<identity>.* annotate:bugreport[exclude] ::\n \tIdentity-specific versions of the 'sendemail.*' parameters\n \tfound below, taking precedence over those when this\n \tidentity is selected, through either the command-line or\n@@ -23,41 +23,41 @@ sendemail.<identity>.*::\n \n sendemail.aliasesFile::\n sendemail.aliasFileType::\n-sendemail.annotate::\n-sendemail.bcc::\n-sendemail.cc::\n-sendemail.ccCmd::\n-sendemail.chainReplyTo::\n-sendemail.confirm::\n-sendemail.envelopeSender::\n-sendemail.from::\n-sendemail.multiEdit::\n-sendemail.signedoffbycc::\n-sendemail.smtpPass::\n-sendemail.suppresscc::\n-sendemail.suppressFrom::\n-sendemail.to::\n-sendemail.tocmd::\n-sendemail.smtpDomain::\n-sendemail.smtpServer::\n-sendemail.smtpServerPort::\n-sendemail.smtpServerOption::\n-sendemail.smtpUser::\n-sendemail.thread::\n-sendemail.transferEncoding::\n-sendemail.validate::\n-sendemail.xmailer::\n+sendemail.annotate annotate:bugreport[include] ::\n+sendemail.bcc annotate:bugreport[include] ::\n+sendemail.cc annotate:bugreport[include] ::\n+sendemail.ccCmd annotate:bugreport[include] ::\n+sendemail.chainReplyTo annotate:bugreport[include] ::\n+sendemail.confirm annotate:bugreport[include] ::\n+sendemail.envelopeSender annotate:bugreport[include] ::\n+sendemail.from annotate:bugreport[include] ::\n+sendemail.multiEdit annotate:bugreport[include] ::\n+sendemail.signedoffbycc annotate:bugreport[include] ::\n+sendemail.smtpPass annotate:bugreport[exclude] ::\n+sendemail.suppresscc annotate:bugreport[include] ::\n+sendemail.suppressFrom annotate:bugreport[include] ::\n+sendemail.to annotate:bugreport[include] ::\n+sendemail.tocmd annotate:bugreport[include] ::\n+sendemail.smtpDomain annotate:bugreport[include] ::\n+sendemail.smtpServer annotate:bugreport[include] ::\n+sendemail.smtpServerPort annotate:bugreport[include] ::\n+sendemail.smtpServerOption annotate:bugreport[include] ::\n+sendemail.smtpUser annotate:bugreport[exclude] ::\n+sendemail.thread annotate:bugreport[include] ::\n+sendemail.transferEncoding annotate:bugreport[include] ::\n+sendemail.validate annotate:bugreport[include] ::\n+sendemail.xmailer annotate:bugreport[include] ::\n \tSee linkgit:git-send-email[1] for description.\n \n sendemail.signedoffcc (deprecated)::\n \tDeprecated alias for `sendemail.signedoffbycc`.\n \n-sendemail.smtpBatchSize::\n+sendemail.smtpBatchSize annotate:bugreport[include] ::\n \tNumber of messages to be sent per connection, after that a relogin\n \twill happen.  If the value is 0 or undefined, send all messages in\n \tone connection.\n \tSee also the `--batch-size` option of linkgit:git-send-email[1].\n \n-sendemail.smtpReloginDelay::\n+sendemail.smtpReloginDelay annotate:bugreport[include] ::\n \tSeconds wait before reconnecting to smtp server.\n \tSee also the `--relogin-delay` option of linkgit:git-send-email[1].\ndiff --git a/Makefile b/Makefile\nindex 9e6705061d..6bdd3b9337 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -818,6 +818,7 @@ VCSSVN_LIB = vcs-svn/lib.a\n \n GENERATED_H += config-list.h\n GENERATED_H += command-list.h\n+GENERATED_H += bugreport-config-safelist.h\n \n LIB_H := $(sort $(patsubst ./%,%,$(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \\\n \t$(FIND) . \\\n@@ -2167,6 +2168,12 @@ command-list.h: $(wildcard Documentation/git*.txt) Documentation/*config.txt Doc\n \t\t$(patsubst %,--exclude-program %,$(EXCLUDED_PROGRAMS)) \\\n \t\tcommand-list.txt >$@+ && mv $@+ $@\n \n+bugreport-config-safelist.h: generate-bugreport-config-safelist.sh\n+\n+bugreport-config-safelist.h: Documentation/config/*.txt\n+\t$(QUIET_GEN)$(SHELL_PATH) ./generate-bugreport-config-safelist.sh \\\n+\t\t>$@+ && mv $@+ $@\n+\n SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\\\n \t$(localedir_SQ):$(NO_CURL):$(USE_GETTEXT_SCHEME):$(SANE_TOOL_PATH_SQ):\\\n \t$(gitwebdir_SQ):$(PERL_PATH_SQ):$(SANE_TEXT_GREP):$(PAGER_ENV):\\\ndiff --git a/generate-bugreport-config-safelist.sh b/generate-bugreport-config-safelist.sh\nnew file mode 100755\nindex 0000000000..a9e5b6b2a0\n--- /dev/null\n+++ b/generate-bugreport-config-safelist.sh\n@@ -0,0 +1,18 @@\n+#!/bin/sh\n+\n+cat <<EOF\n+/* Automatically generated by bugreport-generate-config-safelist.sh */\n+\n+\n+static const char *bugreport_config_safelist[] = {\n+EOF\n+\n+# cat all regular files in Documentation/config\n+find Documentation/config -type f -exec cat {} \\; |\n+# print the command name which matches the annotate-bugreport macro\n+sed -n 's/^\\([^ ]*\\)  *annotate:bugreport\\[include\\].* ::$/  \"\\1\",/p' \\\n+\t| sort\n+\n+cat <<EOF\n+};\n+EOF\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392145","messageId":"20200220015858.181086-11-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 10/15] bugreport: add config values from safelist","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:53Z","receivedAt":"2020-02-20T01:59:32Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"Teach bugreport to gather the values of config options which are present\nin 'bugreport-config-safelist.h', and show their origin scope.\n\nMany config options are sensitive, and many Git add-ons use config\noptions which git-core does not know about; it is better only to gather\nconfig options which we know to be safe, rather than excluding options\nwhich we know to be unsafe.\n\nRather than including the path to someone's config, which can reveal\nfilesystem layout and project names, just name the scope (e.g. system,\nglobal, local) of the config source.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt |  1 +\n Makefile                        |  2 ++\n bugreport.c                     | 34 +++++++++++++++++++++++++++++++++\n 3 files changed, 37 insertions(+)\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex f7a13c0374..efe9719ea4 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -30,6 +30,7 @@ The following information is captured automatically:\n  - Compiler-specific info string\n  - 'git remote-https --build-info'\n  - $SHELL\n+ - Selected config values\n \n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\ndiff --git a/Makefile b/Makefile\nindex 6bdd3b9337..bf4f3ede2a 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -2135,6 +2135,8 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)\n \n help.sp help.s help.o: command-list.h\n \n+bugreport.sp bugreport.s bugreport.o: bugreport-config-safelist.h\n+\n builtin/help.sp builtin/help.s builtin/help.o: config-list.h GIT-PREFIX\n builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \\\n \t'-DGIT_HTML_PATH=\"$(htmldir_relative_SQ)\"' \\\ndiff --git a/bugreport.c b/bugreport.c\nindex f143b9a8f8..70fb3b8fa6 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -6,6 +6,9 @@\n #include \"help.h\"\n #include \"compat/compiler.h\"\n #include \"run-command.h\"\n+#include \"config.h\"\n+#include \"bugreport-config-safelist.h\"\n+#include \"khash.h\"\n \n static void get_git_remote_https_version_info(struct strbuf *version_info)\n {\n@@ -52,6 +55,29 @@ static void get_system_info(struct strbuf *sys_info)\n \tstrbuf_complete_line(sys_info);\n }\n \n+static void get_safelisted_config(struct strbuf *config_info)\n+{\n+\tsize_t idx;\n+\tstruct string_list_item *it = NULL;\n+\tstruct key_value_info *kv_info = NULL;\n+\n+\tfor (idx = 0; idx < ARRAY_SIZE(bugreport_config_safelist); idx++) {\n+\t\tconst struct string_list *list =\n+\t\t\tgit_config_get_value_multi(bugreport_config_safelist[idx]);\n+\n+\t\tif (!list)\n+\t\t\tcontinue;\n+\n+\t\tstrbuf_addf(config_info, \"%s:\\n\", bugreport_config_safelist[idx]);\n+\t\tfor_each_string_list_item(it, list) {\n+\t\t\tkv_info = it->util;\n+\t\t\tstrbuf_addf(config_info, \"  %s (%s)\\n\", it->string,\n+\t\t\t\t    kv_info ? config_scope_name(kv_info->scope)\n+\t\t\t\t\t    : \"source unknown\");\n+\t\t}\n+\t}\n+}\n+\n static const char * const bugreport_usage[] = {\n \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n \tNULL\n@@ -94,6 +120,7 @@ int cmd_main(int argc, const char **argv)\n \tchar *option_output = NULL;\n \tchar *option_suffix = \"%F-%H%M\";\n \tstruct stat statbuf;\n+\tint nongit_ok = 0;\n \n \tconst struct option bugreport_options[] = {\n \t\tOPT_STRING('o', \"output-directory\", &option_output, N_(\"path\"),\n@@ -102,6 +129,10 @@ int cmd_main(int argc, const char **argv)\n \t\t\t   N_(\"specify a strftime format suffix for the filename\")),\n \t\tOPT_END()\n \t};\n+\n+\t/* Prerequisite for hooks and config checks */\n+\tsetup_git_directory_gently(&nongit_ok);\n+\n \targc = parse_options(argc, argv, \"\", bugreport_options,\n \t\t\t     bugreport_usage, 0);\n \n@@ -132,6 +163,9 @@ int cmd_main(int argc, const char **argv)\n \tget_header(&buffer, \"System Info\");\n \tget_system_info(&buffer);\n \n+\tget_header(&buffer, \"Safelisted Config Info\");\n+\tget_safelisted_config(&buffer);\n+\n \treport = fopen_for_writing(report_path.buf);\n \n \tif (report == NULL) {\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392146","messageId":"20200220015858.181086-12-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 11/15] bugreport: collect list of populated hooks","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:54Z","receivedAt":"2020-02-20T01:59:34Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"Occasionally a failure a user is seeing may be related to a specific\nhook which is being run, perhaps without the user realizing. While the\ncontents of hooks can be sensitive - containing user data or process\ninformation specific to the user's organization - simply knowing that a\nhook is being run at a certain stage can help us to understand whether\nsomething is going wrong.\n\nWithout a definitive list of hook names within the code, we compile our\nown list from the documentation. This is likely prone to bitrot. To\nreduce the amount of code humans need to read, we turn the list into a\nstring_list and iterate over it (as we are calling the same find_hook\noperation on each string). However, since bugreport should primarily be\ncalled by the user, the performance loss from massaging the string\nseems acceptable.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt |  1 +\n bugreport.c                     | 53 +++++++++++++++++++++++++++++++++\n 2 files changed, 54 insertions(+)\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex efe9719ea4..4d01528540 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -31,6 +31,7 @@ The following information is captured automatically:\n  - 'git remote-https --build-info'\n  - $SHELL\n  - Selected config values\n+ - A list of enabled hooks\n \n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\ndiff --git a/bugreport.c b/bugreport.c\nindex 70fb3b8fa6..b5a0714a7f 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -9,6 +9,7 @@\n #include \"config.h\"\n #include \"bugreport-config-safelist.h\"\n #include \"khash.h\"\n+#include \"run-command.h\"\n \n static void get_git_remote_https_version_info(struct strbuf *version_info)\n {\n@@ -78,6 +79,55 @@ static void get_safelisted_config(struct strbuf *config_info)\n \t}\n }\n \n+static void get_populated_hooks(struct strbuf *hook_info, int nongit)\n+{\n+\t/*\n+\t * Doesn't look like there is a list of all possible hooks; so below is\n+\t * a transcription of `git help hooks`.\n+\t */\n+\tconst char *hooks = \"applypatch-msg,\"\n+\t\t\t    \"pre-applypatch,\"\n+\t\t\t    \"post-applypatch,\"\n+\t\t\t    \"pre-commit,\"\n+\t\t\t    \"pre-merge-commit,\"\n+\t\t\t    \"prepare-commit-msg,\"\n+\t\t\t    \"commit-msg,\"\n+\t\t\t    \"post-commit,\"\n+\t\t\t    \"pre-rebase,\"\n+\t\t\t    \"post-checkout,\"\n+\t\t\t    \"post-merge,\"\n+\t\t\t    \"pre-push,\"\n+\t\t\t    \"pre-receive,\"\n+\t\t\t    \"update,\"\n+\t\t\t    \"post-receive,\"\n+\t\t\t    \"post-update,\"\n+\t\t\t    \"push-to-checkout,\"\n+\t\t\t    \"pre-auto-gc,\"\n+\t\t\t    \"post-rewrite,\"\n+\t\t\t    \"sendemail-validate,\"\n+\t\t\t    \"fsmonitor-watchman,\"\n+\t\t\t    \"p4-pre-submit,\"\n+\t\t\t    \"post-index-changex\";\n+\tstruct string_list hooks_list = STRING_LIST_INIT_DUP;\n+\tstruct string_list_item *iter = NULL;\n+\n+\n+\tif (nongit) {\n+\t\tstrbuf_addstr(hook_info,\n+\t\t\t\"not run from a git repository - no hooks to show\\n\");\n+\t\treturn;\n+\t}\n+\n+\tstring_list_split(&hooks_list, hooks, ',', -1);\n+\n+\tfor_each_string_list_item(iter, &hooks_list) {\n+\t\tif (find_hook(iter->string)) {\n+\t\t\tstrbuf_addstr(hook_info, iter->string);\n+\t\t\tstrbuf_complete_line(hook_info);\n+\t\t}\n+\t}\n+}\n+\n static const char * const bugreport_usage[] = {\n \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n \tNULL\n@@ -166,6 +216,9 @@ int cmd_main(int argc, const char **argv)\n \tget_header(&buffer, \"Safelisted Config Info\");\n \tget_safelisted_config(&buffer);\n \n+\tget_header(&buffer, \"Enabled Hooks\");\n+\tget_populated_hooks(&buffer, nongit_ok);\n+\n \treport = fopen_for_writing(report_path.buf);\n \n \tif (report == NULL) {\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392147","messageId":"20200220015858.181086-13-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 12/15] bugreport: count loose objects","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:55Z","receivedAt":"2020-02-20T01:59:38Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"The number of unpacked objects in a user's repository may help us\nunderstand the root of the problem they're seeing, especially if a\ncommand is running unusually slowly.\n\nHelped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt |  1 +\n bugreport.c                     | 52 +++++++++++++++++++++++++++++++++\n 2 files changed, 53 insertions(+)\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex 4d01528540..4fe1c60506 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -32,6 +32,7 @@ The following information is captured automatically:\n  - $SHELL\n  - Selected config values\n  - A list of enabled hooks\n+ - The number of loose objects in the repository\n \n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\ndiff --git a/bugreport.c b/bugreport.c\nindex b5a0714a7f..fb7bc72723 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -10,6 +10,7 @@\n #include \"bugreport-config-safelist.h\"\n #include \"khash.h\"\n #include \"run-command.h\"\n+#include \"object-store.h\"\n \n static void get_git_remote_https_version_info(struct strbuf *version_info)\n {\n@@ -128,6 +129,54 @@ static void get_populated_hooks(struct strbuf *hook_info, int nongit)\n \t}\n }\n \n+static int loose_object_cb(const struct object_id *oid, const char *path,\n+\t\t\t   void *data) {\n+\tint *loose_object_count = data;\n+\n+\tif (loose_object_count) {\n+\t\t(*loose_object_count)++;\n+\t\treturn 0;\n+\t}\n+\n+\treturn 1;\n+}\n+\n+static void get_loose_object_summary(struct strbuf *obj_info, int nongit) {\n+\n+\tint local_loose_object_count = 0, total_loose_object_count = 0;\n+\tint local_count_questionable = 0, total_count_questionable = 0;\n+\n+\tif (nongit) {\n+\t\tstrbuf_addstr(obj_info,\n+\t\t\t\"not run from a git repository - no objects to show\\n\");\n+\t\treturn;\n+\t}\n+\n+\tlocal_count_questionable = for_each_loose_object(\n+\t\t\t\t\tloose_object_cb,\n+\t\t\t\t\t&local_loose_object_count,\n+\t\t\t\t\tFOR_EACH_OBJECT_LOCAL_ONLY);\n+\n+\ttotal_count_questionable = for_each_loose_object(\n+\t\t\t\t\tloose_object_cb,\n+\t\t\t\t\t&total_loose_object_count,\n+\t\t\t\t\t0);\n+\n+\tstrbuf_addf(obj_info, \"%d local loose objects%s\\n\",\n+\t\t    local_loose_object_count,\n+\t\t    local_count_questionable ? \" (problem during count)\" : \"\");\n+\n+\tstrbuf_addf(obj_info, \"%d alternate loose objects%s\\n\",\n+\t\t    total_loose_object_count - local_loose_object_count,\n+\t\t    (local_count_questionable || total_count_questionable)\n+\t\t\t? \" (problem during count)\"\n+\t\t\t: \"\");\n+\n+\tstrbuf_addf(obj_info, \"%d total loose objects%s\\n\",\n+\t\t    total_loose_object_count,\n+\t\t    total_count_questionable ? \" (problem during count)\" : \"\");\n+}\n+\n static const char * const bugreport_usage[] = {\n \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n \tNULL\n@@ -219,6 +268,9 @@ int cmd_main(int argc, const char **argv)\n \tget_header(&buffer, \"Enabled Hooks\");\n \tget_populated_hooks(&buffer, nongit_ok);\n \n+\tget_header(&buffer, \"Loose Object Counts\");\n+\tget_loose_object_summary(&buffer, nongit_ok);\n+\n \treport = fopen_for_writing(report_path.buf);\n \n \tif (report == NULL) {\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392148","messageId":"20200220015858.181086-14-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 13/15] bugreport: add packed object summary","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:56Z","receivedAt":"2020-02-20T01:59:39Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"Alongside the loose object counts, it can be useful to show the number\nof packs and packed objects. This way we can check whether the repo has\nan appropriate ratio of packed to loose objects to help determine\nwhether it's behaving correctly.\n\nAdd a utility to easily traverse all packfiles in a given repository.\nUse it in packfile.c and remove a redundant call to\nprepare_packed_git(), which is already called in get_all_packs().\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt |  1 +\n bugreport.c                     | 30 ++++++++++++++++++++++++++++++\n object-store.h                  |  6 ++++++\n packfile.c                      |  3 +--\n 4 files changed, 38 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex 4fe1c60506..eb41f0677f 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -33,6 +33,7 @@ The following information is captured automatically:\n  - Selected config values\n  - A list of enabled hooks\n  - The number of loose objects in the repository\n+ - The number of packs and packed objects in the repository\n \n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\ndiff --git a/bugreport.c b/bugreport.c\nindex fb7bc72723..71191f1331 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -177,6 +177,33 @@ static void get_loose_object_summary(struct strbuf *obj_info, int nongit) {\n \t\t    total_count_questionable ? \" (problem during count)\" : \"\");\n }\n \n+static void get_packed_object_summary(struct strbuf *obj_info, int nongit)\n+{\n+\tstruct packed_git *pack = NULL;\n+\tint pack_count = 0;\n+\tint object_count = 0;\n+\n+\tif (nongit) {\n+\t\tstrbuf_addstr(obj_info,\n+\t\t\t\"not run from a git repository - no objects to show\\n\");\n+\t\treturn;\n+\t}\n+\n+\tfor_each_pack(the_repository, pack) {\n+\t\tpack_count++;\n+\t\t/*\n+\t\t * To accurately count how many objects are packed, look inside\n+\t\t * the packfile's index.\n+\t\t */\n+\t\topen_pack_index(pack);\n+\t\tobject_count += pack->num_objects;\n+\t}\n+\n+\tstrbuf_addf(obj_info, \"%d total packs (%d objects)\\n\", pack_count,\n+\t\t    object_count);\n+\n+}\n+\n static const char * const bugreport_usage[] = {\n \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n \tNULL\n@@ -271,6 +298,9 @@ int cmd_main(int argc, const char **argv)\n \tget_header(&buffer, \"Loose Object Counts\");\n \tget_loose_object_summary(&buffer, nongit_ok);\n \n+\tget_header(&buffer, \"Packed Object Summary\");\n+\tget_packed_object_summary(&buffer, nongit_ok);\n+\n \treport = fopen_for_writing(report_path.buf);\n \n \tif (report == NULL) {\ndiff --git a/object-store.h b/object-store.h\nindex 5b047637e3..f881a1756e 100644\n--- a/object-store.h\n+++ b/object-store.h\n@@ -7,6 +7,7 @@\n #include \"sha1-array.h\"\n #include \"strbuf.h\"\n #include \"thread-utils.h\"\n+#include \"packfile.h\"\n \n struct object_directory {\n \tstruct object_directory *next;\n@@ -447,4 +448,9 @@ int for_each_object_in_pack(struct packed_git *p,\n int for_each_packed_object(each_packed_object_fn, void *,\n \t\t\t   enum for_each_object_flags flags);\n \n+#define for_each_pack(repo, pack) \t\t\\\n+\t\tfor (pack = get_all_packs(repo);\\\n+\t\t     pack;\t\t\t\\\n+\t\t     pack = pack->next)\n+\n #endif /* OBJECT_STORE_H */\ndiff --git a/packfile.c b/packfile.c\nindex 99dd1a7d09..95afcc1187 100644\n--- a/packfile.c\n+++ b/packfile.c\n@@ -2095,8 +2095,7 @@ int for_each_packed_object(each_packed_object_fn cb, void *data,\n \tint r = 0;\n \tint pack_errors = 0;\n \n-\tprepare_packed_git(the_repository);\n-\tfor (p = get_all_packs(the_repository); p; p = p->next) {\n+\tfor_each_pack(the_repository, p) {\n \t\tif ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)\n \t\t\tcontinue;\n \t\tif ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) &&\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392149","messageId":"20200220015858.181086-15-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 14/15] bugreport: list contents of $OBJDIR/info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:57Z","receivedAt":"2020-02-20T01:59:41Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"Miscellaneous information used about the object store can end up in\n.git/objects/info; this can help us understand what may be going on with\nthe object store when the user is reporting a bug. Otherwise, it could\nbe difficult to track down what is going wrong with an object which\nisn't kept locally to .git/objects/ or .git/objects/pack. Having some\nunderstanding of where the user's objects may be kept can save us some\nhops during the bug reporting process.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt |  1 +\n bugreport.c                     | 54 +++++++++++++++++++++++++++++++++\n 2 files changed, 55 insertions(+)\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex eb41f0677f..a7ef3360d2 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -34,6 +34,7 @@ The following information is captured automatically:\n  - A list of enabled hooks\n  - The number of loose objects in the repository\n  - The number of packs and packed objects in the repository\n+ - A list of the contents of .git/objects/info (or equivalent)\n \n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\ndiff --git a/bugreport.c b/bugreport.c\nindex 71191f1331..1d61e0f642 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -204,6 +204,57 @@ static void get_packed_object_summary(struct strbuf *obj_info, int nongit)\n \n }\n \n+static void list_contents_of_dir_recursively(struct strbuf *contents,\n+\t\t\t\t\t     struct strbuf *dirpath)\n+{\n+\tstruct dirent *d;\n+\tDIR *dir;\n+\tsize_t path_len;\n+\n+\tdir = opendir(dirpath->buf);\n+\tif (!dir)\n+\t\treturn;\n+\n+\tstrbuf_complete(dirpath, '/');\n+\tpath_len = dirpath->len;\n+\n+\twhile ((d = readdir(dir))) {\n+\t\tif (!strcmp(d->d_name, \".\") || !strcmp(d->d_name, \"..\"))\n+\t\t\tcontinue;\n+\n+\t\tstrbuf_addbuf(contents, dirpath);\n+\t\tstrbuf_addstr(contents, d->d_name);\n+\t\tstrbuf_complete_line(contents);\n+\n+\t\tif (d->d_type == DT_DIR) {\n+\t\t\tstrbuf_addstr(dirpath, d->d_name);\n+\t\t\tlist_contents_of_dir_recursively(contents, dirpath);\n+\t\t}\n+\t\tstrbuf_setlen(dirpath, path_len);\n+\t}\n+\n+\tclosedir(dir);\n+}\n+\n+static void get_object_info_summary(struct strbuf *obj_info, int nongit)\n+{\n+\tstruct strbuf dirpath = STRBUF_INIT;\n+\n+\tif (nongit) {\n+\t\tstrbuf_addstr(obj_info,\n+\t\t\t\"not run from a git repository - object info unavailable\\n\");\n+\t\treturn;\n+\t}\n+\n+\tstrbuf_addstr(&dirpath, get_object_directory());\n+\tstrbuf_complete(&dirpath, '/');\n+\tstrbuf_addstr(&dirpath, \"info/\");\n+\n+\tlist_contents_of_dir_recursively(obj_info, &dirpath);\n+\n+\tstrbuf_release(&dirpath);\n+}\n+\n static const char * const bugreport_usage[] = {\n \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n \tNULL\n@@ -301,6 +352,9 @@ int cmd_main(int argc, const char **argv)\n \tget_header(&buffer, \"Packed Object Summary\");\n \tget_packed_object_summary(&buffer, nongit_ok);\n \n+\tget_header(&buffer, \"Object Info Summary\");\n+\tget_object_info_summary(&buffer, nongit_ok);\n+\n \treport = fopen_for_writing(report_path.buf);\n \n \tif (report == NULL) {\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392150","messageId":"20200220015858.181086-16-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v8 15/15] bugreport: summarize contents of alternates file","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T01:58:58Z","receivedAt":"2020-02-20T01:59:45Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"In some cases, it could be that the user is having a problem with an\nobject which isn't present in their normal object directory. We can get\na hint that that might be the case by examining the list of alternates\nwhere their object may be stored instead. Since paths to alternates may\nbe sensitive, we'll instead count how many alternates have been\nspecified and note how many of them exist or are broken.\n\nWhile object-cache.h describes a function \"foreach_alt_odb()\", this\nfunction does not provide information on broken alternates, which are\nskipped over in \"link_alt_odb_entry()\". Since the goal is to identify\nmissing alternates, we can gather the contents of\n.git/objects/info/alternates manually.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt |  1 +\n bugreport.c                     | 45 +++++++++++++++++++++++++++++++++\n 2 files changed, 46 insertions(+)\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex a7ef3360d2..1f60fb9456 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -35,6 +35,7 @@ The following information is captured automatically:\n  - The number of loose objects in the repository\n  - The number of packs and packed objects in the repository\n  - A list of the contents of .git/objects/info (or equivalent)\n+ - The number of valid and invalid alternates\n \n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\ndiff --git a/bugreport.c b/bugreport.c\nindex 1d61e0f642..1640a71086 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -255,6 +255,48 @@ static void get_object_info_summary(struct strbuf *obj_info, int nongit)\n \tstrbuf_release(&dirpath);\n }\n \n+static void get_alternates_summary(struct strbuf *alternates_info, int nongit)\n+{\n+\tstruct strbuf alternates_path = STRBUF_INIT;\n+\tstruct strbuf alternate = STRBUF_INIT;\n+\tFILE *file;\n+\tsize_t exists = 0, broken = 0;\n+\n+\tif (nongit) {\n+\t\tstrbuf_addstr(alternates_info,\n+\t\t\t\"not run from a git repository - alternates unavailable\\n\");\n+\t\treturn;\n+\t}\n+\n+\tstrbuf_addstr(&alternates_path, get_object_directory());\n+\tstrbuf_complete(&alternates_path, '/');\n+\tstrbuf_addstr(&alternates_path, \"info/alternates\");\n+\n+\tfile = fopen(alternates_path.buf, \"r\");\n+\tif (!file) {\n+\t\tstrbuf_addstr(alternates_info, \"No alternates file found.\\n\");\n+\t\tstrbuf_release(&alternates_path);\n+\t\treturn;\n+\t}\n+\n+\twhile (strbuf_getline(&alternate, file) != EOF) {\n+\t\tif (!access(alternate.buf, F_OK))\n+\t\t\texists++;\n+\t\telse\n+\t\t\tbroken++;\n+\t}\n+\n+\tstrbuf_addf(alternates_info,\n+\t\t    \"%zd alternates found (%zd working, %zd broken)\\n\",\n+\t\t    exists + broken,\n+\t\t    exists,\n+\t\t    broken);\n+\n+\tfclose(file);\n+\tstrbuf_release(&alternate);\n+\tstrbuf_release(&alternates_path);\n+}\n+\n static const char * const bugreport_usage[] = {\n \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n \tNULL\n@@ -355,6 +397,9 @@ int cmd_main(int argc, const char **argv)\n \tget_header(&buffer, \"Object Info Summary\");\n \tget_object_info_summary(&buffer, nongit_ok);\n \n+\tget_header(&buffer, \"Alternates\");\n+\tget_alternates_summary(&buffer, nongit_ok);\n+\n \treport = fopen_for_writing(report_path.buf);\n \n \tif (report == NULL) {\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392157","messageId":"20200220024903.GC8390@danh.dev","threadId":"52845","inReplyTo":"20200220015858.181086-7-emilyshaffer@google.com","subject":"Re: [PATCH v8 06/15] bugreport: add compiler info","fromName":"Danh Doan","fromEmail":"congdanhqx@gmail.com","sentAt":"2020-02-20T02:49:03Z","receivedAt":"2020-02-20T02:49:10Z","isPatch":true,"sender":{"key":"congdanhqx@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42673067?v=4"},"body":"On 2020-02-19 17:58:49-0800, Emily Shaffer <emilyshaffer@google.com> wrote:\n> diff --git a/compat/compiler.h b/compat/compiler.h\n> new file mode 100644\n> index 0000000000..ef41177233\n> --- /dev/null\n> +++ b/compat/compiler.h\n> @@ -0,0 +1,27 @@\n> +#ifndef COMPILER_H\n> +#define COMPILER_H\n> +\n> +#include \"git-compat-util.h\"\n> +#include \"strbuf.h\"\n> +\n> +#ifdef __GLIBC__\n> +#include <gnu/libc-version.h>\n> +\n> +static inline void get_compiler_info(struct strbuf *info)\n> +{\n> +\tstrbuf_addf(info, \"glibc: %s\\n\", gnu_get_libc_version());\n> +#ifdef __GNUC__\n> +\tstrbuf_addf(info, \"gnuc: %d.%d\\n\", __GNUC__, __GNUC_MINOR__);\n> +#endif\n\nI think we're better having\n\n- get_compiler_info placed under #ifdef __GNUC__ gate,\n- get_libc_info under #ifdef __GLIBC\n\nThen have a function to merge those information together.\nCorrect me if I were wrong, as it is now,\nthis is only useful for Linux people with glibc.\n\nAnyway, clang also defines __GNUC__ and __GNUC_MINOR__,\nIIRC, FreeBSD people started to move to use clang instead of gcc\nas their default compiler.\n\nGentoo forks are also known to use clang to compile their ports.\n\n\n-- \nDanh\n"},{"id":"392167","messageId":"nycvar.QRO.7.76.6.2002201458120.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"20200220015858.181086-16-emilyshaffer@google.com","subject":"Re: [PATCH v8 15/15] bugreport: summarize contents of alternates file","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-02-20T14:08:27Z","receivedAt":"2020-02-20T14:08:36Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Emily,\n\nOn Wed, 19 Feb 2020, Emily Shaffer wrote:\n\n> In some cases, it could be that the user is having a problem with an\n> object which isn't present in their normal object directory. We can get\n> a hint that that might be the case by examining the list of alternates\n> where their object may be stored instead. Since paths to alternates may\n> be sensitive, we'll instead count how many alternates have been\n> specified and note how many of them exist or are broken.\n>\n> While object-cache.h describes a function \"foreach_alt_odb()\", this\n> function does not provide information on broken alternates, which are\n> skipped over in \"link_alt_odb_entry()\". Since the goal is to identify\n> missing alternates, we can gather the contents of\n> .git/objects/info/alternates manually.\n\nMakes sense.\n\n> diff --git a/bugreport.c b/bugreport.c\n> index 1d61e0f642..1640a71086 100644\n> --- a/bugreport.c\n> +++ b/bugreport.c\n> @@ -255,6 +255,48 @@ static void get_object_info_summary(struct strbuf *obj_info, int nongit)\n>  \tstrbuf_release(&dirpath);\n>  }\n>\n> +static void get_alternates_summary(struct strbuf *alternates_info, int nongit)\n> +{\n> +\tstruct strbuf alternates_path = STRBUF_INIT;\n> +\tstruct strbuf alternate = STRBUF_INIT;\n\nI am not sure that those variables and the parameter need to repeat\n\"alternate\", I find it rather distracting. If it were me, I would rename\nthe parameter to `info`, the first strbuf to `path` and the second to\n`line`. This function is so specific to read the alternates file that it\nis quite obvious what their roles are.\n\n> +\tFILE *file;\n> +\tsize_t exists = 0, broken = 0;\n> +\n> +\tif (nongit) {\n> +\t\tstrbuf_addstr(alternates_info,\n> +\t\t\t\"not run from a git repository - alternates unavailable\\n\");\n> +\t\treturn;\n> +\t}\n> +\n> +\tstrbuf_addstr(&alternates_path, get_object_directory());\n> +\tstrbuf_complete(&alternates_path, '/');\n> +\tstrbuf_addstr(&alternates_path, \"info/alternates\");\n> +\n> +\tfile = fopen(alternates_path.buf, \"r\");\n> +\tif (!file) {\n> +\t\tstrbuf_addstr(alternates_info, \"No alternates file found.\\n\");\n> +\t\tstrbuf_release(&alternates_path);\n> +\t\treturn;\n> +\t}\n> +\n> +\twhile (strbuf_getline(&alternate, file) != EOF) {\n> +\t\tif (!access(alternate.buf, F_OK))\n\nShould we make sure that the alternate is actually valid objects directory\nhere? Like, look whether it is a directory, not a file or a (possibly\ndangling) symbolic link. This seems to be the only check\n`alt_odb_usable()` performs, so that should probably be good enough here,\ntoo.\n\n> +\t\t\texists++;\n> +\t\telse\n> +\t\t\tbroken++;\n> +\t}\n> +\n> +\tstrbuf_addf(alternates_info,\n> +\t\t    \"%zd alternates found (%zd working, %zd broken)\\n\",\n\nSadly, `%zd` is not portable. Therefore, `pu` (and `es/bugreport`) do not\neven _build_ on Windows. I need this to make it work:\n\n-- snip --\ndiff --git a/bugreport.c b/bugreport.c\nindex 3770aa73fae..5033668e22f 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -287,10 +287,11 @@ static void get_alternates_summary(struct strbuf *alternates_info, int nongit)\n \t}\n\n \tstrbuf_addf(alternates_info,\n-\t\t    \"%zd alternates found (%zd working, %zd broken)\\n\",\n-\t\t    exists + broken,\n-\t\t    exists,\n-\t\t    broken);\n+\t\t    \"%\"PRIuMAX\" alternates found \"\n+\t\t    \"(%\"PRIuMAX\" working, %\"PRIuMAX\" broken)\\n\",\n+\t\t    (uintmax_t)(exists + broken),\n+\t\t    (uintmax_t)exists,\n+\t\t    (uintmax_t)broken);\n\n \tfclose(file);\n \tstrbuf_release(&alternate);\n-- snap --\n\nCould you incorporate that into the next iteration, please?\n\nThanks,\nDscho\n\n> +\t\t    exists + broken,\n> +\t\t    exists,\n> +\t\t    broken);\n> +\n> +\tfclose(file);\n> +\tstrbuf_release(&alternate);\n> +\tstrbuf_release(&alternates_path);\n> +}\n> +\n>  static const char * const bugreport_usage[] = {\n>  \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n>  \tNULL\n> @@ -355,6 +397,9 @@ int cmd_main(int argc, const char **argv)\n>  \tget_header(&buffer, \"Object Info Summary\");\n>  \tget_object_info_summary(&buffer, nongit_ok);\n>\n> +\tget_header(&buffer, \"Alternates\");\n> +\tget_alternates_summary(&buffer, nongit_ok);\n> +\n>  \treport = fopen_for_writing(report_path.buf);\n>\n>  \tif (report == NULL) {\n> --\n> 2.25.0.265.gbab2e86ba0-goog\n>\n>\n"},{"id":"392186","messageId":"xmqqeeupaxnk.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-3-emilyshaffer@google.com","subject":"Re: [PATCH v8 02/15] help: add shell-path to --build-options","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T19:03:59Z","receivedAt":"2020-02-20T19:04:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> It may be useful to know which shell Git was built to try to point to,\n> in the event that shell-based Git commands are failing. $SHELL_PATH is\n> set during the build and used to launch the manpage viewer, as well as\n> by git-compat-util.h, and it's used during tests. 'git version\n> --build-options' is encouraged for use in bug reports, so it makes sense\n> to include this information there.\n\nIt probably makes sense to capture PERL_PATH, PYTHON_PATH,\nTCLTK_PATH, and TCL_PATH, as they fall into exactly the same\ncategory as this one.\n\n> Signed-off-by: Emily Shaffer <emilyshaffer@google.com>\n> ---\n>  help.c | 1 +\n>  1 file changed, 1 insertion(+)\n>\n> diff --git a/help.c b/help.c\n> index a21487db77..190722fb0a 100644\n> --- a/help.c\n> +++ b/help.c\n> @@ -654,6 +654,7 @@ int cmd_version(int argc, const char **argv, const char *prefix)\n>  \t\t\tprintf(\"no commit associated with this build\\n\");\n>  \t\tprintf(\"sizeof-long: %d\\n\", (int)sizeof(long));\n>  \t\tprintf(\"sizeof-size_t: %d\\n\", (int)sizeof(size_t));\n> +\t\tprintf(\"shell-path: %s\\n\", SHELL_PATH);\n>  \t\t/* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */\n>  \t}\n>  \treturn 0;\n"},{"id":"392188","messageId":"xmqq8skxawah.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-4-emilyshaffer@google.com","subject":"Re: [PATCH v8 03/15] bugreport: add tool to generate debugging info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T19:33:26Z","receivedAt":"2020-02-20T19:33:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> +\targc = parse_options(argc, argv, \"\", bugreport_options,\n> +\t\t\t     bugreport_usage, 0);\n\nWhich one between an empty string and NULL is more appropriate to be\npassed as \"prefix\" here?  I assume that this is *not* really a git\nprogram, and no repository/working-tree discovery is involved, and\nyou won't be using OPT_FILENAME, so it would probably be OK.\n\n> +\n> +\tif (option_output) {\n> +\t\tstrbuf_addstr(&report_path, option_output);\n> +\t\tstrbuf_complete(&report_path, '/');\n> +\t}\n> +\n> +\n> +\tstrbuf_addstr(&report_path, \"git-bugreport-\");\n> +\tstrbuf_addftime(&report_path, option_suffix, localtime(&now), 0, 0);\n> +\tstrbuf_addstr(&report_path, \".txt\");\n> +\n> +\tif (!stat(report_path.buf, &statbuf))\n> +\t\tdie(\"'%s' already exists\", report_path.buf);\n\nMissed i18n/l10n, but I do not think it is a useful thing for this\ncheck to be here in the first place.\n\n> +\tswitch (safe_create_leading_directories(report_path.buf)) {\n> +\tcase SCLD_OK:\n> +\tcase SCLD_EXISTS:\n> +\t\tbreak;\n> +\tdefault:\n> +\t\tdie(_(\"could not create leading directories for '%s'\"),\n> +\t\t    report_path.buf);\n> +\t}\n> +\n> +\tget_bug_template(&buffer);\n> +\n> +\treport = fopen_for_writing(report_path.buf);\n\nfopen_for_writing() does not give good semantics for what you seem\nto want to do here (i.e. to make sure you do not overwrite an\nexisting one).  It even has \"if we cannot open it, retry after\nunlinking\" logic in it, which screams \"this function is designed for\nthose who want to overwrite the file\", and if you look at its\ncallers, they are _all_ about opening a file for writing with a well\nknown name like FETCH_HEAD, COMMIT_EDITMSG, etc.\n\nBesides, a stat() that dies when a file exists would not\nhelp---since that check, you've spent non-zero time, creating\nleading directories and preparing boilerplate in the buffer,\nand there is no guarantee somebody else used the same filename\nin the meantime.\n\nIf you want to avoid overwriting an existing file (which I think is\na good idea---I just do not think the earlier \"if (!stat()) die()\"\nis a good way to do so), the only sensible way to do so is to ask\nyour open/creat to fail if there already is a file---that is how\nyou'd avoid racing with another process that may be creating such a\nfile.  Grep for O_EXCL to find where the flag is used with O_CREAT\nto see how it is done.\n\n> +\tif (report == NULL) {\n\nStyle. \"if (!report)\"\n\n> +\t\tstrbuf_release(&report_path);\n> +\t\tdie(\"couldn't open '%s' for writing\", report_path.buf);\n\nDo we see a use-after-free here?  Also missed i18n/l10n.\n\nIt is embarrassing on the reviewers' side that this (which is not\nnew in this round at all and hasn't changed since v6) hasn't been\ncaught for a few rounds X-<.\n\nThanks.\n"},{"id":"392192","messageId":"xmqq4kvlaup9.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-5-emilyshaffer@google.com","subject":"Re: [PATCH v8 04/15] bugreport: gather git version and build info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T20:07:46Z","receivedAt":"2020-02-20T20:07:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> +static void get_system_info(struct strbuf *sys_info)\n> +{\n> +\t/* get git version from native cmd */\n> +\tstrbuf_addstr(sys_info, \"git version:\\n\");\n> +\tget_version_info(sys_info, 1);\n> +\tstrbuf_complete_line(sys_info);\n\nIt is a bit curious use of \"don't do anything if sys_info ends with\na complete line, but complete it if it ends with an imcomplete\nline\".  That tells the readers that we do not know what\nget_version_info() will do (now or in the future) to its output\nbuffer.\n\n> +}\n> ...\n> diff --git a/help.c b/help.c\n> index 190722fb0a..44cee69c11 100644\n> --- a/help.c\n> +++ b/help.c\n> @@ -622,8 +622,33 @@ const char *help_unknown_cmd(const char *cmd)\n>  \texit(1);\n>  }\n>  \n> +void get_version_info(struct strbuf *buf, int show_build_options)\n> +{\n> +\t/*\n> +\t * The format of this string should be kept stable for compatibility\n> +\t * with external projects that rely on the output of \"git version\".\n> +\t *\n> +\t * Always show the version, even if other options are given.\n> +\t */\n> +\tstrbuf_addf(buf, \"git version %s\\n\", git_version_string);\n\nThis ends the output with a complete line when !show_build_options ...\n\n> +\tif (show_build_options) {\n> +\t\tstrbuf_addf(buf, \"cpu: %s\\n\", GIT_HOST_CPU);\n> +\t\tif (git_built_from_commit_string[0])\n> +\t\t\tstrbuf_addf(buf, \"built from commit: %s\\n\",\n> +\t\t\t       git_built_from_commit_string);\n> +\t\telse\n> +\t\t\tstrbuf_addstr(buf, \"no commit associated with this build\\n\");\n> +\t\tstrbuf_addf(buf, \"sizeof-long: %d\\n\", (int)sizeof(long));\n> +\t\tstrbuf_addf(buf, \"sizeof-size_t: %d\\n\", (int)sizeof(size_t));\n> +\t\tstrbuf_addf(buf, \"shell-path: %s\\n\", SHELL_PATH);\n> +\t\t/* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */\n\n... and the pattern indicates the output will end with a complete\nline when !!show_build_options, too.\n\n> +\t}\n> +}\n\nSo, was the strbuf_complete_line() merely defensive programming?  It\nmay deserve a comment if it will stay there.\n\n>  int cmd_version(int argc, const char **argv, const char *prefix)\n>  {\n> +\tstruct strbuf buf = STRBUF_INIT;\n>  \tint build_options = 0;\n>  \tconst char * const usage[] = {\n>  \t\tN_(\"git version [<options>]\"),\n> @@ -637,26 +662,11 @@ int cmd_version(int argc, const char **argv, const char *prefix)\n>  \n>  \targc = parse_options(argc, argv, prefix, options, usage, 0);\n>  \n> -\t/*\n> -\t * The format of this string should be kept stable for compatibility\n> -\t * with external projects that rely on the output of \"git version\".\n> -\t *\n> -\t * Always show the version, even if other options are given.\n> -\t */\n> -\tprintf(\"git version %s\\n\", git_version_string);\n> +\tget_version_info(&buf, build_options);\n> +\tprintf(\"%s\", buf.buf);\n> +\n> +\tstrbuf_release(&buf);\n>  \n> -\tif (build_options) {\n> -\t\tprintf(\"cpu: %s\\n\", GIT_HOST_CPU);\n> -\t\tif (git_built_from_commit_string[0])\n> -\t\t\tprintf(\"built from commit: %s\\n\",\n> -\t\t\t       git_built_from_commit_string);\n> -\t\telse\n> -\t\t\tprintf(\"no commit associated with this build\\n\");\n> -\t\tprintf(\"sizeof-long: %d\\n\", (int)sizeof(long));\n> -\t\tprintf(\"sizeof-size_t: %d\\n\", (int)sizeof(size_t));\n> -\t\tprintf(\"shell-path: %s\\n\", SHELL_PATH);\n> -\t\t/* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */\n> -\t}\n>  \treturn 0;\n\nMakes sense.\n"},{"id":"392193","messageId":"xmqqzhdd9fw5.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-6-emilyshaffer@google.com","subject":"Re: [PATCH v8 05/15] bugreport: add uname info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T20:12:58Z","receivedAt":"2020-02-20T20:13:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> +\t/* system call for other version info */\n> +\tstrbuf_addstr(sys_info, \"uname -a: \");\n\nIs that \"-a\" portable across systems?  That is, when given \"-a\",\nwould \"uname\" on all platforms show sysname, release, version and\nmachine in that order and nothing else?\n\nIf we are merely saying \"in this section, we are showing a selected\nsubset from what we learned about the system with uname(2)\", perhaps\njust stop at saying \"uname: \"?\n\n> +\tif (uname(&uname_info))\n> +\t\tstrbuf_addf(sys_info, \"uname() failed with code %d\\n\", errno);\n\ni18n/l10n?  Don't we want to use strerror() here?\n\n> +\telse\n> +\t\tstrbuf_addf(sys_info, \"%s %s %s %s\\n\",\n> +\t\t\t    uname_info.sysname,\n> +\t\t\t    uname_info.release,\n> +\t\t\t    uname_info.version,\n> +\t\t\t    uname_info.machine);\n>  }\n>  \n>  static const char * const bugreport_usage[] = {\n"},{"id":"392194","messageId":"xmqqv9o19fez.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-7-emilyshaffer@google.com","subject":"Re: [PATCH v8 06/15] bugreport: add compiler info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T20:23:16Z","receivedAt":"2020-02-20T20:23:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> @@ -24,6 +25,10 @@ static void get_system_info(struct strbuf *sys_info)\n>  \t\t\t    uname_info.release,\n>  \t\t\t    uname_info.version,\n>  \t\t\t    uname_info.machine);\n> +\n> +\tstrbuf_addstr(sys_info, \"compiler info: \");\n> +\tget_compiler_info(sys_info);\n> +\tstrbuf_complete_line(sys_info);\n>  }\n>  \n>  static const char * const bugreport_usage[] = {\n> diff --git a/compat/compiler.h b/compat/compiler.h\n> new file mode 100644\n> index 0000000000..ef41177233\n> --- /dev/null\n> +++ b/compat/compiler.h\n> @@ -0,0 +1,27 @@\n> +#ifndef COMPILER_H\n> +#define COMPILER_H\n> +\n> +#include \"git-compat-util.h\"\n> +#include \"strbuf.h\"\n> +\n> +#ifdef __GLIBC__\n> +#include <gnu/libc-version.h>\n> +\n> +static inline void get_compiler_info(struct strbuf *info)\n> +{\n> +\tstrbuf_addf(info, \"glibc: %s\\n\", gnu_get_libc_version());\n> +#ifdef __GNUC__\n> +\tstrbuf_addf(info, \"gnuc: %d.%d\\n\", __GNUC__, __GNUC_MINOR__);\n> +#endif\n> +}\n> +\n> +#else\n> +\n> +static inline void get_compiler_info(struct strbuf *info)\n> +{\n> +\tstrbuf_addstr(info, \"get_compiler_info() not implemented\");\n\ni18n/l10n?  Also don't deliberately leave the buffer end with an\nincomplete line like so---doing so _requires_ the caller above to\nhave strbuf_complete_line() call, but there is no reason to do so.\n\nstrbuf_complete_line() does make sense if you insert something that\nis not controlled by us (e.g. \"Please type whatever other comments\nyou may have\" to let the user give us free-form text, which may or\nmay not end with a complete line), but otherwise it probably is a\nsign of being unnecessary sloppy.\n\n> +}\n\nOK, so the idea is to insert \"#elif ...\" and definition of\nget_compiler_info() for non GLIBC systems?\n\nI am not sure why you want to make this a header with static inline\nimplementations.  Is it expected for this to be included from\nmultiple source files?  It would be more understandable if these\nwere in the same file as where get_system_info() is, perhaps\nimmediately before that function.\n\nAlso, it would probably be easier to manage if you have two separate\nhelpers, one for what compiler is in use, and the other for what\nlibc is in use.\n\n> +\n> +#endif\n> +\n> +#endif /* COMPILER_H */\n\nThanks.\n"},{"id":"392196","messageId":"xmqqr1yp9eue.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-8-emilyshaffer@google.com","subject":"Re: [PATCH v8 07/15] bugreport: add git-remote-https version","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T20:35:37Z","receivedAt":"2020-02-20T20:35:45Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> +static void get_git_remote_https_version_info(struct strbuf *version_info)\n> +{\n> +\tstruct child_process cp = CHILD_PROCESS_INIT;\n> +\n> +\tcp.git_cmd = 1;\n> +\targv_array_push(&cp.args, \"remote-https\");\n> +\targv_array_push(&cp.args, \"--build-info\");\n> +\tif (capture_command(&cp, version_info, 0))\n> +\t    strbuf_addstr(version_info, \"'git-remote-https --build-info' not supported\\n\");\n> +}\n>  \n>  static void get_system_info(struct strbuf *sys_info)\n>  {\n> @@ -29,6 +41,10 @@ static void get_system_info(struct strbuf *sys_info)\n>  \tstrbuf_addstr(sys_info, \"compiler info: \");\n>  \tget_compiler_info(sys_info);\n>  \tstrbuf_complete_line(sys_info);\n> +\n> +\tstrbuf_addstr(sys_info, \"git-remote-https --build-info:\\n\");\n> +\tget_git_remote_https_version_info(sys_info);\n> +\tstrbuf_complete_line(sys_info);\n>  }\n>  \n>  static const char * const bugreport_usage[] = {\n> diff --git a/remote-curl.c b/remote-curl.c\n> index 8eb96152f5..73e52175c0 100644\n> --- a/remote-curl.c\n> +++ b/remote-curl.c\n> @@ -17,6 +17,7 @@\n>  #include \"protocol.h\"\n>  #include \"quote.h\"\n>  #include \"transport.h\"\n> +#include \"version.h\"\n>  \n>  static struct remote *remote;\n>  /* always ends with a trailing slash */\n> @@ -1375,6 +1376,13 @@ int cmd_main(int argc, const char **argv)\n>  \tstring_list_init(&options.deepen_not, 1);\n>  \tstring_list_init(&options.push_options, 1);\n>  \n> +\tif (!strcmp(\"--build-info\", argv[1])) {\n> +\t\tprintf(\"git-http-fetch version: %s\\n\", git_version_string);\n\nWe are letting bugreport grab this information from remote-curl, and\nthey are different binaries, so git_version_string we see here is\nthat of the remote-curl.  Good.\n\n> +\t\tprintf(\"built from commit: %s\\n\", git_built_from_commit_string);\n> +\t\tprintf(\"curl version: %s\\n\", curl_version());\n> +\t\treturn 0;\n> +\t}\n> +\n>  \t/*\n>  \t * Just report \"remote-curl\" here (folding all the various aliases\n>  \t * (\"git-remote-http\", \"git-remote-https\", and etc.) here since they\n\nMakes sense, except that it is not clear what our overall stance on\ni18n/l10n of the bugreport output.\n\nI think there are two schools of thought.  \n\n - You can stick to C local, with an expectation that developers can\n   read reports in C locale.  This will allow developers to avoid\n   having to read reports written in a language they do not\n   understand, and also makes it easier to mechanically process\n   reports.\n\n - You can make sure what matters in the report is localized to the\n   end-users' locale.  This will avoid forcing end-users to send out\n   a report that they may not even able to read (which is what\n   happens if we did not do i18n/l10n).\n\nI am not sure which way you are aiming at.  The boilerplate text\nwe saw in a very early part of the series were marked N_() but some\nof the messages in later parts of the series are not.\n"},{"id":"392197","messageId":"xmqqmu9d9elo.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-10-emilyshaffer@google.com","subject":"Re: [PATCH v8 09/15] bugreport: generate config safelist based on docs","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T20:40:51Z","receivedAt":"2020-02-20T20:40:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> --- /dev/null\n> +++ b/generate-bugreport-config-safelist.sh\n> @@ -0,0 +1,18 @@\n> +#!/bin/sh\n> +\n> +cat <<EOF\n\nQuote the EOF if you are not doing parameter expansion in HERE-DOC.\n\n> +/* Automatically generated by bugreport-generate-config-safelist.sh */\n> +\n> +\n> +static const char *bugreport_config_safelist[] = {\n> +EOF\n> +\n> +# cat all regular files in Documentation/config\n> +find Documentation/config -type f -exec cat {} \\; |\n> +# print the command name which matches the annotate-bugreport macro\n> +sed -n 's/^\\([^ ]*\\)  *annotate:bugreport\\[include\\].* ::$/  \"\\1\",/p' \\\n> +\t| sort\n> +\n\nEnd the first line with a pipe '|' instead of a backslash, and lose\nthe pipe from the beginning of the second line.\n\n> +cat <<EOF\n> +};\n> +EOF\n"},{"id":"392198","messageId":"xmqqimk19ear.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-11-emilyshaffer@google.com","subject":"Re: [PATCH v8 10/15] bugreport: add config values from safelist","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T20:47:24Z","receivedAt":"2020-02-20T20:47:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> @@ -94,6 +120,7 @@ int cmd_main(int argc, const char **argv)\n>  \tchar *option_output = NULL;\n>  \tchar *option_suffix = \"%F-%H%M\";\n>  \tstruct stat statbuf;\n> +\tint nongit_ok = 0;\n>  \n>  \tconst struct option bugreport_options[] = {\n>  \t\tOPT_STRING('o', \"output-directory\", &option_output, N_(\"path\"),\n> @@ -102,6 +129,10 @@ int cmd_main(int argc, const char **argv)\n>  \t\t\t   N_(\"specify a strftime format suffix for the filename\")),\n>  \t\tOPT_END()\n>  \t};\n> +\n> +\t/* Prerequisite for hooks and config checks */\n> +\tsetup_git_directory_gently(&nongit_ok);\n\nNow this starts to break \"-o\" option when the command is run from a\nsubdirectory of a git working tree, I suspect.\n\nThe setup() will discover that you are in a Git controlled working\ntree, goes up to the top-level of the working tree, so a user may\nexpect\n\n\tcd t && git bugreport -o frotz\n\nto create a new directory t/frotz, but it would instead create the\ndirectory frotz next to t/, no?\n\nUsing OPT_FILENAME and feeding correct prefix to parse_options()\nwill correct this.\n\n>  \targc = parse_options(argc, argv, \"\", bugreport_options,\n>  \t\t\t     bugreport_usage, 0);\n"},{"id":"392199","messageId":"xmqqeeup9ds7.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-12-emilyshaffer@google.com","subject":"Re: [PATCH v8 11/15] bugreport: collect list of populated hooks","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T20:58:32Z","receivedAt":"2020-02-20T20:58:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> +static void get_populated_hooks(struct strbuf *hook_info, int nongit)\n> +{\n> +\t/*\n> +\t * Doesn't look like there is a list of all possible hooks; so below is\n> +\t * a transcription of `git help hooks`.\n> +\t */\n\nIt may want to become a NEEDSWORK comment.\n\n> +\tconst char *hooks = \"applypatch-msg,\"\n> +\t\t\t    \"pre-applypatch,\"\n> +\t\t\t    \"post-applypatch,\"\n> +\t\t\t    \"pre-commit,\"\n> +\t\t\t    \"pre-merge-commit,\"\n> +\t\t\t    \"prepare-commit-msg,\"\n> +\t\t\t    \"commit-msg,\"\n> +\t\t\t    \"post-commit,\"\n> +\t\t\t    \"pre-rebase,\"\n> +\t\t\t    \"post-checkout,\"\n> +\t\t\t    \"post-merge,\"\n> +\t\t\t    \"pre-push,\"\n> +\t\t\t    \"pre-receive,\"\n> +\t\t\t    \"update,\"\n> +\t\t\t    \"post-receive,\"\n> +\t\t\t    \"post-update,\"\n> +\t\t\t    \"push-to-checkout,\"\n> +\t\t\t    \"pre-auto-gc,\"\n> +\t\t\t    \"post-rewrite,\"\n> +\t\t\t    \"sendemail-validate,\"\n> +\t\t\t    \"fsmonitor-watchman,\"\n> +\t\t\t    \"p4-pre-submit,\"\n> +\t\t\t    \"post-index-changex\";\n\nTypo here?\n\n> +\tstruct string_list hooks_list = STRING_LIST_INIT_DUP;\n> +\tstruct string_list_item *iter = NULL;\n> +\n> +\n> +\tif (nongit) {\n> +\t\tstrbuf_addstr(hook_info,\n> +\t\t\t\"not run from a git repository - no hooks to show\\n\");\n> +\t\treturn;\n> +\t}\n> +\n> +\tstring_list_split(&hooks_list, hooks, ',', -1);\n> +\n> +\tfor_each_string_list_item(iter, &hooks_list) {\n\nI do not get why you want to use string_list for this, especially if\nyou need to use string_list_split.\n\nTo me,\n\n\tint i;\n\tconst char *hook[] = {\n\t\t\"applypatch-msg\",\n\t        \"pre-applypatch\",\n\t\t...\n\t\t\"post-index-change\",\n\t};\n\n\tfor (i = 0; i < ARRAY_SIZE(hook); i++) {\n\t\tif (hook[i] is enabled)\n\t\t\tstrbuf_addf(hook_info, \"%s\\n\", hook[i]);\n\t}\n\nwould be far easier to understand.  Do you have an external source\nthat can feed you a single long string of comma separated hook names\nin mind, so that the initialization of *hooks will become simpler\nthat way, or something?\n\n> +\t\tif (find_hook(iter->string)) {\n> +\t\t\tstrbuf_addstr(hook_info, iter->string);\n> +\t\t\tstrbuf_complete_line(hook_info);\n> +\t\t}\n> +\t}\n> +}\n> +\n>  static const char * const bugreport_usage[] = {\n>  \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n>  \tNULL\n> @@ -166,6 +216,9 @@ int cmd_main(int argc, const char **argv)\n>  \tget_header(&buffer, \"Safelisted Config Info\");\n>  \tget_safelisted_config(&buffer);\n>  \n> +\tget_header(&buffer, \"Enabled Hooks\");\n> +\tget_populated_hooks(&buffer, nongit_ok);\n> +\n>  \treport = fopen_for_writing(report_path.buf);\n>  \n>  \tif (report == NULL) {\n"},{"id":"392200","messageId":"xmqqa75d9di6.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-13-emilyshaffer@google.com","subject":"Re: [PATCH v8 12/15] bugreport: count loose objects","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T21:04:33Z","receivedAt":"2020-02-20T21:04:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> The number of unpacked objects in a user's repository may help us\n> understand the root of the problem they're seeing, especially if a\n> command is running unusually slowly.\n>\n> Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n> Signed-off-by: Emily Shaffer <emilyshaffer@google.com>\n> ---\n>  Documentation/git-bugreport.txt |  1 +\n>  bugreport.c                     | 52 +++++++++++++++++++++++++++++++++\n>  2 files changed, 53 insertions(+)\n>\n> diff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\n> index 4d01528540..4fe1c60506 100644\n> --- a/Documentation/git-bugreport.txt\n> +++ b/Documentation/git-bugreport.txt\n> @@ -32,6 +32,7 @@ The following information is captured automatically:\n>   - $SHELL\n>   - Selected config values\n>   - A list of enabled hooks\n> + - The number of loose objects in the repository\n>  \n>  This tool is invoked via the typical Git setup process, which means that in some\n>  cases, it might not be able to launch - for example, if a relevant config file\n> diff --git a/bugreport.c b/bugreport.c\n> index b5a0714a7f..fb7bc72723 100644\n> --- a/bugreport.c\n> +++ b/bugreport.c\n> @@ -10,6 +10,7 @@\n>  #include \"bugreport-config-safelist.h\"\n>  #include \"khash.h\"\n>  #include \"run-command.h\"\n> +#include \"object-store.h\"\n>  \n>  static void get_git_remote_https_version_info(struct strbuf *version_info)\n>  {\n> @@ -128,6 +129,54 @@ static void get_populated_hooks(struct strbuf *hook_info, int nongit)\n>  \t}\n>  }\n>  \n> +static int loose_object_cb(const struct object_id *oid, const char *path,\n> +\t\t\t   void *data) {\n> +\tint *loose_object_count = data;\n> +\n> +\tif (loose_object_count) {\n> +\t\t(*loose_object_count)++;\n> +\t\treturn 0;\n> +\t}\n> +\n> +\treturn 1;\n\nWhat is the point of returning 1 here to abort the iteration early?\nWouldn't it be a BUG() if this callback ends up gettting called with\nNULL in data?\n\n> +}\n> +\n> +static void get_loose_object_summary(struct strbuf *obj_info, int nongit) {\n> +\n> +\tint local_loose_object_count = 0, total_loose_object_count = 0;\n> +\tint local_count_questionable = 0, total_count_questionable = 0;\n> +\n> +\tif (nongit) {\n> +\t\tstrbuf_addstr(obj_info,\n> +\t\t\t\"not run from a git repository - no objects to show\\n\");\n> +\t\treturn;\n> +\t}\n> +\n> +\tlocal_count_questionable = for_each_loose_object(\n> +\t\t\t\t\tloose_object_cb,\n> +\t\t\t\t\t&local_loose_object_count,\n> +\t\t\t\t\tFOR_EACH_OBJECT_LOCAL_ONLY);\n> +\n> +\ttotal_count_questionable = for_each_loose_object(\n> +\t\t\t\t\tloose_object_cb,\n> +\t\t\t\t\t&total_loose_object_count,\n> +\t\t\t\t\t0);\n> +\tstrbuf_addf(obj_info, \"%d local loose objects%s\\n\",\n> +\t\t    local_loose_object_count,\n> +\t\t    local_count_questionable ? \" (problem during count)\" : \"\");\n> +\n> +\tstrbuf_addf(obj_info, \"%d alternate loose objects%s\\n\",\n> +\t\t    total_loose_object_count - local_loose_object_count,\n> +\t\t    (local_count_questionable || total_count_questionable)\n> +\t\t\t? \" (problem during count)\"\n> +\t\t\t: \"\");\n> +\n> +\tstrbuf_addf(obj_info, \"%d total loose objects%s\\n\",\n> +\t\t    total_loose_object_count,\n> +\t\t    total_count_questionable ? \" (problem during count)\" : \"\");\n> +}\n> +\n>  static const char * const bugreport_usage[] = {\n>  \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n>  \tNULL\n> @@ -219,6 +268,9 @@ int cmd_main(int argc, const char **argv)\n>  \tget_header(&buffer, \"Enabled Hooks\");\n>  \tget_populated_hooks(&buffer, nongit_ok);\n>  \n> +\tget_header(&buffer, \"Loose Object Counts\");\n> +\tget_loose_object_summary(&buffer, nongit_ok);\n> +\n>  \treport = fopen_for_writing(report_path.buf);\n>  \n>  \tif (report == NULL) {\n"},{"id":"392202","messageId":"20200220211526.GC2447@google.com","threadId":"52845","inReplyTo":"xmqqeeupaxnk.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v8 02/15] help: add shell-path to --build-options","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T21:15:26Z","receivedAt":"2020-02-20T21:15:33Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Thu, Feb 20, 2020 at 11:03:59AM -0800, Junio C Hamano wrote:\n> Emily Shaffer <emilyshaffer@google.com> writes:\n> \n> > It may be useful to know which shell Git was built to try to point to,\n> > in the event that shell-based Git commands are failing. $SHELL_PATH is\n> > set during the build and used to launch the manpage viewer, as well as\n> > by git-compat-util.h, and it's used during tests. 'git version\n> > --build-options' is encouraged for use in bug reports, so it makes sense\n> > to include this information there.\n> \n> It probably makes sense to capture PERL_PATH, PYTHON_PATH,\n> TCLTK_PATH, and TCL_PATH, as they fall into exactly the same\n> category as this one.\n\nSHELL_PATH was already made sure to exist in git-compat-util.h before\nthis change; these other utility paths are not. Do you want me to add\nthem now?\n\n> \n> > Signed-off-by: Emily Shaffer <emilyshaffer@google.com>\n> > ---\n> >  help.c | 1 +\n> >  1 file changed, 1 insertion(+)\n> >\n> > diff --git a/help.c b/help.c\n> > index a21487db77..190722fb0a 100644\n> > --- a/help.c\n> > +++ b/help.c\n> > @@ -654,6 +654,7 @@ int cmd_version(int argc, const char **argv, const char *prefix)\n> >  \t\t\tprintf(\"no commit associated with this build\\n\");\n> >  \t\tprintf(\"sizeof-long: %d\\n\", (int)sizeof(long));\n> >  \t\tprintf(\"sizeof-size_t: %d\\n\", (int)sizeof(size_t));\n> > +\t\tprintf(\"shell-path: %s\\n\", SHELL_PATH);\n> >  \t\t/* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */\n> >  \t}\n> >  \treturn 0;\n"},{"id":"392205","messageId":"xmqq1rqoapa3.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-14-emilyshaffer@google.com","subject":"Re: [PATCH v8 13/15] bugreport: add packed object summary","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T22:04:52Z","receivedAt":"2020-02-20T22:05:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> +static void get_packed_object_summary(struct strbuf *obj_info, int nongit)\n> +{\n> +\tstruct packed_git *pack = NULL;\n> +\tint pack_count = 0;\n> +\tint object_count = 0;\n> +\n> +\tif (nongit) {\n> +\t\tstrbuf_addstr(obj_info,\n> +\t\t\t\"not run from a git repository - no objects to show\\n\");\n> +\t\treturn;\n> +\t}\n> +\n> +\tfor_each_pack(the_repository, pack) {\n> +\t\tpack_count++;\n> +\t\t/*\n> +\t\t * To accurately count how many objects are packed, look inside\n> +\t\t * the packfile's index.\n> +\t\t */\n> +\t\topen_pack_index(pack);\n> +\t\tobject_count += pack->num_objects;\n> +\t}\n> +\n> +\tstrbuf_addf(obj_info, \"%d total packs (%d objects)\\n\", pack_count,\n> +\t\t    object_count);\n> +\n> +}\n\nMakes sense.\n\n> @@ -447,4 +448,9 @@ int for_each_object_in_pack(struct packed_git *p,\n>  int for_each_packed_object(each_packed_object_fn, void *,\n>  \t\t\t   enum for_each_object_flags flags);\n>  \n> +#define for_each_pack(repo, pack) \t\t\\\n> +\t\tfor (pack = get_all_packs(repo);\\\n> +\t\t     pack;\t\t\t\\\n> +\t\t     pack = pack->next)\n\nI generally avoid #define'ing a control loop pseudo-syntax unless it\nmakes the resulting code hide overly ugly implementation detail.\n\nfor_each_string_list() is there to hide the fact that items are\nstored in an embedded array whose name is .items and size is .nr\nthat is sufficiently ugnly to expose, but iterating over packs\ndoes not look so bad.\n\nIf you MUST have this as a pseudo-syntax macro, we need\n\n - to match for_each_string_list_item(), have iterating variable\n   'pack' as the first parameter, and the scope of what's iterated\n   'repo' as the second.\n\n - to make sure the syntax works correctly even if a parameter is\n   *not* a simple identifier (I think the above is OK, but there may\n   be cases that it does not work well).\n\nRegarding the latter, the way 'item' is incremented at the end of\niteration in for_each_string_list_item() is subtle and correct.\n\n#define for_each_string_list_item(item,list)            \\\n\tfor (item = (list)->items;                      \\\n\t     item && item < (list)->items + (list)->nr; \\\n\t     ++item)\n\nYou would break it if you changed pre-increment to post-increment\nfor a user like this:\n\n\tstruct string_list *list;\n\tstruct string_list_item *i, **p;\n\tp = &i;\n\n\tfor_each_string_list_item(*p, list) {\n\t\t...\n\t}\n\nbecause ++*p is ++(*p), while *p++ is (*p)++, and we do want the\nformer (i.e. increment the memory cell pointed at by pointer p).\n\nPersonally, I would prefer not to introduce this macro if I were\nworking on this topic.\n\n>  #endif /* OBJECT_STORE_H */\n> diff --git a/packfile.c b/packfile.c\n> index 99dd1a7d09..95afcc1187 100644\n> --- a/packfile.c\n> +++ b/packfile.c\n> @@ -2095,8 +2095,7 @@ int for_each_packed_object(each_packed_object_fn cb, void *data,\n>  \tint r = 0;\n>  \tint pack_errors = 0;\n>  \n> -\tprepare_packed_git(the_repository);\n> -\tfor (p = get_all_packs(the_repository); p; p = p->next) {\n> +\tfor_each_pack(the_repository, p) {\n>  \t\tif ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)\n>  \t\t\tcontinue;\n>  \t\tif ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) &&\n"},{"id":"392207","messageId":"xmqqwo8g9a2a.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-15-emilyshaffer@google.com","subject":"Re: [PATCH v8 14/15] bugreport: list contents of $OBJDIR/info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T22:18:53Z","receivedAt":"2020-02-20T22:18:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> +static void list_contents_of_dir_recursively(struct strbuf *contents,\n> +\t\t\t\t\t     struct strbuf *dirpath)\n> +{\n> +\tstruct dirent *d;\n> +\tDIR *dir;\n> +\tsize_t path_len;\n> +\n> +\tdir = opendir(dirpath->buf);\n> +\tif (!dir)\n> +\t\treturn;\n\nNo error detected?\n\n> +\tstrbuf_complete(dirpath, '/');\n> +\tpath_len = dirpath->len;\n> +\n> +\twhile ((d = readdir(dir))) {\n> +\t\tif (!strcmp(d->d_name, \".\") || !strcmp(d->d_name, \"..\"))\n> +\t\t\tcontinue;\n> +\n> +\t\tstrbuf_addbuf(contents, dirpath);\n> +\t\tstrbuf_addstr(contents, d->d_name);\n> +\t\tstrbuf_complete_line(contents);\n> +\n> +\t\tif (d->d_type == DT_DIR) {\n> +\t\t\tstrbuf_addstr(dirpath, d->d_name);\n> +\t\t\tlist_contents_of_dir_recursively(contents, dirpath);\n> +\t\t}\n> +\t\tstrbuf_setlen(dirpath, path_len);\n\nShouldn't we be sorting the output?\n\n> +\t}\n> +\n> +\tclosedir(dir);\n> +}\n\nHmph, it is somewhat sad that we have to reinvent a degraded copy of\n\"ls -aR\" like this.\n\n> +static void get_object_info_summary(struct strbuf *obj_info, int nongit)\n> +{\n> +\tstruct strbuf dirpath = STRBUF_INIT;\n> +\n> +\tif (nongit) {\n> +\t\tstrbuf_addstr(obj_info,\n> +\t\t\t\"not run from a git repository - object info unavailable\\n\");\n> +\t\treturn;\n> +\t}\n> +\n> +\tstrbuf_addstr(&dirpath, get_object_directory());\n> +\tstrbuf_complete(&dirpath, '/');\n> +\tstrbuf_addstr(&dirpath, \"info/\");\n\nWould it help to use git_path() for this, perhaps like\ngit_path(\"objects/info/\")?\n\nBy the way, do we store anything worth knowing in $GIT_DIR/info too?\nPerhaps the per-repo attributes and excludes files whose presence\nmay hint at another question to ask when a user reports unexpected\nbehaviour from .gitignore?\n\n> +\tlist_contents_of_dir_recursively(obj_info, &dirpath);\n> +\tstrbuf_release(&dirpath);\n> +}\n> +\n>  static const char * const bugreport_usage[] = {\n>  \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n>  \tNULL\n> @@ -301,6 +352,9 @@ int cmd_main(int argc, const char **argv)\n>  \tget_header(&buffer, \"Packed Object Summary\");\n>  \tget_packed_object_summary(&buffer, nongit_ok);\n>  \n> +\tget_header(&buffer, \"Object Info Summary\");\n> +\tget_object_info_summary(&buffer, nongit_ok);\n> +\n>  \treport = fopen_for_writing(report_path.buf);\n>  \n>  \tif (report == NULL) {\n"},{"id":"392209","messageId":"xmqqsgj499w3.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-16-emilyshaffer@google.com","subject":"Re: [PATCH v8 15/15] bugreport: summarize contents of alternates file","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T22:22:36Z","receivedAt":"2020-02-20T22:22:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> +static void get_alternates_summary(struct strbuf *alternates_info, int nongit)\n> +{\n> +\tstruct strbuf alternates_path = STRBUF_INIT;\n> +\tstruct strbuf alternate = STRBUF_INIT;\n> +\tFILE *file;\n> +\tsize_t exists = 0, broken = 0;\n> +\n> +\tif (nongit) {\n> +\t\tstrbuf_addstr(alternates_info,\n> +\t\t\t\"not run from a git repository - alternates unavailable\\n\");\n> +\t\treturn;\n> +\t}\n> +\n> +\tstrbuf_addstr(&alternates_path, get_object_directory());\n> +\tstrbuf_complete(&alternates_path, '/');\n> +\tstrbuf_addstr(&alternates_path, \"info/alternates\");\n\ngit_path()?\n\n> +\tfile = fopen(alternates_path.buf, \"r\");\n> +\tif (!file) {\n> +\t\tstrbuf_addstr(alternates_info, \"No alternates file found.\\n\");\n> +\t\tstrbuf_release(&alternates_path);\n> +\t\treturn;\n> +\t}\n> +\n> +\twhile (strbuf_getline(&alternate, file) != EOF) {\n> +\t\tif (!access(alternate.buf, F_OK))\n> +\t\t\texists++;\n\nF_OK reported as \"exists\" makes quite a lot of sense.\n\n> +\t\telse\n> +\t\t\tbroken++;\n\nSo, shouldn't this rather be \"missing\"?\n\n> +\t}\n> +\n> +\tstrbuf_addf(alternates_info,\n> +\t\t    \"%zd alternates found (%zd working, %zd broken)\\n\",\n> +\t\t    exists + broken,\n> +\t\t    exists,\n> +\t\t    broken);\n\nI don't see the point of using size_t for this.  Just use int for\nboth, like you did for object count in the step that counds loose\nand packed objects.\n\n> +\tfclose(file);\n> +\tstrbuf_release(&alternate);\n> +\tstrbuf_release(&alternates_path);\n> +}\n> +\n>  static const char * const bugreport_usage[] = {\n>  \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n>  \tNULL\n> @@ -355,6 +397,9 @@ int cmd_main(int argc, const char **argv)\n>  \tget_header(&buffer, \"Object Info Summary\");\n>  \tget_object_info_summary(&buffer, nongit_ok);\n>  \n> +\tget_header(&buffer, \"Alternates\");\n> +\tget_alternates_summary(&buffer, nongit_ok);\n> +\n>  \treport = fopen_for_writing(report_path.buf);\n>  \n>  \tif (report == NULL) {\n"},{"id":"392212","messageId":"20200220223323.GD2447@google.com","threadId":"52845","inReplyTo":"xmqq8skxawah.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v8 03/15] bugreport: add tool to generate debugging info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T22:33:23Z","receivedAt":"2020-02-20T22:33:30Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Thu, Feb 20, 2020 at 11:33:26AM -0800, Junio C Hamano wrote:\n> Emily Shaffer <emilyshaffer@google.com> writes:\n> \n> > +\targc = parse_options(argc, argv, \"\", bugreport_options,\n> > +\t\t\t     bugreport_usage, 0);\n> \n> Which one between an empty string and NULL is more appropriate to be\n> passed as \"prefix\" here?  I assume that this is *not* really a git\n> program, and no repository/working-tree discovery is involved, and\n> you won't be using OPT_FILENAME, so it would probably be OK.\n> \n> > +\n> > +\tif (option_output) {\n> > +\t\tstrbuf_addstr(&report_path, option_output);\n> > +\t\tstrbuf_complete(&report_path, '/');\n> > +\t}\n> > +\n> > +\n> > +\tstrbuf_addstr(&report_path, \"git-bugreport-\");\n> > +\tstrbuf_addftime(&report_path, option_suffix, localtime(&now), 0, 0);\n> > +\tstrbuf_addstr(&report_path, \".txt\");\n> > +\n> > +\tif (!stat(report_path.buf, &statbuf))\n> > +\t\tdie(\"'%s' already exists\", report_path.buf);\n> \n> Missed i18n/l10n, but I do not think it is a useful thing for this\n> check to be here in the first place.\n> \n> > +\tswitch (safe_create_leading_directories(report_path.buf)) {\n> > +\tcase SCLD_OK:\n> > +\tcase SCLD_EXISTS:\n> > +\t\tbreak;\n> > +\tdefault:\n> > +\t\tdie(_(\"could not create leading directories for '%s'\"),\n> > +\t\t    report_path.buf);\n> > +\t}\n> > +\n> > +\tget_bug_template(&buffer);\n> > +\n> > +\treport = fopen_for_writing(report_path.buf);\n> \n> fopen_for_writing() does not give good semantics for what you seem\n> to want to do here (i.e. to make sure you do not overwrite an\n> existing one).  It even has \"if we cannot open it, retry after\n> unlinking\" logic in it, which screams \"this function is designed for\n> those who want to overwrite the file\", and if you look at its\n> callers, they are _all_ about opening a file for writing with a well\n> known name like FETCH_HEAD, COMMIT_EDITMSG, etc.\n> \n> Besides, a stat() that dies when a file exists would not\n> help---since that check, you've spent non-zero time, creating\n> leading directories and preparing boilerplate in the buffer,\n> and there is no guarantee somebody else used the same filename\n> in the meantime.\n\nGood point. Ouch.\n\n> \n> If you want to avoid overwriting an existing file (which I think is\n> a good idea---I just do not think the earlier \"if (!stat()) die()\"\n> is a good way to do so), the only sensible way to do so is to ask\n> your open/creat to fail if there already is a file---that is how\n> you'd avoid racing with another process that may be creating such a\n> file.  Grep for O_EXCL to find where the flag is used with O_CREAT\n> to see how it is done.\n\nSure. Thanks, I reworked it to use open().\n\nBy the way, I noticed reading the GNU manual that file descriptors may\nnot be supported outside of GNU environments; but I also noticed that 1)\nGit uses open() lots of places to use O_EXCL, and 2) fopen() doesn't\nsupport exclusive opens (except in glibc, and nobody is using that\nparticular option in the Git codebase now). So I guess it's safe to use\nopen()...\n\n> \n> > +\tif (report == NULL) {\n> \n> Style. \"if (!report)\"\n\nThe type of 'report' changes using open(), so this check changes too.\nNow it says \"if (report < 0)\" - per the open() doc, it returns a\npositive fd or -1.\n\n> \n> > +\t\tstrbuf_release(&report_path);\n> > +\t\tdie(\"couldn't open '%s' for writing\", report_path.buf);\n> \n> Do we see a use-after-free here?  Also missed i18n/l10n.\n\nHm. I suppose it's OK to UNLEAK() like we do at the successful exit\nsince the die() will end the process. Added i18n too.\n\n> It is embarrassing on the reviewers' side that this (which is not\n> new in this round at all and hasn't changed since v6) hasn't been\n> caught for a few rounds X-<.\n\nWell, I'm embarrassed to have written it in the first place.\n\n - Emily\n"},{"id":"392216","messageId":"20200220230320.GE2447@google.com","threadId":"52845","inReplyTo":"xmqq4kvlaup9.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v8 04/15] bugreport: gather git version and build info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T23:03:20Z","receivedAt":"2020-02-20T23:03:28Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Thu, Feb 20, 2020 at 12:07:46PM -0800, Junio C Hamano wrote:\n> Emily Shaffer <emilyshaffer@google.com> writes:\n> \n> > +static void get_system_info(struct strbuf *sys_info)\n> > +{\n> > +\t/* get git version from native cmd */\n> > +\tstrbuf_addstr(sys_info, \"git version:\\n\");\n> > +\tget_version_info(sys_info, 1);\n> > +\tstrbuf_complete_line(sys_info);\n> \n> It is a bit curious use of \"don't do anything if sys_info ends with\n> a complete line, but complete it if it ends with an imcomplete\n> line\".  That tells the readers that we do not know what\n> get_version_info() will do (now or in the future) to its output\n> buffer.\n> \n> > +}\n> > ...\n> > diff --git a/help.c b/help.c\n> > index 190722fb0a..44cee69c11 100644\n> > --- a/help.c\n> > +++ b/help.c\n> > @@ -622,8 +622,33 @@ const char *help_unknown_cmd(const char *cmd)\n> >  \texit(1);\n> >  }\n> >  \n> > +void get_version_info(struct strbuf *buf, int show_build_options)\n> > +{\n> > +\t/*\n> > +\t * The format of this string should be kept stable for compatibility\n> > +\t * with external projects that rely on the output of \"git version\".\n> > +\t *\n> > +\t * Always show the version, even if other options are given.\n> > +\t */\n> > +\tstrbuf_addf(buf, \"git version %s\\n\", git_version_string);\n> \n> This ends the output with a complete line when !show_build_options ...\n> \n> > +\tif (show_build_options) {\n> > +\t\tstrbuf_addf(buf, \"cpu: %s\\n\", GIT_HOST_CPU);\n> > +\t\tif (git_built_from_commit_string[0])\n> > +\t\t\tstrbuf_addf(buf, \"built from commit: %s\\n\",\n> > +\t\t\t       git_built_from_commit_string);\n> > +\t\telse\n> > +\t\t\tstrbuf_addstr(buf, \"no commit associated with this build\\n\");\n> > +\t\tstrbuf_addf(buf, \"sizeof-long: %d\\n\", (int)sizeof(long));\n> > +\t\tstrbuf_addf(buf, \"sizeof-size_t: %d\\n\", (int)sizeof(size_t));\n> > +\t\tstrbuf_addf(buf, \"shell-path: %s\\n\", SHELL_PATH);\n> > +\t\t/* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */\n> \n> ... and the pattern indicates the output will end with a complete\n> line when !!show_build_options, too.\n> \n> > +\t}\n> > +}\n> \n> So, was the strbuf_complete_line() merely defensive programming?  It\n> may deserve a comment if it will stay there.\n\nIt was meant defensively, here and elsewhere in the series. I figured\nthat for something like this, which is mostly bounded by human writing\nin an editor and then by file IO, spurious string-checking was not such\na big deal.\n\nAre you suggesting to comment around the strbuf_complete_line() calls,\nor to comment around get_version_info() that it should end in newline?\n\n - Emily\n"},{"id":"392218","messageId":"xmqqblps97bd.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220230320.GE2447@google.com","subject":"Re: [PATCH v8 04/15] bugreport: gather git version and build info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-20T23:18:14Z","receivedAt":"2020-02-20T23:18:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> On Thu, Feb 20, 2020 at 12:07:46PM -0800, Junio C Hamano wrote:\n>> Emily Shaffer <emilyshaffer@google.com> writes:\n>> \n>> > +static void get_system_info(struct strbuf *sys_info)\n>> > +{\n>> > +\t/* get git version from native cmd */\n>> > +\tstrbuf_addstr(sys_info, \"git version:\\n\");\n>> > +\tget_version_info(sys_info, 1);\n>> > +\tstrbuf_complete_line(sys_info);\n>> \n>> It is a bit curious use of \"don't do anything if sys_info ends with\n>> a complete line, but complete it if it ends with an imcomplete\n>> line\".  That tells the readers that we do not know what\n>> get_version_info() will do (now or in the future) to its output\n>> buffer.\n>>  ...\n>> So, was the strbuf_complete_line() merely defensive programming?  It\n>> may deserve a comment if it will stay there.\n>\n> It was meant defensively, here and elsewhere in the series. I figured\n> that for something like this, which is mostly bounded by human writing\n> in an editor and then by file IO, spurious string-checking was not such\n> a big deal.\n>\n> Are you suggesting to comment around the strbuf_complete_line() calls,\n> or to comment around get_version_info() that it should end in newline?\n\nI meant a comment in get_system_info() next to the use of this\nparticular use of strbuf_complete_line(), if the use stays there.\n\nBut after reading the whole series through, I saw no need to use\nstrbuf_complete_line() in the first place, as there is no source of\ninput that is not under our control (if we do not count sloppy\nprogramming, that is).\n"},{"id":"392219","messageId":"20200220232044.GF2447@google.com","threadId":"52845","inReplyTo":"xmqqzhdd9fw5.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v8 05/15] bugreport: add uname info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T23:20:44Z","receivedAt":"2020-02-20T23:20:54Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Thu, Feb 20, 2020 at 12:12:58PM -0800, Junio C Hamano wrote:\n> Emily Shaffer <emilyshaffer@google.com> writes:\n> \n> > +\t/* system call for other version info */\n> > +\tstrbuf_addstr(sys_info, \"uname -a: \");\n> \n> Is that \"-a\" portable across systems?  That is, when given \"-a\",\n> would \"uname\" on all platforms show sysname, release, version and\n> machine in that order and nothing else?\n> \n> If we are merely saying \"in this section, we are showing a selected\n> subset from what we learned about the system with uname(2)\", perhaps\n> just stop at saying \"uname: \"?\n\nSure, that's good enough for me. I think actually 'uname -a' on a GNU\nsystem isn't going to match what's output here anyways, since I don't\nshow the nodename and 'uname -a' would.\n\n> \n> > +\tif (uname(&uname_info))\n> > +\t\tstrbuf_addf(sys_info, \"uname() failed with code %d\\n\", errno);\n> \n> i18n/l10n?  Don't we want to use strerror() here?\n\nMuch much earlier[1] in the series, you suggested not i18n/l10n the\ncontents of the bugreport, as this list would probably be ill-equipped\nto process such a report. Since it's being added to sys_info, that means this line\nis bound for the finished report, not for the user.\n\nSpeaking of locale, strerror() will print the error in the current\nlocale; if we're still assuming \"the list only takes reports in English\"\nshould I be explicit and use strerror_l()? Should I print strerror() in\ncurrent locale and include the errno, e.g. (\"uname() failed with '%s'\n(%d)\\n\", strerror(errno), errno)?\n\n[1] https://lore.kernel.org/git/xmqqzhka2tbv.fsf@gitster-ct.c.googlers.com\n"},{"id":"392220","messageId":"20200220232320.GG2447@google.com","threadId":"52845","inReplyTo":"20200220024903.GC8390@danh.dev","subject":"Re: [PATCH v8 06/15] bugreport: add compiler info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T23:23:20Z","receivedAt":"2020-02-20T23:23:28Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Thu, Feb 20, 2020 at 09:49:03AM +0700, Danh Doan wrote:\n> On 2020-02-19 17:58:49-0800, Emily Shaffer <emilyshaffer@google.com> wrote:\n> > diff --git a/compat/compiler.h b/compat/compiler.h\n> > new file mode 100644\n> > index 0000000000..ef41177233\n> > --- /dev/null\n> > +++ b/compat/compiler.h\n> > @@ -0,0 +1,27 @@\n> > +#ifndef COMPILER_H\n> > +#define COMPILER_H\n> > +\n> > +#include \"git-compat-util.h\"\n> > +#include \"strbuf.h\"\n> > +\n> > +#ifdef __GLIBC__\n> > +#include <gnu/libc-version.h>\n> > +\n> > +static inline void get_compiler_info(struct strbuf *info)\n> > +{\n> > +\tstrbuf_addf(info, \"glibc: %s\\n\", gnu_get_libc_version());\n> > +#ifdef __GNUC__\n> > +\tstrbuf_addf(info, \"gnuc: %d.%d\\n\", __GNUC__, __GNUC_MINOR__);\n> > +#endif\n> \n> I think we're better having\n> \n> - get_compiler_info placed under #ifdef __GNUC__ gate,\n> - get_libc_info under #ifdef __GLIBC\n> \n> Then have a function to merge those information together.\n> Correct me if I were wrong, as it is now,\n> this is only useful for Linux people with glibc.\n> \n> Anyway, clang also defines __GNUC__ and __GNUC_MINOR__,\n> IIRC, FreeBSD people started to move to use clang instead of gcc\n> as their default compiler.\n> \n> Gentoo forks are also known to use clang to compile their ports.\n\nYeah, between your comments now and Dscho's comments on this patch in\nthe last rollup, I'll go ahead and refactor it like you suggest.\n\n - Emily\n"},{"id":"392221","messageId":"20200220232812.GH2447@google.com","threadId":"52845","inReplyTo":"xmqqr1yp9eue.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v8 07/15] bugreport: add git-remote-https version","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-20T23:28:12Z","receivedAt":"2020-02-20T23:28:19Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Thu, Feb 20, 2020 at 12:35:37PM -0800, Junio C Hamano wrote:\n> Emily Shaffer <emilyshaffer@google.com> writes:\n> \n> > +static void get_git_remote_https_version_info(struct strbuf *version_info)\n> > +{\n> > +\tstruct child_process cp = CHILD_PROCESS_INIT;\n> > +\n> > +\tcp.git_cmd = 1;\n> > +\targv_array_push(&cp.args, \"remote-https\");\n> > +\targv_array_push(&cp.args, \"--build-info\");\n> > +\tif (capture_command(&cp, version_info, 0))\n> > +\t    strbuf_addstr(version_info, \"'git-remote-https --build-info' not supported\\n\");\n> > +}\n> >  \n> >  static void get_system_info(struct strbuf *sys_info)\n> >  {\n> > @@ -29,6 +41,10 @@ static void get_system_info(struct strbuf *sys_info)\n> >  \tstrbuf_addstr(sys_info, \"compiler info: \");\n> >  \tget_compiler_info(sys_info);\n> >  \tstrbuf_complete_line(sys_info);\n> > +\n> > +\tstrbuf_addstr(sys_info, \"git-remote-https --build-info:\\n\");\n> > +\tget_git_remote_https_version_info(sys_info);\n> > +\tstrbuf_complete_line(sys_info);\n> >  }\n> >  \n> >  static const char * const bugreport_usage[] = {\n> > diff --git a/remote-curl.c b/remote-curl.c\n> > index 8eb96152f5..73e52175c0 100644\n> > --- a/remote-curl.c\n> > +++ b/remote-curl.c\n> > @@ -17,6 +17,7 @@\n> >  #include \"protocol.h\"\n> >  #include \"quote.h\"\n> >  #include \"transport.h\"\n> > +#include \"version.h\"\n> >  \n> >  static struct remote *remote;\n> >  /* always ends with a trailing slash */\n> > @@ -1375,6 +1376,13 @@ int cmd_main(int argc, const char **argv)\n> >  \tstring_list_init(&options.deepen_not, 1);\n> >  \tstring_list_init(&options.push_options, 1);\n> >  \n> > +\tif (!strcmp(\"--build-info\", argv[1])) {\n> > +\t\tprintf(\"git-http-fetch version: %s\\n\", git_version_string);\n> \n> We are letting bugreport grab this information from remote-curl, and\n> they are different binaries, so git_version_string we see here is\n> that of the remote-curl.  Good.\n> \n> > +\t\tprintf(\"built from commit: %s\\n\", git_built_from_commit_string);\n> > +\t\tprintf(\"curl version: %s\\n\", curl_version());\n> > +\t\treturn 0;\n> > +\t}\n> > +\n> >  \t/*\n> >  \t * Just report \"remote-curl\" here (folding all the various aliases\n> >  \t * (\"git-remote-http\", \"git-remote-https\", and etc.) here since they\n> \n> Makes sense, except that it is not clear what our overall stance on\n> i18n/l10n of the bugreport output.\n> \n> I think there are two schools of thought.  \n> \n>  - You can stick to C local, with an expectation that developers can\n>    read reports in C locale.  This will allow developers to avoid\n>    having to read reports written in a language they do not\n>    understand, and also makes it easier to mechanically process\n>    reports.\n> \n>  - You can make sure what matters in the report is localized to the\n>    end-users' locale.  This will avoid forcing end-users to send out\n>    a report that they may not even able to read (which is what\n>    happens if we did not do i18n/l10n).\n> \n> I am not sure which way you are aiming at.  The boilerplate text\n> we saw in a very early part of the series were marked N_() but some\n> of the messages in later parts of the series are not.\n\nI mentioned it in another reply to you at a different point in the v8\nconversation; I took away the localization on the boilerplate at your\nsuggestion. Unfortunately I agree that we wouldn't be equipped to handle\nreports in other languages. Not being able to understand the\nuser-fillable part of the report extends, I think, to not being able to\nunderstand the diagnostic info. If the point of the report is to skip\nback-and-forth, then writing back to say \"actually, run all this stuff\nmanually so we can see the output in English\" is not going to achieve\nthat goal.\n\n - Emily\n"},{"id":"392228","messageId":"xmqq7e0g946f.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220015858.181086-7-emilyshaffer@google.com","subject":"Re: [PATCH v8 06/15] bugreport: add compiler info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-21T00:26:00Z","receivedAt":"2020-02-21T00:26:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> +\tstrbuf_addstr(sys_info, \"compiler info: \");\n> +\tget_compiler_info(sys_info);\n> +\tstrbuf_complete_line(sys_info);\n\nContinuing the response to 04/15 review, I do not think this is a\ngood use of complete_line(), either.  On an exotic platform you\nhaven't seen, get_compiler_info() might stuff nothing in the output\nbuffer, in which case we are left with an incomplete line that just\nsays \"compiler info: \", and it might be better not to leave that\nincomplete line hanging around by calling complete_line(), but an\neven better solution would be to make sure get_compiler_info()\nexplicitly say it encountered a system totally new to it.  And at\nthat point, as long as everybody in get_compiler_info() ends its\noutput with a complete line, there is no need for complete_line()\non the caller's side.\n\nOf course, you can make it a convention that all case arms or ifdef\nblocks in get_compiler_info() uniformly end what they have to say\nwith an incomplete line and make it a responsibility of the caller\nto terminate the incomplete line.  But in that case, you'd not be\nusing complete_line(), but strbuf_addch('\\n').\n\n"},{"id":"392250","messageId":"xmqqo8ts7gf5.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200220232812.GH2447@google.com","subject":"Re: [PATCH v8 07/15] bugreport: add git-remote-https version","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-21T03:44:30Z","receivedAt":"2020-02-21T03:44:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> ... Unfortunately I agree that we wouldn't be equipped to handle\n> reports in other languages.\n\nI actually was anticipating a far better world ;-) \n\nThere is no reason to limit the recipient of reports only to *us*.\nUse of Git and population proficient in Git would become wide enough\nthat we should be able to expect that users who speak language X can\nbe helped by experts who speak the same language X with their\nissues.\n"},{"id":"392486","messageId":"20200225220838.GB212281@google.com","threadId":"52845","inReplyTo":"xmqqo8ts7gf5.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v8 07/15] bugreport: add git-remote-https version","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-25T22:08:38Z","receivedAt":"2020-02-25T22:08:48Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Thu, Feb 20, 2020 at 07:44:30PM -0800, Junio C Hamano wrote:\n> Emily Shaffer <emilyshaffer@google.com> writes:\n> \n> > ... Unfortunately I agree that we wouldn't be equipped to handle\n> > reports in other languages.\n> \n> I actually was anticipating a far better world ;-) \n> \n> There is no reason to limit the recipient of reports only to *us*.\n> Use of Git and population proficient in Git would become wide enough\n> that we should be able to expect that users who speak language X can\n> be helped by experts who speak the same language X with their\n> issues.\n\nHm. I guess I got the opposite impression from you way back in v1. I do\nwish it had been communicated a little more clearly; it's frustrating to\nperceive a reversal after seven months of review. But that's probably on\nmy own reading comprehension :)\n\nWell, I certainly don't mind - but I did have a pretty long conversation\nwith Jonathan Nieder last week about whether it's feasible to make the\nbugreport extremely stable while also being locale aware. As I\nunderstood it, he worried about someone having a misconfigured locale\ncausing the bugreport tool to crash when it tries to set the locale.\n\nBut I'm having trouble figuring out how that can happen. It looks like\nwe use libintl.h to do almost all of our string localization, which I\nhave to assume is pretty robust. Or to put it another way, if the user's\nenvironment has broken libintl.h, then it seems like they also have\nbigger problems outside of Git which they would notice already.\n\n(Side note: I went down a rabbit hole of trying to break my locale, and\ndid manage to generate some garbage by setting 'LANG' to a non-UTF-8\ncharacter set and setting 'LANGUAGE' to a character set which does\nrequire UTF-8, that is, 'LANG=es_MX LANGUAGE=ko git status'.)\n\nHow about if I localize the bugreport template, headers, and formatted\ncomments (e.g. \"3745 local loose objects\"), and include a tip in 'git\nhelp bugreport' suggesting that if it doesn't look right, maybe the user\nwants to run it with 'LANG= LANGUAGE= git bugreport' to ensure it\nactually gets generated?\n\n\nI had another thought, actually, that this is maybe semantically similar\nproblem to the malformed config we discussed earlier in the review. Does\nit make sense to include some kind of --safemode flag to 'git' which\nasks it to not perform localization and not read configs? I would\npropose adding it just to git-bugreport, and I could work around some\nlocale weirdness that way, but with a broken config the attempt dies\nbefore git-bugreport binary is invoked at all.\n\n - Emily\n"},{"id":"392487","messageId":"xmqqtv3el2w5.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200225220838.GB212281@google.com","subject":"Re: [PATCH v8 07/15] bugreport: add git-remote-https version","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-25T22:26:34Z","receivedAt":"2020-02-25T22:26:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> How about if I localize the bugreport template, headers, and formatted\n> comments (e.g. \"3745 local loose objects\"), and include a tip in 'git\n> help bugreport' suggesting that if it doesn't look right, maybe the user\n> wants to run it with 'LANG= LANGUAGE= git bugreport' to ensure it\n> actually gets generated?\n\nI think that will be what is going to happen anyway in the real\nworld.  We'd spend a reasonable effort for localization (and I\npersonally am perfectly OK if the effort for the initial round is\n\"almost zero\"), but make sure C-locale is left as an escape hatch.\n\n> I had another thought, actually, that this is maybe semantically similar\n> problem to the malformed config we discussed earlier in the review. Does\n> it make sense to include some kind of --safemode flag to 'git' which\n> asks it to not perform localization and not read configs?\n\nI suspect that \"git --safemode\" would always end up being buggy than\nrunning \"git\" under LANG=C LC_ALL=C GIT_CONFIG=/dev/null or something\nlike that ;-)\n\nWouldn't it defeat more than 30% of the value of the tool if we\ndo not read and report the contents of the configuration file(s)?\n"},{"id":"392489","messageId":"20200225231918.GC212281@google.com","threadId":"52845","inReplyTo":"xmqqeeup9ds7.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v8 11/15] bugreport: collect list of populated hooks","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-25T23:19:18Z","receivedAt":"2020-02-25T23:19:25Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Thu, Feb 20, 2020 at 12:58:32PM -0800, Junio C Hamano wrote:\n> Emily Shaffer <emilyshaffer@google.com> writes:\n> \n> > +static void get_populated_hooks(struct strbuf *hook_info, int nongit)\n> > +{\n> > +\t/*\n> > +\t * Doesn't look like there is a list of all possible hooks; so below is\n> > +\t * a transcription of `git help hooks`.\n> > +\t */\n> \n> It may want to become a NEEDSWORK comment.\n\nOh, good point. I'll rephrase it.\n> \n> > +\tconst char *hooks = \"applypatch-msg,\"\n> > +\t\t\t    \"pre-applypatch,\"\n> > +\t\t\t    \"post-applypatch,\"\n> > +\t\t\t    \"pre-commit,\"\n> > +\t\t\t    \"pre-merge-commit,\"\n> > +\t\t\t    \"prepare-commit-msg,\"\n> > +\t\t\t    \"commit-msg,\"\n> > +\t\t\t    \"post-commit,\"\n> > +\t\t\t    \"pre-rebase,\"\n> > +\t\t\t    \"post-checkout,\"\n> > +\t\t\t    \"post-merge,\"\n> > +\t\t\t    \"pre-push,\"\n> > +\t\t\t    \"pre-receive,\"\n> > +\t\t\t    \"update,\"\n> > +\t\t\t    \"post-receive,\"\n> > +\t\t\t    \"post-update,\"\n> > +\t\t\t    \"push-to-checkout,\"\n> > +\t\t\t    \"pre-auto-gc,\"\n> > +\t\t\t    \"post-rewrite,\"\n> > +\t\t\t    \"sendemail-validate,\"\n> > +\t\t\t    \"fsmonitor-watchman,\"\n> > +\t\t\t    \"p4-pre-submit,\"\n> > +\t\t\t    \"post-index-changex\";\n> \n> Typo here?\n\nYep, I imagine from trying to press 'x' to remove the ',' from my list.\n\n> \n> > +\tstruct string_list hooks_list = STRING_LIST_INIT_DUP;\n> > +\tstruct string_list_item *iter = NULL;\n> > +\n> > +\n> > +\tif (nongit) {\n> > +\t\tstrbuf_addstr(hook_info,\n> > +\t\t\t\"not run from a git repository - no hooks to show\\n\");\n> > +\t\treturn;\n> > +\t}\n> > +\n> > +\tstring_list_split(&hooks_list, hooks, ',', -1);\n> > +\n> > +\tfor_each_string_list_item(iter, &hooks_list) {\n> \n> I do not get why you want to use string_list for this, especially if\n> you need to use string_list_split.\n> \n> To me,\n> \n> \tint i;\n> \tconst char *hook[] = {\n> \t\t\"applypatch-msg\",\n> \t        \"pre-applypatch\",\n> \t\t...\n> \t\t\"post-index-change\",\n> \t};\n> \n> \tfor (i = 0; i < ARRAY_SIZE(hook); i++) {\n> \t\tif (hook[i] is enabled)\n> \t\t\tstrbuf_addf(hook_info, \"%s\\n\", hook[i]);\n> \t}\n> \n> would be far easier to understand.  Do you have an external source\n> that can feed you a single long string of comma separated hook names\n> in mind, so that the initialization of *hooks will become simpler\n> that way, or something?\n\nHuh. I'm having a hard time remembering why I did it this way. I think I\nwanted to use the string_list foreach? But you're right that it is\npretty hard to understand, plus expensive; I'll just use an array like\nyou suggest.\n\n> \n> > +\t\tif (find_hook(iter->string)) {\n> > +\t\t\tstrbuf_addstr(hook_info, iter->string);\n> > +\t\t\tstrbuf_complete_line(hook_info);\n> > +\t\t}\n> > +\t}\n> > +}\n> > +\n> >  static const char * const bugreport_usage[] = {\n> >  \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n> >  \tNULL\n> > @@ -166,6 +216,9 @@ int cmd_main(int argc, const char **argv)\n> >  \tget_header(&buffer, \"Safelisted Config Info\");\n> >  \tget_safelisted_config(&buffer);\n> >  \n> > +\tget_header(&buffer, \"Enabled Hooks\");\n> > +\tget_populated_hooks(&buffer, nongit_ok);\n> > +\n> >  \treport = fopen_for_writing(report_path.buf);\n> >  \n> >  \tif (report == NULL) {\n"},{"id":"392490","messageId":"20200225232200.GD212281@google.com","threadId":"52845","inReplyTo":"xmqqa75d9di6.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v8 12/15] bugreport: count loose objects","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-25T23:22:00Z","receivedAt":"2020-02-25T23:22:08Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Thu, Feb 20, 2020 at 01:04:33PM -0800, Junio C Hamano wrote:\n> Emily Shaffer <emilyshaffer@google.com> writes:\n> \n> > The number of unpacked objects in a user's repository may help us\n> > understand the root of the problem they're seeing, especially if a\n> > command is running unusually slowly.\n> >\n> > Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n> > Signed-off-by: Emily Shaffer <emilyshaffer@google.com>\n> > ---\n> >  Documentation/git-bugreport.txt |  1 +\n> >  bugreport.c                     | 52 +++++++++++++++++++++++++++++++++\n> >  2 files changed, 53 insertions(+)\n> >\n> > diff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\n> > index 4d01528540..4fe1c60506 100644\n> > --- a/Documentation/git-bugreport.txt\n> > +++ b/Documentation/git-bugreport.txt\n> > @@ -32,6 +32,7 @@ The following information is captured automatically:\n> >   - $SHELL\n> >   - Selected config values\n> >   - A list of enabled hooks\n> > + - The number of loose objects in the repository\n> >  \n> >  This tool is invoked via the typical Git setup process, which means that in some\n> >  cases, it might not be able to launch - for example, if a relevant config file\n> > diff --git a/bugreport.c b/bugreport.c\n> > index b5a0714a7f..fb7bc72723 100644\n> > --- a/bugreport.c\n> > +++ b/bugreport.c\n> > @@ -10,6 +10,7 @@\n> >  #include \"bugreport-config-safelist.h\"\n> >  #include \"khash.h\"\n> >  #include \"run-command.h\"\n> > +#include \"object-store.h\"\n> >  \n> >  static void get_git_remote_https_version_info(struct strbuf *version_info)\n> >  {\n> > @@ -128,6 +129,54 @@ static void get_populated_hooks(struct strbuf *hook_info, int nongit)\n> >  \t}\n> >  }\n> >  \n> > +static int loose_object_cb(const struct object_id *oid, const char *path,\n> > +\t\t\t   void *data) {\n> > +\tint *loose_object_count = data;\n> > +\n> > +\tif (loose_object_count) {\n> > +\t\t(*loose_object_count)++;\n> > +\t\treturn 0;\n> > +\t}\n> > +\n> > +\treturn 1;\n> \n> What is the point of returning 1 here to abort the iteration early?\n> Wouldn't it be a BUG() if this callback ends up gettting called with\n> NULL in data?\n\nHrm. Wouldn't BUG() throw away the rest of the generated report?\n\nMaybe it's better, in NULL case, to indicate an error occurred there and\nwrite that information into the report, and continue gathering the rest\nof the info.\n"},{"id":"392491","messageId":"20200225232626.GE212281@google.com","threadId":"52845","inReplyTo":"20200225232200.GD212281@google.com","subject":"Re: [PATCH v8 12/15] bugreport: count loose objects","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-25T23:26:26Z","receivedAt":"2020-02-25T23:26:38Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Tue, Feb 25, 2020 at 03:22:00PM -0800, Emily Shaffer wrote:\n> On Thu, Feb 20, 2020 at 01:04:33PM -0800, Junio C Hamano wrote:\n> > Emily Shaffer <emilyshaffer@google.com> writes:\n> > \n> > > The number of unpacked objects in a user's repository may help us\n> > > understand the root of the problem they're seeing, especially if a\n> > > command is running unusually slowly.\n> > >\n> > > Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n> > > Signed-off-by: Emily Shaffer <emilyshaffer@google.com>\n> > > ---\n> > >  Documentation/git-bugreport.txt |  1 +\n> > >  bugreport.c                     | 52 +++++++++++++++++++++++++++++++++\n> > >  2 files changed, 53 insertions(+)\n> > >\n> > > diff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\n> > > index 4d01528540..4fe1c60506 100644\n> > > --- a/Documentation/git-bugreport.txt\n> > > +++ b/Documentation/git-bugreport.txt\n> > > @@ -32,6 +32,7 @@ The following information is captured automatically:\n> > >   - $SHELL\n> > >   - Selected config values\n> > >   - A list of enabled hooks\n> > > + - The number of loose objects in the repository\n> > >  \n> > >  This tool is invoked via the typical Git setup process, which means that in some\n> > >  cases, it might not be able to launch - for example, if a relevant config file\n> > > diff --git a/bugreport.c b/bugreport.c\n> > > index b5a0714a7f..fb7bc72723 100644\n> > > --- a/bugreport.c\n> > > +++ b/bugreport.c\n> > > @@ -10,6 +10,7 @@\n> > >  #include \"bugreport-config-safelist.h\"\n> > >  #include \"khash.h\"\n> > >  #include \"run-command.h\"\n> > > +#include \"object-store.h\"\n> > >  \n> > >  static void get_git_remote_https_version_info(struct strbuf *version_info)\n> > >  {\n> > > @@ -128,6 +129,54 @@ static void get_populated_hooks(struct strbuf *hook_info, int nongit)\n> > >  \t}\n> > >  }\n> > >  \n> > > +static int loose_object_cb(const struct object_id *oid, const char *path,\n> > > +\t\t\t   void *data) {\n> > > +\tint *loose_object_count = data;\n> > > +\n> > > +\tif (loose_object_count) {\n> > > +\t\t(*loose_object_count)++;\n> > > +\t\treturn 0;\n> > > +\t}\n> > > +\n> > > +\treturn 1;\n> > \n> > What is the point of returning 1 here to abort the iteration early?\n> > Wouldn't it be a BUG() if this callback ends up gettting called with\n> > NULL in data?\n> \n> Hrm. Wouldn't BUG() throw away the rest of the generated report?\n> \n> Maybe it's better, in NULL case, to indicate an error occurred there and\n> write that information into the report, and continue gathering the rest\n> of the info.\n\nOh, hm. Now that I look twice, you're saying \"bugreport gave its own\ncallback a NULL\". I guess it could also be that\nfor_each_loose_object() decided to give a NULL context instead of the\none we gave...\n\nEven so, I dislike the idea of BUG() called from the tool you are trying\nto use to report a BUG() message. We do already report if 1 was returned\n\"(problem during count)\". I suppose I can try and make a more specific\nerror if we know the callback data was definitely the problem.\n\n - Emily\n"},{"id":"392492","messageId":"xmqqimjukzzv.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200225220838.GB212281@google.com","subject":"Re: [PATCH v8 07/15] bugreport: add git-remote-https version","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-25T23:29:08Z","receivedAt":"2020-02-25T23:29:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> Hm. I guess I got the opposite impression from you way back in v1. I do\n> wish it had been communicated a little more clearly; it's frustrating to\n> perceive a reversal after seven months of review. But that's probably on\n> my own reading comprehension :)\n\nWell, seven months is a long time for anybody to learn from repeated\nreading and gained experience to form an opinion and get affected by\nothers' opinions.  In any case, this is one of the reasons why I try\nto discourage people to have too many topics in flight before moving\non to a new and different topic---the risk of ending up with fliping\nand flopping is just too high when you give people chance to forget.\nRather, I'd prefer to see something simple to land first and then\nlater refined.\n\nOn this particular issue, I actually do not have a preference.  As\nlong as the topic has a coherent position/stance, any one of\n\n (a) we do as much i18n as possible to help end-users, or\n\n (b) we stay away from i18n to ensure the reports are machine\n     readable, or\n\n (c) somewhere in between with a clear criterion where you are\n     drawing the line (e.g. \"the introductory text is what we want\n     the end-user to read, so it is i18ned, but the report about\n     their environment are primarily for our use and we avoid\n     localizing so that we can process mechanically\"),\n\nis fine.  The important point is that we choose what we do with a\nsolid guiding principle behind the decision.\n\nIn practice, every string in bugreport.c you have control over the\nuse (or non-use) of _() around it, but codepaths that you call from\nexisting parts of the system are likely to have their messages\nlocalized if they are meant for Porcelain use.  So from that point\nof view, (a) would be easier to arrange than (b), I suspect.\n\nThanks.\n"},{"id":"392493","messageId":"20200225232940.GF212281@google.com","threadId":"52845","inReplyTo":"xmqqtv3el2w5.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v8 07/15] bugreport: add git-remote-https version","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-25T23:29:40Z","receivedAt":"2020-02-25T23:29:50Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Tue, Feb 25, 2020 at 02:26:34PM -0800, Junio C Hamano wrote:\n> Emily Shaffer <emilyshaffer@google.com> writes:\n> \n> > How about if I localize the bugreport template, headers, and formatted\n> > comments (e.g. \"3745 local loose objects\"), and include a tip in 'git\n> > help bugreport' suggesting that if it doesn't look right, maybe the user\n> > wants to run it with 'LANG= LANGUAGE= git bugreport' to ensure it\n> > actually gets generated?\n> \n> I think that will be what is going to happen anyway in the real\n> world.  We'd spend a reasonable effort for localization (and I\n> personally am perfectly OK if the effort for the initial round is\n> \"almost zero\"), but make sure C-locale is left as an escape hatch.\n\nOK.\n\n> \n> > I had another thought, actually, that this is maybe semantically similar\n> > problem to the malformed config we discussed earlier in the review. Does\n> > it make sense to include some kind of --safemode flag to 'git' which\n> > asks it to not perform localization and not read configs?\n> \n> I suspect that \"git --safemode\" would always end up being buggy than\n> running \"git\" under LANG=C LC_ALL=C GIT_CONFIG=/dev/null or something\n> like that ;-)\n> \n> Wouldn't it defeat more than 30% of the value of the tool if we\n> do not read and report the contents of the configuration file(s)?\n\nIf you mean \"the tool\" = \"Git\", I won't argue with you. But if you mean\n\"the tool\" = \"git-bugreport\", I'd say that 70% of the value of the tool\nis better than 0% because my config is broken and I don't know why or\nhow.\n\n - Emily\n"},{"id":"392494","messageId":"20200225235558.GG212281@google.com","threadId":"52845","inReplyTo":"xmqqimjukzzv.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v8 07/15] bugreport: add git-remote-https version","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-25T23:55:58Z","receivedAt":"2020-02-25T23:56:07Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Tue, Feb 25, 2020 at 03:29:08PM -0800, Junio C Hamano wrote:\n> Emily Shaffer <emilyshaffer@google.com> writes:\n> \n> > Hm. I guess I got the opposite impression from you way back in v1. I do\n> > wish it had been communicated a little more clearly; it's frustrating to\n> > perceive a reversal after seven months of review. But that's probably on\n> > my own reading comprehension :)\n> \n> Well, seven months is a long time for anybody to learn from repeated\n> reading and gained experience to form an opinion and get affected by\n> others' opinions.  In any case, this is one of the reasons why I try\n> to discourage people to have too many topics in flight before moving\n> on to a new and different topic---the risk of ending up with fliping\n> and flopping is just too high when you give people chance to forget.\n> Rather, I'd prefer to see something simple to land first and then\n> later refined.\n\nI think it's exactly what happened with this topic. It's easy to say\n\"don't have too many things out at once\" in theory - but becomes less\neasy when you combine it with things like quarterly planning at dayjob,\netc. In fact I have been trying to revive and push through old topics I\nhad in flight because I had this same realization - my six topics were\nonly each updated every month or so, meaning everyone (including me)\nforgot what was going on from revision to revision.\n\nI wonder whether it makes sense to try and finalize the bare minimums of\nthis feature, and then move the rest of the work to their own topics. I\nsee a couple benefits:\n\n - Users can start trying out 'git bugreport' when they write us mails\n   much sooner. Even the template alone would increase the quality of a\n   number of the reports I see come into this list.\n - It may help insulate this topic from 'feature creep,' which in my\n   opinion has plagued it from the start. While the entire topic of 15\n   patches is in flux, it's hard for someone else to write their own\n   patch adding, say, midex/commit-graph support, and so I feel\n   obligated to write it myself - which of course increases the amount\n   of time the topic lives on in review.\n - Of course smaller topics are easier to review, and a commit-graph\n   expert is much more likely to click on the subject \"[PATCH]\n   bugreport: gather commit-graph diagnostics\" than they are to click on\n   the subject \"[PATCH] add bugreport utility\". That is, I'm guessing\n   there will be more reviews on the semantics of the patch (is it the\n   right diagnostic info? is it useful?) than there have been so far.\n\nThe downside is mailing list churn, and the possibility that with a\nminimum 'git-bugreport' checked in I find something better to do. I'm\nnot too worried about the former; after all, that's what this list is\nfor, right? As for the latter, after 7 months of flip and flop I don't\nthink the risk is greater than it is now anyways ;) I think it makes\nsense to send the following topics:\n\n/* To me, this sounds like minimum viable bugreport. \"What went wrong,\n * and how do I build the same binary as you so I can reproduce it?\"\nadd git-bugreport tool:\n - bugreport: add tool to generate debugging info\n - bugreport: gather git version and build info\n - bugreport: add uname info\n - bugreport: add compiler info\n\nbugreport: add git-remote-https version\n\nbugreport: include shell info\n - help: add shell-path to --build-options\n - bugreport: include user interactive shell\n\nbugreport: include config info\n - help: move list_config_help to builtin/help\n - bugreport: generate config safelist based on docs\n - bugreport: add config values from safelist\n\nbugreport: collect list of populated hooks\n\nbugreport: include object store info\n - bugreport: count loose objects\n - bugreport: add packed object summary\n - bugreport: list contents of $OBJDIR/info\n\nI'd like to send that first topic as vN+1 of this one, and I can hold\nthe rest of the branches locally until we get it ironed out; once that\ntopic makes it through to 'next' then I can send the rest again. What do\nyou think?\n\n> On this particular issue, I actually do not have a preference.  As\n> long as the topic has a coherent position/stance, any one of\n> \n>  (a) we do as much i18n as possible to help end-users, or\n> \n>  (b) we stay away from i18n to ensure the reports are machine\n>      readable, or\n> \n>  (c) somewhere in between with a clear criterion where you are\n>      drawing the line (e.g. \"the introductory text is what we want\n>      the end-user to read, so it is i18ned, but the report about\n>      their environment are primarily for our use and we avoid\n>      localizing so that we can process mechanically\"),\n> \n> is fine.  The important point is that we choose what we do with a\n> solid guiding principle behind the decision.\n> \n> In practice, every string in bugreport.c you have control over the\n> use (or non-use) of _() around it, but codepaths that you call from\n> existing parts of the system are likely to have their messages\n> localized if they are meant for Porcelain use.  So from that point\n> of view, (a) would be easier to arrange than (b), I suspect.\n\nHm. Sounds convincing enough to me.\n\n - Emily\n"},{"id":"392495","messageId":"20200225235846.GH212281@google.com","threadId":"52845","inReplyTo":"xmqq1rqoapa3.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v8 13/15] bugreport: add packed object summary","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-02-25T23:58:46Z","receivedAt":"2020-02-25T23:58:54Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Thu, Feb 20, 2020 at 02:04:52PM -0800, Junio C Hamano wrote:\n> Emily Shaffer <emilyshaffer@google.com> writes:\n> \n> > +static void get_packed_object_summary(struct strbuf *obj_info, int nongit)\n> > +{\n> > +\tstruct packed_git *pack = NULL;\n> > +\tint pack_count = 0;\n> > +\tint object_count = 0;\n> > +\n> > +\tif (nongit) {\n> > +\t\tstrbuf_addstr(obj_info,\n> > +\t\t\t\"not run from a git repository - no objects to show\\n\");\n> > +\t\treturn;\n> > +\t}\n> > +\n> > +\tfor_each_pack(the_repository, pack) {\n> > +\t\tpack_count++;\n> > +\t\t/*\n> > +\t\t * To accurately count how many objects are packed, look inside\n> > +\t\t * the packfile's index.\n> > +\t\t */\n> > +\t\topen_pack_index(pack);\n> > +\t\tobject_count += pack->num_objects;\n> > +\t}\n> > +\n> > +\tstrbuf_addf(obj_info, \"%d total packs (%d objects)\\n\", pack_count,\n> > +\t\t    object_count);\n> > +\n> > +}\n> \n> Makes sense.\n> \n> > @@ -447,4 +448,9 @@ int for_each_object_in_pack(struct packed_git *p,\n> >  int for_each_packed_object(each_packed_object_fn, void *,\n> >  \t\t\t   enum for_each_object_flags flags);\n> >  \n> > +#define for_each_pack(repo, pack) \t\t\\\n> > +\t\tfor (pack = get_all_packs(repo);\\\n> > +\t\t     pack;\t\t\t\\\n> > +\t\t     pack = pack->next)\n> \n> I generally avoid #define'ing a control loop pseudo-syntax unless it\n> makes the resulting code hide overly ugly implementation detail.\n> \n> for_each_string_list() is there to hide the fact that items are\n> stored in an embedded array whose name is .items and size is .nr\n> that is sufficiently ugnly to expose, but iterating over packs\n> does not look so bad.\n> \n> If you MUST have this as a pseudo-syntax macro, we need\n> \n>  - to match for_each_string_list_item(), have iterating variable\n>    'pack' as the first parameter, and the scope of what's iterated\n>    'repo' as the second.\n> \n>  - to make sure the syntax works correctly even if a parameter is\n>    *not* a simple identifier (I think the above is OK, but there may\n>    be cases that it does not work well).\n> \n> Regarding the latter, the way 'item' is incremented at the end of\n> iteration in for_each_string_list_item() is subtle and correct.\n> \n> #define for_each_string_list_item(item,list)            \\\n> \tfor (item = (list)->items;                      \\\n> \t     item && item < (list)->items + (list)->nr; \\\n> \t     ++item)\n> \n> You would break it if you changed pre-increment to post-increment\n> for a user like this:\n> \n> \tstruct string_list *list;\n> \tstruct string_list_item *i, **p;\n> \tp = &i;\n> \n> \tfor_each_string_list_item(*p, list) {\n> \t\t...\n> \t}\n> \n> because ++*p is ++(*p), while *p++ is (*p)++, and we do want the\n> former (i.e. increment the memory cell pointed at by pointer p).\n> \n> Personally, I would prefer not to introduce this macro if I were\n> working on this topic.\n\nAh, I thought this is the kind of thing you meant here[1]. But I agree\nwith what you point out about the shortcomings of this kind of macro.\nThe implementation details are not so ugly; I'll drop it.\n\n - Emily\n\n[1] https://lore.kernel.org/git/xmqq8sli89eu.fsf@gitster-ct.c.googlers.com\n\n> \n> >  #endif /* OBJECT_STORE_H */\n> > diff --git a/packfile.c b/packfile.c\n> > index 99dd1a7d09..95afcc1187 100644\n> > --- a/packfile.c\n> > +++ b/packfile.c\n> > @@ -2095,8 +2095,7 @@ int for_each_packed_object(each_packed_object_fn cb, void *data,\n> >  \tint r = 0;\n> >  \tint pack_errors = 0;\n> >  \n> > -\tprepare_packed_git(the_repository);\n> > -\tfor (p = get_all_packs(the_repository); p; p = p->next) {\n> > +\tfor_each_pack(the_repository, p) {\n> >  \t\tif ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)\n> >  \t\t\tcontinue;\n> >  \t\tif ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) &&\n"},{"id":"392538","messageId":"nycvar.QRO.7.76.6.2002261652400.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"20200220015858.181086-4-emilyshaffer@google.com","subject":"Re: [PATCH v8 03/15] bugreport: add tool to generate debugging info","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-02-26T16:12:50Z","receivedAt":"2020-02-26T16:12:58Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Emily,\n\nOn Wed, 19 Feb 2020, Emily Shaffer wrote:\n\n> diff --git a/bugreport.c b/bugreport.c\n> new file mode 100644\n> index 0000000000..8d4a76fdac\n> --- /dev/null\n> +++ b/bugreport.c\n> @@ -0,0 +1,94 @@\n> +#include \"builtin.h\"\n> +#include \"parse-options.h\"\n> +#include \"stdio.h\"\n> +#include \"strbuf.h\"\n> +#include \"time.h\"\n> +\n> +static const char * const bugreport_usage[] = {\n> +\tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n> +\tNULL\n> +};\n> +\n> +static int get_bug_template(struct strbuf *template)\n> +{\n> +\tconst char template_text[] = N_(\n> +\"Thank you for filling out a Git bug report!\\n\"\n> +\"Please answer the following questions to help us understand your issue.\\n\"\n> +\"\\n\"\n> +\"What did you do before the bug happened? (Steps to reproduce your issue)\\n\"\n> +\"\\n\"\n> +\"What did you expect to happen? (Expected behavior)\\n\"\n> +\"\\n\"\n> +\"What happened instead? (Actual behavior)\\n\"\n> +\"\\n\"\n> +\"What's different between what you expected and what actually happened?\\n\"\n> +\"\\n\"\n> +\"Anything else you want to add:\\n\"\n> +\"\\n\"\n> +\"Please review the rest of the bug report below.\\n\"\n> +\"You can delete any lines you don't wish to share.\\n\");\n> +\n> +\tstrbuf_addstr(template, template_text);\n> +\treturn 0;\n> +}\n> +\n> +int cmd_main(int argc, const char **argv)\n> +{\n> +\tstruct strbuf buffer = STRBUF_INIT;\n> +\tstruct strbuf report_path = STRBUF_INIT;\n> +\tFILE *report;\n> +\ttime_t now = time(NULL);\n> +\tchar *option_output = NULL;\n> +\tchar *option_suffix = \"%F-%H%M\";\n\nThis is not a portable `strftime()` format. Let's squash this in?\n\n-- snipsnap --\nSubject: [PATCH] fixup??? bugreport: add tool to generate debugging info\n\nThe `%F` format is an optional extension to the ISO C standard, see\nhttps://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html\n\nAnd sure enough, in Git for Windows, this leads to a test failure\nbecause that format is not supported in the version of the MSVC runtime\nthat we're stuck with.\n\nLet's just use the long-hand instead.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n bugreport.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/bugreport.c b/bugreport.c\nindex a3528a2e2b8..3f78db182e6 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -338,7 +338,7 @@ int cmd_main(int argc, const char **argv)\n \tFILE *report;\n \ttime_t now = time(NULL);\n \tchar *option_output = NULL;\n-\tchar *option_suffix = \"%F-%H%M\";\n+\tchar *option_suffix = \"%Y-%m-%d-%H%M\";\n \tstruct stat statbuf;\n \tint nongit_ok = 0;\n\n--\n2.25.1.windows.1\n\n"},{"id":"392539","messageId":"nycvar.QRO.7.76.6.2002261649550.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"20200220015858.181086-10-emilyshaffer@google.com","subject":"Re: [PATCH v8 09/15] bugreport: generate config safelist based on docs","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-02-26T16:13:00Z","receivedAt":"2020-02-26T16:13:06Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Emily,\n\nOn Wed, 19 Feb 2020, Emily Shaffer wrote:\n\n> diff --git a/Makefile b/Makefile\n> index 9e6705061d..6bdd3b9337 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -818,6 +818,7 @@ VCSSVN_LIB = vcs-svn/lib.a\n>\n>  GENERATED_H += config-list.h\n>  GENERATED_H += command-list.h\n> +GENERATED_H += bugreport-config-safelist.h\n>\n>  LIB_H := $(sort $(patsubst ./%,%,$(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \\\n>  \t$(FIND) . \\\n\nIn order to pretend that we actually care about developers on Windows,\nlet's squash this in?\n\n-- snipsnap --\nSubject: [PATCH] fixup??? bugreport: generate config safelist based on docs\n\nThe Visual Studio build is a special beast: as we cannot assume the\npresence of any Unix tools on Windows, we have to commit all of the\nfiles generated via shell scripts.\n\nThese two generated header files are no exception.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n config.mak.uname | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/config.mak.uname b/config.mak.uname\nindex 6d58d22cd5a..f1f36e43e47 100644\n--- a/config.mak.uname\n+++ b/config.mak.uname\n@@ -788,8 +788,10 @@ vcxproj:\n \tgit add -f git/LinkOrCopyBuiltins.targets git-remote-http/LinkOrCopyRemoteHttp.targets\n\n \t# Add command-list.h\n-\t$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 command-list.h\n-\tgit add -f command-list.h\n+\t$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 command-list.h \\\n+\t\tconfig-list.h bugreport-config-safelist.h\n+\tgit add -f command-list.h \\\n+\t \tconfig-list.h bugreport-config-safelist.h\n\n \t# Add scripts\n \trm -f perl/perl.mak\n--\n2.25.1.windows.1\n\n"},{"id":"392542","messageId":"xmqqr1yhjnte.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"nycvar.QRO.7.76.6.2002261649550.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v8 09/15] bugreport: generate config safelist based on docs","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-02-26T16:49:49Z","receivedAt":"2020-02-26T16:50:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Subject: [PATCH] fixup??? bugreport: generate config safelist based on docs\n>\n> The Visual Studio build is a special beast: as we cannot assume the\n> presence of any Unix tools on Windows, we have to commit all of the\n> files generated via shell scripts.\n>\n> These two generated header files are no exception.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  config.mak.uname | 6 ++++--\n>  1 file changed, 4 insertions(+), 2 deletions(-)\n>\n> diff --git a/config.mak.uname b/config.mak.uname\n> index 6d58d22cd5a..f1f36e43e47 100644\n> --- a/config.mak.uname\n> +++ b/config.mak.uname\n> @@ -788,8 +788,10 @@ vcxproj:\n>  \tgit add -f git/LinkOrCopyBuiltins.targets git-remote-http/LinkOrCopyRemoteHttp.targets\n>\n>  \t# Add command-list.h\n> -\t$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 command-list.h\n> -\tgit add -f command-list.h\n> +\t$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 command-list.h \\\n> +\t\tconfig-list.h bugreport-config-safelist.h\n> +\tgit add -f command-list.h \\\n> +\t \tconfig-list.h bugreport-config-safelist.h\n\nTwo important questions are \n\n - Is $(GENERATED_H) visible to you at this point in this makefile\n   snippet that is included from the main Makefile?\n\n - Currently the list of files listed on $(GENERATED_H) match what\n   you are building and adding here.  Is there a reason to believe\n   two would ever diverge?\n\nIf the answers to the above are yes and no, there is an obvious\nfutureproofing of the suggested patch, i.e.\n\n-\t$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 command-list.h\n-\tgit add -f command-list.h\n+\t$(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 $(GENERATED_H)\n+\tgit add -f $(GENERATED_H)\n\n"},{"id":"392761","messageId":"20200302230400.107428-1-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200220015858.181086-1-emilyshaffer@google.com","subject":"[PATCH v9 0/5] add git-bugreport tool","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-03-02T23:03:55Z","receivedAt":"2020-03-02T23:04:11Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"I did run this set through the Azure Pipelines CI [2] and hope that\nmeans it's platform-safe; if that's not the case, please let me know\nyour concerns.\n\nFor the relevant patches, I made the following changes since v8:\n\n - More portable strftime format\n - Use open() instead of fopen_for_writing() in order to specify O_CREAT\n   | O_EXCL | O_WRONLY.\n - Fix a use-after-free.\n - Add i18n/l10n macro all over the place; per [3] let's translate the\n   whole contents of the report, because it's easy to force to a\n   different language and we may not be the only ones reading reports\n - Use a lot less strbuf_complete_line() - when we're making library\n   calls, we have control over the format, so we do know whether it ends\n   in \\n or not; let's not waste the time checking it.\n - Minor nit on uname header phrasing\n - Reword the structure of compat/compiler.h to separate libc and\n   compiler.\n - Add MSVC reporting in compat/compiler.h (thanks Dscho).\n\nThanks all.\n - Emily\n\n[1]: https://lore.kernel.org/git/20200225235558.GG212281@google.com\n[2]: https://github.com/gitgitgadget/git/pull/566\n[3]: https://lore.kernel.org/git/xmqqimjukzzv.fsf@gitster-ct.c.googlers.com\n\nEmily Shaffer (5):\n  help: move list_config_help to builtin/help\n    Note that this patch is still required for this series because the\n    help library (for version/build info) is unusable without it.\n  bugreport: add tool to generate debugging info\n  bugreport: gather git version and build info\n  bugreport: add uname info\n  bugreport: add compiler info\n\n .gitignore                      |   2 +\n Documentation/git-bugreport.txt |  52 ++++++++++++\n Makefile                        |  18 +++-\n bugreport.c                     | 142 ++++++++++++++++++++++++++++++++\n builtin/help.c                  |  86 +++++++++++++++++++\n command-list.txt                |   1 +\n compat/compiler.h               |  38 +++++++++\n generate-cmdlist.sh             |  19 -----\n generate-configlist.sh          |  21 +++++\n help.c                          | 131 +++++++----------------------\n help.h                          |   2 +-\n strbuf.c                        |   4 +\n strbuf.h                        |   1 +\n t/t0091-bugreport.sh            |  61 ++++++++++++++\n 14 files changed, 452 insertions(+), 126 deletions(-)\n create mode 100644 Documentation/git-bugreport.txt\n create mode 100644 bugreport.c\n create mode 100644 compat/compiler.h\n create mode 100755 generate-configlist.sh\n create mode 100755 t/t0091-bugreport.sh\n\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392762","messageId":"20200302230400.107428-2-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200302230400.107428-1-emilyshaffer@google.com","subject":"[PATCH v9 1/5] help: move list_config_help to builtin/help","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-03-02T23:03:56Z","receivedAt":"2020-03-02T23:04:13Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"Starting in 3ac68a93fd2, help.o began to depend on builtin/branch.o,\nbuiltin/clean.o, and builtin/config.o. This meant that help.o was\nunusable outside of the context of the main Git executable.\n\nTo make help.o usable by other commands again, move list_config_help()\ninto builtin/help.c (where it makes sense to assume other builtin libraries\nare present).\n\nWhen command-list.h is included but a member is not used, we start to\nhear a compiler warning. Since the config list is generated in a fairly\ndifferent way than the command list, and since commands and config\noptions are semantically different, move the config list into its own\nheader and move the generator into its own script and build rule.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n .gitignore             |  1 +\n Makefile               | 13 +++++--\n builtin/help.c         | 86 ++++++++++++++++++++++++++++++++++++++++++\n generate-cmdlist.sh    | 19 ----------\n generate-configlist.sh | 21 +++++++++++\n help.c                 | 85 -----------------------------------------\n help.h                 |  1 -\n 7 files changed, 118 insertions(+), 108 deletions(-)\n create mode 100755 generate-configlist.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex aebe7c0908..ea97de83f3 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -189,6 +189,7 @@\n /gitweb/gitweb.cgi\n /gitweb/static/gitweb.js\n /gitweb/static/gitweb.min.*\n+/config-list.h\n /command-list.h\n *.tar.gz\n *.dsc\ndiff --git a/Makefile b/Makefile\nindex 6134104ae6..c552312d3f 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -815,6 +815,7 @@ LIB_FILE = libgit.a\n XDIFF_LIB = xdiff/lib.a\n VCSSVN_LIB = vcs-svn/lib.a\n \n+GENERATED_H += config-list.h\n GENERATED_H += command-list.h\n \n LIB_H := $(sort $(patsubst ./%,%,$(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \\\n@@ -2132,7 +2133,7 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)\n \n help.sp help.s help.o: command-list.h\n \n-builtin/help.sp builtin/help.s builtin/help.o: command-list.h GIT-PREFIX\n+builtin/help.sp builtin/help.s builtin/help.o: config-list.h GIT-PREFIX\n builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \\\n \t'-DGIT_HTML_PATH=\"$(htmldir_relative_SQ)\"' \\\n \t'-DGIT_MAN_PATH=\"$(mandir_relative_SQ)\"' \\\n@@ -2152,6 +2153,12 @@ $(BUILT_INS): git$X\n \tln -s $< $@ 2>/dev/null || \\\n \tcp $< $@\n \n+config-list.h: generate-configlist.sh\n+\n+config-list.h:\n+\t$(QUIET_GEN)$(SHELL_PATH) ./generate-configlist.sh \\\n+\t\t>$@+ && mv $@+ $@\n+\n command-list.h: generate-cmdlist.sh command-list.txt\n \n command-list.h: $(wildcard Documentation/git*.txt) Documentation/*config.txt Documentation/config/*.txt\n@@ -2785,7 +2792,7 @@ $(SP_OBJ): %.sp: %.c GIT-CFLAGS FORCE\n .PHONY: sparse $(SP_OBJ)\n sparse: $(SP_OBJ)\n \n-EXCEPT_HDRS := command-list.h unicode-width.h compat/% xdiff/%\n+EXCEPT_HDRS := command-list.h config-list.h unicode-width.h compat/% xdiff/%\n ifndef GCRYPT_SHA256\n \tEXCEPT_HDRS += sha256/gcrypt.h\n endif\n@@ -2807,7 +2814,7 @@ hdr-check: $(HCO)\n style:\n \tgit clang-format --style file --diff --extensions c,h\n \n-check: command-list.h\n+check: config-list.h command-list.h\n \t@if sparse; \\\n \tthen \\\n \t\techo >&2 \"Use 'make sparse' instead\"; \\\ndiff --git a/builtin/help.c b/builtin/help.c\nindex e5590d7787..1c5f2b9255 100644\n--- a/builtin/help.c\n+++ b/builtin/help.c\n@@ -8,6 +8,7 @@\n #include \"parse-options.h\"\n #include \"run-command.h\"\n #include \"column.h\"\n+#include \"config-list.h\"\n #include \"help.h\"\n #include \"alias.h\"\n \n@@ -62,6 +63,91 @@ static const char * const builtin_help_usage[] = {\n \tNULL\n };\n \n+struct slot_expansion {\n+\tconst char *prefix;\n+\tconst char *placeholder;\n+\tvoid (*fn)(struct string_list *list, const char *prefix);\n+\tint found;\n+};\n+\n+static void list_config_help(int for_human)\n+{\n+\tstruct slot_expansion slot_expansions[] = {\n+\t\t{ \"advice\", \"*\", list_config_advices },\n+\t\t{ \"color.branch\", \"<slot>\", list_config_color_branch_slots },\n+\t\t{ \"color.decorate\", \"<slot>\", list_config_color_decorate_slots },\n+\t\t{ \"color.diff\", \"<slot>\", list_config_color_diff_slots },\n+\t\t{ \"color.grep\", \"<slot>\", list_config_color_grep_slots },\n+\t\t{ \"color.interactive\", \"<slot>\", list_config_color_interactive_slots },\n+\t\t{ \"color.remote\", \"<slot>\", list_config_color_sideband_slots },\n+\t\t{ \"color.status\", \"<slot>\", list_config_color_status_slots },\n+\t\t{ \"fsck\", \"<msg-id>\", list_config_fsck_msg_ids },\n+\t\t{ \"receive.fsck\", \"<msg-id>\", list_config_fsck_msg_ids },\n+\t\t{ NULL, NULL, NULL }\n+\t};\n+\tconst char **p;\n+\tstruct slot_expansion *e;\n+\tstruct string_list keys = STRING_LIST_INIT_DUP;\n+\tint i;\n+\n+\tfor (p = config_name_list; *p; p++) {\n+\t\tconst char *var = *p;\n+\t\tstruct strbuf sb = STRBUF_INIT;\n+\n+\t\tfor (e = slot_expansions; e->prefix; e++) {\n+\n+\t\t\tstrbuf_reset(&sb);\n+\t\t\tstrbuf_addf(&sb, \"%s.%s\", e->prefix, e->placeholder);\n+\t\t\tif (!strcasecmp(var, sb.buf)) {\n+\t\t\t\te->fn(&keys, e->prefix);\n+\t\t\t\te->found++;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\tstrbuf_release(&sb);\n+\t\tif (!e->prefix)\n+\t\t\tstring_list_append(&keys, var);\n+\t}\n+\n+\tfor (e = slot_expansions; e->prefix; e++)\n+\t\tif (!e->found)\n+\t\t\tBUG(\"slot_expansion %s.%s is not used\",\n+\t\t\t    e->prefix, e->placeholder);\n+\n+\tstring_list_sort(&keys);\n+\tfor (i = 0; i < keys.nr; i++) {\n+\t\tconst char *var = keys.items[i].string;\n+\t\tconst char *wildcard, *tag, *cut;\n+\n+\t\tif (for_human) {\n+\t\t\tputs(var);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\twildcard = strchr(var, '*');\n+\t\ttag = strchr(var, '<');\n+\n+\t\tif (!wildcard && !tag) {\n+\t\t\tputs(var);\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (wildcard && !tag)\n+\t\t\tcut = wildcard;\n+\t\telse if (!wildcard && tag)\n+\t\t\tcut = tag;\n+\t\telse\n+\t\t\tcut = wildcard < tag ? wildcard : tag;\n+\n+\t\t/*\n+\t\t * We may produce duplicates, but that's up to\n+\t\t * git-completion.bash to handle\n+\t\t */\n+\t\tprintf(\"%.*s\\n\", (int)(cut - var), var);\n+\t}\n+\tstring_list_clear(&keys, 0);\n+}\n+\n static enum help_format parse_help_format(const char *format)\n {\n \tif (!strcmp(format, \"man\"))\ndiff --git a/generate-cmdlist.sh b/generate-cmdlist.sh\nindex 71158f7d8b..45fecf8bdf 100755\n--- a/generate-cmdlist.sh\n+++ b/generate-cmdlist.sh\n@@ -76,23 +76,6 @@ print_command_list () {\n \techo \"};\"\n }\n \n-print_config_list () {\n-\tcat <<EOF\n-static const char *config_name_list[] = {\n-EOF\n-\tgrep -h '^[a-zA-Z].*\\..*::$' Documentation/*config.txt Documentation/config/*.txt |\n-\tsed '/deprecated/d; s/::$//; s/,  */\\n/g' |\n-\tsort |\n-\twhile read line\n-\tdo\n-\t\techo \"\t\\\"$line\\\",\"\n-\tdone\n-\tcat <<EOF\n-\tNULL,\n-};\n-EOF\n-}\n-\n exclude_programs=\n while test \"--exclude-program\" = \"$1\"\n do\n@@ -113,5 +96,3 @@ echo\n define_category_names \"$1\"\n echo\n print_command_list \"$1\"\n-echo\n-print_config_list\ndiff --git a/generate-configlist.sh b/generate-configlist.sh\nnew file mode 100755\nindex 0000000000..8692fe5cf4\n--- /dev/null\n+++ b/generate-configlist.sh\n@@ -0,0 +1,21 @@\n+#!/bin/sh\n+\n+echo \"/* Automatically generated by generate-configlist.sh */\"\n+echo\n+\n+print_config_list () {\n+\tcat <<EOF\n+static const char *config_name_list[] = {\n+EOF\n+\tgrep -h '^[a-zA-Z].*\\..*::$' Documentation/*config.txt Documentation/config/*.txt |\n+\tsed '/deprecated/d; s/::$//; s/,  */\\n/g' |\n+\tsort |\n+\tsed 's/^.*$/\t\"&\",/'\n+\tcat <<EOF\n+\tNULL,\n+};\n+EOF\n+}\n+\n+echo\n+print_config_list\ndiff --git a/help.c b/help.c\nindex cf67624a94..a21487db77 100644\n--- a/help.c\n+++ b/help.c\n@@ -407,91 +407,6 @@ void list_common_guides_help(void)\n \tputchar('\\n');\n }\n \n-struct slot_expansion {\n-\tconst char *prefix;\n-\tconst char *placeholder;\n-\tvoid (*fn)(struct string_list *list, const char *prefix);\n-\tint found;\n-};\n-\n-void list_config_help(int for_human)\n-{\n-\tstruct slot_expansion slot_expansions[] = {\n-\t\t{ \"advice\", \"*\", list_config_advices },\n-\t\t{ \"color.branch\", \"<slot>\", list_config_color_branch_slots },\n-\t\t{ \"color.decorate\", \"<slot>\", list_config_color_decorate_slots },\n-\t\t{ \"color.diff\", \"<slot>\", list_config_color_diff_slots },\n-\t\t{ \"color.grep\", \"<slot>\", list_config_color_grep_slots },\n-\t\t{ \"color.interactive\", \"<slot>\", list_config_color_interactive_slots },\n-\t\t{ \"color.remote\", \"<slot>\", list_config_color_sideband_slots },\n-\t\t{ \"color.status\", \"<slot>\", list_config_color_status_slots },\n-\t\t{ \"fsck\", \"<msg-id>\", list_config_fsck_msg_ids },\n-\t\t{ \"receive.fsck\", \"<msg-id>\", list_config_fsck_msg_ids },\n-\t\t{ NULL, NULL, NULL }\n-\t};\n-\tconst char **p;\n-\tstruct slot_expansion *e;\n-\tstruct string_list keys = STRING_LIST_INIT_DUP;\n-\tint i;\n-\n-\tfor (p = config_name_list; *p; p++) {\n-\t\tconst char *var = *p;\n-\t\tstruct strbuf sb = STRBUF_INIT;\n-\n-\t\tfor (e = slot_expansions; e->prefix; e++) {\n-\n-\t\t\tstrbuf_reset(&sb);\n-\t\t\tstrbuf_addf(&sb, \"%s.%s\", e->prefix, e->placeholder);\n-\t\t\tif (!strcasecmp(var, sb.buf)) {\n-\t\t\t\te->fn(&keys, e->prefix);\n-\t\t\t\te->found++;\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t}\n-\t\tstrbuf_release(&sb);\n-\t\tif (!e->prefix)\n-\t\t\tstring_list_append(&keys, var);\n-\t}\n-\n-\tfor (e = slot_expansions; e->prefix; e++)\n-\t\tif (!e->found)\n-\t\t\tBUG(\"slot_expansion %s.%s is not used\",\n-\t\t\t    e->prefix, e->placeholder);\n-\n-\tstring_list_sort(&keys);\n-\tfor (i = 0; i < keys.nr; i++) {\n-\t\tconst char *var = keys.items[i].string;\n-\t\tconst char *wildcard, *tag, *cut;\n-\n-\t\tif (for_human) {\n-\t\t\tputs(var);\n-\t\t\tcontinue;\n-\t\t}\n-\n-\t\twildcard = strchr(var, '*');\n-\t\ttag = strchr(var, '<');\n-\n-\t\tif (!wildcard && !tag) {\n-\t\t\tputs(var);\n-\t\t\tcontinue;\n-\t\t}\n-\n-\t\tif (wildcard && !tag)\n-\t\t\tcut = wildcard;\n-\t\telse if (!wildcard && tag)\n-\t\t\tcut = tag;\n-\t\telse\n-\t\t\tcut = wildcard < tag ? wildcard : tag;\n-\n-\t\t/*\n-\t\t * We may produce duplicates, but that's up to\n-\t\t * git-completion.bash to handle\n-\t\t */\n-\t\tprintf(\"%.*s\\n\", (int)(cut - var), var);\n-\t}\n-\tstring_list_clear(&keys, 0);\n-}\n-\n static int get_alias(const char *var, const char *value, void *data)\n {\n \tstruct string_list *list = data;\ndiff --git a/help.h b/help.h\nindex 7a455beeb7..9071894e8c 100644\n--- a/help.h\n+++ b/help.h\n@@ -22,7 +22,6 @@ static inline void mput_char(char c, unsigned int num)\n void list_common_cmds_help(void);\n void list_all_cmds_help(void);\n void list_common_guides_help(void);\n-void list_config_help(int for_human);\n \n void list_all_main_cmds(struct string_list *list);\n void list_all_other_cmds(struct string_list *list);\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392763","messageId":"20200302230400.107428-3-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200302230400.107428-1-emilyshaffer@google.com","subject":"[PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-03-02T23:03:57Z","receivedAt":"2020-03-02T23:04:14Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"Teach Git how to prompt the user for a good bug report: reproduction\nsteps, expected behavior, and actual behavior. Later, Git can learn how\nto collect some diagnostic information from the repository.\n\nIf users can send us a well-written bug report which contains diagnostic\ninformation we would otherwise need to ask the user for, we can reduce\nthe number of question-and-answer round trips between the reporter and\nthe Git contributor.\n\nUsers may also wish to send a report like this to their local \"Git\nexpert\" if they have put their repository into a state they are confused\nby.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n .gitignore                      |   1 +\n Documentation/git-bugreport.txt |  46 ++++++++++++++\n Makefile                        |   5 ++\n bugreport.c                     | 105 ++++++++++++++++++++++++++++++++\n command-list.txt                |   1 +\n strbuf.c                        |   4 ++\n strbuf.h                        |   1 +\n t/t0091-bugreport.sh            |  61 +++++++++++++++++++\n 8 files changed, 224 insertions(+)\n create mode 100644 Documentation/git-bugreport.txt\n create mode 100644 bugreport.c\n create mode 100755 t/t0091-bugreport.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex ea97de83f3..d89bf9e11e 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -25,6 +25,7 @@\n /git-bisect--helper\n /git-blame\n /git-branch\n+/git-bugreport\n /git-bundle\n /git-cat-file\n /git-check-attr\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nnew file mode 100644\nindex 0000000000..1f9fde5cde\n--- /dev/null\n+++ b/Documentation/git-bugreport.txt\n@@ -0,0 +1,46 @@\n+git-bugreport(1)\n+================\n+\n+NAME\n+----\n+git-bugreport - Collect information for user to file a bug report\n+\n+SYNOPSIS\n+--------\n+[verse]\n+'git bugreport' [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n+\n+DESCRIPTION\n+-----------\n+Captures information about the user's machine, Git client, and repository state,\n+as well as a form requesting information about the behavior the user observed,\n+into a single text file which the user can then share, for example to the Git\n+mailing list, in order to report an observed bug.\n+\n+The following information is requested from the user:\n+\n+ - Reproduction steps\n+ - Expected behavior\n+ - Actual behavior\n+\n+This tool is invoked via the typical Git setup process, which means that in some\n+cases, it might not be able to launch - for example, if a relevant config file\n+is unreadable. In this kind of scenario, it may be helpful to manually gather\n+the kind of information listed above when manually asking for help.\n+\n+OPTIONS\n+-------\n+-o <path>::\n+--output-directory <path>::\n+\tPlace the resulting bug report file in `<path>` instead of the root of\n+\tthe Git repository.\n+\n+-s <format>::\n+--suffix <format>::\n+\tSpecify an alternate suffix for the bugreport name, to create a file\n+\tnamed 'git-bugreport-<formatted suffix>'. This should take the form of a\n+\tlink:strftime[3] format string; the current local time will be used.\n+\n+GIT\n+---\n+Part of the linkgit:git[1] suite\ndiff --git a/Makefile b/Makefile\nindex c552312d3f..9e6705061d 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -681,6 +681,7 @@ EXTRA_PROGRAMS =\n # ... and all the rest that could be moved out of bindir to gitexecdir\n PROGRAMS += $(EXTRA_PROGRAMS)\n \n+PROGRAM_OBJS += bugreport.o\n PROGRAM_OBJS += credential-store.o\n PROGRAM_OBJS += daemon.o\n PROGRAM_OBJS += fast-import.o\n@@ -2461,6 +2462,10 @@ endif\n git-%$X: %.o GIT-LDFLAGS $(GITLIBS)\n \t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)\n \n+git-bugreport$X: bugreport.o GIT-LDFLAGS $(GITLIBS)\n+\t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \\\n+\t\t$(LIBS)\n+\n git-imap-send$X: imap-send.o $(IMAP_SEND_BUILDDEPS) GIT-LDFLAGS $(GITLIBS)\n \t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \\\n \t\t$(IMAP_SEND_LDFLAGS) $(LIBS)\ndiff --git a/bugreport.c b/bugreport.c\nnew file mode 100644\nindex 0000000000..f473d606f2\n--- /dev/null\n+++ b/bugreport.c\n@@ -0,0 +1,105 @@\n+#include \"builtin.h\"\n+#include \"parse-options.h\"\n+#include \"stdio.h\"\n+#include \"strbuf.h\"\n+#include \"time.h\"\n+\n+static const char * const bugreport_usage[] = {\n+\tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n+\tNULL\n+};\n+\n+static int get_bug_template(struct strbuf *template)\n+{\n+\tconst char template_text[] = N_(\n+\"Thank you for filling out a Git bug report!\\n\"\n+\"Please answer the following questions to help us understand your issue.\\n\"\n+\"\\n\"\n+\"What did you do before the bug happened? (Steps to reproduce your issue)\\n\"\n+\"\\n\"\n+\"What did you expect to happen? (Expected behavior)\\n\"\n+\"\\n\"\n+\"What happened instead? (Actual behavior)\\n\"\n+\"\\n\"\n+\"What's different between what you expected and what actually happened?\\n\"\n+\"\\n\"\n+\"Anything else you want to add:\\n\"\n+\"\\n\"\n+\"Please review the rest of the bug report below.\\n\"\n+\"You can delete any lines you don't wish to share.\\n\");\n+\n+\tstrbuf_addstr(template, _(template_text));\n+\treturn 0;\n+}\n+\n+int cmd_main(int argc, const char **argv)\n+{\n+\tstruct strbuf buffer = STRBUF_INIT;\n+\tstruct strbuf report_path = STRBUF_INIT;\n+\tint report = -1;\n+\ttime_t now = time(NULL);\n+\tchar *option_output = NULL;\n+\tchar *option_suffix = \"%F-%H%M\";\n+\tint nongit_ok = 0;\n+\tconst char *prefix = NULL;\n+\tconst char *user_relative_path = NULL;\n+\n+\tconst struct option bugreport_options[] = {\n+\t\tOPT_STRING('o', \"output-directory\", &option_output, N_(\"path\"),\n+\t\t\t   N_(\"specify a destination for the bugreport file\")),\n+\t\tOPT_STRING('s', \"suffix\", &option_suffix, N_(\"format\"),\n+\t\t\t   N_(\"specify a strftime format suffix for the filename\")),\n+\t\tOPT_END()\n+\t};\n+\n+\tprefix = setup_git_directory_gently(&nongit_ok);\n+\n+\targc = parse_options(argc, argv, prefix, bugreport_options,\n+\t\t\t     bugreport_usage, 0);\n+\n+\t/* Prepare the path to put the result */\n+\tstrbuf_addstr(&report_path,\n+\t\t      prefix_filename(prefix,\n+\t\t\t\t      option_output ? option_output : \"\"));\n+\tstrbuf_complete(&report_path, '/');\n+\n+\tstrbuf_addstr(&report_path, \"git-bugreport-\");\n+\tstrbuf_addftime(&report_path, option_suffix, localtime(&now), 0, 0);\n+\tstrbuf_addstr(&report_path, \".txt\");\n+\n+\tswitch (safe_create_leading_directories(report_path.buf)) {\n+\tcase SCLD_OK:\n+\tcase SCLD_EXISTS:\n+\t\tbreak;\n+\tdefault:\n+\t\tdie(_(\"could not create leading directories for '%s'\"),\n+\t\t    report_path.buf);\n+\t}\n+\n+\t/* Prepare the report contents */\n+\tget_bug_template(&buffer);\n+\n+\t/* fopen doesn't offer us an O_EXCL alternative, except with glibc. */\n+\treport = open(report_path.buf, O_CREAT | O_EXCL | O_WRONLY, 0666);\n+\n+\tif (report < 0) {\n+\t\tUNLEAK(report_path);\n+\t\tdie(_(\"couldn't create a new file at '%s'\"), report_path.buf);\n+\t}\n+\n+\tstrbuf_write_fd(&buffer, report);\n+\tclose(report);\n+\n+\t/*\n+\t * We want to print the path relative to the user, but we still need the\n+\t * path relative to us to give to the editor.\n+\t */\n+\tif (!(prefix && skip_prefix(report_path.buf, prefix, &user_relative_path)))\n+\t\tuser_relative_path = report_path.buf;\n+\tfprintf(stderr, _(\"Created new report at '%s'.\\n\"),\n+\t\tuser_relative_path);\n+\n+\tUNLEAK(buffer);\n+\tUNLEAK(report_path);\n+\treturn !!launch_editor(report_path.buf, NULL, NULL);\n+}\ndiff --git a/command-list.txt b/command-list.txt\nindex 2087894655..185e5e3f05 100644\n--- a/command-list.txt\n+++ b/command-list.txt\n@@ -54,6 +54,7 @@ git-archive                             mainporcelain\n git-bisect                              mainporcelain           info\n git-blame                               ancillaryinterrogators          complete\n git-branch                              mainporcelain           history\n+git-bugreport                           ancillaryinterrogators\n git-bundle                              mainporcelain\n git-cat-file                            plumbinginterrogators\n git-check-attr                          purehelpers\ndiff --git a/strbuf.c b/strbuf.c\nindex f19da55b07..f1d66c7848 100644\n--- a/strbuf.c\n+++ b/strbuf.c\n@@ -539,6 +539,10 @@ ssize_t strbuf_write(struct strbuf *sb, FILE *f)\n \treturn sb->len ? fwrite(sb->buf, 1, sb->len, f) : 0;\n }\n \n+ssize_t strbuf_write_fd(struct strbuf *sb, int fd)\n+{\n+\treturn sb->len ? write(fd, sb->buf, sb->len) : 0;\n+}\n \n #define STRBUF_MAXLINK (2*PATH_MAX)\n \ndiff --git a/strbuf.h b/strbuf.h\nindex aae7ac3a82..bbf6204de7 100644\n--- a/strbuf.h\n+++ b/strbuf.h\n@@ -462,6 +462,7 @@ int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);\n  * NUL bytes.\n  */\n ssize_t strbuf_write(struct strbuf *sb, FILE *stream);\n+ssize_t strbuf_write_fd(struct strbuf *sb, int fd);\n \n /**\n  * Read a line from a FILE *, overwriting the existing contents of\ndiff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh\nnew file mode 100755\nindex 0000000000..65f664fdac\n--- /dev/null\n+++ b/t/t0091-bugreport.sh\n@@ -0,0 +1,61 @@\n+#!/bin/sh\n+\n+test_description='git bugreport'\n+\n+. ./test-lib.sh\n+\n+# Headers \"[System Info]\" will be followed by a non-empty line if we put some\n+# information there; we can make sure all our headers were followed by some\n+# information to check if the command was successful.\n+HEADER_PATTERN=\"^\\[.*\\]$\"\n+\n+check_all_headers_populated () {\n+\twhile read -r line\n+\tdo\n+\t\tif test \"$(grep \"$HEADER_PATTERN\" \"$line\")\"\n+\t\tthen\n+\t\t\techo \"$line\"\n+\t\t\tread -r nextline\n+\t\t\tif test -z \"$nextline\"; then\n+\t\t\t\treturn 1;\n+\t\t\tfi\n+\t\tfi\n+\tdone\n+}\n+\n+test_expect_success 'creates a report with content in the right places' '\n+\tgit bugreport -s check-headers &&\n+\tcheck_all_headers_populated <git-bugreport-check-headers.txt &&\n+\ttest_when_finished rm git-bugreport-check-headers.txt\n+'\n+\n+test_expect_success 'dies if file with same name as report already exists' '\n+\t>>git-bugreport-duplicate.txt &&\n+\ttest_must_fail git bugreport --suffix duplicate &&\n+\ttest_when_finished rm git-bugreport-duplicate.txt\n+'\n+\n+test_expect_success '--output-directory puts the report in the provided dir' '\n+\tgit bugreport -o foo/ &&\n+\ttest_path_is_file foo/git-bugreport-* &&\n+\ttest_when_finished rm -fr foo/\n+'\n+\n+test_expect_success 'incorrect arguments abort with usage' '\n+\ttest_must_fail git bugreport --false 2>output &&\n+\ttest_i18ngrep usage output &&\n+\ttest_path_is_missing git-bugreport-*\n+'\n+\n+test_expect_success 'runs outside of a git dir' '\n+\tnongit git bugreport &&\n+\ttest_when_finished rm non-repo/git-bugreport-*\n+'\n+\n+test_expect_success 'can create leading directories outside of a git dir' '\n+\tnongit git bugreport -o foo/bar/baz &&\n+\ttest_when_finished rm -fr foo/bar/baz\n+'\n+\n+\n+test_done\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392764","messageId":"20200302230400.107428-4-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200302230400.107428-1-emilyshaffer@google.com","subject":"[PATCH v9 3/5] bugreport: gather git version and build info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-03-02T23:03:58Z","receivedAt":"2020-03-02T23:04:18Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"Knowing which version of Git a user has and how it was built allows us\nto more precisely pin down the circumstances when a certain issue\noccurs, so teach bugreport how to tell us the same output as 'git\nversion --build-options'.\n\nIt's not ideal to directly call 'git version --build-options' because\nthat output goes to stdout. Instead, wrap the version string in a helper\nwithin help.[ch] library, and call that helper from within the bugreport\nlibrary.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt |  4 +++\n bugreport.c                     | 19 +++++++++++++-\n help.c                          | 46 ++++++++++++++++++++-------------\n help.h                          |  1 +\n 4 files changed, 51 insertions(+), 19 deletions(-)\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex 1f9fde5cde..f44ae8cbe7 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -23,6 +23,10 @@ The following information is requested from the user:\n  - Expected behavior\n  - Actual behavior\n \n+The following information is captured automatically:\n+\n+ - 'git version --build-options'\n+\n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\n is unreadable. In this kind of scenario, it may be helpful to manually gather\ndiff --git a/bugreport.c b/bugreport.c\nindex f473d606f2..c20437dc6a 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -1,8 +1,17 @@\n-#include \"builtin.h\"\n+#include \"cache.h\"\n #include \"parse-options.h\"\n #include \"stdio.h\"\n #include \"strbuf.h\"\n #include \"time.h\"\n+#include \"help.h\"\n+\n+static void get_system_info(struct strbuf *sys_info)\n+{\n+\t/* get git version from native cmd */\n+\tstrbuf_addstr(sys_info, _(\"git version:\\n\"));\n+\tget_version_info(sys_info, 1);\n+\tstrbuf_complete_line(sys_info);\n+}\n \n static const char * const bugreport_usage[] = {\n \tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n@@ -32,6 +41,11 @@ static int get_bug_template(struct strbuf *template)\n \treturn 0;\n }\n \n+static void get_header(struct strbuf *buf, const char *title)\n+{\n+\tstrbuf_addf(buf, \"\\n\\n[%s]\\n\", title);\n+}\n+\n int cmd_main(int argc, const char **argv)\n {\n \tstruct strbuf buffer = STRBUF_INIT;\n@@ -79,6 +93,9 @@ int cmd_main(int argc, const char **argv)\n \t/* Prepare the report contents */\n \tget_bug_template(&buffer);\n \n+\tget_header(&buffer, _(\"System Info\"));\n+\tget_system_info(&buffer);\n+\n \t/* fopen doesn't offer us an O_EXCL alternative, except with glibc. */\n \treport = open(report_path.buf, O_CREAT | O_EXCL | O_WRONLY, 0666);\n \ndiff --git a/help.c b/help.c\nindex a21487db77..1de9c0d589 100644\n--- a/help.c\n+++ b/help.c\n@@ -622,8 +622,32 @@ const char *help_unknown_cmd(const char *cmd)\n \texit(1);\n }\n \n+void get_version_info(struct strbuf *buf, int show_build_options)\n+{\n+\t/*\n+\t * The format of this string should be kept stable for compatibility\n+\t * with external projects that rely on the output of \"git version\".\n+\t *\n+\t * Always show the version, even if other options are given.\n+\t */\n+\tstrbuf_addf(buf, \"git version %s\\n\", git_version_string);\n+\n+\tif (show_build_options) {\n+\t\tstrbuf_addf(buf, \"cpu: %s\\n\", GIT_HOST_CPU);\n+\t\tif (git_built_from_commit_string[0])\n+\t\t\tstrbuf_addf(buf, \"built from commit: %s\\n\",\n+\t\t\t       git_built_from_commit_string);\n+\t\telse\n+\t\t\tstrbuf_addstr(buf, \"no commit associated with this build\\n\");\n+\t\tstrbuf_addf(buf, \"sizeof-long: %d\\n\", (int)sizeof(long));\n+\t\tstrbuf_addf(buf, \"sizeof-size_t: %d\\n\", (int)sizeof(size_t));\n+\t\t/* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */\n+\t}\n+}\n+\n int cmd_version(int argc, const char **argv, const char *prefix)\n {\n+\tstruct strbuf buf = STRBUF_INIT;\n \tint build_options = 0;\n \tconst char * const usage[] = {\n \t\tN_(\"git version [<options>]\"),\n@@ -637,25 +661,11 @@ int cmd_version(int argc, const char **argv, const char *prefix)\n \n \targc = parse_options(argc, argv, prefix, options, usage, 0);\n \n-\t/*\n-\t * The format of this string should be kept stable for compatibility\n-\t * with external projects that rely on the output of \"git version\".\n-\t *\n-\t * Always show the version, even if other options are given.\n-\t */\n-\tprintf(\"git version %s\\n\", git_version_string);\n+\tget_version_info(&buf, build_options);\n+\tprintf(\"%s\", buf.buf);\n+\n+\tstrbuf_release(&buf);\n \n-\tif (build_options) {\n-\t\tprintf(\"cpu: %s\\n\", GIT_HOST_CPU);\n-\t\tif (git_built_from_commit_string[0])\n-\t\t\tprintf(\"built from commit: %s\\n\",\n-\t\t\t       git_built_from_commit_string);\n-\t\telse\n-\t\t\tprintf(\"no commit associated with this build\\n\");\n-\t\tprintf(\"sizeof-long: %d\\n\", (int)sizeof(long));\n-\t\tprintf(\"sizeof-size_t: %d\\n\", (int)sizeof(size_t));\n-\t\t/* NEEDSWORK: also save and output GIT-BUILD_OPTIONS? */\n-\t}\n \treturn 0;\n }\n \ndiff --git a/help.h b/help.h\nindex 9071894e8c..500521b908 100644\n--- a/help.h\n+++ b/help.h\n@@ -37,6 +37,7 @@ void add_cmdname(struct cmdnames *cmds, const char *name, int len);\n void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes);\n int is_in_cmdlist(struct cmdnames *cmds, const char *name);\n void list_commands(unsigned int colopts, struct cmdnames *main_cmds, struct cmdnames *other_cmds);\n+void get_version_info(struct strbuf *buf, int show_build_options);\n \n /*\n  * call this to die(), when it is suspected that the user mistyped a\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392765","messageId":"20200302230400.107428-5-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200302230400.107428-1-emilyshaffer@google.com","subject":"[PATCH v9 4/5] bugreport: add uname info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-03-02T23:03:59Z","receivedAt":"2020-03-02T23:04:19Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"The contents of uname() can give us some insight into what sort of\nsystem the user is running on, and help us replicate their setup if need\nbe. The domainname field is not guaranteed to be available, so don't\ncollect it.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt |  1 +\n bugreport.c                     | 16 +++++++++++++++-\n 2 files changed, 16 insertions(+), 1 deletion(-)\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex f44ae8cbe7..17b0d14e8d 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -26,6 +26,7 @@ The following information is requested from the user:\n The following information is captured automatically:\n \n  - 'git version --build-options'\n+ - uname sysname, release, version, and machine strings\n \n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\ndiff --git a/bugreport.c b/bugreport.c\nindex c20437dc6a..857b4f712c 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -7,10 +7,24 @@\n \n static void get_system_info(struct strbuf *sys_info)\n {\n+\tstruct utsname uname_info;\n+\n \t/* get git version from native cmd */\n \tstrbuf_addstr(sys_info, _(\"git version:\\n\"));\n \tget_version_info(sys_info, 1);\n-\tstrbuf_complete_line(sys_info);\n+\n+\t/* system call for other version info */\n+\tstrbuf_addstr(sys_info, \"uname: \");\n+\tif (uname(&uname_info))\n+\t\tstrbuf_addf(sys_info, _(\"uname() failed with error '%s' (%d)\\n\"),\n+\t\t\t    strerror(errno),\n+\t\t\t    errno);\n+\telse\n+\t\tstrbuf_addf(sys_info, \"%s %s %s %s\\n\",\n+\t\t\t    uname_info.sysname,\n+\t\t\t    uname_info.release,\n+\t\t\t    uname_info.version,\n+\t\t\t    uname_info.machine);\n }\n \n static const char * const bugreport_usage[] = {\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392766","messageId":"20200302230400.107428-6-emilyshaffer@google.com","threadId":"52845","inReplyTo":"20200302230400.107428-1-emilyshaffer@google.com","subject":"[PATCH v9 5/5] bugreport: add compiler info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-03-02T23:04:00Z","receivedAt":"2020-03-02T23:04:21Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"To help pinpoint the source of a regression, it is useful to know some\ninfo about the compiler which the user's Git client was built with. By\nadding a generic get_compiler_info() in 'compat/' we can choose which\nrelevant information to share per compiler; to get started, let's\ndemonstrate the version of glibc if the user built with 'gcc'.\n\nSigned-off-by: Emily Shaffer <emilyshaffer@google.com>\n---\n Documentation/git-bugreport.txt |  1 +\n bugreport.c                     |  6 ++++++\n compat/compiler.h               | 38 +++++++++++++++++++++++++++++++++\n 3 files changed, 45 insertions(+)\n create mode 100644 compat/compiler.h\n\ndiff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\nindex 17b0d14e8d..643d1b2884 100644\n--- a/Documentation/git-bugreport.txt\n+++ b/Documentation/git-bugreport.txt\n@@ -27,6 +27,7 @@ The following information is captured automatically:\n \n  - 'git version --build-options'\n  - uname sysname, release, version, and machine strings\n+ - Compiler-specific info string\n \n This tool is invoked via the typical Git setup process, which means that in some\n cases, it might not be able to launch - for example, if a relevant config file\ndiff --git a/bugreport.c b/bugreport.c\nindex 857b4f712c..5073c901cd 100644\n--- a/bugreport.c\n+++ b/bugreport.c\n@@ -4,6 +4,7 @@\n #include \"strbuf.h\"\n #include \"time.h\"\n #include \"help.h\"\n+#include \"compat/compiler.h\"\n \n static void get_system_info(struct strbuf *sys_info)\n {\n@@ -25,6 +26,11 @@ static void get_system_info(struct strbuf *sys_info)\n \t\t\t    uname_info.release,\n \t\t\t    uname_info.version,\n \t\t\t    uname_info.machine);\n+\n+\tstrbuf_addstr(sys_info, _(\"compiler info: \"));\n+\tget_compiler_info(sys_info);\n+\tstrbuf_addstr(sys_info, _(\"libc info: \"));\n+\tget_libc_info(sys_info);\n }\n \n static const char * const bugreport_usage[] = {\ndiff --git a/compat/compiler.h b/compat/compiler.h\nnew file mode 100644\nindex 0000000000..21f098e6a4\n--- /dev/null\n+++ b/compat/compiler.h\n@@ -0,0 +1,38 @@\n+#ifndef COMPILER_H\n+#define COMPILER_H\n+\n+#include \"git-compat-util.h\"\n+#include \"strbuf.h\"\n+\n+#ifdef __GLIBC__\n+#include <gnu/libc-version.h>\n+#endif\n+\n+static inline void get_compiler_info(struct strbuf *info)\n+{\n+\tint len = info->len;\n+#ifdef __GNUC__\n+\tstrbuf_addf(info, \"gnuc: %d.%d\\n\", __GNUC__, __GNUC_MINOR__);\n+#endif\n+\n+#ifdef _MSC_VER\n+\tstrbuf_addf(info, \"MSVC version: %s\\n\", _MSC_FULL_VER);\n+#endif\n+\n+\tif (len == info->len)\n+\t\tstrbuf_addf(info, _(\"no compiler information available\\n\"));\n+}\n+\n+static inline void get_libc_info(struct strbuf *info)\n+{\n+\tint len = info->len;\n+\n+#ifdef __GLIBC__\n+\tstrbuf_addf(info, \"glibc: %s\\n\", gnu_get_libc_version());\n+#endif\n+\n+\tif (len == info->len)\n+\t\tstrbuf_addf(info, _(\"no libc information available\\n\"));\n+}\n+\n+#endif /* COMPILER_H */\n-- \n2.25.0.265.gbab2e86ba0-goog\n\n"},{"id":"392776","messageId":"20200303114653.GB3610@danh.dev","threadId":"52845","inReplyTo":"20200302230400.107428-6-emilyshaffer@google.com","subject":"Re: [PATCH v9 5/5] bugreport: add compiler info","fromName":"Danh Doan","fromEmail":"congdanhqx@gmail.com","sentAt":"2020-03-03T11:46:53Z","receivedAt":"2020-03-03T11:46:59Z","isPatch":true,"sender":{"key":"congdanhqx@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42673067?v=4"},"body":"On 2020-03-02 15:04:00-0800, Emily Shaffer <emilyshaffer@google.com> wrote:\n> To help pinpoint the source of a regression, it is useful to know some\n> info about the compiler which the user's Git client was built with. By\n> adding a generic get_compiler_info() in 'compat/' we can choose which\n> relevant information to share per compiler; to get started, let's\n> demonstrate the version of glibc if the user built with 'gcc'.\n> \n> Signed-off-by: Emily Shaffer <emilyshaffer@google.com>\n> ---\n>  Documentation/git-bugreport.txt |  1 +\n>  bugreport.c                     |  6 ++++++\n>  compat/compiler.h               | 38 +++++++++++++++++++++++++++++++++\n>  3 files changed, 45 insertions(+)\n>  create mode 100644 compat/compiler.h\n> \n> diff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\n> index 17b0d14e8d..643d1b2884 100644\n> --- a/Documentation/git-bugreport.txt\n> +++ b/Documentation/git-bugreport.txt\n> @@ -27,6 +27,7 @@ The following information is captured automatically:\n>  \n>   - 'git version --build-options'\n>   - uname sysname, release, version, and machine strings\n> + - Compiler-specific info string\n>  \n>  This tool is invoked via the typical Git setup process, which means that in some\n>  cases, it might not be able to launch - for example, if a relevant config file\n> diff --git a/bugreport.c b/bugreport.c\n> index 857b4f712c..5073c901cd 100644\n> --- a/bugreport.c\n> +++ b/bugreport.c\n> @@ -4,6 +4,7 @@\n>  #include \"strbuf.h\"\n>  #include \"time.h\"\n>  #include \"help.h\"\n> +#include \"compat/compiler.h\"\n>  \n>  static void get_system_info(struct strbuf *sys_info)\n>  {\n> @@ -25,6 +26,11 @@ static void get_system_info(struct strbuf *sys_info)\n>  \t\t\t    uname_info.release,\n>  \t\t\t    uname_info.version,\n>  \t\t\t    uname_info.machine);\n> +\n> +\tstrbuf_addstr(sys_info, _(\"compiler info: \"));\n> +\tget_compiler_info(sys_info);\n> +\tstrbuf_addstr(sys_info, _(\"libc info: \"));\n> +\tget_libc_info(sys_info);\n>  }\n>  \n>  static const char * const bugreport_usage[] = {\n> diff --git a/compat/compiler.h b/compat/compiler.h\n> new file mode 100644\n> index 0000000000..21f098e6a4\n> --- /dev/null\n> +++ b/compat/compiler.h\n> @@ -0,0 +1,38 @@\n> +#ifndef COMPILER_H\n> +#define COMPILER_H\n> +\n> +#include \"git-compat-util.h\"\n> +#include \"strbuf.h\"\n> +\n> +#ifdef __GLIBC__\n> +#include <gnu/libc-version.h>\n> +#endif\n> +\n> +static inline void get_compiler_info(struct strbuf *info)\n> +{\n> +\tint len = info->len;\n> +#ifdef __GNUC__\n> +\tstrbuf_addf(info, \"gnuc: %d.%d\\n\", __GNUC__, __GNUC_MINOR__);\n> +#endif\n\nThis fixup can be used for clang on Linux, I guess it could be applied\nfor macOS too (since default gcc on macOS is symlinked to clang?)\n\n--------------8<----------------------\ndiff --git a/compat/compiler.h b/compat/compiler.h\nindex 21f098e6a4..055dbb5e1b 100644\n--- a/compat/compiler.h\n+++ b/compat/compiler.h\n@@ -11,7 +11,9 @@\n static inline void get_compiler_info(struct strbuf *info)\n {\n \tint len = info->len;\n-#ifdef __GNUC__\n+#ifdef __clang__\n+\tstrbuf_addf(info, \"clang: %s\\n\", __clang_version__);\n+#elif defined(__GNUC__)\n \tstrbuf_addf(info, \"gnuc: %d.%d\\n\", __GNUC__, __GNUC_MINOR__);\n #endif\n \n-------------------->8---------------------\n\n> +\n> +#ifdef _MSC_VER\n> +\tstrbuf_addf(info, \"MSVC version: %s\\n\", _MSC_FULL_VER);\n> +#endif\n> +\n> +\tif (len == info->len)\n> +\t\tstrbuf_addf(info, _(\"no compiler information available\\n\"));\n> +}\n> +\n> +static inline void get_libc_info(struct strbuf *info)\n> +{\n> +\tint len = info->len;\n> +\n> +#ifdef __GLIBC__\n> +\tstrbuf_addf(info, \"glibc: %s\\n\", gnu_get_libc_version());\n> +#endif\n> +\n> +\tif (len == info->len)\n> +\t\tstrbuf_addf(info, _(\"no libc information available\\n\"));\n> +}\n> +\n> +#endif /* COMPILER_H */\n> -- \n> 2.25.0.265.gbab2e86ba0-goog\n> \n\n-- \nDanh\n"},{"id":"392779","messageId":"xmqqpndta5vy.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"20200302230400.107428-6-emilyshaffer@google.com","subject":"Re: [PATCH v9 5/5] bugreport: add compiler info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-03-03T14:07:45Z","receivedAt":"2020-03-03T14:07:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> +static inline void get_compiler_info(struct strbuf *info)\n> +{\n> + ...\n> +\tif (len == info->len)\n> +\t\tstrbuf_addf(info, _(\"no compiler information available\\n\"));\n\ns/addf/addstr/ to squelch https://travis-ci.org/git/git/jobs/657572439\n\n> +}\n> +\n> +static inline void get_libc_info(struct strbuf *info)\n> +{\n> + ...\n> +\tif (len == info->len)\n> +\t\tstrbuf_addf(info, _(\"no libc information available\\n\"));\n\nDitto.\n\n> +}\n> +\n> +#endif /* COMPILER_H */\n"},{"id":"392782","messageId":"nycvar.QRO.7.76.6.2003031516501.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"20200302230400.107428-3-emilyshaffer@google.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-03-03T14:18:10Z","receivedAt":"2020-03-03T14:18:15Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Emily,\n\nOn Mon, 2 Mar 2020, Emily Shaffer wrote:\n\n> +\tchar *option_suffix = \"%F-%H%M\";\n\nUnfortunately, this still is not an `strftime` format we can use on\nWindows. I still needed to fix that in the previously-mentioned manner to\nfix the test run on Windows.\n\nThanks,\nDscho\n"},{"id":"392875","messageId":"nycvar.QRO.7.76.6.2003042232340.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"20200302230400.107428-3-emilyshaffer@google.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-03-04T21:35:04Z","receivedAt":"2020-03-04T21:35:11Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 2 Mar 2020, Emily Shaffer wrote:\n\n>  .gitignore                      |   1 +\n>  Documentation/git-bugreport.txt |  46 ++++++++++++++\n>  Makefile                        |   5 ++\n>  bugreport.c                     | 105 ++++++++++++++++++++++++++++++++\n>  command-list.txt                |   1 +\n>  strbuf.c                        |   4 ++\n>  strbuf.h                        |   1 +\n>  t/t0091-bugreport.sh            |  61 +++++++++++++++++++\n>  8 files changed, 224 insertions(+)\n>  create mode 100644 Documentation/git-bugreport.txt\n>  create mode 100644 bugreport.c\n>  create mode 100755 t/t0091-bugreport.sh\n\nHmm. I am still _quite_ convinced that this would be much better as a\nbuilt-in. Remember, non-built-ins come with a footprint, and I do not\nnecessarily think that you will want to spend 3MB on a `git-bugreport`\nexecutable when you could have it for a couple dozen kilobytes inside\n`git` instead.\n\nCiao,\nDscho\n\n>\n> diff --git a/.gitignore b/.gitignore\n> index ea97de83f3..d89bf9e11e 100644\n> --- a/.gitignore\n> +++ b/.gitignore\n> @@ -25,6 +25,7 @@\n>  /git-bisect--helper\n>  /git-blame\n>  /git-branch\n> +/git-bugreport\n>  /git-bundle\n>  /git-cat-file\n>  /git-check-attr\n> diff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt\n> new file mode 100644\n> index 0000000000..1f9fde5cde\n> --- /dev/null\n> +++ b/Documentation/git-bugreport.txt\n> @@ -0,0 +1,46 @@\n> +git-bugreport(1)\n> +================\n> +\n> +NAME\n> +----\n> +git-bugreport - Collect information for user to file a bug report\n> +\n> +SYNOPSIS\n> +--------\n> +[verse]\n> +'git bugreport' [(-o | --output-directory) <path>] [(-s | --suffix) <format>]\n> +\n> +DESCRIPTION\n> +-----------\n> +Captures information about the user's machine, Git client, and repository state,\n> +as well as a form requesting information about the behavior the user observed,\n> +into a single text file which the user can then share, for example to the Git\n> +mailing list, in order to report an observed bug.\n> +\n> +The following information is requested from the user:\n> +\n> + - Reproduction steps\n> + - Expected behavior\n> + - Actual behavior\n> +\n> +This tool is invoked via the typical Git setup process, which means that in some\n> +cases, it might not be able to launch - for example, if a relevant config file\n> +is unreadable. In this kind of scenario, it may be helpful to manually gather\n> +the kind of information listed above when manually asking for help.\n> +\n> +OPTIONS\n> +-------\n> +-o <path>::\n> +--output-directory <path>::\n> +\tPlace the resulting bug report file in `<path>` instead of the root of\n> +\tthe Git repository.\n> +\n> +-s <format>::\n> +--suffix <format>::\n> +\tSpecify an alternate suffix for the bugreport name, to create a file\n> +\tnamed 'git-bugreport-<formatted suffix>'. This should take the form of a\n> +\tlink:strftime[3] format string; the current local time will be used.\n> +\n> +GIT\n> +---\n> +Part of the linkgit:git[1] suite\n> diff --git a/Makefile b/Makefile\n> index c552312d3f..9e6705061d 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -681,6 +681,7 @@ EXTRA_PROGRAMS =\n>  # ... and all the rest that could be moved out of bindir to gitexecdir\n>  PROGRAMS += $(EXTRA_PROGRAMS)\n>\n> +PROGRAM_OBJS += bugreport.o\n>  PROGRAM_OBJS += credential-store.o\n>  PROGRAM_OBJS += daemon.o\n>  PROGRAM_OBJS += fast-import.o\n> @@ -2461,6 +2462,10 @@ endif\n>  git-%$X: %.o GIT-LDFLAGS $(GITLIBS)\n>  \t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)\n>\n> +git-bugreport$X: bugreport.o GIT-LDFLAGS $(GITLIBS)\n> +\t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \\\n> +\t\t$(LIBS)\n> +\n>  git-imap-send$X: imap-send.o $(IMAP_SEND_BUILDDEPS) GIT-LDFLAGS $(GITLIBS)\n>  \t$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \\\n>  \t\t$(IMAP_SEND_LDFLAGS) $(LIBS)\n> diff --git a/bugreport.c b/bugreport.c\n> new file mode 100644\n> index 0000000000..f473d606f2\n> --- /dev/null\n> +++ b/bugreport.c\n> @@ -0,0 +1,105 @@\n> +#include \"builtin.h\"\n> +#include \"parse-options.h\"\n> +#include \"stdio.h\"\n> +#include \"strbuf.h\"\n> +#include \"time.h\"\n> +\n> +static const char * const bugreport_usage[] = {\n> +\tN_(\"git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]\"),\n> +\tNULL\n> +};\n> +\n> +static int get_bug_template(struct strbuf *template)\n> +{\n> +\tconst char template_text[] = N_(\n> +\"Thank you for filling out a Git bug report!\\n\"\n> +\"Please answer the following questions to help us understand your issue.\\n\"\n> +\"\\n\"\n> +\"What did you do before the bug happened? (Steps to reproduce your issue)\\n\"\n> +\"\\n\"\n> +\"What did you expect to happen? (Expected behavior)\\n\"\n> +\"\\n\"\n> +\"What happened instead? (Actual behavior)\\n\"\n> +\"\\n\"\n> +\"What's different between what you expected and what actually happened?\\n\"\n> +\"\\n\"\n> +\"Anything else you want to add:\\n\"\n> +\"\\n\"\n> +\"Please review the rest of the bug report below.\\n\"\n> +\"You can delete any lines you don't wish to share.\\n\");\n> +\n> +\tstrbuf_addstr(template, _(template_text));\n> +\treturn 0;\n> +}\n> +\n> +int cmd_main(int argc, const char **argv)\n> +{\n> +\tstruct strbuf buffer = STRBUF_INIT;\n> +\tstruct strbuf report_path = STRBUF_INIT;\n> +\tint report = -1;\n> +\ttime_t now = time(NULL);\n> +\tchar *option_output = NULL;\n> +\tchar *option_suffix = \"%F-%H%M\";\n> +\tint nongit_ok = 0;\n> +\tconst char *prefix = NULL;\n> +\tconst char *user_relative_path = NULL;\n> +\n> +\tconst struct option bugreport_options[] = {\n> +\t\tOPT_STRING('o', \"output-directory\", &option_output, N_(\"path\"),\n> +\t\t\t   N_(\"specify a destination for the bugreport file\")),\n> +\t\tOPT_STRING('s', \"suffix\", &option_suffix, N_(\"format\"),\n> +\t\t\t   N_(\"specify a strftime format suffix for the filename\")),\n> +\t\tOPT_END()\n> +\t};\n> +\n> +\tprefix = setup_git_directory_gently(&nongit_ok);\n> +\n> +\targc = parse_options(argc, argv, prefix, bugreport_options,\n> +\t\t\t     bugreport_usage, 0);\n> +\n> +\t/* Prepare the path to put the result */\n> +\tstrbuf_addstr(&report_path,\n> +\t\t      prefix_filename(prefix,\n> +\t\t\t\t      option_output ? option_output : \"\"));\n> +\tstrbuf_complete(&report_path, '/');\n> +\n> +\tstrbuf_addstr(&report_path, \"git-bugreport-\");\n> +\tstrbuf_addftime(&report_path, option_suffix, localtime(&now), 0, 0);\n> +\tstrbuf_addstr(&report_path, \".txt\");\n> +\n> +\tswitch (safe_create_leading_directories(report_path.buf)) {\n> +\tcase SCLD_OK:\n> +\tcase SCLD_EXISTS:\n> +\t\tbreak;\n> +\tdefault:\n> +\t\tdie(_(\"could not create leading directories for '%s'\"),\n> +\t\t    report_path.buf);\n> +\t}\n> +\n> +\t/* Prepare the report contents */\n> +\tget_bug_template(&buffer);\n> +\n> +\t/* fopen doesn't offer us an O_EXCL alternative, except with glibc. */\n> +\treport = open(report_path.buf, O_CREAT | O_EXCL | O_WRONLY, 0666);\n> +\n> +\tif (report < 0) {\n> +\t\tUNLEAK(report_path);\n> +\t\tdie(_(\"couldn't create a new file at '%s'\"), report_path.buf);\n> +\t}\n> +\n> +\tstrbuf_write_fd(&buffer, report);\n> +\tclose(report);\n> +\n> +\t/*\n> +\t * We want to print the path relative to the user, but we still need the\n> +\t * path relative to us to give to the editor.\n> +\t */\n> +\tif (!(prefix && skip_prefix(report_path.buf, prefix, &user_relative_path)))\n> +\t\tuser_relative_path = report_path.buf;\n> +\tfprintf(stderr, _(\"Created new report at '%s'.\\n\"),\n> +\t\tuser_relative_path);\n> +\n> +\tUNLEAK(buffer);\n> +\tUNLEAK(report_path);\n> +\treturn !!launch_editor(report_path.buf, NULL, NULL);\n> +}\n> diff --git a/command-list.txt b/command-list.txt\n> index 2087894655..185e5e3f05 100644\n> --- a/command-list.txt\n> +++ b/command-list.txt\n> @@ -54,6 +54,7 @@ git-archive                             mainporcelain\n>  git-bisect                              mainporcelain           info\n>  git-blame                               ancillaryinterrogators          complete\n>  git-branch                              mainporcelain           history\n> +git-bugreport                           ancillaryinterrogators\n>  git-bundle                              mainporcelain\n>  git-cat-file                            plumbinginterrogators\n>  git-check-attr                          purehelpers\n> diff --git a/strbuf.c b/strbuf.c\n> index f19da55b07..f1d66c7848 100644\n> --- a/strbuf.c\n> +++ b/strbuf.c\n> @@ -539,6 +539,10 @@ ssize_t strbuf_write(struct strbuf *sb, FILE *f)\n>  \treturn sb->len ? fwrite(sb->buf, 1, sb->len, f) : 0;\n>  }\n>\n> +ssize_t strbuf_write_fd(struct strbuf *sb, int fd)\n> +{\n> +\treturn sb->len ? write(fd, sb->buf, sb->len) : 0;\n> +}\n>\n>  #define STRBUF_MAXLINK (2*PATH_MAX)\n>\n> diff --git a/strbuf.h b/strbuf.h\n> index aae7ac3a82..bbf6204de7 100644\n> --- a/strbuf.h\n> +++ b/strbuf.h\n> @@ -462,6 +462,7 @@ int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);\n>   * NUL bytes.\n>   */\n>  ssize_t strbuf_write(struct strbuf *sb, FILE *stream);\n> +ssize_t strbuf_write_fd(struct strbuf *sb, int fd);\n>\n>  /**\n>   * Read a line from a FILE *, overwriting the existing contents of\n> diff --git a/t/t0091-bugreport.sh b/t/t0091-bugreport.sh\n> new file mode 100755\n> index 0000000000..65f664fdac\n> --- /dev/null\n> +++ b/t/t0091-bugreport.sh\n> @@ -0,0 +1,61 @@\n> +#!/bin/sh\n> +\n> +test_description='git bugreport'\n> +\n> +. ./test-lib.sh\n> +\n> +# Headers \"[System Info]\" will be followed by a non-empty line if we put some\n> +# information there; we can make sure all our headers were followed by some\n> +# information to check if the command was successful.\n> +HEADER_PATTERN=\"^\\[.*\\]$\"\n> +\n> +check_all_headers_populated () {\n> +\twhile read -r line\n> +\tdo\n> +\t\tif test \"$(grep \"$HEADER_PATTERN\" \"$line\")\"\n> +\t\tthen\n> +\t\t\techo \"$line\"\n> +\t\t\tread -r nextline\n> +\t\t\tif test -z \"$nextline\"; then\n> +\t\t\t\treturn 1;\n> +\t\t\tfi\n> +\t\tfi\n> +\tdone\n> +}\n> +\n> +test_expect_success 'creates a report with content in the right places' '\n> +\tgit bugreport -s check-headers &&\n> +\tcheck_all_headers_populated <git-bugreport-check-headers.txt &&\n> +\ttest_when_finished rm git-bugreport-check-headers.txt\n> +'\n> +\n> +test_expect_success 'dies if file with same name as report already exists' '\n> +\t>>git-bugreport-duplicate.txt &&\n> +\ttest_must_fail git bugreport --suffix duplicate &&\n> +\ttest_when_finished rm git-bugreport-duplicate.txt\n> +'\n> +\n> +test_expect_success '--output-directory puts the report in the provided dir' '\n> +\tgit bugreport -o foo/ &&\n> +\ttest_path_is_file foo/git-bugreport-* &&\n> +\ttest_when_finished rm -fr foo/\n> +'\n> +\n> +test_expect_success 'incorrect arguments abort with usage' '\n> +\ttest_must_fail git bugreport --false 2>output &&\n> +\ttest_i18ngrep usage output &&\n> +\ttest_path_is_missing git-bugreport-*\n> +'\n> +\n> +test_expect_success 'runs outside of a git dir' '\n> +\tnongit git bugreport &&\n> +\ttest_when_finished rm non-repo/git-bugreport-*\n> +'\n> +\n> +test_expect_success 'can create leading directories outside of a git dir' '\n> +\tnongit git bugreport -o foo/bar/baz &&\n> +\ttest_when_finished rm -fr foo/bar/baz\n> +'\n> +\n> +\n> +test_done\n> --\n> 2.25.0.265.gbab2e86ba0-goog\n>\n>\n"},{"id":"392876","messageId":"nycvar.QRO.7.76.6.2003042236060.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"20200302230400.107428-6-emilyshaffer@google.com","subject":"Re: [PATCH v9 5/5] bugreport: add compiler info","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-03-04T21:39:53Z","receivedAt":"2020-03-04T21:39:59Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Emily,\n\nOn Mon, 2 Mar 2020, Emily Shaffer wrote:\n\n> diff --git a/compat/compiler.h b/compat/compiler.h\n> new file mode 100644\n> index 0000000000..21f098e6a4\n> --- /dev/null\n> +++ b/compat/compiler.h\n> @@ -0,0 +1,38 @@\n> +#ifndef COMPILER_H\n> +#define COMPILER_H\n> +\n> +#include \"git-compat-util.h\"\n> +#include \"strbuf.h\"\n> +\n> +#ifdef __GLIBC__\n> +#include <gnu/libc-version.h>\n> +#endif\n> +\n> +static inline void get_compiler_info(struct strbuf *info)\n> +{\n> +\tint len = info->len;\n> +#ifdef __GNUC__\n> +\tstrbuf_addf(info, \"gnuc: %d.%d\\n\", __GNUC__, __GNUC_MINOR__);\n> +#endif\n> +\n> +#ifdef _MSC_VER\n> +\tstrbuf_addf(info, \"MSVC version: %s\\n\", _MSC_FULL_VER);\n\nI need this to fix a crash in the Visual Studio build's test run:\n\n-- snip --\nSubject: [PATCH] fixup??? bugreport: add compiler info\n\nAs documented at\nhttps://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2019,\n`_MSC_FULL_VER` is an integer, not a string. Therefore this fix is\nneeded to prevent a segmentation fault in the test t0091.1.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/compiler.h | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/compat/compiler.h b/compat/compiler.h\nindex ce6a7f6de9a..ac90fa051dd 100644\n--- a/compat/compiler.h\n+++ b/compat/compiler.h\n@@ -16,7 +16,8 @@ static inline void get_compiler_info(struct strbuf *info)\n #endif\n\n #ifdef _MSC_VER\n-\tstrbuf_addf(info, \"MSVC version: %s\\n\", _MSC_FULL_VER);\n+\tstrbuf_addf(info, \"MSVC version: %02d.%02d.%05d\\n\",\n+\t\t    _MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 100000);\n #endif\n\n \tif (len == info->len)\n-- snap --\n\nCould you squash that in, please?\n\nBTW the two issues I reported in the earlier round are still problems.\nCould you squash my fixes, please? For your convenience, you can pluck all\nfour of them right off of\nhttps://github.com/git-for-windows/git/commits/shears/pu\n\nJust replace the `???` by `!` and you can even use `git rebase\n--autosquash`.\n\nCiao,\nDscho\n\n\n> +#endif\n> +\n> +\tif (len == info->len)\n> +\t\tstrbuf_addf(info, _(\"no compiler information available\\n\"));\n> +}\n> +\n> +static inline void get_libc_info(struct strbuf *info)\n> +{\n> +\tint len = info->len;\n> +\n> +#ifdef __GLIBC__\n> +\tstrbuf_addf(info, \"glibc: %s\\n\", gnu_get_libc_version());\n> +#endif\n> +\n> +\tif (len == info->len)\n> +\t\tstrbuf_addf(info, _(\"no libc information available\\n\"));\n> +}\n> +\n> +#endif /* COMPILER_H */\n> --\n> 2.25.0.265.gbab2e86ba0-goog\n>\n>\n"},{"id":"392891","messageId":"5aae34d7-ed76-0e71-d0c4-959deeb1b2ca@jeffhostetler.com","threadId":"52845","inReplyTo":"nycvar.QRO.7.76.6.2003042232340.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Jeff Hostetler","fromEmail":"git@jeffhostetler.com","sentAt":"2020-03-05T23:34:39Z","receivedAt":"2020-03-05T23:45:14Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"\n\nOn 3/4/2020 4:35 PM, Johannes Schindelin wrote:\n> Hi,\n> \n> On Mon, 2 Mar 2020, Emily Shaffer wrote:\n> \n>>   .gitignore                      |   1 +\n>>   Documentation/git-bugreport.txt |  46 ++++++++++++++\n>>   Makefile                        |   5 ++\n>>   bugreport.c                     | 105 ++++++++++++++++++++++++++++++++\n>>   command-list.txt                |   1 +\n>>   strbuf.c                        |   4 ++\n>>   strbuf.h                        |   1 +\n>>   t/t0091-bugreport.sh            |  61 +++++++++++++++++++\n>>   8 files changed, 224 insertions(+)\n>>   create mode 100644 Documentation/git-bugreport.txt\n>>   create mode 100644 bugreport.c\n>>   create mode 100755 t/t0091-bugreport.sh\n> \n> Hmm. I am still _quite_ convinced that this would be much better as a\n> built-in. Remember, non-built-ins come with a footprint, and I do not\n> necessarily think that you will want to spend 3MB on a `git-bugreport`\n> executable when you could have it for a couple dozen kilobytes inside\n> `git` instead.\n> \n> Ciao,\n> Dscho\n\nHaving this command be a stand-alone exe rather than a builtin allows\nit to have a different linkage.  For example, you could include the\nlibcurl and other libraries that are only linked into the transports.\nAnd then report version numbers for them if you wanted.\n\nJeff\n"},{"id":"392901","messageId":"nycvar.QRO.7.76.6.2003061453260.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"5aae34d7-ed76-0e71-d0c4-959deeb1b2ca@jeffhostetler.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-03-06T13:57:52Z","receivedAt":"2020-03-06T13:57:59Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Jeff,\n\nOn Thu, 5 Mar 2020, Jeff Hostetler wrote:\n\n> On 3/4/2020 4:35 PM, Johannes Schindelin wrote:\n> >\n> > On Mon, 2 Mar 2020, Emily Shaffer wrote:\n> >\n> > >   .gitignore                      |   1 +\n> > >   Documentation/git-bugreport.txt |  46 ++++++++++++++\n> > >   Makefile                        |   5 ++\n> > >   bugreport.c                     | 105 ++++++++++++++++++++++++++++++++\n> > >   command-list.txt                |   1 +\n> > >   strbuf.c                        |   4 ++\n> > >   strbuf.h                        |   1 +\n> > >   t/t0091-bugreport.sh            |  61 +++++++++++++++++++\n> > >   8 files changed, 224 insertions(+)\n> > >   create mode 100644 Documentation/git-bugreport.txt\n> > >   create mode 100644 bugreport.c\n> > >   create mode 100755 t/t0091-bugreport.sh\n> >\n> > Hmm. I am still _quite_ convinced that this would be much better as a\n> > built-in. Remember, non-built-ins come with a footprint, and I do not\n> > necessarily think that you will want to spend 3MB on a `git-bugreport`\n> > executable when you could have it for a couple dozen kilobytes inside\n> > `git` instead.\n> >\n> > Ciao,\n> > Dscho\n>\n> Having this command be a stand-alone exe rather than a builtin allows\n> it to have a different linkage.  For example, you could include the\n> libcurl and other libraries that are only linked into the transports.\n> And then report version numbers for them if you wanted.\n\nWhile that is true, I would argue that this is quite likely using the\n_wrong_ information if the user has a different `git-remote-https` in\ntheir `PATH`. In other words, that information could _mislead_ the\nrecipient of the bug report.\n\nNow, other people might argue that the different linkage lets\n`git-bugreport` maybe work where `git` would fail to load a required\ndynamic library. But again, I would counter that this is a false\nassumption: since `git-bugreport` relies on `libgit.a`, it essentially\n_has_ to have the same linkage as `git`, or a superset thereof.\n\nSo: No, I really think this is going the wrong direction.\n\nIf we want `bugreport` to be a first-class citizen, we should treat it as\nsuch. That entails making it a built-in. That entails teaching\n`git-remote-https` (and potentially other non-builtins) to sprout that\noption to enquire other information that should be included in the\ngenerated part of the bug report.\n\nCiao,\nDscho\n"},{"id":"392913","messageId":"xmqqr1y52w5y.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"5aae34d7-ed76-0e71-d0c4-959deeb1b2ca@jeffhostetler.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-03-06T18:08:41Z","receivedAt":"2020-03-06T18:08:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff Hostetler <git@jeffhostetler.com> writes:\n\n> Having this command be a stand-alone exe rather than a builtin allows\n> it to have a different linkage.  For example, you could include the\n> libcurl and other libraries that are only linked into the transports.\n> And then report version numbers for them if you wanted.\n\nI actually do not think that is a good rationale.  Unless your\nversion of \"git bugreport\" links into the same binary as the\n\"transports\", it still is possible that the version of cURL (for\nexample) \"git bugreport\" can learn internally from may not have\nanything to do with the version of the library used by the\ntransports.  \n\nOf course, making \"bugreport\" a built-in, i.e. the same binary as\nthe non-transport part of Git, is not a solution for that issue,\neither.  As Dscho suggested and recent rounds of \"git bugreport\"\nimplements, teaching the transport binaries an option to report\nrelevant pieces of information regarding the libraries they use, and\nmaking \"git bugreport\" ask them, is a very good solution for that.\n\nWhat makes it possible by making \"git bugreport\" stand-alone is for\nit to link with libraries that the remainder of Git, including the\ntransports that link with libcurl, has no business linking with (a\nlibrary to obtain system details for diagnostic purposes, for\nexample).  Early versions of \"git bugreport\" may not link with\nanything special, but making sure it starts and stays standalone\nleaves it easier to do so _without_ having to worry about splitting\nthe code that started as a built-in out to make it independent later.\n\n\n"},{"id":"392915","messageId":"xmqqmu8t2ved.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"nycvar.QRO.7.76.6.2003061453260.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-03-06T18:25:14Z","receivedAt":"2020-03-06T18:25:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> If we want `bugreport` to be a first-class citizen, we should\n> treat it as such.  That entails making it a built-in.\n\nThe question is, for \"bugreport\", if it is better to be standalone\nor to be built-in, and I do not think 'first-class' has anything to\ndo with the question.  The transport based on curl-library are\nseparate binaries but they are of course first-class citizens.\n\nPushing and fetching will happen a lot less often than local\noperations like \"add\", \"commit\", \"show\", and not paying start-up\nlatencies to load code and link libraries that are not necessary for\nlocal operations in built-in, while paying the cost of having to\nduplicate the memory and disk footprint necessary for libgit.a stuff\nby making the transport binaries separate from the built-ins, was\nconscious implementation decision we made earlier to prioritize the\nreduction of overhead of subcommands for local operation.  Yes, the\ndecision de-prioritizes the transport, but that does not mean they\nare not first-class citizens.  It just means that the start-up\nlatency for them (e.g. linking with libcurl) is not huge burden for\nthe overall time cost for the network transfer, and it is necessary\ncost for them to perform what they need to do anyway, while it is\nsomething subcommands for local operations should not have to pay.\n\n> That entails teaching\n> `git-remote-https` (and potentially other non-builtins) to sprout that\n> option to enquire other information that should be included in the\n> generated part of the bug report.\n\nI think later rounds of \"git bugreports\" already did so.\n\nAs I mentioned in a separate message to JeffH, this is a good thing\nto do, whether \"git bugreport\" is a built-in or a standalone.\n\n\n\n"},{"id":"392917","messageId":"c3ab15b9-c143-2251-0e5d-a990e50a72ea@jeffhostetler.com","threadId":"52845","inReplyTo":"xmqqr1y52w5y.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Jeff Hostetler","fromEmail":"git@jeffhostetler.com","sentAt":"2020-03-06T18:58:02Z","receivedAt":"2020-03-06T18:58:10Z","isPatch":true,"sender":{"key":"git@jeffhostetler.com","avatar":null},"body":"\n\nOn 3/6/2020 1:08 PM, Junio C Hamano wrote:\n> Jeff Hostetler <git@jeffhostetler.com> writes:\n> \n>> Having this command be a stand-alone exe rather than a builtin allows\n>> it to have a different linkage.  For example, you could include the\n>> libcurl and other libraries that are only linked into the transports.\n>> And then report version numbers for them if you wanted.\n> \n> I actually do not think that is a good rationale.  Unless your\n> version of \"git bugreport\" links into the same binary as the\n> \"transports\", it still is possible that the version of cURL (for\n> example) \"git bugreport\" can learn internally from may not have\n> anything to do with the version of the library used by the\n> transports.\n> \n> Of course, making \"bugreport\" a built-in, i.e. the same binary as\n> the non-transport part of Git, is not a solution for that issue,\n> either.  As Dscho suggested and recent rounds of \"git bugreport\"\n> implements, teaching the transport binaries an option to report\n> relevant pieces of information regarding the libraries they use, and\n> making \"git bugreport\" ask them, is a very good solution for that.\n> \n> What makes it possible by making \"git bugreport\" stand-alone is for\n> it to link with libraries that the remainder of Git, including the\n> transports that link with libcurl, has no business linking with (a\n> library to obtain system details for diagnostic purposes, for\n> example).  Early versions of \"git bugreport\" may not link with\n> anything special, but making sure it starts and stays standalone\n> leaves it easier to do so _without_ having to worry about splitting\n> the code that started as a built-in out to make it independent later.\n> \n> \n\nYeah, that makes sense.\nThanks\nJeff\n"},{"id":"392957","messageId":"nycvar.QRO.7.76.6.2003082319260.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"xmqqr1y52w5y.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-03-08T22:24:39Z","receivedAt":"2020-03-08T22:25:10Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Fri, 6 Mar 2020, Junio C Hamano wrote:\n\n> What makes it possible by making \"git bugreport\" stand-alone is for\n> it to link with libraries that the remainder of Git, including the\n> transports that link with libcurl, has no business linking with (a\n> library to obtain system details for diagnostic purposes, for\n> example).\n\nThat would, however, make `git-bugreport` more fragile than `git`, i.e.\nthe former might fail to launch under more circumstances than the latter.\n\nNot a good idea for a tool meant to help reporting bugs, to be more\nfragile to even _start_ than `git`.\n\nA tool that is intended to help users come up with bug reports, despite\nthe fact that users are totally unfamiliar with the implementation details\nof Git and hence unable to judge competently what information to include\nor to omit, needs to be _robust_.\n\nYou do not want to end up, for example, calling a stale `git-bugreport`\nfrom an earlier `make install` (or from a different installation\naltogether). That would give the recipient not only bogus information, it\nwould be outright misleading.\n\nAnd that's what I meant by \"a stand-alone `git-bugreport` would not be a\n1st-class citizen\".\n\nI would see it as a serious design issue if this command is anything but a\nbuilt-in.\n\nCiao,\nDscho\n"},{"id":"392963","messageId":"xmqqr1y11sn7.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"nycvar.QRO.7.76.6.2003082319260.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-03-09T14:59:08Z","receivedAt":"2020-03-09T14:59:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Hi Junio,\n>\n> On Fri, 6 Mar 2020, Junio C Hamano wrote:\n>\n>> What makes it possible by making \"git bugreport\" stand-alone is for\n>> it to link with libraries that the remainder of Git, including the\n>> transports that link with libcurl, has no business linking with (a\n>> library to obtain system details for diagnostic purposes, for\n>> example).\n>\n> That would, however, make `git-bugreport` more fragile than `git`, i.e.\n> the former might fail to launch under more circumstances than the latter.\n\nThat's a bug.  You can go fix it when it happens.\n"},{"id":"392970","messageId":"nycvar.QRO.7.76.6.2003092013090.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"xmqqr1y11sn7.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-03-09T19:17:04Z","receivedAt":"2020-03-09T19:17:16Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Mon, 9 Mar 2020, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n>\n> > On Fri, 6 Mar 2020, Junio C Hamano wrote:\n> >\n> >> What makes it possible by making \"git bugreport\" stand-alone is for\n> >> it to link with libraries that the remainder of Git, including the\n> >> transports that link with libcurl, has no business linking with (a\n> >> library to obtain system details for diagnostic purposes, for\n> >> example).\n> >\n> > That would, however, make `git-bugreport` more fragile than `git`, i.e.\n> > the former might fail to launch under more circumstances than the latter.\n>\n> That's a bug.  You can go fix it when it happens.\n\nHeh... yeah, that would be a bug, and the user would not be able to report\nit via `git bugreport`...\n\nWhich is the whole point of my complaint.\n\nIsn't it obvious that we should not have an independent `git-bugreport` by\nnow? With a stand-alone `git-bugreport`, we might\n\n- fail to load the .so files under more circumstances than `git` would\n  (since we link to `libgit.a`, we cannot have a subset of dependencies,\n  only a superset, or the same),\n\n- launch a stale `git-bugreport` from a completely different Git,\n\n- make users angry for wasting 3MB of their diskspace for `git-bugreport`\n  when only a dozen kilobyte would suffice.\n\nOn the other hand, if we make `git-bugreport` a built-in, I cannot see any\ndownsides.\n\nFor me, therefore, having it as a built-in is a clear win. What am I\nmissing?\n\nCiao,\nDscho\n"},{"id":"392972","messageId":"xmqq36ah1fao.fsf@gitster-ct.c.googlers.com","threadId":"52845","inReplyTo":"nycvar.QRO.7.76.6.2003092013090.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-03-09T19:47:27Z","receivedAt":"2020-03-09T19:47:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> On the other hand, if we make `git-bugreport` a built-in, I cannot see any\n> downsides.\n>\n> For me, therefore, having it as a built-in is a clear win. What am I\n> missing?\n\nThe right sense of relative importance between efficiently running\nthe rest of Git by not bloting the main binary and making sure not\nto ship Git that does not run unless \"git bugreport\" runs (which\nmakes sure that \"bugreport\" runs) is what you are missing, I\nsuspect.\n\nAnother thing is that you are giving \"git bugreport\" too much weight\nand too little credit to inexperienced users, by assuming that we\nwill never hear from them when \"bugreport\" is incapable to run for\nthem.  They will report, with or without \"git bugreport\", and the\nmore important thing you seem to be missing is that after the\ninitial contact it would become an interactive process---there is\nno reason to prioritize to ensure that the initial contact has\neverything that is needed to diagnose any issue without further \ninteraction.  \"With my build, even 'bugreport' dumps core.\" is\nperfectly good place to start.\n\nBesides, wouldn't the ones on platforms, on which \"git bugreport\"\nmay have trouble running, i.e. the ones on minority and exotic\nplatforms, tend to be self sufficient and capable (both diagnosing\nthe issue for themselves, and reaching out to us as appropriate)\nones in practice (e.g. I have NonStop folks in mind)?\n"},{"id":"392986","messageId":"nycvar.QRO.7.76.6.2003101239000.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"xmqq36ah1fao.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-03-10T11:42:03Z","receivedAt":"2020-03-10T11:42:29Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Mon, 9 Mar 2020, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n>\n> > On the other hand, if we make `git-bugreport` a built-in, I cannot see any\n> > downsides.\n> >\n> > For me, therefore, having it as a built-in is a clear win. What am I\n> > missing?\n>\n> The right sense of relative importance between efficiently running\n> the rest of Git by not bloting the main binary and making sure not\n> to ship Git that does not run unless \"git bugreport\" runs (which\n> makes sure that \"bugreport\" runs) is what you are missing, I\n> suspect.\n\nBy that reasoning, `git bugreport` should not be included in core Git.\n\n> Another thing is that you are giving \"git bugreport\" too much weight\n> and too little credit to inexperienced users, by assuming that we\n> will never hear from them when \"bugreport\" is incapable to run for\n> them.  They will report, with or without \"git bugreport\", and the\n> more important thing you seem to be missing is that after the\n> initial contact it would become an interactive process---there is\n> no reason to prioritize to ensure that the initial contact has\n> everything that is needed to diagnose any issue without further\n> interaction.  \"With my build, even 'bugreport' dumps core.\" is\n> perfectly good place to start.\n>\n> Besides, wouldn't the ones on platforms, on which \"git bugreport\"\n> may have trouble running, i.e. the ones on minority and exotic\n> platforms, tend to be self sufficient and capable (both diagnosing\n> the issue for themselves, and reaching out to us as appropriate)\n> ones in practice (e.g. I have NonStop folks in mind)?\n\nYes, I can agree that inexperienced users will not give up and keep\nup the conversation until they see their problems fixed.\n\nI can also agree that inexperienced users will report bugs even if it is\nnot made super easy for them to do so.\n\nI can agree to that _iff_ I ignore my entire experience maintaining Git\nfor Windows, that is.\n\nSarcasm aside, I think that you underestimate the importance of a good bug\nreporting tool like `git bugreport`, and I suspect that Emily does not.\n\nCiao,\nDscho\n"},{"id":"393027","messageId":"xmqq36agjbt3.fsf@gitster.c.googlers.com","threadId":"52845","inReplyTo":"nycvar.QRO.7.76.6.2003101239000.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-03-10T18:37:44Z","receivedAt":"2020-03-10T18:37:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>> The right sense of relative importance between efficiently running\n>> the rest of Git by not bloting the main binary and making sure not\n>> to ship Git that does not run unless \"git bugreport\" runs (which\n>> makes sure that \"bugreport\" runs) is what you are missing, I\n>> suspect.\n>\n> By that reasoning, `git bugreport` should not be included in core Git.\n\nThe world does not have to be black-or-white.  \"git bugreport\" that\ncovers mainstream platforms in widely-used configurations may be\nonly an 80% solution, but that is better than nothing at all.\n\n>> Another thing is that you are giving \"git bugreport\" too much weight\n>> and too little credit to inexperienced users, by assuming that we\n>> will never hear from them when \"bugreport\" is incapable to run for\n>> them.  They will report, with or without \"git bugreport\", and the\n>> more important thing you seem to be missing is that after the\n>> initial contact it would become an interactive process---there is\n>> no reason to prioritize to ensure that the initial contact has\n>> everything that is needed to diagnose any issue without further\n>> interaction.  \"With my build, even 'bugreport' dumps core.\" is\n>> perfectly good place to start.\n>>\n>> Besides, wouldn't the ones on platforms, on which \"git bugreport\"\n>> may have trouble running, i.e. the ones on minority and exotic\n>> platforms, tend to be self sufficient and capable (both diagnosing\n>> the issue for themselves, and reaching out to us as appropriate)\n>> ones in practice (e.g. I have NonStop folks in mind)?\n>\n> Yes, I can agree that inexperienced users will not give up and keep\n> up the conversation until they see their problems fixed.\n\nInexperienced users won't be on minority platforms for which we do\nnot have enough resource to get \"git bugreport\" to run adequetly in\nthe first place.  Even if those on minority platforms whose userbase\nare all technically incapable ones, if they do not help us help\nthem, what can \"git bugreport\" can do, and more importantly, how\nwould it make a difference between \"bugreport\" being a built-in vs a\nstandalone?\n\nAt this point, I'd have to say that your quibbling does not deserve\na serious response and it would be better use of my time to\ndisengage from this thread.\n\n"},{"id":"393045","messageId":"nycvar.QRO.7.76.6.2003102306150.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"xmqq36agjbt3.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-03-10T22:08:23Z","receivedAt":"2020-03-10T22:08:48Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Tue, 10 Mar 2020, Junio C Hamano wrote:\n\n> At this point, I'd have to say that your quibbling does not deserve\n> a serious response and it would be better use of my time to\n> disengage from this thread.\n\nI thought we were discussing whether it makes sense to leave\n`git-bugreport` as a stand-alone executable, or rather make it a built-in.\n\nIf my attempts to convince you that it would be better as a built-in\nstrike you as \"quibbling\", then I should probably pull out from trying to\nreview and help with this here patch series. I really thought I was\nhelping. My apologies for annoying you instead.\n\nCiao,\nDscho\n"},{"id":"393488","messageId":"20200319213902.GB45325@google.com","threadId":"52845","inReplyTo":"nycvar.QRO.7.76.6.2003042232340.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-03-19T21:39:02Z","receivedAt":"2020-03-19T21:39:11Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Wed, Mar 04, 2020 at 10:35:04PM +0100, Johannes Schindelin wrote:\n> Hi,\n> \n> On Mon, 2 Mar 2020, Emily Shaffer wrote:\n> \n> >  .gitignore                      |   1 +\n> >  Documentation/git-bugreport.txt |  46 ++++++++++++++\n> >  Makefile                        |   5 ++\n> >  bugreport.c                     | 105 ++++++++++++++++++++++++++++++++\n> >  command-list.txt                |   1 +\n> >  strbuf.c                        |   4 ++\n> >  strbuf.h                        |   1 +\n> >  t/t0091-bugreport.sh            |  61 +++++++++++++++++++\n> >  8 files changed, 224 insertions(+)\n> >  create mode 100644 Documentation/git-bugreport.txt\n> >  create mode 100644 bugreport.c\n> >  create mode 100755 t/t0091-bugreport.sh\n> \n> Hmm. I am still _quite_ convinced that this would be much better as a\n> built-in. Remember, non-built-ins come with a footprint, and I do not\n> necessarily think that you will want to spend 3MB on a `git-bugreport`\n> executable when you could have it for a couple dozen kilobytes inside\n> `git` instead.\n\nThis is the kind of stuff I really wanted to get straightened out by\nsending the smaller changeset, so I'm glad to be having this\nconversation (again, and hopefully for the last time). I read the\nreplies to this mail, which I'm truncating as I think many of them are\ndistracting rather than discussion-worthy, and have tried to summarize:\n\nBuiltin:\n+ Don't have to call out-of-process to identify 'git version --build-options'\n+ Better assurance that we aren't shipping a broken bugreport alongside a new\n  version\n- Binary bloat, possible startup time hit\n? Libraries will behave identically to where the user is seeing issues\n  (This point is a possible pro but also a possible con; see similar point in\n  standalone list)\n\nStandalone:\n+ Could investigate libraries who aren't behaving the way they should.\n  (This seems like it'd be better addressed by regression tests, and if we're so\n  sure that git-bugreport is working with the info at hand correctly, why don't\n  we just write the git binary that way too?)\n+ Avoid binary bloat in the main executable.\n- Have to ship a big standalone binary instead.\n- To get accurate version/build info, need to query the Git executable in a new\n  process\n\nOf course if I missed capturing something, please add/correct. Some of\nthese concerns are quantifiable - binary size and overhead, for example\n- so I'm planning on doing some experiments in the coming days. I plan\nput together the handful of patches in the latest version of the topic\nin both standalone and builtin mode, and then gather the following info:\n\n - Binary size of 'git'\n - Binary size of 'git-bugreport' when applicable\n - Time for \"make\" following clean\n - Time for 'git status' on an identical real-world repo (I'll use ours,\n   without touching the repo state e.g. changing branch or fetching in\n   between)\n - Time to editor for 'git bugreport' with the same setup as previous\n - Peak memory footprint during 'git status'\n\nAnd of course, if there's more to compare that I can quantify, please\nlet me know that too. I expect I'll be ready to run the experiments by\nMonday (taking some time off tomorrow) so there's time for me to hear\nabout other concerns.\n\nI'll hold off on sharing my own preference until after we've got some\nbenchmarking to look at, so I can understand the whole picture.\n\n - Emily\n"},{"id":"393500","messageId":"xmqqd097dg4k.fsf@gitster.c.googlers.com","threadId":"52845","inReplyTo":"20200319213902.GB45325@google.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-03-20T00:28:11Z","receivedAt":"2020-03-20T00:28:39Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> Builtin:\n> + Don't have to call out-of-process to identify 'git version --build-options'\n> + Better assurance that we aren't shipping a broken bugreport alongside a new\n>   version\n> - Binary bloat, possible startup time hit\n> ? Libraries will behave identically to where the user is seeing issues\n>   (This point is a possible pro but also a possible con; see similar point in\n>   standalone list)\n\n - Makes it hard to pull in libraries that \"bugreport\" alone will\n   want to use in the future without negatively impacting the rest\n   of Git.\n\n>  - Time to editor for 'git bugreport' with the same setup as previous\n\nThis is something we absolutely should totally ignore.  Even if the\nbulitin version takes 1 sec to spawn an editor while a standalone\none took only 0.1 sec, if other criteria you listed that are more\nimportant favours the builtin solution, we should pick it.\n\nIn any case, I think we've wasted enough time on this.  Let's see a\nminimum working version that won't break/affect the rest of Git and\nship it standalone.\n\nThanks.\n"},{"id":"393531","messageId":"nycvar.QRO.7.76.6.2003201633560.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"xmqqd097dg4k.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-03-20T15:35:45Z","receivedAt":"2020-03-20T15:36:08Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"On Thu, 19 Mar 2020, Junio C Hamano wrote:\n\n> Emily Shaffer <emilyshaffer@google.com> writes:\n>\n> > Builtin:\n> > + Don't have to call out-of-process to identify 'git version --build-options'\n> > + Better assurance that we aren't shipping a broken bugreport alongside a new\n> >   version\n> > - Binary bloat, possible startup time hit\n> > ? Libraries will behave identically to where the user is seeing issues\n> >   (This point is a possible pro but also a possible con; see similar point in\n> >   standalone list)\n>\n>  - Makes it hard to pull in libraries that \"bugreport\" alone will\n>    want to use in the future without negatively impacting the rest\n>    of Git.\n\nAnd of course we should never do that, lest `git bugreport` won't even\nload because of it while `git` would.\n\nSo even in the purely speculative scenario that we _wanted_ to add more\nlibraries (which we don't, why should we?), we wouldn't actually do it.\n\n> >  - Time to editor for 'git bugreport' with the same setup as previous\n>\n> This is something we absolutely should totally ignore.  Even if the\n> bulitin version takes 1 sec to spawn an editor while a standalone\n> one took only 0.1 sec, if other criteria you listed that are more\n> important favours the builtin solution, we should pick it.\n>\n> In any case, I think we've wasted enough time on this.  Let's see a\n> minimum working version that won't break/affect the rest of Git and\n> ship it standalone.\n\nI still disagree with that, but it seems that no amount of arguments will\nconvince Junio, and he's dead set on the standalone version.\n"},{"id":"393533","messageId":"nycvar.QRO.7.76.6.2003201636040.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"20200319213902.GB45325@google.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-03-20T15:42:36Z","receivedAt":"2020-03-20T15:42:54Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Emily,\n\nOn Thu, 19 Mar 2020, Emily Shaffer wrote:\n\n> On Wed, Mar 04, 2020 at 10:35:04PM +0100, Johannes Schindelin wrote:\n>\n> > On Mon, 2 Mar 2020, Emily Shaffer wrote:\n> >\n> > >  .gitignore                      |   1 +\n> > >  Documentation/git-bugreport.txt |  46 ++++++++++++++\n> > >  Makefile                        |   5 ++\n> > >  bugreport.c                     | 105 ++++++++++++++++++++++++++++++++\n> > >  command-list.txt                |   1 +\n> > >  strbuf.c                        |   4 ++\n> > >  strbuf.h                        |   1 +\n> > >  t/t0091-bugreport.sh            |  61 +++++++++++++++++++\n> > >  8 files changed, 224 insertions(+)\n> > >  create mode 100644 Documentation/git-bugreport.txt\n> > >  create mode 100644 bugreport.c\n> > >  create mode 100755 t/t0091-bugreport.sh\n> >\n> > Hmm. I am still _quite_ convinced that this would be much better as a\n> > built-in. Remember, non-built-ins come with a footprint, and I do not\n> > necessarily think that you will want to spend 3MB on a `git-bugreport`\n> > executable when you could have it for a couple dozen kilobytes inside\n> > `git` instead.\n>\n> This is the kind of stuff I really wanted to get straightened out by\n> sending the smaller changeset, so I'm glad to be having this\n> conversation (again, and hopefully for the last time). I read the\n> replies to this mail, which I'm truncating as I think many of them are\n> distracting rather than discussion-worthy, and have tried to summarize:\n>\n> Builtin:\n> + Don't have to call out-of-process to identify 'git version --build-options'\n> + Better assurance that we aren't shipping a broken bugreport alongside a new\n>   version\n> - Binary bloat, possible startup time hit\n> ? Libraries will behave identically to where the user is seeing issues\n>   (This point is a possible pro but also a possible con; see similar point in\n>   standalone list)\n>\n> Standalone:\n> + Could investigate libraries who aren't behaving the way they should.\n>   (This seems like it'd be better addressed by regression tests, and if we're so\n>   sure that git-bugreport is working with the info at hand correctly, why don't\n>   we just write the git binary that way too?)\n\nNo, you're linking with libgit.a, you will have _at least_ the same set of\ndependencies as `git`. I made that point before.\n\n> + Avoid binary bloat in the main executable.\n\nWhat? What bloat? Have you measured this?\n\n> - Have to ship a big standalone binary instead.\n> - To get accurate version/build info, need to query the Git executable in a new\n>   process\n\nWorse. You might pick up inconsistent info from unrelated Git versions,\nand would be none the wiser. I made that point before.\n\nFor example, if you call `git bugreport` in a Git version that does not\neven include `git-bugreport`, you could pick up a `git-bugreport` from a\n_different_ Git version. This is a very real scenario on Windows, where we\nhave many applications that ship with their own minimal version of Git for\nWindows.\n\n> Of course if I missed capturing something, please add/correct. Some of\n> these concerns are quantifiable - binary size and overhead, for example\n> - so I'm planning on doing some experiments in the coming days. I plan\n> put together the handful of patches in the latest version of the topic\n> in both standalone and builtin mode, and then gather the following info:\n>\n>  - Binary size of 'git'\n>  - Binary size of 'git-bugreport' when applicable\n>  - Time for \"make\" following clean\n>  - Time for 'git status' on an identical real-world repo (I'll use ours,\n>    without touching the repo state e.g. changing branch or fetching in\n>    between)\n>  - Time to editor for 'git bugreport' with the same setup as previous\n>  - Peak memory footprint during 'git status'\n\nSomething that you cannot quantify, of course, is the robustness. Which in\nmy mind is more important than all of the above, and of course you would\nonly be able to guarantee that with a built-in version.\n\n> And of course, if there's more to compare that I can quantify, please\n> let me know that too. I expect I'll be ready to run the experiments by\n> Monday (taking some time off tomorrow) so there's time for me to hear\n> about other concerns.\n>\n> I'll hold off on sharing my own preference until after we've got some\n> benchmarking to look at, so I can understand the whole picture.\n\nWhy? Why not strong-arm your preference? Junio and I are not shy doing the\nsame, and those are _your_ patches. Junio is clearly not interested in the\ncommand at all, but you are clearly interested in it [*1*]. You should\nhave more than just the final say over this.\n\nCiao,\nDscho\n\nFootnote *1*: I am *obviously* interested in this because it might\npotentially make my life as Git for Windows' maintainer a lot easier. If\nit is robust enough that I don't get bug reports about `git-bugreport`\nitself.\n"},{"id":"393542","messageId":"xmqq8sjudirm.fsf@gitster.c.googlers.com","threadId":"52845","inReplyTo":"20200319213902.GB45325@google.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-03-20T17:43:25Z","receivedAt":"2020-03-20T17:43:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> This is the kind of stuff I really wanted to get straightened out by\n> sending the smaller changeset, so I'm glad to be having this\n> conversation (again, and hopefully for the last time).\n\nI actually have a suspicion that \"git bugreport\" that is spawned via\n\"git\" wrapper is a bad idea (in other words, /usr/bin/git-bug that\nis totally standalone may be better).\n\nThe thing is, anything launched by \"git\" as its subcommand (be it\nstandalone or builtin) sees an environment already modified by\n\"git\", so inspecting say \"$PATH\" from \"git bugreport\" (be it\nstandalone or builtin) does not show what the end-user, who may be\nhaving trouble, actually has.  The mangling of $PATH alone happens\nto be simple and (we may think) we can easily reverse without losing\nbits, but there would probably other differences that we think is so\nsubtle and insignificant, right now in this discussion without\nhaving actual end-user who is having trouble in front of us, that\nhaving \"git\" layer in between may hide from us.\n\nHaving \"git-bug\" a totally separate tool, that does not even go\nthrough git.c::cmd_main(), would also allow (and force) us to treat\n\"git\" just like any system component on the end-users' system whose\nversions and configurations may affect the use of \"git\" by the end\nuser.  The tool, instead of relying on git_version_string[] that is\ndetermined at the compile time, would ask \"git version\" just like\nthe end-users would when asked by us \"what version of git do you\nrun?\"  It also means that \"git-bug\" can be updated at different\ncadence and the mismatch of versions between it and \"git\" does not\nmatter at all.\n\nHaving said all that, after suggesting to make the tool even more\ndistant from the remainder of the binary, quite honestly, I do not\neven want to see us wasting any more time on builtin/standalone at\nthis point, and instead would like to see reports from the end-users\nproduced by a lets-start-small version of the tool and measure how\nhaving the tool actually helps.\n\nThanks.\n"},{"id":"393565","messageId":"nycvar.QRO.7.76.6.2003202336390.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"xmqq8sjudirm.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-03-20T22:38:12Z","receivedAt":"2020-03-20T22:38:36Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Fri, 20 Mar 2020, Junio C Hamano wrote:\n\n> Emily Shaffer <emilyshaffer@google.com> writes:\n>\n> > This is the kind of stuff I really wanted to get straightened out by\n> > sending the smaller changeset, so I'm glad to be having this\n> > conversation (again, and hopefully for the last time).\n>\n> I actually have a suspicion that \"git bugreport\" that is spawned via\n> \"git\" wrapper is a bad idea (in other words, /usr/bin/git-bug that\n> is totally standalone may be better).\n\nThe obvious downside of `/usr/bin/git-bug`, of course, is that it has no\nway to provide accurate data regarding, say, the cURL version in use.\n\nThat's a pretty severe downside if you are truly interested in helping bug\nreporters and bug receivers.\n\nCiao,\nDscho\n\n>\n> The thing is, anything launched by \"git\" as its subcommand (be it\n> standalone or builtin) sees an environment already modified by\n> \"git\", so inspecting say \"$PATH\" from \"git bugreport\" (be it\n> standalone or builtin) does not show what the end-user, who may be\n> having trouble, actually has.  The mangling of $PATH alone happens\n> to be simple and (we may think) we can easily reverse without losing\n> bits, but there would probably other differences that we think is so\n> subtle and insignificant, right now in this discussion without\n> having actual end-user who is having trouble in front of us, that\n> having \"git\" layer in between may hide from us.\n>\n> Having \"git-bug\" a totally separate tool, that does not even go\n> through git.c::cmd_main(), would also allow (and force) us to treat\n> \"git\" just like any system component on the end-users' system whose\n> versions and configurations may affect the use of \"git\" by the end\n> user.  The tool, instead of relying on git_version_string[] that is\n> determined at the compile time, would ask \"git version\" just like\n> the end-users would when asked by us \"what version of git do you\n> run?\"  It also means that \"git-bug\" can be updated at different\n> cadence and the mismatch of versions between it and \"git\" does not\n> matter at all.\n>\n> Having said all that, after suggesting to make the tool even more\n> distant from the remainder of the binary, quite honestly, I do not\n> even want to see us wasting any more time on builtin/standalone at\n> this point, and instead would like to see reports from the end-users\n> produced by a lets-start-small version of the tool and measure how\n> having the tool actually helps.\n>\n> Thanks.\n>\n"},{"id":"393566","messageId":"xmqq7dzebq4j.fsf@gitster.c.googlers.com","threadId":"52845","inReplyTo":"nycvar.QRO.7.76.6.2003202336390.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-03-20T22:47:24Z","receivedAt":"2020-03-20T22:47:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>> I actually have a suspicion that \"git bugreport\" that is spawned via\n>> \"git\" wrapper is a bad idea (in other words, /usr/bin/git-bug that\n>> is totally standalone may be better).\n>\n> The obvious downside of `/usr/bin/git-bug`, of course, is that it has no\n> way to provide accurate data regarding, say, the cURL version in use.\n\nSorry, but I do not see what's new in your argument this time.\n\nI thought we've already established that the best solution for the\n\"accurate data regarding, say, the cURL version in use\" is to use\nyour earlier idea, i.e. give an interface to git-remote-curl so that\n\"git bugreport\" can ask it such details, because \"git bugreport\"\nthat is known by git.c::cmd_main(), whether it is builtin or\nstandalone, is *NOT* linked to the transport anyway.\n\nAnd the same interface can be used by an independent \"git-bug\", or\neven by the end user who is sitting at a terminal when asked by git\ndevelopers \"what version of curl library does your build link\nwith?\".\n"},{"id":"393614","messageId":"nycvar.QRO.7.76.6.2003211152080.46@tvgsbejvaqbjf.bet","threadId":"52845","inReplyTo":"xmqq7dzebq4j.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-03-21T10:53:33Z","receivedAt":"2020-03-21T10:53:39Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Fri, 20 Mar 2020, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n>\n> >> I actually have a suspicion that \"git bugreport\" that is spawned via\n> >> \"git\" wrapper is a bad idea (in other words, /usr/bin/git-bug that\n> >> is totally standalone may be better).\n> >\n> > The obvious downside of `/usr/bin/git-bug`, of course, is that it has no\n> > way to provide accurate data regarding, say, the cURL version in use.\n>\n> Sorry, but I do not see what's new in your argument this time.\n>\n> I thought we've already established that the best solution for the\n> \"accurate data regarding, say, the cURL version in use\" is to use\n> your earlier idea, i.e. give an interface to git-remote-curl so that\n> \"git bugreport\" can ask it such details, because \"git bugreport\"\n> that is known by git.c::cmd_main(), whether it is builtin or\n> standalone, is *NOT* linked to the transport anyway.\n>\n> And the same interface can be used by an independent \"git-bug\", or\n> even by the end user who is sitting at a terminal when asked by git\n> developers \"what version of curl library does your build link\n> with?\".\n\nYou are _asking_ for version mismatch here. If `git-bug` is a totally\nstandalone program, then it cannot rely at all on `git` to give it the\ninformation it wants. Forward compatibility becomes another concern.\n\nIn other words, all the avoidably incurred complexity will come back to\nmake the entire `git bugreport` not worth all the effort Emily put into\nit.\n\nCiao,\nDscho\n"},{"id":"393800","messageId":"20200323185021.GC45325@google.com","threadId":"52845","inReplyTo":"nycvar.QRO.7.76.6.2003201636040.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-03-23T18:50:21Z","receivedAt":"2020-03-23T18:50:31Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Fri, Mar 20, 2020 at 04:42:36PM +0100, Johannes Schindelin wrote:\n> Hi Emily,\n> \n> On Thu, 19 Mar 2020, Emily Shaffer wrote:\n> > I'll hold off on sharing my own preference until after we've got some\n> > benchmarking to look at, so I can understand the whole picture.\n> \n> Why? Why not strong-arm your preference? Junio and I are not shy doing the\n> same, and those are _your_ patches. Junio is clearly not interested in the\n> command at all, but you are clearly interested in it [*1*]. You should\n> have more than just the final say over this.\n\nWe are different people, and we approach problems and disagreements\ndifferently. I am almost never the type to strong-arm my preference; I'd\nrather listen to other arguments and look at data, which is why I\nproposed the experiments I mentioned here. As for you and Junio not\nbeing shy, as you put it, I found most of the discussion offputting, and\nthe tone used absolutely contributed to me finding other things to work\non instead of coming back to this minefield sooner.\n\n - Emily\n"},{"id":"393801","messageId":"20200323185203.GD45325@google.com","threadId":"52845","inReplyTo":"nycvar.QRO.7.76.6.2003201633560.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v9 2/5] bugreport: add tool to generate debugging info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-03-23T18:52:03Z","receivedAt":"2020-03-23T18:52:13Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Fri, Mar 20, 2020 at 04:35:45PM +0100, Johannes Schindelin wrote:\n> On Thu, 19 Mar 2020, Junio C Hamano wrote:\n> \n> > In any case, I think we've wasted enough time on this.  Let's see a\n> > minimum working version that won't break/affect the rest of Git and\n> > ship it standalone.\n> \n> I still disagree with that, but it seems that no amount of arguments will\n> convince Junio, and he's dead set on the standalone version.\n\nIn this case, I'll leave the build settings alone and focus on other\ncomments on this patch. Will try to work on it today.\n\n - Emily\n"},{"id":"393821","messageId":"xmqq4kue4vkx.fsf@gitster.c.googlers.com","threadId":"52845","inReplyTo":"20200302230400.107428-4-emilyshaffer@google.com","subject":"Re: [PATCH v9 3/5] bugreport: gather git version and build info","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-03-23T21:20:30Z","receivedAt":"2020-03-23T21:20:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> +The following information is captured automatically:\n> +\n> + - 'git version --build-options'\n\nGood.  \n\nDo make sure to give us the same information as if the end user\ntyped that command from the command line.  There may be more than\none directory on $PATH that has \"git\" in it; we want to see the one\nthat is giving trouble to the end user, not necessarily the one that\ncame from the same source as running \"git bugreport\" was compiled\nfrom, so it is a good idea not to rely on the contents of static\ngit_version_string[] array that came in libgit.a that the bugreport\ntool happened to be linked with.\n   \nIt may not be in the scope of this step, but we'd want to see\nversions of executables for the python interpreter (2vs3), the\ntcl/tk interpreter (i.e. wish), the shell (i.e. bash, dash, etc.).\n\nIn addition to them, we would want to see versions of some of our\nown binaries (i.e. \"git\", and transports that are separate\nexecutable files).  It would lead to a confusing diagnositic session\nif the end-user's PATH has /usr/bin and then $HOME/bin, and the\nend-user has a newer version of \"git\" with \"bugreport\" only in\n$HOME/bin.  The user may think s/he is using the latest\nself-compiled \"git\", and \"bugreport\" might even agree if it trusts\nanything determined when \"bugreport\" was compiled, but in reality\nthe version of \"git\" used largely was coming from \"/usr/bin\" except\nfor any new subcommands, or something silly like that, and asking\nthe environment just like the end user does is the only way to make\nsure we are getting the true piture.\n\nThanks.\n"},{"id":"393823","messageId":"20200323212753.GE45325@google.com","threadId":"52845","inReplyTo":"nycvar.QRO.7.76.6.2003042236060.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v9 5/5] bugreport: add compiler info","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2020-03-23T21:27:53Z","receivedAt":"2020-03-23T21:28:01Z","isPatch":true,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Wed, Mar 04, 2020 at 10:39:53PM +0100, Johannes Schindelin wrote:\n> Hi Emily,\n> \n> On Mon, 2 Mar 2020, Emily Shaffer wrote:\n> \n> > diff --git a/compat/compiler.h b/compat/compiler.h\n> > new file mode 100644\n> > index 0000000000..21f098e6a4\n> > --- /dev/null\n> > +++ b/compat/compiler.h\n> > @@ -0,0 +1,38 @@\n> > +#ifndef COMPILER_H\n> > +#define COMPILER_H\n> > +\n> > +#include \"git-compat-util.h\"\n> > +#include \"strbuf.h\"\n> > +\n> > +#ifdef __GLIBC__\n> > +#include <gnu/libc-version.h>\n> > +#endif\n> > +\n> > +static inline void get_compiler_info(struct strbuf *info)\n> > +{\n> > +\tint len = info->len;\n> > +#ifdef __GNUC__\n> > +\tstrbuf_addf(info, \"gnuc: %d.%d\\n\", __GNUC__, __GNUC_MINOR__);\n> > +#endif\n> > +\n> > +#ifdef _MSC_VER\n> > +\tstrbuf_addf(info, \"MSVC version: %s\\n\", _MSC_FULL_VER);\n> \n> I need this to fix a crash in the Visual Studio build's test run:\n\nHummm, is that not part of the GGG suite? I saw it pass (and then failed\nto include the updated patches with v9 with the changes you mentioned\nbelow).\n\n> \n> -- snip --\n> Subject: [PATCH] fixup??? bugreport: add compiler info\n> \n> As documented at\n> https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=vs-2019,\n> `_MSC_FULL_VER` is an integer, not a string. Therefore this fix is\n> needed to prevent a segmentation fault in the test t0091.1.\n> \n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  compat/compiler.h | 3 ++-\n>  1 file changed, 2 insertions(+), 1 deletion(-)\n> \n> diff --git a/compat/compiler.h b/compat/compiler.h\n> index ce6a7f6de9a..ac90fa051dd 100644\n> --- a/compat/compiler.h\n> +++ b/compat/compiler.h\n> @@ -16,7 +16,8 @@ static inline void get_compiler_info(struct strbuf *info)\n>  #endif\n> \n>  #ifdef _MSC_VER\n> -\tstrbuf_addf(info, \"MSVC version: %s\\n\", _MSC_FULL_VER);\n> +\tstrbuf_addf(info, \"MSVC version: %02d.%02d.%05d\\n\",\n> +\t\t    _MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 100000);\n>  #endif\n> \n>  \tif (len == info->len)\n> -- snap --\n> \n> Could you squash that in, please?\n> \n> BTW the two issues I reported in the earlier round are still problems.\n> Could you squash my fixes, please? For your convenience, you can pluck all\n> four of them right off of\n> https://github.com/git-for-windows/git/commits/shears/pu\n\nYes, I think these two issues earlier I have locally and thumbfingered\nrunning format-patch.\n\n> \n> Just replace the `???` by `!` and you can even use `git rebase\n> --autosquash`.\n> \n> Ciao,\n> Dscho\n> \n> \n> > +#endif\n> > +\n> > +\tif (len == info->len)\n> > +\t\tstrbuf_addf(info, _(\"no compiler information available\\n\"));\n> > +}\n> > +\n> > +static inline void get_libc_info(struct strbuf *info)\n> > +{\n> > +\tint len = info->len;\n> > +\n> > +#ifdef __GLIBC__\n> > +\tstrbuf_addf(info, \"glibc: %s\\n\", gnu_get_libc_version());\n> > +#endif\n> > +\n> > +\tif (len == info->len)\n> > +\t\tstrbuf_addf(info, _(\"no libc information available\\n\"));\n> > +}\n> > +\n> > +#endif /* COMPILER_H */\n> > --\n> > 2.25.0.265.gbab2e86ba0-goog\n> >\n> >\n"}]}