Skip to content

Commit c301beb

Browse files
committed
bugreport: summarize contents of alternates file
In some cases, it could be that the user is having a problem with an object which isn't present in their normal object directory. We can get a hint that that might be the case by examining the list of alternates where their object may be stored instead. Since paths to alternates may be sensitive, we'll instead count how many alternates have been specified and note how many of them exist or are broken. While object-cache.h describes a function "foreach_alt_odb()", this function does not provide information on broken alternates, which are skipped over in "link_alt_odb_entry()". Since the goal is to identify missing alternates, we can gather the contents of .git/objects/info/alternates manually. Signed-off-by: Emily Shaffer <[email protected]>
1 parent 239faf2 commit c301beb

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

Documentation/git-bugreport.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ The following information is captured automatically:
3535
- The number of loose objects in the repository
3636
- The number of packs and packed objects in the repository
3737
- A list of the contents of .git/objects/info (or equivalent)
38+
- The number of valid and invalid alternates
3839

3940
This tool is invoked via the typical Git setup process, which means that in some
4041
cases, it might not be able to launch - for example, if a relevant config file

bugreport.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,48 @@ static void get_object_info_summary(struct strbuf *obj_info, int nongit)
257257
strbuf_release(&dirpath);
258258
}
259259

260+
static void get_alternates_summary(struct strbuf *alternates_info, int nongit)
261+
{
262+
struct strbuf alternates_path = STRBUF_INIT;
263+
struct strbuf alternate = STRBUF_INIT;
264+
FILE *file;
265+
size_t exists = 0, broken = 0;
266+
267+
if (nongit) {
268+
strbuf_addstr(alternates_info,
269+
"not run from a git repository - alternates unavailable\n");
270+
return;
271+
}
272+
273+
strbuf_addstr(&alternates_path, get_object_directory());
274+
strbuf_complete(&alternates_path, '/');
275+
strbuf_addstr(&alternates_path, "info/alternates");
276+
277+
file = fopen(alternates_path.buf, "r");
278+
if (!file) {
279+
strbuf_addstr(alternates_info, "No alternates file found.\n");
280+
strbuf_release(&alternates_path);
281+
return;
282+
}
283+
284+
while (strbuf_getline(&alternate, file) != EOF) {
285+
if (!access(alternate.buf, F_OK))
286+
exists++;
287+
else
288+
broken++;
289+
}
290+
291+
strbuf_addf(alternates_info,
292+
"%zd alternates found (%zd working, %zd broken)\n",
293+
exists + broken,
294+
exists,
295+
broken);
296+
297+
fclose(file);
298+
strbuf_release(&alternate);
299+
strbuf_release(&alternates_path);
300+
}
301+
260302
static const char * const bugreport_usage[] = {
261303
N_("git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]"),
262304
NULL
@@ -352,6 +394,9 @@ int cmd_main(int argc, const char **argv)
352394
get_header(&buffer, "Object Info Summary");
353395
get_object_info_summary(&buffer, nongit_ok);
354396

397+
get_header(&buffer, "Alternates");
398+
get_alternates_summary(&buffer, nongit_ok);
399+
355400
/* fopen doesn't offer us an O_EXCL alternative, except with glibc. */
356401
report = open(report_path.buf, O_CREAT | O_EXCL | O_WRONLY, 0666);
357402

0 commit comments

Comments
 (0)