{"thread":{"id":"52521","subject":"Git Test Coverage Report (v2.25.0-rc0)","startedAt":"2019-12-26T17:19:31Z","lastAt":"2019-12-26T17:55:46Z","messageCount":2,"participants":["Derrick Stolee"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"388925","messageId":"02febb94-9749-c219-8fae-d109720f4c71@gmail.com","threadId":"52521","inReplyTo":null,"subject":"Git Test Coverage Report (v2.25.0-rc0)","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2019-12-26T17:19:24Z","receivedAt":"2019-12-26T17:19:31Z","isPatch":false,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"Here is the test-coverage report for v2.25.0-rc0 against v2.24.1.\n\nI've included the old version of the report because my build definition for\ngenerating a report from a single branch didn't create the commit-by-commit\nview correctly. Also, some of these are easier to see in-context with the\nother lines in the file.\n\nThanks,\n-Stolee\n\n--------------------------------------------------------\n\nadd-interactive.c\n1daaebca 13) static void init_color(struct repository *r, struct add_i_state *s,\n1daaebca 17) char *key = xstrfmt(\"color.interactive.%s\", slot_name);\n1daaebca 20) if (!s->use_color)\n1daaebca 21) dst[0] = '\\0';\n1daaebca 22) else if (repo_config_get_value(r, key, &value) ||\n1daaebca 23)  color_parse(value, dst))\n1daaebca 24) strlcpy(dst, default_color, COLOR_MAXLEN);\n1daaebca 26) free(key);\n1daaebca 27) }\n25ea47af 29) void init_add_i_state(struct add_i_state *s, struct repository *r)\n1daaebca 33) s->r = r;\n1daaebca 35) if (repo_config_get_value(r, \"color.interactive\", &value))\n1daaebca 36) s->use_color = -1;\n1daaebca 38) s->use_color =\n1daaebca 39) git_config_colorbool(\"color.interactive\", value);\n1daaebca 40) s->use_color = want_color(s->use_color);\n1daaebca 42) init_color(r, s, \"header\", s->header_color, GIT_COLOR_BOLD);\n68db1cbf 43) init_color(r, s, \"help\", s->help_color, GIT_COLOR_BOLD_RED);\n3d965c76 44) init_color(r, s, \"prompt\", s->prompt_color, GIT_COLOR_BOLD_BLUE);\n3d965c76 45) init_color(r, s, \"error\", s->error_color, GIT_COLOR_BOLD_RED);\n3d965c76 46) init_color(r, s, \"reset\", s->reset_color, GIT_COLOR_RESET);\n25ea47af 47) init_color(r, s, \"fraginfo\", s->fraginfo_color,\nbcdd297b 49) init_color(r, s, \"context\", s->context_color,\nbcdd297b 51) init_color(r, s, \"old\", s->file_old_color,\nbcdd297b 53) init_color(r, s, \"new\", s->file_new_color,\n5e82b9e4 55) }\n76b74323 82) static void prefix_item_list_clear(struct prefix_item_list *list)\n76b74323 84) string_list_clear(&list->items, 1);\n76b74323 85) string_list_clear(&list->sorted, 0);\nf37c2264 86) FREE_AND_NULL(list->selected);\n76b74323 87) }\n76b74323 89) static void extend_prefix_length(struct string_list_item *p,\n76b74323 92) size_t *len = p->util;\n76b74323 94) if (!*len || memcmp(p->string, other_string, *len))\n76b74323 95) return;\n76b74323 98) char c = p->string[*len];\n76b74323 106) if (!c || ++*len > max_length || !isascii(c)) {\n76b74323 107) *len = 0;\n76b74323 108) break;\n76b74323 111) if (c != other_string[*len - 1])\n76b74323 112) break;\n76b74323 113) }\n76b74323 116) static void find_unique_prefixes(struct prefix_item_list *list)\n76b74323 120) if (list->sorted.nr == list->items.nr)\n76b74323 121) return;\n76b74323 123) string_list_clear(&list->sorted, 0);\n76b74323 125) list->sorted.items = xmalloc(st_mult(sizeof(*list->sorted.items),\n76b74323 126)      list->items.nr));\n76b74323 127) list->sorted.nr = list->sorted.alloc = list->items.nr;\n76b74323 129) for (i = 0; i < list->items.nr; i++) {\n76b74323 130) list->sorted.items[i].string = list->items.items[i].string;\n76b74323 131) list->sorted.items[i].util = list->items.items + i;\n76b74323 134) string_list_sort(&list->sorted);\n76b74323 136) for (i = 0; i < list->sorted.nr; i++) {\n76b74323 137) struct string_list_item *sorted_item = list->sorted.items + i;\n76b74323 138) struct string_list_item *item = sorted_item->util;\n76b74323 139) size_t *len = item->util;\n76b74323 141) *len = 0;\n76b74323 142) while (*len < list->min_length) {\n76b74323 143) char c = item->string[(*len)++];\n76b74323 145) if (!c || !isascii(c)) {\n76b74323 146) *len = 0;\n76b74323 147) break;\n76b74323 151) if (i > 0)\n76b74323 152) extend_prefix_length(item, sorted_item[-1].string,\n76b74323 154) if (i + 1 < list->sorted.nr)\n76b74323 155) extend_prefix_length(item, sorted_item[1].string,\n76b74323 160) static ssize_t find_unique(const char *string, struct prefix_item_list *list)\n76b74323 162) int index = string_list_find_insert_index(&list->sorted, string, 1);\n76b74323 165) if (list->items.nr != list->sorted.nr)\n76b74323 170) if (index < 0)\n76b74323 171) item = list->sorted.items[-1 - index].util;\n76b74323 172) else if (index > 0 &&\n76b74323 173)  starts_with(list->sorted.items[index - 1].string, string))\n76b74323 174) return -1;\n76b74323 175) else if (index + 1 < list->sorted.nr &&\n76b74323 176)  starts_with(list->sorted.items[index + 1].string, string))\n76b74323 177) return -1;\n76b74323 178) else if (index < list->sorted.nr)\n76b74323 179) item = list->sorted.items[index].util;\n76b74323 181) return -1;\n76b74323 182) return item - list->items.items;\nf37c2264 193) static void list(struct add_i_state *s, struct string_list *list, int *selected,\n6348bfba 196) int i, last_lf = 0;\n5e82b9e4 198) if (!list->nr)\n5e82b9e4 199) return;\n5e82b9e4 201) if (opts->header)\n1daaebca 202) color_fprintf_ln(stdout, s->header_color,\n5e82b9e4 205) for (i = 0; i < list->nr; i++) {\nf37c2264 206) opts->print_item(i, selected ? selected[i] : 0, list->items + i,\n6348bfba 209) if ((opts->columns) && ((i + 1) % (opts->columns))) {\n6348bfba 210) putchar('\\t');\n6348bfba 211) last_lf = 0;\n6348bfba 214) putchar('\\n');\n6348bfba 215) last_lf = 1;\n6348bfba 219) if (!last_lf)\n5e82b9e4 220) putchar('\\n');\n76b74323 243) static ssize_t list_and_choose(struct add_i_state *s,\nf37c2264 247) int singleton = opts->flags & SINGLETON;\nf37c2264 248) int immediate = opts->flags & IMMEDIATE;\n6348bfba 250) struct strbuf input = STRBUF_INIT;\nf37c2264 251) ssize_t res = singleton ? LIST_AND_CHOOSE_ERROR : 0;\nf37c2264 253) if (!singleton) {\nf37c2264 254) free(items->selected);\nf37c2264 255) CALLOC_ARRAY(items->selected, items->items.nr);\nf37c2264 258) if (singleton && !immediate)\n76b74323 261) find_unique_prefixes(items);\n6348bfba 266) strbuf_reset(&input);\nf37c2264 268) list(s, &items->items, items->selected, &opts->list_opts);\n3d965c76 270) color_fprintf(stdout, s->prompt_color, \"%s\", opts->prompt);\nf37c2264 271) fputs(singleton ? \"> \" : \">> \", stdout);\n6348bfba 272) fflush(stdout);\n6348bfba 274) if (strbuf_getline(&input, stdin) == EOF) {\n6348bfba 275) putchar('\\n');\nf37c2264 276) if (immediate)\nf37c2264 277) res = LIST_AND_CHOOSE_QUIT;\n6348bfba 278) break;\n6348bfba 280) strbuf_trim(&input);\n6348bfba 282) if (!input.len)\n6348bfba 283) break;\n68db1cbf 285) if (!strcmp(input.buf, \"?\")) {\n68db1cbf 286) opts->print_help(s);\n68db1cbf 287) continue;\n6348bfba 290) p = input.buf;\n6348bfba 292) size_t sep = strcspn(p, \" \\t\\r\\n,\");\nf37c2264 293) int choose = 1;\nf37c2264 295) ssize_t from = -1, to = -1;\n6348bfba 297) if (!sep) {\n6348bfba 298) if (!*p)\n6348bfba 299) break;\n6348bfba 300) p++;\n6348bfba 301) continue;\nf37c2264 305) if (*p == '-') {\nf37c2264 306) choose = 0;\nf37c2264 307) p++;\nf37c2264 308) sep--;\nf37c2264 311) if (sep == 1 && *p == '*') {\nf37c2264 312) from = 0;\nf37c2264 313) to = items->items.nr;\nf37c2264 314) } else if (isdigit(*p)) {\nf37c2264 325) from = strtoul(p, &endp, 10) - 1;\nf37c2264 326) if (endp == p + sep)\nf37c2264 327) to = from + 1;\nf37c2264 328) else if (*endp == '-') {\nf37c2264 329) to = strtoul(++endp, &endp, 10);\nf37c2264 331) if (endp != p + sep)\nf37c2264 332) from = -1;\n6348bfba 336) if (p[sep])\n6348bfba 337) p[sep++] = '\\0';\nf37c2264 338) if (from < 0) {\nf37c2264 339) from = find_unique(p, items);\nf37c2264 340) if (from >= 0)\nf37c2264 341) to = from + 1;\nf37c2264 344) if (from < 0 || from >= items->items.nr ||\nf37c2264 345)     (singleton && from + 1 != to)) {\n3d965c76 346) color_fprintf_ln(stdout, s->error_color,\nf37c2264 348) break;\nf37c2264 349) } else if (singleton) {\nf37c2264 350) res = from;\n6348bfba 351) break;\nf37c2264 354) if (to > items->items.nr)\nf37c2264 355) to = items->items.nr;\nf37c2264 357) for (; from < to; from++)\nf37c2264 358) if (items->selected[from] != choose) {\nf37c2264 359) items->selected[from] = choose;\nf37c2264 360) res += choose ? +1 : -1;\n6348bfba 363) p += sep;\n6348bfba 364) }\nf37c2264 366) if ((immediate && res != LIST_AND_CHOOSE_ERROR) ||\nf37c2264 367)     !strcmp(input.buf, \"*\"))\n5e82b9e4 369) }\n6348bfba 371) strbuf_release(&input);\n6348bfba 372) return res;\n5e82b9e4 385) static void add_file_item(struct string_list *files, const char *name)\n5e82b9e4 387) struct file_item *item = xcalloc(sizeof(*item), 1);\n5e82b9e4 389) string_list_append(files, name)->util = item;\n5e82b9e4 390) }\n5e82b9e4 398) static int pathname_entry_cmp(const void *unused_cmp_data,\n5e82b9e4 403) const struct pathname_entry *e1 =\n5e82b9e4 405) const struct pathname_entry *e2 =\n5e82b9e4 408) return strcmp(e1->name, name ? (const char *)name : e2->name);\n5e82b9e4 422) static void collect_changes_cb(struct diff_queue_struct *q,\n5e82b9e4 426) struct collection_status *s = data;\n5e82b9e4 427) struct diffstat_t stat = { 0 };\n5e82b9e4 430) if (!q->nr)\n5e82b9e4 431) return;\n5e82b9e4 433) compute_diffstat(options, &stat, q);\n5e82b9e4 435) for (i = 0; i < stat.nr; i++) {\n5e82b9e4 436) const char *name = stat.files[i]->name;\n5e82b9e4 437) int hash = strhash(name);\n5e82b9e4 442) entry = hashmap_get_entry_from_hash(&s->file_map, hash, name,\n5e82b9e4 444) if (!entry) {\nc08171d1 445) if (s->skip_unseen)\nc08171d1 446) continue;\n5e82b9e4 448) add_file_item(s->files, name);\n5e82b9e4 450) entry = xcalloc(sizeof(*entry), 1);\n5e82b9e4 451) hashmap_entry_init(&entry->ent, hash);\n5e82b9e4 452) entry->name = s->files->items[s->files->nr - 1].string;\n5e82b9e4 453) entry->item = s->files->items[s->files->nr - 1].util;\n5e82b9e4 454) hashmap_add(&s->file_map, &entry->ent);\n5e82b9e4 457) file_item = entry->item;\nc08171d1 458) adddel = s->mode == FROM_INDEX ?\n5e82b9e4 459) &file_item->index : &file_item->worktree;\n8746e072 460) other_adddel = s->mode == FROM_INDEX ?\n8746e072 461) &file_item->worktree : &file_item->index;\n5e82b9e4 462) adddel->seen = 1;\n5e82b9e4 463) adddel->add = stat.files[i]->added;\n5e82b9e4 464) adddel->del = stat.files[i]->deleted;\n8746e072 465) if (stat.files[i]->is_binary) {\n8746e072 466) if (!other_adddel->binary)\n8746e072 467) s->binary_count++;\n5e82b9e4 468) adddel->binary = 1;\n8746e072 470) if (stat.files[i]->is_unmerged) {\n8746e072 471) if (!other_adddel->unmerged)\n8746e072 472) s->unmerged_count++;\n8746e072 473) adddel->unmerged = 1;\n5e82b9e4 476) free_diffstat_info(&stat);\nc08171d1 485) static int get_modified_files(struct repository *r,\n5e82b9e4 493) int is_initial = !resolve_ref_unsafe(\"HEAD\", RESOLVE_REF_READING,\nc08171d1 495) struct collection_status s = { 0 };\n5e82b9e4 498) if (discard_index(r->index) < 0 ||\n5e82b9e4 499)     repo_read_index_preload(r, ps, 0) < 0)\na8c45be9 502) prefix_item_list_clear(files);\na8c45be9 503) s.files = &files->items;\n5e82b9e4 504) hashmap_init(&s.file_map, pathname_entry_cmp, NULL, 0);\nc08171d1 506) for (i = 0; i < 2; i++) {\n5e82b9e4 508) struct setup_revision_opt opt = { 0 };\nc08171d1 510) if (filter == INDEX_ONLY)\nc08171d1 511) s.mode = (i == 0) ? FROM_INDEX : FROM_WORKTREE;\nc08171d1 513) s.mode = (i == 0) ? FROM_WORKTREE : FROM_INDEX;\nc08171d1 514) s.skip_unseen = filter && i;\n5e82b9e4 516) opt.def = is_initial ?\n5e82b9e4 517) empty_tree_oid_hex() : oid_to_hex(&head_oid);\n5e82b9e4 519) init_revisions(&rev, NULL);\n5e82b9e4 520) setup_revisions(0, NULL, &rev, &opt);\n5e82b9e4 522) rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;\n5e82b9e4 523) rev.diffopt.format_callback = collect_changes_cb;\n5e82b9e4 524) rev.diffopt.format_callback_data = &s;\n5e82b9e4 526) if (ps)\n5e82b9e4 527) copy_pathspec(&rev.prune_data, ps);\nc08171d1 529) if (s.mode == FROM_INDEX)\n5e82b9e4 530) run_diff_index(&rev, 1);\n5e82b9e4 532) rev.diffopt.flags.ignore_dirty_submodules = 1;\n5e82b9e4 533) run_diff_files(&rev, 0);\n0c3944a6 536) if (ps)\n0c3944a6 537) clear_pathspec(&rev.prune_data);\n5e82b9e4 539) hashmap_free_entries(&s.file_map, struct pathname_entry, ent);\n8746e072 540) if (unmerged_count)\n8746e072 541) *unmerged_count = s.unmerged_count;\n8746e072 542) if (binary_count)\n8746e072 543) *binary_count = s.binary_count;\na8c45be9 546) string_list_sort(&files->items);\n5e82b9e4 548) return 0;\n5e82b9e4 551) static void render_adddel(struct strbuf *buf,\n5e82b9e4 554) if (ad->binary)\n5e82b9e4 555) strbuf_addstr(buf, _(\"binary\"));\n5e82b9e4 556) else if (ad->seen)\n5e82b9e4 557) strbuf_addf(buf, \"+%\"PRIuMAX\"/-%\"PRIuMAX,\n5e82b9e4 558)     (uintmax_t)ad->add, (uintmax_t)ad->del);\n5e82b9e4 560) strbuf_addstr(buf, no_changes);\n5e82b9e4 561) }\n76b74323 564) static int is_valid_prefix(const char *prefix, size_t prefix_len)\n76b74323 566) return prefix_len && prefix &&\n76b74323 572) strcspn(prefix, \" \\t\\r\\n,\") >= prefix_len &&\t/* separators */\n76b74323 573) *prefix != '-' &&\t\t\t\t/* deselection */\n76b74323 574) !isdigit(*prefix) &&\t\t\t\t/* selection */\n76b74323 575) (prefix_len != 1 ||\n76b74323 576)  (*prefix != '*' &&\t\t\t\t/* \"all\" wildcard */\n76b74323 577)   *prefix != '?'));\t\t\t\t/* prompt help */\nf37c2264 586) static void print_file_item(int i, int selected, struct string_list_item *item,\n5e82b9e4 589) struct file_item *c = item->util;\n5e82b9e4 590) struct print_file_item_data *d = print_file_item_data;\na8c45be9 591) const char *highlighted = NULL;\n5e82b9e4 593) strbuf_reset(&d->index);\n5e82b9e4 594) strbuf_reset(&d->worktree);\n5e82b9e4 595) strbuf_reset(&d->buf);\na8c45be9 598) if (c->prefix_length > 0 &&\na8c45be9 599)     is_valid_prefix(item->string, c->prefix_length)) {\na8c45be9 600) strbuf_reset(&d->name);\na8c45be9 601) strbuf_addf(&d->name, \"%s%.*s%s%s\", d->color,\na8c45be9 602)     (int)c->prefix_length, item->string, d->reset,\na8c45be9 603)     item->string + c->prefix_length);\na8c45be9 604) highlighted = d->name.buf;\nab1e1ccc 607) if (d->only_names) {\nab1e1ccc 608) printf(\"%c%2d: %s\", selected ? '*' : ' ', i + 1,\nab1e1ccc 610) return;\n5e82b9e4 613) render_adddel(&d->worktree, &c->worktree, _(\"nothing\"));\n5e82b9e4 614) render_adddel(&d->index, &c->index, _(\"unchanged\"));\na8c45be9 616) strbuf_addf(&d->buf, d->modified_fmt, d->index.buf, d->worktree.buf,\nf37c2264 619) printf(\"%c%2d: %s\", selected ? '*' : ' ', i + 1, d->buf.buf);\n5e82b9e4 622) static int run_status(struct add_i_state *s, const struct pathspec *ps,\n8746e072 626) if (get_modified_files(s->r, NO_FILTER, files, ps, NULL, NULL) < 0)\n5e82b9e4 627) return -1;\na8c45be9 629) list(s, &files->items, NULL, &opts->list_opts);\n5e82b9e4 630) putchar('\\n');\n5e82b9e4 632) return 0;\na8c45be9 635) static int run_update(struct add_i_state *s, const struct pathspec *ps,\na8c45be9 639) int res = 0, fd;\n8746e072 643) if (get_modified_files(s->r, WORKTREE_ONLY, files, ps, NULL, NULL) < 0)\na8c45be9 644) return -1;\na8c45be9 646) if (!files->items.nr) {\na8c45be9 647) putchar('\\n');\na8c45be9 648) return 0;\na8c45be9 651) opts->prompt = N_(\"Update\");\na8c45be9 652) count = list_and_choose(s, files, opts);\na8c45be9 653) if (count <= 0) {\na8c45be9 654) putchar('\\n');\na8c45be9 655) return 0;\na8c45be9 658) fd = repo_hold_locked_index(s->r, &index_lock, LOCK_REPORT_ON_ERROR);\na8c45be9 659) if (fd < 0) {\na8c45be9 660) putchar('\\n');\na8c45be9 661) return -1;\na8c45be9 664) for (i = 0; i < files->items.nr; i++) {\na8c45be9 665) const char *name = files->items.items[i].string;\na8c45be9 666) if (files->selected[i] &&\na8c45be9 667)     add_file_to_index(s->r->index, name, 0) < 0) {\na8c45be9 669) break;\na8c45be9 673) if (!res && write_locked_index(s->r->index, &index_lock, COMMIT_LOCK) < 0)\na8c45be9 676) if (!res)\na8c45be9 677) printf(Q_(\"updated %d path\\n\",\na8c45be9 680) putchar('\\n');\na8c45be9 681) return res;\nc54ef5e4 684) static void revert_from_diff(struct diff_queue_struct *q,\nc54ef5e4 687) int i, add_flags = ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE;\nc54ef5e4 689) for (i = 0; i < q->nr; i++) {\nc54ef5e4 690) struct diff_filespec *one = q->queue[i]->one;\nc54ef5e4 693) if (!(one->mode && !is_null_oid(&one->oid))) {\nc54ef5e4 694) remove_file_from_index(opt->repo->index, one->path);\nc54ef5e4 695) printf(_(\"note: %s is untracked now.\\n\"), one->path);\nc54ef5e4 697) ce = make_cache_entry(opt->repo->index, one->mode,\nc54ef5e4 698)       &one->oid, one->path, 0, 0);\nc54ef5e4 699) if (!ce)\nc54ef5e4 702) add_index_entry(opt->repo->index, ce, add_flags);\nc54ef5e4 705) }\nc54ef5e4 707) static int run_revert(struct add_i_state *s, const struct pathspec *ps,\nc54ef5e4 711) int res = 0, fd;\nc54ef5e4 715) int is_initial = !resolve_ref_unsafe(\"HEAD\", RESOLVE_REF_READING, &oid,\nc54ef5e4 720) struct diff_options diffopt = { NULL };\n8746e072 722) if (get_modified_files(s->r, INDEX_ONLY, files, ps, NULL, NULL) < 0)\nc54ef5e4 723) return -1;\nc54ef5e4 725) if (!files->items.nr) {\nc54ef5e4 726) putchar('\\n');\nc54ef5e4 727) return 0;\nc54ef5e4 730) opts->prompt = N_(\"Revert\");\nc54ef5e4 731) count = list_and_choose(s, files, opts);\nc54ef5e4 732) if (count <= 0)\nc54ef5e4 733) goto finish_revert;\nc54ef5e4 735) fd = repo_hold_locked_index(s->r, &index_lock, LOCK_REPORT_ON_ERROR);\nc54ef5e4 736) if (fd < 0) {\nc54ef5e4 737) res = -1;\nc54ef5e4 738) goto finish_revert;\nc54ef5e4 741) if (is_initial)\nc54ef5e4 742) oidcpy(&oid, s->r->hash_algo->empty_tree);\nc54ef5e4 744) tree = parse_tree_indirect(&oid);\nc54ef5e4 745) if (!tree) {\nc54ef5e4 747) goto finish_revert;\nc54ef5e4 749) oidcpy(&oid, &tree->object.oid);\nc54ef5e4 752) ALLOC_ARRAY(paths, count + 1);\nc54ef5e4 753) for (i = j = 0; i < files->items.nr; i++)\nc54ef5e4 754) if (files->selected[i])\nc54ef5e4 755) paths[j++] = files->items.items[i].string;\nc54ef5e4 756) paths[j] = NULL;\nc54ef5e4 758) parse_pathspec(&diffopt.pathspec, 0,\nc54ef5e4 762) diffopt.output_format = DIFF_FORMAT_CALLBACK;\nc54ef5e4 763) diffopt.format_callback = revert_from_diff;\nc54ef5e4 764) diffopt.flags.override_submodule_config = 1;\nc54ef5e4 765) diffopt.repo = s->r;\nc54ef5e4 767) if (do_diff_cache(&oid, &diffopt))\nc54ef5e4 768) res = -1;\nc54ef5e4 770) diffcore_std(&diffopt);\nc54ef5e4 771) diff_flush(&diffopt);\nc54ef5e4 773) free(paths);\nc54ef5e4 774) clear_pathspec(&diffopt.pathspec);\nc54ef5e4 776) if (!res && write_locked_index(s->r->index, &index_lock,\nc54ef5e4 778) res = -1;\nc54ef5e4 780) res = repo_refresh_and_write_index(s->r, REFRESH_QUIET, 0, 1,\nc54ef5e4 783) if (!res)\nc54ef5e4 784) printf(Q_(\"reverted %d path\\n\",\nc54ef5e4 788) putchar('\\n');\nc54ef5e4 789) return res;\nab1e1ccc 792) static int get_untracked_files(struct repository *r,\nab1e1ccc 796) struct dir_struct dir = { 0 };\nab1e1ccc 798) struct strbuf buf = STRBUF_INIT;\nab1e1ccc 800) if (repo_read_index(r) < 0)\nab1e1ccc 803) prefix_item_list_clear(files);\nab1e1ccc 804) setup_standard_excludes(&dir);\nab1e1ccc 805) add_pattern_list(&dir, EXC_CMDL, \"--exclude option\");\nab1e1ccc 806) fill_directory(&dir, r->index, ps);\nab1e1ccc 808) for (i = 0; i < dir.nr; i++) {\nab1e1ccc 809) struct dir_entry *ent = dir.entries[i];\nab1e1ccc 811) if (index_name_is_other(r->index, ent->name, ent->len)) {\nab1e1ccc 812) strbuf_reset(&buf);\nab1e1ccc 813) strbuf_add(&buf, ent->name, ent->len);\nab1e1ccc 814) add_file_item(&files->items, buf.buf);\nab1e1ccc 818) strbuf_release(&buf);\nab1e1ccc 819) return 0;\nab1e1ccc 822) static int run_add_untracked(struct add_i_state *s, const struct pathspec *ps,\nab1e1ccc 826) struct print_file_item_data *d = opts->list_opts.print_item_data;\nab1e1ccc 827) int res = 0, fd;\nab1e1ccc 831) if (get_untracked_files(s->r, files, ps) < 0)\nab1e1ccc 832) return -1;\nab1e1ccc 834) if (!files->items.nr) {\nab1e1ccc 835) printf(_(\"No untracked files.\\n\"));\nab1e1ccc 836) goto finish_add_untracked;\nab1e1ccc 839) opts->prompt = N_(\"Add untracked\");\nab1e1ccc 840) d->only_names = 1;\nab1e1ccc 841) count = list_and_choose(s, files, opts);\nab1e1ccc 842) d->only_names = 0;\nab1e1ccc 843) if (count <= 0)\nab1e1ccc 844) goto finish_add_untracked;\nab1e1ccc 846) fd = repo_hold_locked_index(s->r, &index_lock, LOCK_REPORT_ON_ERROR);\nab1e1ccc 847) if (fd < 0) {\nab1e1ccc 848) res = -1;\nab1e1ccc 849) goto finish_add_untracked;\nab1e1ccc 852) for (i = 0; i < files->items.nr; i++) {\nab1e1ccc 853) const char *name = files->items.items[i].string;\nab1e1ccc 854) if (files->selected[i] &&\nab1e1ccc 855)     add_file_to_index(s->r->index, name, 0) < 0) {\nab1e1ccc 857) break;\nab1e1ccc 861) if (!res &&\nab1e1ccc 862)     write_locked_index(s->r->index, &index_lock, COMMIT_LOCK) < 0)\nab1e1ccc 865) if (!res)\nab1e1ccc 866) printf(Q_(\"added %d path\\n\",\nab1e1ccc 870) putchar('\\n');\nab1e1ccc 871) return res;\n8746e072 874) static int run_patch(struct add_i_state *s, const struct pathspec *ps,\n8746e072 878) int res = 0;\n8746e072 880) size_t unmerged_count = 0, binary_count = 0;\n8746e072 882) if (get_modified_files(s->r, WORKTREE_ONLY, files, ps,\n8746e072 884) return -1;\n8746e072 886) if (unmerged_count || binary_count) {\n8746e072 887) for (i = j = 0; i < files->items.nr; i++) {\n8746e072 888) struct file_item *item = files->items.items[i].util;\n8746e072 890) if (item->index.binary || item->worktree.binary) {\n8746e072 891) free(item);\n8746e072 892) free(files->items.items[i].string);\n8746e072 893) } else if (item->index.unmerged ||\n8746e072 895) color_fprintf_ln(stderr, s->error_color,\n8746e072 897)  files->items.items[i].string);\n8746e072 898) free(item);\n8746e072 899) free(files->items.items[i].string);\n8746e072 901) files->items.items[j++] = files->items.items[i];\n8746e072 903) files->items.nr = j;\n8746e072 906) if (!files->items.nr) {\n8746e072 907) if (binary_count)\n8746e072 908) fprintf(stderr, _(\"Only binary files changed.\\n\"));\n8746e072 910) fprintf(stderr, _(\"No changes.\\n\"));\n8746e072 911) return 0;\n8746e072 914) opts->prompt = N_(\"Patch update\");\n8746e072 915) count = list_and_choose(s, files, opts);\n8746e072 916) if (count >= 0) {\n8746e072 917) struct argv_array args = ARGV_ARRAY_INIT;\n1942ee44 918) struct pathspec ps_selected = { 0 };\n8746e072 920) for (i = 0; i < files->items.nr; i++)\n8746e072 921) if (files->selected[i])\n8746e072 922) argv_array_push(&args,\n8746e072 923) files->items.items[i].string);\n1942ee44 924) parse_pathspec(&ps_selected,\n1942ee44 927) res = run_add_p(s->r, &ps_selected);\n8746e072 928) argv_array_clear(&args);\n1942ee44 929) clear_pathspec(&ps_selected);\n8746e072 932) return res;\nd7633578 935) static int run_diff(struct add_i_state *s, const struct pathspec *ps,\nd7633578 939) int res = 0;\nd7633578 943) int is_initial = !resolve_ref_unsafe(\"HEAD\", RESOLVE_REF_READING, &oid,\nd7633578 945) if (get_modified_files(s->r, INDEX_ONLY, files, ps, NULL, NULL) < 0)\nd7633578 946) return -1;\nd7633578 948) if (!files->items.nr) {\nd7633578 949) putchar('\\n');\nd7633578 950) return 0;\nd7633578 953) opts->prompt = N_(\"Review diff\");\nd7633578 954) opts->flags = IMMEDIATE;\nd7633578 955) count = list_and_choose(s, files, opts);\nd7633578 956) opts->flags = 0;\nd7633578 957) if (count >= 0) {\nd7633578 958) struct argv_array args = ARGV_ARRAY_INIT;\nd7633578 960) argv_array_pushl(&args, \"git\", \"diff\", \"-p\", \"--cached\",\nd7633578 962)     s->r->hash_algo->empty_tree),\nd7633578 964) for (i = 0; i < files->items.nr; i++)\nd7633578 965) if (files->selected[i])\nd7633578 966) argv_array_push(&args,\nd7633578 967) files->items.items[i].string);\nd7633578 968) res = run_command_v_opt(args.argv, 0);\nd7633578 969) argv_array_clear(&args);\nd7633578 972) putchar('\\n');\nd7633578 973) return res;\n8c159044 976) static int run_help(struct add_i_state *s, const struct pathspec *unused_ps,\n8c159044 980) color_fprintf_ln(stdout, s->help_color, \"status        - %s\",\n8c159044 982) color_fprintf_ln(stdout, s->help_color, \"update        - %s\",\n8c159044 984) color_fprintf_ln(stdout, s->help_color, \"revert        - %s\",\n8c159044 986) color_fprintf_ln(stdout, s->help_color, \"patch         - %s\",\n8c159044 988) color_fprintf_ln(stdout, s->help_color, \"diff          - %s\",\n8c159044 990) color_fprintf_ln(stdout, s->help_color, \"add untracked - %s\",\n8c159044 993) return 0;\na8c45be9 996) static void choose_prompt_help(struct add_i_state *s)\na8c45be9 998) color_fprintf_ln(stdout, s->help_color, \"%s\",\na8c45be9 1000) color_fprintf_ln(stdout, s->help_color, \"1          - %s\",\na8c45be9 1002) color_fprintf_ln(stdout, s->help_color, \"3-5        - %s\",\na8c45be9 1004) color_fprintf_ln(stdout, s->help_color, \"2-3,6-9    - %s\",\na8c45be9 1006) color_fprintf_ln(stdout, s->help_color, \"foo        - %s\",\na8c45be9 1008) color_fprintf_ln(stdout, s->help_color, \"-...       - %s\",\na8c45be9 1010) color_fprintf_ln(stdout, s->help_color, \"*          - %s\",\na8c45be9 1012) color_fprintf_ln(stdout, s->help_color, \"           - %s\",\na8c45be9 1014) }\nf37c2264 1029) static void print_command_item(int i, int selected,\n3d965c76 1033) struct print_command_item_data *d = print_command_item_data;\n76b74323 1034) struct command_item *util = item->util;\n76b74323 1036) if (!util->prefix_length ||\n76b74323 1037)     !is_valid_prefix(item->string, util->prefix_length))\n76b74323 1038) printf(\" %2d: %s\", i + 1, item->string);\n3d965c76 1040) printf(\" %2d: %s%.*s%s%s\", i + 1,\n3d965c76 1041)        d->color, (int)util->prefix_length, item->string,\n3d965c76 1042)        d->reset, item->string + util->prefix_length);\n6348bfba 1043) }\n68db1cbf 1045) static void command_prompt_help(struct add_i_state *s)\n68db1cbf 1047) const char *help_color = s->help_color;\n68db1cbf 1048) color_fprintf_ln(stdout, help_color, \"%s\", _(\"Prompt help:\"));\n68db1cbf 1049) color_fprintf_ln(stdout, help_color, \"1          - %s\",\n68db1cbf 1051) color_fprintf_ln(stdout, help_color, \"foo        - %s\",\n68db1cbf 1053) color_fprintf_ln(stdout, help_color, \"           - %s\",\n68db1cbf 1055) }\nf83dff60 1057) int run_add_i(struct repository *r, const struct pathspec *ps)\n5e82b9e4 1059) struct add_i_state s = { NULL };\n3d965c76 1060) struct print_command_item_data data = { \"[\", \"]\" };\n6348bfba 1061) struct list_and_choose_options main_loop_opts = {\n6348bfba 1068) } command_list[] = {\n76b74323 1078) struct prefix_item_list commands = PREFIX_ITEM_LIST_INIT;\n5e82b9e4 1080) struct print_file_item_data print_file_item_data = {\na8c45be9 1084) struct list_and_choose_options opts = {\n5e82b9e4 1088) struct strbuf header = STRBUF_INIT;\na8c45be9 1089) struct prefix_item_list files = PREFIX_ITEM_LIST_INIT;\n5e82b9e4 1091) int res = 0;\n76b74323 1093) for (i = 0; i < ARRAY_SIZE(command_list); i++) {\n76b74323 1094) struct command_item *util = xcalloc(sizeof(*util), 1);\n76b74323 1095) util->command = command_list[i].command;\n76b74323 1096) string_list_append(&commands.items, command_list[i].string)\n76b74323 1097) ->util = util;\n5e82b9e4 1100) init_add_i_state(&s, r);\n3d965c76 1106) if (s.use_color) {\n3d965c76 1107) data.color = s.prompt_color;\n3d965c76 1108) data.reset = s.reset_color;\na8c45be9 1110) print_file_item_data.color = data.color;\na8c45be9 1111) print_file_item_data.reset = data.reset;\n5e82b9e4 1113) strbuf_addstr(&header, \"      \");\n5e82b9e4 1114) strbuf_addf(&header, print_file_item_data.modified_fmt,\na8c45be9 1116) opts.list_opts.header = header.buf;\n5e82b9e4 1118) if (discard_index(r->index) < 0 ||\n5e82b9e4 1119)     repo_read_index(r) < 0 ||\n5e82b9e4 1120)     repo_refresh_and_write_index(r, REFRESH_QUIET, 0, 1,\n5e82b9e4 1124) res = run_status(&s, ps, &files, &opts);\n6348bfba 1129) i = list_and_choose(&s, &commands, &main_loop_opts);\n2e697ced 1130) if (i < 0 || i >= commands.items.nr)\n2e697ced 1131) util = NULL;\n2e697ced 1133) util = commands.items.items[i].util;\n2e697ced 1135) if (i == LIST_AND_CHOOSE_QUIT || (util && !util->command)) {\n6348bfba 1136) printf(_(\"Bye.\\n\"));\n6348bfba 1137) res = 0;\n6348bfba 1138) break;\n2e697ced 1141) if (util)\n76b74323 1142) res = util->command(&s, ps, &files, &opts);\n6348bfba 1143) }\na8c45be9 1145) prefix_item_list_clear(&files);\n5e82b9e4 1146) strbuf_release(&print_file_item_data.buf);\na8c45be9 1147) strbuf_release(&print_file_item_data.name);\n5e82b9e4 1148) strbuf_release(&print_file_item_data.index);\n5e82b9e4 1149) strbuf_release(&print_file_item_data.worktree);\n5e82b9e4 1150) strbuf_release(&header);\n76b74323 1151) prefix_item_list_clear(&commands);\n5e82b9e4 1153) return res;\n\nadd-patch.c\n7584dd3c 52) static void err(struct add_p_state *s, const char *fmt, ...)\n7584dd3c 56) va_start(args, fmt);\n7584dd3c 57) fputs(s->s.error_color, stderr);\n7584dd3c 58) vfprintf(stderr, fmt, args);\n7584dd3c 59) fputs(s->s.reset_color, stderr);\n7584dd3c 60) fputc('\\n', stderr);\n7584dd3c 61) va_end(args);\n7584dd3c 62) }\nf6aa7ecc 64) static void setup_child_process(struct add_p_state *s,\nf6aa7ecc 70) va_start(ap, cp);\nf6aa7ecc 71) while ((arg = va_arg(ap, const char *)))\nf6aa7ecc 72) argv_array_push(&cp->args, arg);\nf6aa7ecc 73) va_end(ap);\nf6aa7ecc 75) cp->git_cmd = 1;\nf6aa7ecc 76) argv_array_pushf(&cp->env_array,\n25ea47af 77)  INDEX_ENVIRONMENT \"=%s\", s->s.r->index_file);\n25ea47af 78) }\n25ea47af 80) static int parse_range(const char **p,\n25ea47af 85) *offset = strtoul(*p, &pend, 10);\n25ea47af 86) if (pend == *p)\n25ea47af 87) return -1;\n25ea47af 88) if (*pend != ',') {\n25ea47af 89) *count = 1;\n25ea47af 90) *p = pend;\n25ea47af 91) return 0;\n25ea47af 93) *count = strtoul(pend + 1, (char **)p, 10);\n25ea47af 94) return *p == pend + 1 ? -1 : 0;\n25ea47af 97) static int parse_hunk_header(struct add_p_state *s, struct hunk *hunk)\n25ea47af 99) struct hunk_header *header = &hunk->header;\n25ea47af 100) const char *line = s->plain.buf + hunk->start, *p = line;\n25ea47af 101) char *eol = memchr(p, '\\n', s->plain.len - hunk->start);\n25ea47af 103) if (!eol)\n25ea47af 104) eol = s->plain.buf + s->plain.len;\n25ea47af 106) if (!skip_prefix(p, \"@@ -\", &p) ||\n25ea47af 107)     parse_range(&p, &header->old_offset, &header->old_count) < 0 ||\n25ea47af 108)     !skip_prefix(p, \" +\", &p) ||\n25ea47af 109)     parse_range(&p, &header->new_offset, &header->new_count) < 0 ||\n25ea47af 110)     !skip_prefix(p, \" @@\", &p))\n25ea47af 114) hunk->start = eol - s->plain.buf + (*eol == '\\n');\n25ea47af 115) header->extra_start = p - s->plain.buf;\n25ea47af 116) header->extra_end = hunk->start;\n25ea47af 118) if (!s->colored.len) {\n25ea47af 119) header->colored_extra_start = header->colored_extra_end = 0;\n25ea47af 120) return 0;\n25ea47af 124) line = s->colored.buf + hunk->colored_start;\n25ea47af 125) eol = memchr(line, '\\n', s->colored.len - hunk->colored_start);\n25ea47af 126) if (!eol)\n25ea47af 127) eol = s->colored.buf + s->colored.len;\n25ea47af 128) p = memmem(line, eol - line, \"@@ -\", 4);\n25ea47af 129) if (!p)\n25ea47af 132) p = memmem(p + 4, eol - p - 4, \" @@\", 3);\n25ea47af 133) if (!p)\n25ea47af 136) hunk->colored_start = eol - s->colored.buf + (*eol == '\\n');\n25ea47af 137) header->colored_extra_start = p + 3 - s->colored.buf;\n25ea47af 138) header->colored_extra_end = hunk->colored_start;\n25ea47af 140) return 0;\n5906d5de 143) static int is_octal(const char *p, size_t len)\n5906d5de 145) if (!len)\n5906d5de 146) return 0;\n5906d5de 148) while (len--)\n5906d5de 149) if (*p < '0' || *(p++) > '7')\n5906d5de 150) return 0;\n5906d5de 151) return 1;\nf6aa7ecc 154) static int parse_diff(struct add_p_state *s, const struct pathspec *ps)\ne3bd11b4 156) struct argv_array args = ARGV_ARRAY_INIT;\ne3bd11b4 157) struct strbuf *plain = &s->plain, *colored = NULL;\nf6aa7ecc 158) struct child_process cp = CHILD_PROCESS_INIT;\n510aeca1 159) char *p, *pend, *colored_p = NULL, *colored_pend = NULL, marker = '\\0';\n80399aec 160) size_t file_diff_alloc = 0, i, color_arg_index;\n80399aec 161) struct file_diff *file_diff = NULL;\nf6aa7ecc 162) struct hunk *hunk = NULL;\ne3bd11b4 166) argv_array_pushl(&args, \"diff-files\", \"-p\", \"--no-color\", \"--\", NULL);\ne3bd11b4 167) color_arg_index = args.argc - 2;\nf6aa7ecc 168) for (i = 0; i < ps->nr; i++)\ne3bd11b4 169) argv_array_push(&args, ps->items[i].original);\ne3bd11b4 171) setup_child_process(s, &cp, NULL);\ne3bd11b4 172) cp.argv = args.argv;\nf6aa7ecc 173) res = capture_command(&cp, plain, 0);\ne3bd11b4 174) if (res) {\ne3bd11b4 175) argv_array_clear(&args);\ne3bd11b4 178) if (!plain->len) {\ne3bd11b4 179) argv_array_clear(&args);\nf6aa7ecc 180) return 0;\nf6aa7ecc 182) strbuf_complete_line(plain);\ne3bd11b4 184) if (want_color_fd(1, -1)) {\ne3bd11b4 185) struct child_process colored_cp = CHILD_PROCESS_INIT;\ne3bd11b4 187) setup_child_process(s, &colored_cp, NULL);\ne3bd11b4 188) xsnprintf((char *)args.argv[color_arg_index], 8, \"--color\");\ne3bd11b4 189) colored_cp.argv = args.argv;\ne3bd11b4 190) colored = &s->colored;\ne3bd11b4 191) res = capture_command(&colored_cp, colored, 0);\ne3bd11b4 192) argv_array_clear(&args);\ne3bd11b4 193) if (res)\ne3bd11b4 195) strbuf_complete_line(colored);\ne3bd11b4 196) colored_p = colored->buf;\ne3bd11b4 197) colored_pend = colored_p + colored->len;\ne3bd11b4 199) argv_array_clear(&args);\nf6aa7ecc 202) p = plain->buf;\nf6aa7ecc 203) pend = p + plain->len;\nf6aa7ecc 204) while (p != pend) {\nf6aa7ecc 205) char *eol = memchr(p, '\\n', pend - p);\n5906d5de 206) const char *deleted = NULL, *mode_change = NULL;\nf6aa7ecc 208) if (!eol)\nf6aa7ecc 209) eol = pend;\nf6aa7ecc 211) if (starts_with(p, \"diff \")) {\n80399aec 212) s->file_diff_nr++;\n80399aec 213) ALLOC_GROW(s->file_diff, s->file_diff_nr,\n80399aec 215) file_diff = s->file_diff + s->file_diff_nr - 1;\n80399aec 216) memset(file_diff, 0, sizeof(*file_diff));\n80399aec 217) hunk = &file_diff->head;\n80399aec 218) hunk->start = p - plain->buf;\n80399aec 219) if (colored_p)\n80399aec 220) hunk->colored_start = colored_p - colored->buf;\n510aeca1 221) marker = '\\0';\nf6aa7ecc 222) } else if (p == plain->buf)\n47dc4fd5 225) else if (file_diff->deleted)\n47dc4fd5 227) else if (starts_with(p, \"@@ \") ||\n47dc4fd5 228)  (hunk == &file_diff->head &&\n47dc4fd5 229)   skip_prefix(p, \"deleted file\", &deleted))) {\n510aeca1 230) if (marker == '-' || marker == '+')\n510aeca1 235) hunk->splittable_into++;\n80399aec 237) file_diff->hunk_nr++;\n80399aec 238) ALLOC_GROW(file_diff->hunk, file_diff->hunk_nr,\n80399aec 240) hunk = file_diff->hunk + file_diff->hunk_nr - 1;\nf6aa7ecc 241) memset(hunk, 0, sizeof(*hunk));\nf6aa7ecc 243) hunk->start = p - plain->buf;\ne3bd11b4 244) if (colored)\ne3bd11b4 245) hunk->colored_start = colored_p - colored->buf;\n47dc4fd5 247) if (deleted)\n47dc4fd5 248) file_diff->deleted = 1;\n47dc4fd5 249) else if (parse_hunk_header(s, hunk) < 0)\n25ea47af 250) return -1;\n510aeca1 256) marker = *p;\n5906d5de 257) } else if (hunk == &file_diff->head &&\n5906d5de 258)    skip_prefix(p, \"old mode \", &mode_change) &&\n5906d5de 259)    is_octal(mode_change, eol - mode_change)) {\n5906d5de 260) if (file_diff->mode_change)\n5906d5de 263) if (file_diff->hunk_nr++)\n5906d5de 271) file_diff->mode_change = 1;\n5906d5de 272) ALLOC_GROW(file_diff->hunk, file_diff->hunk_nr,\n5906d5de 274) memset(file_diff->hunk, 0, sizeof(struct hunk));\n5906d5de 275) file_diff->hunk->start = p - plain->buf;\n5906d5de 276) if (colored_p)\n5906d5de 277) file_diff->hunk->colored_start =\n5906d5de 278) colored_p - colored->buf;\n5906d5de 279) } else if (hunk == &file_diff->head &&\n5906d5de 280)    skip_prefix(p, \"new mode \", &mode_change) &&\n5906d5de 281)    is_octal(mode_change, eol - mode_change)) {\n5906d5de 287) if (!file_diff->mode_change)\n5906d5de 290) if (file_diff->hunk_nr != 1)\n5906d5de 293) if (p - plain->buf != file_diff->hunk->end)\n2e408319 297) } else if (hunk == &file_diff->head &&\n2e408319 298)    starts_with(p, \"Binary files \"))\n2e408319 299) file_diff->binary = 1;\n5906d5de 301) if (file_diff->deleted && file_diff->mode_change)\n510aeca1 306) if ((marker == '-' || marker == '+') && *p == ' ')\n510aeca1 307) hunk->splittable_into++;\n510aeca1 308) if (marker && *p != '\\\\')\n510aeca1 309) marker = *p;\nf6aa7ecc 311) p = eol == pend ? pend : eol + 1;\nf6aa7ecc 312) hunk->end = p - plain->buf;\ne3bd11b4 314) if (colored) {\ne3bd11b4 315) char *colored_eol = memchr(colored_p, '\\n',\ne3bd11b4 316)    colored_pend - colored_p);\ne3bd11b4 317) if (colored_eol)\ne3bd11b4 318) colored_p = colored_eol + 1;\ne3bd11b4 320) colored_p = colored_pend;\ne3bd11b4 322) hunk->colored_end = colored_p - colored->buf;\n5906d5de 325) if (mode_change) {\n5906d5de 326) if (file_diff->hunk_nr != 1)\n5906d5de 330) file_diff->hunk->end = hunk->end;\n5906d5de 331) if (colored)\n5906d5de 332) file_diff->hunk->colored_end = hunk->colored_end;\n510aeca1 336) if (marker == '-' || marker == '+')\n510aeca1 341) hunk->splittable_into++;\nf6aa7ecc 343) return 0;\n510aeca1 346) static size_t find_next_line(struct strbuf *sb, size_t offset)\n510aeca1 350) if (offset >= sb->len)\n510aeca1 354) eol = memchr(sb->buf + offset, '\\n', sb->len - offset);\n510aeca1 355) if (!eol)\n510aeca1 356) return sb->len;\n510aeca1 357) return eol - sb->buf + 1;\nf6aa7ecc 360) static void render_hunk(struct add_p_state *s, struct hunk *hunk,\n25ea47af 363) struct hunk_header *header = &hunk->header;\n25ea47af 365) if (hunk->header.old_offset != 0 || hunk->header.new_offset != 0) {\n25ea47af 372) unsigned long old_offset = header->old_offset;\n25ea47af 373) unsigned long new_offset = header->new_offset;\n25ea47af 375) if (!colored) {\n25ea47af 376) p = s->plain.buf + header->extra_start;\n25ea47af 377) len = header->extra_end - header->extra_start;\n25ea47af 379) strbuf_addstr(out, s->s.fraginfo_color);\n25ea47af 380) p = s->colored.buf + header->colored_extra_start;\n25ea47af 381) len = header->colored_extra_end\n25ea47af 382) - header->colored_extra_start;\n25ea47af 385) new_offset += delta;\n25ea47af 387) strbuf_addf(out, \"@@ -%lu,%lu +%lu,%lu @@\",\n25ea47af 390) if (len)\n25ea47af 391) strbuf_add(out, p, len);\n25ea47af 392) else if (colored)\n25ea47af 393) strbuf_addf(out, \"%s\\n\", GIT_COLOR_RESET);\n25ea47af 395) strbuf_addch(out, '\\n');\ne3bd11b4 398) if (colored)\ne3bd11b4 399) strbuf_add(out, s->colored.buf + hunk->colored_start,\ne3bd11b4 400)    hunk->colored_end - hunk->colored_start);\ne3bd11b4 402) strbuf_add(out, s->plain.buf + hunk->start,\ne3bd11b4 403)    hunk->end - hunk->start);\nf6aa7ecc 404) }\n5906d5de 406) static void render_diff_header(struct add_p_state *s,\n5906d5de 415) int skip_mode_change =\n5906d5de 416) file_diff->mode_change && file_diff->hunk->use != USE_HUNK;\n5906d5de 417) struct hunk *head = &file_diff->head, *first = file_diff->hunk;\n5906d5de 419) if (!skip_mode_change) {\n5906d5de 420) render_hunk(s, head, 0, colored, out);\n5906d5de 421) return;\n5906d5de 424) if (colored) {\n5906d5de 425) const char *p = s->colored.buf;\n5906d5de 427) strbuf_add(out, p + head->colored_start,\n5906d5de 428)     first->colored_start - head->colored_start);\n5906d5de 429) strbuf_add(out, p + first->colored_end,\n5906d5de 430)     head->colored_end - first->colored_end);\n5906d5de 432) const char *p = s->plain.buf;\n5906d5de 434) strbuf_add(out, p + head->start, first->start - head->start);\n5906d5de 435) strbuf_add(out, p + first->end, head->end - first->end);\n11f2c0da 440) static int merge_hunks(struct add_p_state *s, struct file_diff *file_diff,\nbcdd297b 443) size_t i = *hunk_index, delta;\n11f2c0da 444) struct hunk *hunk = file_diff->hunk + i;\n11f2c0da 446) struct hunk_header *header = &merged->header, *next;\nbcdd297b 448) if (!use_all && hunk->use != USE_HUNK)\n11f2c0da 449) return 0;\n11f2c0da 451) *merged = *hunk;\n11f2c0da 453) merged->colored_start = merged->colored_end = 0;\n11f2c0da 455) for (; i + 1 < file_diff->hunk_nr; i++) {\n11f2c0da 456) hunk++;\n11f2c0da 457) next = &hunk->header;\nbcdd297b 465) if ((!use_all && hunk->use != USE_HUNK) ||\nbcdd297b 466)     header->new_offset >= next->new_offset + merged->delta ||\nbcdd297b 467)     header->new_offset + header->new_count\nbcdd297b 468)     < next->new_offset + merged->delta)\nbcdd297b 475) if (merged->start < hunk->start && merged->end > hunk->start) {\nbcdd297b 476) merged->end = hunk->end;\nbcdd297b 477) merged->colored_end = hunk->colored_end;\nbcdd297b 478) delta = 0;\nbcdd297b 480) const char *plain = s->plain.buf;\nbcdd297b 481) size_t  overlapping_line_count = header->new_offset\nbcdd297b 482) + header->new_count - merged->delta\nbcdd297b 483) - next->new_offset;\nbcdd297b 484) size_t overlap_end = hunk->start;\nbcdd297b 485) size_t overlap_start = overlap_end;\nbcdd297b 496) for (j = 0; j < overlapping_line_count; j++) {\nbcdd297b 497) overlap_next = find_next_line(&s->plain,\nbcdd297b 500) if (overlap_next > hunk->end)\nbcdd297b 507) if (plain[overlap_end] != ' ')\nbcdd297b 515) overlap_start = overlap_end;\nbcdd297b 516) overlap_end = overlap_next;\nbcdd297b 518) len = overlap_end - overlap_start;\nbcdd297b 520) if (len > merged->end - merged->start ||\nbcdd297b 521)     memcmp(plain + merged->end - len,\nbcdd297b 535) if (merged->end != s->plain.len) {\nbcdd297b 536) size_t start = s->plain.len;\nbcdd297b 538) strbuf_add(&s->plain, plain + merged->start,\nbcdd297b 539)    merged->end - merged->start);\nbcdd297b 540) plain = s->plain.buf;\nbcdd297b 541) merged->start = start;\nbcdd297b 542) merged->end = s->plain.len;\nbcdd297b 545) strbuf_add(&s->plain,\nbcdd297b 547)    hunk->end - overlap_end);\nbcdd297b 548) merged->end = s->plain.len;\nbcdd297b 549) merged->splittable_into += hunk->splittable_into;\nbcdd297b 550) delta = merged->delta;\nbcdd297b 551) merged->delta += hunk->delta;\n11f2c0da 554) header->old_count = next->old_offset + next->old_count\n11f2c0da 555) - header->old_offset;\nbcdd297b 556) header->new_count = next->new_offset + delta\nbcdd297b 557) + next->new_count - header->new_offset;\n11f2c0da 560) if (i == *hunk_index)\n11f2c0da 561) return 0;\n11f2c0da 563) *hunk_index = i;\n11f2c0da 564) return 1;\n80399aec 567) static void reassemble_patch(struct add_p_state *s,\nbcdd297b 572) size_t save_len = s->plain.len, i;\n25ea47af 573) ssize_t delta = 0;\n5906d5de 575) render_diff_header(s, file_diff, 0, out);\n5906d5de 577) for (i = file_diff->mode_change; i < file_diff->hunk_nr; i++) {\n11f2c0da 578) struct hunk merged = { 0 };\n80399aec 580) hunk = file_diff->hunk + i;\nbcdd297b 581) if (!use_all && hunk->use != USE_HUNK)\n25ea47af 582) delta += hunk->header.old_count\n25ea47af 583) - hunk->header.new_count;\nbcdd297b 586) if (merge_hunks(s, file_diff, &i, use_all, &merged))\n11f2c0da 587) hunk = &merged;\n25ea47af 589) render_hunk(s, hunk, delta, 0, out);\nbcdd297b 596) strbuf_setlen(&s->plain, save_len);\nbcdd297b 598) delta += hunk->delta;\nf6aa7ecc 601) }\n510aeca1 603) static int split_hunk(struct add_p_state *s, struct file_diff *file_diff,\n510aeca1 606) int colored = !!s->colored.len, first = 1;\n510aeca1 607) struct hunk *hunk = file_diff->hunk + hunk_index;\n510aeca1 609) size_t end, colored_end, current, colored_current = 0, context_line_count;\n510aeca1 613) if (hunk_index >= file_diff->hunk_nr)\n510aeca1 617) if (hunk->splittable_into < 2)\n510aeca1 618) return 0;\n510aeca1 619) splittable_into = hunk->splittable_into;\n510aeca1 621) end = hunk->end;\n510aeca1 622) colored_end = hunk->colored_end;\n510aeca1 624) remaining = hunk->header;\n510aeca1 626) file_diff->hunk_nr += splittable_into - 1;\n510aeca1 627) ALLOC_GROW(file_diff->hunk, file_diff->hunk_nr, file_diff->hunk_alloc);\n510aeca1 628) if (hunk_index + splittable_into < file_diff->hunk_nr)\n510aeca1 629) memmove(file_diff->hunk + hunk_index + splittable_into,\n510aeca1 630) file_diff->hunk + hunk_index + 1,\n510aeca1 631) (file_diff->hunk_nr - hunk_index - splittable_into)\n510aeca1 633) hunk = file_diff->hunk + hunk_index;\n510aeca1 634) hunk->splittable_into = 1;\n510aeca1 635) memset(hunk + 1, 0, (splittable_into - 1) * sizeof(*hunk));\n510aeca1 637) header = &hunk->header;\n510aeca1 638) header->old_count = header->new_count = 0;\n510aeca1 640) current = hunk->start;\n510aeca1 641) if (colored)\n510aeca1 642) colored_current = hunk->colored_start;\n510aeca1 643) marker = '\\0';\n510aeca1 644) context_line_count = 0;\n510aeca1 646) while (splittable_into > 1) {\n510aeca1 647) ch = s->plain.buf[current];\n510aeca1 649) if (!ch)\n510aeca1 656) if ((marker == '-' || marker == '+') && ch == ' ') {\n510aeca1 657) first = 0;\n510aeca1 658) hunk[1].start = current;\n510aeca1 659) if (colored)\n510aeca1 660) hunk[1].colored_start = colored_current;\n510aeca1 661) context_line_count = 0;\n510aeca1 671) if (marker != ' ' || (ch != '-' && ch != '+')) {\n510aeca1 674) if (ch == '\\\\')\n510aeca1 675) ch = marker ? marker : ' ';\n510aeca1 678) if (ch == ' ')\n510aeca1 679) context_line_count++;\n510aeca1 680) else if (ch == '-')\n510aeca1 681) header->old_count++;\n510aeca1 682) else if (ch == '+')\n510aeca1 683) header->new_count++;\n510aeca1 686) marker = ch;\n510aeca1 687) current = find_next_line(&s->plain, current);\n510aeca1 688) if (colored)\n510aeca1 689) colored_current =\n510aeca1 690) find_next_line(&s->colored,\n510aeca1 692) continue;\n510aeca1 702) if (first) {\n510aeca1 703) if (header->old_count || header->new_count)\n510aeca1 708) header->old_count = context_line_count;\n510aeca1 709) header->new_count = context_line_count;\n510aeca1 710) context_line_count = 0;\n510aeca1 711) first = 0;\n510aeca1 712) goto next_hunk_line;\n510aeca1 715) remaining.old_offset += header->old_count;\n510aeca1 716) remaining.old_count -= header->old_count;\n510aeca1 717) remaining.new_offset += header->new_count;\n510aeca1 718) remaining.new_count -= header->new_count;\n510aeca1 721) hunk[1].header.old_offset =\n510aeca1 722) header->old_offset + header->old_count;\n510aeca1 723) hunk[1].header.new_offset =\n510aeca1 724) header->new_offset + header->new_count;\n510aeca1 727) header->old_count += context_line_count;\n510aeca1 728) header->new_count += context_line_count;\n510aeca1 730) hunk->end = current;\n510aeca1 731) if (colored)\n510aeca1 732) hunk->colored_end = colored_current;\n510aeca1 734) hunk++;\n510aeca1 735) hunk->splittable_into = 1;\n510aeca1 736) hunk->use = hunk[-1].use;\n510aeca1 737) header = &hunk->header;\n510aeca1 739) header->old_count = header->new_count = context_line_count;\n510aeca1 740) context_line_count = 0;\n510aeca1 742) splittable_into--;\n510aeca1 743) marker = ch;\n510aeca1 747) if (header->old_offset != remaining.old_offset)\n510aeca1 750) if (header->new_offset != remaining.new_offset)\n510aeca1 753) header->old_count = remaining.old_count;\n510aeca1 754) header->new_count = remaining.new_count;\n510aeca1 755) hunk->end = end;\n510aeca1 756) if (colored)\n510aeca1 757) hunk->colored_end = colored_end;\n510aeca1 759) return 0;\nbcdd297b 762) static void recolor_hunk(struct add_p_state *s, struct hunk *hunk)\nbcdd297b 764) const char *plain = s->plain.buf;\nbcdd297b 767) if (!s->colored.len)\nbcdd297b 768) return;\nbcdd297b 770) hunk->colored_start = s->colored.len;\nbcdd297b 771) for (current = hunk->start; current < hunk->end; ) {\nbcdd297b 772) for (eol = current; eol < hunk->end; eol++)\nbcdd297b 773) if (plain[eol] == '\\n')\nbcdd297b 774) break;\nbcdd297b 775) next = eol + (eol < hunk->end);\nbcdd297b 776) if (eol > current && plain[eol - 1] == '\\r')\nbcdd297b 777) eol--;\nbcdd297b 779) strbuf_addstr(&s->colored,\nbcdd297b 780)       plain[current] == '-' ?\nbcdd297b 782)       plain[current] == '+' ?\nbcdd297b 785) strbuf_add(&s->colored, plain + current, eol - current);\nbcdd297b 786) strbuf_addstr(&s->colored, GIT_COLOR_RESET);\nbcdd297b 787) if (next > eol)\nbcdd297b 788) strbuf_add(&s->colored, plain + eol, next - eol);\nbcdd297b 789) current = next;\nbcdd297b 791) hunk->colored_end = s->colored.len;\nbcdd297b 794) static int edit_hunk_manually(struct add_p_state *s, struct hunk *hunk)\nbcdd297b 798) strbuf_reset(&s->buf);\nbcdd297b 799) strbuf_commented_addf(&s->buf, _(\"Manual hunk edit mode -- see bottom for \"\nbcdd297b 801) render_hunk(s, hunk, 0, 0, &s->buf);\nbcdd297b 802) strbuf_commented_addf(&s->buf,\nbcdd297b 809) strbuf_commented_addf(&s->buf,\nbcdd297b 817) strbuf_commented_addf(&s->buf,\nbcdd297b 824) if (strbuf_edit_interactively(&s->buf, \"addp-hunk-edit.diff\", NULL) < 0)\nbcdd297b 825) return -1;\nbcdd297b 828) hunk->start = s->plain.len;\nbcdd297b 829) for (i = 0; i < s->buf.len; ) {\nbcdd297b 830) size_t next = find_next_line(&s->buf, i);\nbcdd297b 832) if (s->buf.buf[i] != comment_line_char)\nbcdd297b 833) strbuf_add(&s->plain, s->buf.buf + i, next - i);\nbcdd297b 834) i = next;\nbcdd297b 837) hunk->end = s->plain.len;\nbcdd297b 838) if (hunk->end == hunk->start)\nbcdd297b 840) return 0;\nbcdd297b 842) recolor_hunk(s, hunk);\nbcdd297b 849) if (s->plain.buf[hunk->start] == '@' &&\nbcdd297b 850)     parse_hunk_header(s, hunk) < 0)\nbcdd297b 853) return 1;\nbcdd297b 856) static ssize_t recount_edited_hunk(struct add_p_state *s, struct hunk *hunk,\nbcdd297b 859) struct hunk_header *header = &hunk->header;\nbcdd297b 862) header->old_count = header->new_count = 0;\nbcdd297b 863) for (i = hunk->start; i < hunk->end; ) {\nbcdd297b 864) switch (s->plain.buf[i]) {\nbcdd297b 866) header->old_count++;\nbcdd297b 867) break;\nbcdd297b 869) header->new_count++;\nbcdd297b 870) break;\nbcdd297b 872) header->old_count++;\nbcdd297b 873) header->new_count++;\nbcdd297b 874) break;\nbcdd297b 877) i = find_next_line(&s->plain, i);\nbcdd297b 880) return orig_old_count - orig_new_count\nbcdd297b 881) - header->old_count + header->new_count;\nbcdd297b 884) static int run_apply_check(struct add_p_state *s,\nbcdd297b 887) struct child_process cp = CHILD_PROCESS_INIT;\nbcdd297b 889) strbuf_reset(&s->buf);\nbcdd297b 890) reassemble_patch(s, file_diff, 1, &s->buf);\nbcdd297b 892) setup_child_process(s, &cp,\nbcdd297b 894) if (pipe_command(&cp, s->buf.buf, s->buf.len, NULL, 0, NULL, 0))\nbcdd297b 897) return 0;\nbcdd297b 900) static int prompt_yesno(struct add_p_state *s, const char *prompt)\nbcdd297b 903) color_fprintf(stdout, s->s.prompt_color, \"%s\", _(prompt));\nbcdd297b 904) fflush(stdout);\nbcdd297b 905) if (strbuf_getline(&s->answer, stdin) == EOF)\nbcdd297b 906) return -1;\nbcdd297b 907) strbuf_trim_trailing_newline(&s->answer);\nbcdd297b 908) switch (tolower(s->answer.buf[0])) {\nbcdd297b 909) case 'n': return 0;\nbcdd297b 910) case 'y': return 1;\nbcdd297b 912) }\nbcdd297b 915) static int edit_hunk_loop(struct add_p_state *s,\nbcdd297b 918) size_t plain_len = s->plain.len, colored_len = s->colored.len;\nbcdd297b 921) backup = *hunk;\nbcdd297b 924) int res = edit_hunk_manually(s, hunk);\nbcdd297b 925) if (res == 0) {\nbcdd297b 927) *hunk = backup;\nbcdd297b 928) return -1;\nbcdd297b 931) if (res > 0) {\nbcdd297b 932) hunk->delta +=\nbcdd297b 933) recount_edited_hunk(s, hunk,\nbcdd297b 936) if (!run_apply_check(s, file_diff))\nbcdd297b 937) return 0;\nbcdd297b 941) strbuf_setlen(&s->plain, plain_len);\nbcdd297b 942) strbuf_setlen(&s->colored, colored_len);\nbcdd297b 943) *hunk = backup;\nbcdd297b 952) res = prompt_yesno(s, _(\"Your edited hunk does not apply. \"\nbcdd297b 955) if (res < 1)\nbcdd297b 956) return -1;\nbcdd297b 957) }\n9254bdfb 962) static void summarize_hunk(struct add_p_state *s, struct hunk *hunk,\n9254bdfb 965) struct hunk_header *header = &hunk->header;\n9254bdfb 966) struct strbuf *plain = &s->plain;\n9254bdfb 967) size_t len = out->len, i;\n9254bdfb 969) strbuf_addf(out, \" -%lu,%lu +%lu,%lu \",\n9254bdfb 972) if (out->len - len < SUMMARY_HEADER_WIDTH)\n9254bdfb 973) strbuf_addchars(out, ' ',\n9254bdfb 974) SUMMARY_HEADER_WIDTH + len - out->len);\n9254bdfb 975) for (i = hunk->start; i < hunk->end; i = find_next_line(plain, i))\n9254bdfb 976) if (plain->buf[i] != ' ')\n9254bdfb 977) break;\n9254bdfb 978) if (i < hunk->end)\n9254bdfb 979) strbuf_add(out, plain->buf + i, find_next_line(plain, i) - i);\n9254bdfb 980) if (out->len - len > SUMMARY_LINE_WIDTH)\n9254bdfb 981) strbuf_setlen(out, len + SUMMARY_LINE_WIDTH);\n9254bdfb 982) strbuf_complete_line(out);\n9254bdfb 983) }\n9254bdfb 986) static size_t display_hunks(struct add_p_state *s,\n9254bdfb 989) size_t end_index = start_index + DISPLAY_HUNKS_LINES;\n9254bdfb 991) if (end_index > file_diff->hunk_nr)\n9254bdfb 992) end_index = file_diff->hunk_nr;\n9254bdfb 994) while (start_index < end_index) {\n9254bdfb 995) struct hunk *hunk = file_diff->hunk + start_index++;\n9254bdfb 997) strbuf_reset(&s->buf);\n9254bdfb 998) strbuf_addf(&s->buf, \"%c%2d: \", hunk->use == USE_HUNK ? '+'\n9254bdfb 999)     : hunk->use == SKIP_HUNK ? '-' : ' ',\n9254bdfb 1001) summarize_hunk(s, hunk, &s->buf);\n9254bdfb 1002) fputs(s->buf.buf, stdout);\n9254bdfb 1005) return end_index;\n80399aec 1026) static int patch_update_file(struct add_p_state *s,\nf6aa7ecc 1029) size_t hunk_index = 0;\nf6aa7ecc 1033) struct child_process cp = CHILD_PROCESS_INIT;\nade246ef 1034) int colored = !!s->colored.len, quit = 0;\n80399aec 1037) if (!file_diff->hunk_nr)\nf6aa7ecc 1038) return 0;\nf6aa7ecc 1040) strbuf_reset(&s->buf);\n5906d5de 1041) render_diff_header(s, file_diff, colored, &s->buf);\nf6aa7ecc 1042) fputs(s->buf.buf, stdout);\n80399aec 1044) if (hunk_index >= file_diff->hunk_nr)\nf6aa7ecc 1045) hunk_index = 0;\n80399aec 1046) hunk = file_diff->hunk + hunk_index;\nf6aa7ecc 1048) undecided_previous = -1;\nf6aa7ecc 1049) for (i = hunk_index - 1; i >= 0; i--)\n80399aec 1050) if (file_diff->hunk[i].use == UNDECIDED_HUNK) {\nf6aa7ecc 1051) undecided_previous = i;\nf6aa7ecc 1052) break;\nf6aa7ecc 1055) undecided_next = -1;\n80399aec 1056) for (i = hunk_index + 1; i < file_diff->hunk_nr; i++)\n80399aec 1057) if (file_diff->hunk[i].use == UNDECIDED_HUNK) {\nf6aa7ecc 1058) undecided_next = i;\nf6aa7ecc 1059) break;\nf6aa7ecc 1063) if (undecided_previous < 0 && undecided_next < 0 &&\nf6aa7ecc 1064)     hunk->use != UNDECIDED_HUNK)\nf6aa7ecc 1065) break;\nf6aa7ecc 1067) strbuf_reset(&s->buf);\n25ea47af 1068) render_hunk(s, hunk, 0, colored, &s->buf);\nf6aa7ecc 1069) fputs(s->buf.buf, stdout);\nf6aa7ecc 1071) strbuf_reset(&s->buf);\nf6aa7ecc 1072) if (undecided_previous >= 0)\nf6aa7ecc 1073) strbuf_addstr(&s->buf, \",k\");\nf6aa7ecc 1074) if (hunk_index)\nf6aa7ecc 1075) strbuf_addstr(&s->buf, \",K\");\nf6aa7ecc 1076) if (undecided_next >= 0)\nf6aa7ecc 1077) strbuf_addstr(&s->buf, \",j\");\n80399aec 1078) if (hunk_index + 1 < file_diff->hunk_nr)\nf6aa7ecc 1079) strbuf_addstr(&s->buf, \",J\");\n9254bdfb 1080) if (file_diff->hunk_nr > 1)\nd6cf8733 1081) strbuf_addstr(&s->buf, \",g,/\");\n510aeca1 1082) if (hunk->splittable_into > 1)\n510aeca1 1083) strbuf_addstr(&s->buf, \",s\");\nbcdd297b 1084) if (hunk_index + 1 > file_diff->mode_change &&\nbcdd297b 1085)     !file_diff->deleted)\nbcdd297b 1086) strbuf_addstr(&s->buf, \",e\");\n0ecd9d27 1088) if (file_diff->deleted)\n0ecd9d27 1089) prompt_mode_type = PROMPT_DELETION;\n0ecd9d27 1090) else if (file_diff->mode_change && !hunk_index)\n0ecd9d27 1091) prompt_mode_type = PROMPT_MODE_CHANGE;\n0ecd9d27 1093) prompt_mode_type = PROMPT_HUNK;\n12c24cf8 1095) color_fprintf(stdout, s->s.prompt_color,\n80399aec 1098)       (uintmax_t)file_diff->hunk_nr);\n12c24cf8 1099) color_fprintf(stdout, s->s.prompt_color,\nf6aa7ecc 1101) fflush(stdout);\nf6aa7ecc 1102) if (strbuf_getline(&s->answer, stdin) == EOF)\nf6aa7ecc 1103) break;\nf6aa7ecc 1104) strbuf_trim_trailing_newline(&s->answer);\nf6aa7ecc 1106) if (!s->answer.len)\nf6aa7ecc 1107) continue;\nf6aa7ecc 1108) ch = tolower(s->answer.buf[0]);\nf6aa7ecc 1109) if (ch == 'y') {\nf6aa7ecc 1110) hunk->use = USE_HUNK;\nf6aa7ecc 1112) hunk_index = undecided_next < 0 ?\n80399aec 1113) file_diff->hunk_nr : undecided_next;\nf6aa7ecc 1114) } else if (ch == 'n') {\nf6aa7ecc 1115) hunk->use = SKIP_HUNK;\nf6aa7ecc 1116) goto soft_increment;\nf6aa7ecc 1117) } else if (ch == 'a') {\n80399aec 1118) for (; hunk_index < file_diff->hunk_nr; hunk_index++) {\n80399aec 1119) hunk = file_diff->hunk + hunk_index;\nf6aa7ecc 1120) if (hunk->use == UNDECIDED_HUNK)\nf6aa7ecc 1121) hunk->use = USE_HUNK;\nade246ef 1123) } else if (ch == 'd' || ch == 'q') {\n80399aec 1124) for (; hunk_index < file_diff->hunk_nr; hunk_index++) {\n80399aec 1125) hunk = file_diff->hunk + hunk_index;\nf6aa7ecc 1126) if (hunk->use == UNDECIDED_HUNK)\nf6aa7ecc 1127) hunk->use = SKIP_HUNK;\nade246ef 1129) if (ch == 'q') {\nade246ef 1130) quit = 1;\nade246ef 1131) break;\n7584dd3c 1133) } else if (s->answer.buf[0] == 'K') {\n7584dd3c 1134) if (hunk_index)\n7584dd3c 1135) hunk_index--;\n7584dd3c 1137) err(s, _(\"No previous hunk\"));\n7584dd3c 1138) } else if (s->answer.buf[0] == 'J') {\n80399aec 1139) if (hunk_index + 1 < file_diff->hunk_nr)\n7584dd3c 1140) hunk_index++;\n7584dd3c 1142) err(s, _(\"No next hunk\"));\n7584dd3c 1143) } else if (s->answer.buf[0] == 'k') {\n7584dd3c 1144) if (undecided_previous >= 0)\n7584dd3c 1145) hunk_index = undecided_previous;\n7584dd3c 1147) err(s, _(\"No previous hunk\"));\n7584dd3c 1148) } else if (s->answer.buf[0] == 'j') {\n7584dd3c 1149) if (undecided_next >= 0)\n7584dd3c 1150) hunk_index = undecided_next;\n7584dd3c 1152) err(s, _(\"No next hunk\"));\n9254bdfb 1153) } else if (s->answer.buf[0] == 'g') {\n9254bdfb 1157) if (file_diff->hunk_nr < 2) {\n9254bdfb 1158) err(s, _(\"No other hunks to goto\"));\n9254bdfb 1159) continue;\n9254bdfb 1161) strbuf_remove(&s->answer, 0, 1);\n9254bdfb 1162) strbuf_trim(&s->answer);\n9254bdfb 1163) i = hunk_index - DISPLAY_HUNKS_LINES / 2;\n9254bdfb 1164) if (i < file_diff->mode_change)\n9254bdfb 1165) i = file_diff->mode_change;\n9254bdfb 1166) while (s->answer.len == 0) {\n9254bdfb 1167) i = display_hunks(s, file_diff, i);\n9254bdfb 1168) printf(\"%s\", i < file_diff->hunk_nr ?\n9254bdfb 1171) fflush(stdout);\n9254bdfb 1172) if (strbuf_getline(&s->answer,\n9254bdfb 1174) break;\n9254bdfb 1175) strbuf_trim_trailing_newline(&s->answer);\n9254bdfb 1178) strbuf_trim(&s->answer);\n9254bdfb 1179) response = strtoul(s->answer.buf, &pend, 10);\n9254bdfb 1180) if (*pend || pend == s->answer.buf)\n9254bdfb 1181) err(s, _(\"Invalid number: '%s'\"),\n9254bdfb 1183) else if (0 < response && response <= file_diff->hunk_nr)\n9254bdfb 1184) hunk_index = response - 1;\n9254bdfb 1186) err(s, Q_(\"Sorry, only %d hunk available.\",\n9254bdfb 1189)     (int)file_diff->hunk_nr);\nd6cf8733 1190) } else if (s->answer.buf[0] == '/') {\nd6cf8733 1194) if (file_diff->hunk_nr < 2) {\nd6cf8733 1195) err(s, _(\"No other hunks to search\"));\nd6cf8733 1196) continue;\nd6cf8733 1198) strbuf_remove(&s->answer, 0, 1);\nd6cf8733 1199) strbuf_trim_trailing_newline(&s->answer);\nd6cf8733 1200) if (s->answer.len == 0) {\nd6cf8733 1201) printf(\"%s\", _(\"search for regex? \"));\nd6cf8733 1202) fflush(stdout);\nd6cf8733 1203) if (strbuf_getline(&s->answer,\nd6cf8733 1205) break;\nd6cf8733 1206) strbuf_trim_trailing_newline(&s->answer);\nd6cf8733 1207) if (s->answer.len == 0)\nd6cf8733 1208) continue;\nd6cf8733 1210) ret = regcomp(&regex, s->answer.buf,\nd6cf8733 1212) if (ret) {\nd6cf8733 1216) err(s, _(\"Malformed search regexp %s: %s\"),\nd6cf8733 1218) continue;\nd6cf8733 1220) i = hunk_index;\nd6cf8733 1223) render_hunk(s, file_diff->hunk + i, 0, 0,\nd6cf8733 1225) if (regexec(&regex, s->buf.buf, 0, NULL, 0)\nd6cf8733 1227) break;\nd6cf8733 1228) i++;\nd6cf8733 1229) if (i == file_diff->hunk_nr)\nd6cf8733 1230) i = 0;\nd6cf8733 1231) if (i != hunk_index)\nd6cf8733 1232) continue;\nd6cf8733 1233) err(s, _(\"No hunk matches the given pattern\"));\nd6cf8733 1234) break;\nd6cf8733 1235) }\nd6cf8733 1236) hunk_index = i;\n510aeca1 1237) } else if (s->answer.buf[0] == 's') {\n510aeca1 1238) size_t splittable_into = hunk->splittable_into;\n510aeca1 1239) if (splittable_into < 2)\n510aeca1 1240) err(s, _(\"Sorry, cannot split this hunk\"));\n510aeca1 1241) else if (!split_hunk(s, file_diff,\n510aeca1 1242)      hunk - file_diff->hunk))\n510aeca1 1243) color_fprintf_ln(stdout, s->s.header_color,\nbcdd297b 1246) } else if (s->answer.buf[0] == 'e') {\nbcdd297b 1247) if (hunk_index + 1 == file_diff->mode_change)\nbcdd297b 1248) err(s, _(\"Sorry, cannot edit this hunk\"));\nbcdd297b 1249) else if (edit_hunk_loop(s, file_diff, hunk) >= 0) {\nbcdd297b 1250) hunk->use = USE_HUNK;\nbcdd297b 1251) goto soft_increment;\n54d9d9b2 1254) const char *p = _(help_patch_remainder), *eol = p;\n54d9d9b2 1256) color_fprintf(stdout, s->s.help_color, \"%s\",\n54d9d9b2 1263) for (; *p; p = eol + (*eol == '\\n')) {\n54d9d9b2 1264) eol = strchrnul(p, '\\n');\n54d9d9b2 1271) if (*p != '?' && !strchr(s->buf.buf, *p))\n54d9d9b2 1272) continue;\n54d9d9b2 1274) color_fprintf_ln(stdout, s->s.help_color,\n54d9d9b2 1275)  \"%.*s\", (int)(eol - p), p);\nf6aa7ecc 1278) }\n80399aec 1281) for (i = 0; i < file_diff->hunk_nr; i++)\n80399aec 1282) if (file_diff->hunk[i].use == USE_HUNK)\nf6aa7ecc 1283) break;\n80399aec 1285) if (i < file_diff->hunk_nr) {\nf6aa7ecc 1287) strbuf_reset(&s->buf);\nbcdd297b 1288) reassemble_patch(s, file_diff, 0, &s->buf);\n25ea47af 1290) discard_index(s->s.r->index);\nf6aa7ecc 1291) setup_child_process(s, &cp, \"apply\", \"--cached\", NULL);\nf6aa7ecc 1292) if (pipe_command(&cp, s->buf.buf, s->buf.len,\n25ea47af 1295) if (!repo_read_index(s->s.r))\n25ea47af 1296) repo_refresh_and_write_index(s->s.r, REFRESH_QUIET, 0,\nf6aa7ecc 1300) putchar('\\n');\nade246ef 1301) return quit;\nf6aa7ecc 1304) int run_add_p(struct repository *r, const struct pathspec *ps)\n25ea47af 1306) struct add_p_state s = {\n2e408319 1309) size_t i, binary_count = 0;\n25ea47af 1311) init_add_i_state(&s.s, r);\nf6aa7ecc 1313) if (discard_index(r->index) < 0 || repo_read_index(r) < 0 ||\nf6aa7ecc 1314)     repo_refresh_and_write_index(r, REFRESH_QUIET, 0, 1,\nf6aa7ecc 1315)  NULL, NULL, NULL) < 0 ||\nf6aa7ecc 1316)     parse_diff(&s, ps) < 0) {\nf6aa7ecc 1317) strbuf_release(&s.plain);\ne3bd11b4 1318) strbuf_release(&s.colored);\nf6aa7ecc 1319) return -1;\n80399aec 1322) for (i = 0; i < s.file_diff_nr; i++)\n2e408319 1323) if (s.file_diff[i].binary && !s.file_diff[i].hunk_nr)\n2e408319 1324) binary_count++;\n2e408319 1325) else if (patch_update_file(&s, s.file_diff + i))\n80399aec 1326) break;\n2e408319 1328) if (s.file_diff_nr == 0)\n2e408319 1329) fprintf(stderr, _(\"No changes.\\n\"));\n2e408319 1330) else if (binary_count == s.file_diff_nr)\n2e408319 1331) fprintf(stderr, _(\"Only binary files changed.\\n\"));\nf6aa7ecc 1333) strbuf_release(&s.answer);\nf6aa7ecc 1334) strbuf_release(&s.buf);\nf6aa7ecc 1335) strbuf_release(&s.plain);\ne3bd11b4 1336) strbuf_release(&s.colored);\nf6aa7ecc 1337) return 0;\n\napply.c\nb4bbbbd5 2672) match_beginning = 0;\n\nbuiltin/add.c\nf6aa7ecc 199) if (!patch_mode)\nf83dff60 200) return !!run_add_i(the_repository, pathspec);\nf6aa7ecc 201) if (strcmp(patch_mode, \"--patch\"))\nf6aa7ecc 204) return !!run_add_p(the_repository, pathspec);\n\nbuiltin/bisect--helper.c\n51a0a4ed 177) return -1;\n\nbuiltin/bundle.c\n79862b6b 85) else if (progress == 1)\n79862b6b 86) argv_array_push(&pack_opts, \"--progress\");\n79862b6b 87) else if (progress == 2)\n79862b6b 88) argv_array_push(&pack_opts, \"--all-progress\");\n79862b6b 90) argv_array_push(&pack_opts, \"--all-progress-implied\");\n2e0afafe 115) return 1;\n73c3253d 138) return 1;\n73c3253d 143) static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) {\n73c3253d 145) int bundle_fd = -1;\n73c3253d 147) struct option options[] = {\n73c3253d 152) argc = parse_options_cmd_bundle(argc, argv, prefix,\n73c3253d 156) memset(&header, 0, sizeof(header));\n73c3253d 157) if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)\n73c3253d 158) return 1;\n73c3253d 159) if (!startup_info->have_repository)\n73c3253d 161) return !!unbundle(the_repository, &header, bundle_fd, 0) ||\n73c3253d 162) list_bundle_refs(&header, argc, argv);\n73c3253d 187) else if (!strcmp(argv[0], \"unbundle\"))\n73c3253d 188) result = cmd_bundle_unbundle(argc, argv, prefix);\n\nbuiltin/checkout.c\n\nbuiltin/clone.c\nd89f09c8 753) result = 1;\nd89f09c8 1132) return 1;\n\nbuiltin/commit.c\n\nbuiltin/fmt-merge-msg.c\n72b006f4 511) strbuf_addstr(&sig, \"gpg verification failed.\\n\");\n\nbuiltin/fsck.c\n82ef89b3 64) type = oid_object_info(the_repository, oid, NULL);\n82ef89b3 309) printf_ln(_(\"unreachable %s %s\"),\n82ef89b3 310)   printable_type(&obj->oid, obj->type),\n82ef89b3 311)   describe_object(&obj->oid));\n82ef89b3 367) fprintf_ln(stderr, _(\"Checking %s\"), describe_object(&obj->oid));\n82ef89b3 425)    printable_type(&obj->oid, obj->type),\n82ef89b3 426)    describe_object(&obj->oid));\n82ef89b3 439)   describe_object(&commit->object.oid));\n\nbuiltin/reset.c\n\nbuiltin/sparse-checkout.c\ne091228e 85) return 0;\nbab3c359 221) return 1;\nbab3c359 275) return 1;\n190a65f9 337)    strihash(e->pattern) :\naf09ce24 352) return;\n\ncommit.c\n\ndir.c\n96cc8ab5 663) pl->use_cone_patterns = 0;\n96cc8ab5 665) goto clear_hashmaps;\n190a65f9 676)    strihash(translated->pattern) :\n96cc8ab5 689) hashmap_add(&pl->parent_hashmap, &translated->ent);\n96cc8ab5 690) hashmap_remove(&pl->recursive_hashmap, &translated->ent, &data);\n96cc8ab5 691) free(data);\n96cc8ab5 692) return;\n96cc8ab5 698) goto clear_hashmaps;\n190a65f9 707)    strihash(translated->pattern) :\n96cc8ab5 716) hashmap_remove(&pl->parent_hashmap, &translated->ent, &data);\n96cc8ab5 717) free(data);\n96cc8ab5 718) free(translated);\n96cc8ab5 1280) return MATCHED;\n\nfetch-pack.c\n\nfsck.c\n73390290 401) fsck_put_object_name(options, &entry.oid, \"%s%s/\",\n73390290 470) fsck_put_object_name(options, oid, \"%s^%d\",\n73390290 473) fsck_put_object_name(options, oid, \"%.*s~%d\",\n73390290 496) fsck_put_object_name(options, &tag->tagged->oid, \"%s\", name);\n7034cd09 630) retval += report(options, oid, OBJ_TREE,\nb2f2039c 639) retval += report(options, oid, OBJ_TREE, FSCK_MSG_BAD_TREE, \"cannot be parsed as a tree\");\nb2f2039c 686) retval += report(options, oid, OBJ_TREE, FSCK_MSG_FULL_PATHNAME, \"contains full pathnames\");\nb2f2039c 688) retval += report(options, oid, OBJ_TREE, FSCK_MSG_EMPTY_NAME, \"contains empty pathname\");\nb2f2039c 696) retval += report(options, oid, OBJ_TREE, FSCK_MSG_ZERO_PADDED_FILEMODE, \"contains zero-padded file modes\");\nb2f2039c 698) retval += report(options, oid, OBJ_TREE, FSCK_MSG_BAD_FILEMODE, \"contains bad file modes\");\nb2f2039c 702) retval += report(options, oid, OBJ_TREE, FSCK_MSG_TREE_NOT_SORTED, \"not properly sorted\");\ncc579000 734) return report(options, oid, type,\n78543993 750) return report(options, oid, type, FSCK_MSG_MISSING_NAME_BEFORE_EMAIL, \"invalid author/committer line - missing space before email\");\n78543993 757) return report(options, oid, type, FSCK_MSG_MISSING_SPACE_BEFORE_EMAIL, \"invalid author/committer line - missing space before email\");\n78543993 761) return report(options, oid, type, FSCK_MSG_BAD_EMAIL, \"invalid author/committer line - bad email\");\n78543993 767) return report(options, oid, type, FSCK_MSG_ZERO_PADDED_DATE, \"invalid author/committer line - zero-padded date\");\n78543993 771) return report(options, oid, type, FSCK_MSG_BAD_DATE, \"invalid author/committer line - bad date\");\n78543993 779) return report(options, oid, type, FSCK_MSG_BAD_TIMEZONE, \"invalid author/committer line - bad time zone\");\nc5b4269b 798) return report(options, oid, OBJ_COMMIT, FSCK_MSG_MISSING_TREE, \"invalid format - expected 'tree' line\");\nc5b4269b 800) err = report(options, oid, OBJ_COMMIT, FSCK_MSG_BAD_TREE_SHA1, \"invalid 'tree' line format - bad sha1\");\nc5b4269b 807) err = report(options, oid, OBJ_COMMIT, FSCK_MSG_BAD_PARENT_SHA1, \"invalid 'parent' line format - bad sha1\");\nc5b4269b 821) err = report(options, oid, OBJ_COMMIT, FSCK_MSG_MISSING_AUTHOR, \"invalid format - expected 'author' line\");\nc5b4269b 827) return report(options, oid, OBJ_COMMIT, FSCK_MSG_MISSING_COMMITTER, \"invalid format - expected 'committer' line\");\n103fb6d4 854) ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_OBJECT, \"invalid format - expected 'object' line\");\n103fb6d4 858) ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_OBJECT_SHA1, \"invalid 'object' line format - bad sha1\");\n103fb6d4 865) ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TYPE_ENTRY, \"invalid format - expected 'type' line\");\n103fb6d4 870) ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TYPE, \"invalid format - unexpected end after 'type' line\");\n103fb6d4 874) ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_TYPE, \"invalid 'type' value\");\n103fb6d4 880) ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TAG_ENTRY, \"invalid format - expected 'tag' line\");\n103fb6d4 885) ret = report(options, oid, OBJ_TAG, FSCK_MSG_MISSING_TAG, \"invalid format - unexpected end after 'type' line\");\n6da40b22 981) return report(options, oid, OBJ_BLOB,\n38370253 1003) return report(options, NULL, OBJ_NONE, FSCK_MSG_BAD_OBJECT_SHA1, \"no valid object to fsck\");\n38370253 1014) return report(options, &obj->oid, obj->type,\n38370253 1017)       obj->type);\nb8b00f16 1050) if (is_promisor_object(oid))\n38370253 1052) ret |= report(options,\n\ngpg-interface.c\n392b862e 115) *field = NULL;\n67a6ea63 184) replace_cstring(field, NULL, NULL);\n72b006f4 223) return error_errno(_(\"could not create temporary file\"));\n72b006f4 226) error_errno(_(\"failed writing detached signature to '%s'\"),\n72b006f4 228) delete_tempfile(&temp);\n72b006f4 229) return -1;\n72b006f4 244) gpg_status = &buf;\n\ngraph.c\n0195285b 422) REALLOC_ARRAY(graph->old_mapping, graph->column_capacity * 2);\nfbccf255 905) graph_line_write_column(line, col, '|');\n\nhttp.c\n4d17fd25 417) string_list_clear(&extra_http_headers, 0);\n\nlog-tree.c\n72b006f4 461) show_sig_lines(opt, status, \"No signature\\n\");\n72b006f4 535) } else if (verify_message.len <= gpg_message_offset)\n\nmidx.c\n840cef0c 973) progress = start_progress(_(\"Writing chunks to multi-pack-index\"),\n\npack-objects.c\nf66e0401 122) if (pack->in_pack)\nf66e0401 125) ALLOC_ARRAY(pack->in_pack, pack->nr_alloc);\n\npath.c\nc72fc40d 386) for (p = common_list; p->path; p++) {\nc72fc40d 387) const char *path = p->path;\n\npathspec.c\n\nprogress.c\n44a4693b 308) return start_progress_delay(title, total, get_default_delay(), 1);\n\nrevision.c\n0aa0c2b2 3202) static void reset_topo_walk(struct rev_info *revs)\n0aa0c2b2 3204) struct topo_walk_info *info = revs->topo_walk_info;\n0aa0c2b2 3206) clear_prio_queue(&info->explore_queue);\n0aa0c2b2 3207) clear_prio_queue(&info->indegree_queue);\n0aa0c2b2 3208) clear_prio_queue(&info->topo_queue);\n0aa0c2b2 3209) clear_indegree_slab(&info->indegree);\n0aa0c2b2 3210) clear_author_date_slab(&info->author_date);\n0aa0c2b2 3212) FREE_AND_NULL(revs->topo_walk_info);\n0aa0c2b2 3213) }\n0aa0c2b2 3220) reset_topo_walk(revs);\n\nsend-pack.c\nad7a4032 582) receive_status(&reader, remote_refs);\n\nsequencer.c\nc068bcc5 840) free(kv.items[date_i].util);\ncbd8db17 890) return NULL;\n08187b4c 903) return NULL;\n08187b4c 920) argv_array_pushf(&child->env_array, \"GIT_COMMITTER_DATE=%s\", date.buf);\ncbd8db17 989) return -1;\n49697cb7 1211) arg1 = \"commit\";\n49697cb7 1212) arg2 = commit;\ncbd8db17 1428) goto out;\ncbd8db17 1432) goto out;\n2d05ef27 1459) goto out;\n08187b4c 1508) res = -1;\n08187b4c 1509) goto out;\ncbd8db17 2603) opts->allow_ff = 0;\ncbd8db17 2604) opts->committer_date_is_author_date = 1;\n08187b4c 2608) opts->allow_ff = 0;\n08187b4c 2609) opts->ignore_date = 1;\n08187b4c 3639) push_dates(&cmd, opts->committer_date_is_author_date);\ncd552227 4648) strbuf_addstr(buf, \"rev-\");\ncd552227 4649) strbuf_add_unique_abbrev(buf, oid, default_abbrev);\n867bc1d2 4673) }\n393adf7a 5272) goto cleanup;\n\nstrbuf.c\nb38dd9e7 1129) int strbuf_edit_interactively(struct strbuf *buffer, const char *path,\nb38dd9e7 1132) char *path2 = NULL;\nb38dd9e7 1133) int fd, res = 0;\nb38dd9e7 1135) if (!is_absolute_path(path))\nb38dd9e7 1136) path = path2 = xstrdup(git_path(\"%s\", path));\nb38dd9e7 1138) fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666);\nb38dd9e7 1139) if (fd < 0)\nb38dd9e7 1140) res = error_errno(_(\"could not open '%s' for writing\"), path);\nb38dd9e7 1141) else if (write_in_full(fd, buffer->buf, buffer->len) < 0) {\nb38dd9e7 1142) res = error_errno(_(\"could not write to '%s'\"), path);\nb38dd9e7 1143) close(fd);\nb38dd9e7 1144) } else if (close(fd) < 0)\nb38dd9e7 1145) res = error_errno(_(\"could not close '%s'\"), path);\nb38dd9e7 1147) strbuf_reset(buffer);\nb38dd9e7 1148) if (launch_editor(path, buffer, env) < 0)\nb38dd9e7 1149) res = error_errno(_(\"could not edit '%s'\"), path);\nb38dd9e7 1150) unlink(path);\nb38dd9e7 1153) free(path2);\nb38dd9e7 1154) return res;\n\nt/helper/test-read-graph.c\n4bd0593e 23) die_errno(_(\"Could not open commit-graph '%s'\"), graph_name);\n4bd0593e 27) return 1;\n\nt/helper/test-run-command.c\neea4a7f4 331) static int inherit_handle(const char *argv0)\neea4a7f4 333) struct child_process cp = CHILD_PROCESS_INIT;\neea4a7f4 338) xsnprintf(path, sizeof(path), \"out-XXXXXX\");\neea4a7f4 339) tmp = xmkstemp(path);\neea4a7f4 341) argv_array_pushl(&cp.args,\neea4a7f4 343) cp.in = -1;\neea4a7f4 344) cp.no_stdout = cp.no_stderr = 1;\neea4a7f4 345) if (start_command(&cp) < 0)\neea4a7f4 349) close(tmp);\neea4a7f4 350) if (unlink(path))\neea4a7f4 353) if (close(cp.in) < 0 || finish_command(&cp) < 0)\neea4a7f4 356) return 0;\neea4a7f4 359) static int inherit_handle_child(void)\neea4a7f4 361) struct strbuf buf = STRBUF_INIT;\neea4a7f4 363) if (strbuf_read(&buf, 0, 0) < 0)\neea4a7f4 365) printf(\"Received %s\\n\", buf.buf);\neea4a7f4 366) strbuf_release(&buf);\neea4a7f4 368) return 0;\neea4a7f4 379) exit(inherit_handle(argv[0]));\neea4a7f4 381) exit(inherit_handle_child());\n\ntag.c\n228c78fb 152) FREE_AND_NULL(item->tag);\n\nusage.c\n116d1fa6 16) fprintf(stderr, \"BUG!!! too long a prefix '%s'\\n\", prefix);\n116d1fa6 17) abort();\n116d1fa6 22) *p = '\\0'; /* vsnprintf() failed, clip at prefix */\n\nCommits introducing uncovered code:\nAlban Gruin\t393adf7a sequencer: directly call pick_commits() from complete_action()\nAlexandr Miloslavskiy\t24e4750c pathspec: add new function to parse file\nAlexandr Miloslavskiy\tbebb5d6d add: support the --pathspec-from-file option\nAlexandr Miloslavskiy\t64bac8df reset: support the `--pathspec-from-file` option\nDaniel Ferreira\t5e82b9e4 built-in add -i: implement the `status` command\nDerrick Stolee\tbab3c359 sparse-checkout: create 'init' subcommand\nDerrick Stolee\t96cc8ab5 sparse-checkout: use hashmaps for cone patterns\nDerrick Stolee\taf09ce24 sparse-checkout: init and set in cone mode\nDerrick Stolee\t190a65f9 sparse-checkout: respect core.ignoreCase in cone mode\nDerrick Stolee\t416adc87 sparse-checkout: update working directory in-process for 'init'\nDerrick Stolee\te091228e sparse-checkout: update working directory in-process\nDerrick Stolee\t72918c1a sparse-checkout: create 'disable' subcommand\nDerrick Stolee\t94c0956b sparse-checkout: create builtin with 'list' subcommand\nDerrick Stolee\t4bd0593e test-tool: use 'read-graph' helper\nDerrick Stolee\td89f09c8 clone: add --sparse mode\nDerrick Stolee\t44a4693b progress: create GIT_PROGRESS_DELAY\nHans Jerry Illikainen\t392b862e gpg-interface: refactor the free-and-xmemdupz pattern\nHans Jerry Illikainen\t67a6ea63 gpg-interface: limit search for primary key fingerprint\nHans Jerry Illikainen\t72b006f4 gpg-interface: prefer check_signature() for GPG verification\nJames Coglan\t0195285b graph: rename `new_mapping` to `old_mapping`\nJames Coglan\tfbccf255 graph: automatically track display width of graph lines\nJeff King\t5afc4b1d fsck: only provide oid/type in fsck_error callback\nJeff King\t82ef89b3 fsck: don't require object structs for display functions\nJeff King\t78543993 fsck: don't require an object struct for fsck_ident()\nJeff King\ta59cfb32 fsck: unify object-name code\nJeff King\tb2f2039c fsck: accept an oid instead of a \"struct tree\" for fsck_tree()\nJeff King\tcc579000 fsck: don't require an object struct in verify_headers()\nJeff King\tc5b4269b fsck: accept an oid instead of a \"struct commit\" for fsck_commit()\nJeff King\t103fb6d4 fsck: accept an oid instead of a \"struct tag\" for fsck_tag()\nJeff King\t6da40b22 fsck: accept an oid instead of a \"struct blob\" for fsck_blob()\nJeff King\t38370253 fsck: don't require an object struct for report()\nJeff King\tb8b00f16 fsck: drop blob struct from fsck_finish()\nJeff King\tf66e0401 pack-objects: avoid pointless oe_map_new_pack() calls\nJeff King\t73390290 fsck: use oids rather than objects for object_name API\nJeff King\t228c78fb commit, tag: don't set parsed bit for parse failures\nJeff King\t78d50148 parse_tag_buffer(): treat NULL tag pointer as parse error\nJeff King\tad7a4032 send-pack: check remote ref status on pack-objects failure\nJohannes Schindelin\td7633578 built-in add -i: re-implement the `diff` command\nJohannes Schindelin\t1942ee44 built-in add -i: wire up the new C code for the `patch` command\nJohannes Schindelin\tc54ef5e4 built-in add -i: re-implement `revert` in C\nJohannes Schindelin\tab1e1ccc built-in add -i: re-implement `add-untracked` in C\nJohannes Schindelin\t0c3944a6 add-interactive: make sure to release `rev.prune_data`\nJohannes Schindelin\ta8c45be9 built-in add -i: implement the `update` command\nJohannes Schindelin\t8746e072 built-in add -i: implement the `patch` command\nJohannes Schindelin\tf83dff60 Start to implement a built-in version of `git add --interactive`\nJohannes Schindelin\tc08171d1 built-in add -i: allow filtering the modified files list\nJohannes Schindelin\t4d17fd25 remote-curl: unbreak http.extraHeader with custom allocators\nJohannes Schindelin\tf37c2264 built-in add -i: prepare for multi-selection commands\nJohannes Schindelin\t76b74323 built-in add -i: show unique prefixes of the commands\nJohannes Schindelin\tb38dd9e7 strbuf: add a helper function to call the editor \"on an strbuf\"\nJohannes Schindelin\tbcdd297b built-in add -p: implement hunk editing\nJohannes Schindelin\t68db1cbf built-in add -i: support `?` (prompt help)\nJohannes Schindelin\t25ea47af built-in add -p: adjust hunk headers as needed\nJohannes Schindelin\t6348bfba built-in add -i: implement the main loop\nJohannes Schindelin\t116d1fa6 vreportf(): avoid relying on stdio buffering\nJohannes Schindelin\t2e697ced built-in add -i: offer the `quit` command\nJohannes Schindelin\teea4a7f4 mingw: demonstrate that all file handles are inherited by child processes\nJohannes Schindelin\t2e0afafe Add git-bundle: move objects and references by archive\nJohannes Schindelin\tb4bbbbd5 apply --allow-overlap: fix a corner case\nJohannes Schindelin\t54d9d9b2 built-in add -p: only show the applicable parts of the help text\nJohannes Schindelin\t12c24cf8 built-in add -p: color the prompt and the help text\nJohannes Schindelin\t0ecd9d27 built-in add -p: show different prompts for mode changes and deletions\nJohannes Schindelin\td6cf8733 built-in add -p: implement the '/' (\"search regex\") command\nJohannes Schindelin\tade246ef built-in add -p: implement the 'q' (\"quit\") command\nJohannes Schindelin\t7584dd3c built-in add -p: offer a helpful error message when hunk navigation failed\nJohannes Schindelin\t9254bdfb built-in add -p: implement the 'g' (\"goto\") command\nJohannes Schindelin\t2e408319 built-in add -p: show helpful hint when nothing can be staged\nJohannes Schindelin\t47dc4fd5 built-in add -p: handle deleted empty files\nJohannes Schindelin\t80399aec built-in add -p: support multi-file diffs\nJohannes Schindelin\t510aeca1 built-in add -p: implement the hunk splitting feature\nJohannes Schindelin\te3bd11b4 built-in add -p: show colored hunks by default\nJohannes Schindelin\t5906d5de built-in app -p: allow selecting a mode change as a \"hunk\"\nJohannes Schindelin\tf6aa7ecc built-in add -i: start implementing the `patch` functionality in C\nJohannes Schindelin\t11f2c0da built-in add -p: coalesce hunks after splitting them\nJohannes Schindelin\t867bc1d2 rebase-merges: move labels' whitespace mangling into `label_oid()`\nJunio C Hamano\t7034cd09 Sync with Git 2.24.1\nMatthew Rogers\tcd552227 rebase -r: let `label` generate safer labels\nMike Hommey\t0aa0c2b2 revision: free topo_walk_info before creating a new one in init_topo_walk\nPhillip Wood\t49697cb7 move run_commit_hook() to libgit and use it there\nPhillip Wood\t2d05ef27 sequencer: fix empty commit check when amending\nRobin H. Johnson\t79862b6b bundle-create: progress output control\nRobin H. Johnson\t73c3253d bundle: framework for options before bundle file\nRohit Ashiwal\t08187b4c rebase -i: support --ignore-date\nRohit Ashiwal\tc068bcc5 sequencer: allow callers of read_author_script() to ignore fields\nRohit Ashiwal\tcbd8db17 rebase -i: support --committer-date-is-author-date\nSlavica Đukić\t8c159044 built-in add -i: implement the `help` command\nSlavica Đukić\t3d965c76 built-in add -i: use color in the main loop\nSlavica Đukić\t1daaebca built-in add -i: color the header in the `status` command\nSZEDER Gábor\tc72fc40d path.c: clarify two field names in 'struct common_dir'\nTanushree Tumane\t51a0a4ed bisect--helper: avoid use-after-free\nWilliam Baker\t840cef0c midx: add progress to write_midx_file\n\n\n"},{"id":"388933","messageId":"a86d6247-22cb-a240-6d9e-08a9e5ffec3f@gmail.com","threadId":"52521","inReplyTo":"02febb94-9749-c219-8fae-d109720f4c71@gmail.com","subject":"Re: Git Test Coverage Report (v2.25.0-rc0)","fromName":"Derrick Stolee","fromEmail":"stolee@gmail.com","sentAt":"2019-12-26T17:55:42Z","receivedAt":"2019-12-26T17:55:46Z","isPatch":false,"sender":{"key":"stolee@gmail.com","avatar":"https://avatars.githubusercontent.com/u/570044?v=4"},"body":"On 12/26/2019 12:19 PM, Derrick Stolee wrote:\n> Here is the test-coverage report for v2.25.0-rc0 against v2.24.1.\n\n> add-interactive.c\n> add-patch.c\n\nThese two files had a lot of changes, but they are related to\nthe \"builtin add -p\" feature, which is still not complete. Hence,\ntests do not cover this logic.\n\n> builtin/bundle.c\n> 73c3253d 143) static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) {\n> 73c3253d 145) int bundle_fd = -1;\n> 73c3253d 147) struct option options[] = {\n> 73c3253d 152) argc = parse_options_cmd_bundle(argc, argv, prefix,\n> 73c3253d 156) memset(&header, 0, sizeof(header));\n> 73c3253d 157) if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)\n> 73c3253d 158) return 1;\n> 73c3253d 159) if (!startup_info->have_repository)\n> 73c3253d 161) return !!unbundle(the_repository, &header, bundle_fd, 0) ||\n> 73c3253d 162) list_bundle_refs(&header, argc, argv);\n> 73c3253d 187) else if (!strcmp(argv[0], \"unbundle\"))\n> 73c3253d 188) result = cmd_bundle_unbundle(argc, argv, prefix);\n\nIt is unfortunate that we never had tests for \"git bundle unbundle\",\nbut this code is just a refactor of the previously-untested code.\n\n> dir.c\n> 96cc8ab5 663) pl->use_cone_patterns = 0;\n> 96cc8ab5 665) goto clear_hashmaps;\n> 190a65f9 676)    strihash(translated->pattern) :\n> 96cc8ab5 689) hashmap_add(&pl->parent_hashmap, &translated->ent);\n> 96cc8ab5 690) hashmap_remove(&pl->recursive_hashmap, &translated->ent, &data);\n> 96cc8ab5 691) free(data);\n> 96cc8ab5 692) return;\n> 96cc8ab5 698) goto clear_hashmaps;\n> 190a65f9 707)    strihash(translated->pattern) :\n> 96cc8ab5 716) hashmap_remove(&pl->parent_hashmap, &translated->ent, &data);\n> 96cc8ab5 717) free(data);\n> 96cc8ab5 718) free(translated);\n> 96cc8ab5 1280) return MATCHED;\n\nMany of these lines are related to verifying cone-mode patterns\nin the sparse-checkout file. I plan to send a series that makes\nthese checks more robust, and that will include more tests that\nshould improve coverage here. I'll try to get that out before\nthe release candidate period to ensure these uncovered lines\ndo not contain a bug that needs fixing.\n> progress.c\n> 44a4693b 308) return start_progress_delay(title, total, get_default_delay(), 1);\n\nThis is the one line in start_delayed_sparse_progress(), which\nhas no callers. Shall we delete?\n\n> revision.c\n> 0aa0c2b2 3202) static void reset_topo_walk(struct rev_info *revs)\n> 0aa0c2b2 3204) struct topo_walk_info *info = revs->topo_walk_info;\n> 0aa0c2b2 3206) clear_prio_queue(&info->explore_queue);\n> 0aa0c2b2 3207) clear_prio_queue(&info->indegree_queue);\n> 0aa0c2b2 3208) clear_prio_queue(&info->topo_queue);\n> 0aa0c2b2 3209) clear_indegree_slab(&info->indegree);\n> 0aa0c2b2 3210) clear_author_date_slab(&info->author_date);\n> 0aa0c2b2 3212) FREE_AND_NULL(revs->topo_walk_info);\n> 0aa0c2b2 3213) }\n> 0aa0c2b2 3220) reset_topo_walk(revs);\n\nWe call reset_topo_walk(revs) on line 3220 only if we run\ninit_topo_walk() a second time on the same revs (and revs->topo_walk_info\nis non-null). 0aa0c2b2 allowed this, but it appears nothing needs it right\nnow. Looks safe, anyway.\n\n> strbuf.c\n> b38dd9e7 1129) int strbuf_edit_interactively(struct strbuf *buffer, const char *path,\n\n(more add-interactive stuff here)\n\n> t/helper/test-run-command.c\n\n(these changes are Windows-specific)\n\nThose are the things that caught my eye. All new behavior\nis looking pretty well tested. Thanks, everyone!\n\nThanks,\n-Stolee\n"}]}