{"thread":{"id":"45977","subject":"[PATCH v2 0/4] Port git-add--interactive.perl:status_cmd to C","startedAt":"2017-05-16T04:00:59Z","lastAt":"2018-11-26T17:18:16Z","messageCount":7,"participants":["Daniel Ferreira","Junio C Hamano","Slavica Djukic"],"isPatch":true,"patchVersion":2,"patchTotal":4},"messages":[{"id":"319877","messageId":"1494907234-28903-1-git-send-email-bnmvco@gmail.com","threadId":"45977","inReplyTo":null,"subject":"[PATCH v2 0/4] Port git-add--interactive.perl:status_cmd to C","fromName":"Daniel Ferreira","fromEmail":"bnmvco@gmail.com","sentAt":"2017-05-16T04:00:30Z","receivedAt":"2017-05-16T04:00:59Z","isPatch":true,"sender":{"key":"bnmvco@gmail.com","avatar":"https://avatars.githubusercontent.com/u/735397?v=4"},"body":"This is the second version of a patch series to start porting\ngit-add--interactive from Perl to C.\n\nSeries:\nv1: https://public-inbox.org/git/1494009820-2090-1-git-send-email-bnmvco@gmail.com/\n\nTravis CI build: https://travis-ci.org/theiostream/git/builds/232669894\n\nI have applied most of the changes suggested by Johannes and Ævar (thank\nyou!). The one exception was Johannes' request to make this a WIP patch\nseries with a sort-of \"design\" of what's next to come. I did not do\nthis because I still have no clue...! I'll begin experimenting on\nupdate_cmd() to see if I gain some insight on this issue that I could\nbring to this series. I do think this would be a good idea, though! :)\n\n-- Daniel.\n\nDaniel Ferreira (4):\n  diff: export diffstat interface\n  add--helper: create builtin helper for interactive add\n  add--helper: implement interactive status command\n  add--interactive: use add-interactive--helper for status_cmd\n\n .gitignore                |   1 +\n Makefile                  |   1 +\n builtin.h                 |   1 +\n builtin/add--helper.c     | 285 ++++++++++++++++++++++++++++++++++++++++++++++\n diff.c                    |  17 +--\n diff.h                    |  19 +++-\n git-add--interactive.perl |   4 +-\n git.c                     |   1 +\n 8 files changed, 309 insertions(+), 20 deletions(-)\n create mode 100644 builtin/add--helper.c\n\n--\n2.7.4 (Apple Git-66)\n\n"},{"id":"319878","messageId":"1494907234-28903-2-git-send-email-bnmvco@gmail.com","threadId":"45977","inReplyTo":"1494907234-28903-1-git-send-email-bnmvco@gmail.com","subject":"[PATCH v2 1/4] diff: export diffstat interface","fromName":"Daniel Ferreira","fromEmail":"bnmvco@gmail.com","sentAt":"2017-05-16T04:00:31Z","receivedAt":"2017-05-16T04:01:01Z","isPatch":true,"sender":{"key":"bnmvco@gmail.com","avatar":"https://avatars.githubusercontent.com/u/735397?v=4"},"body":"Make the diffstat interface (namely, the diffstat_t struct and\ndiff_flush_stat) no longer be internal to diff.c and allow it to be used\nby other parts of git.\n\nThis is helpful for code that may want to easily extract information\nfrom files using the diff machinery, while flushing it differently from\nhow the show_* functions used by diff_flush() do it. One example is the\nbuiltin implementation of git-add--interactive's status.\n\nSigned-off-by: Daniel Ferreira <bnmvco@gmail.com>\n---\n diff.c | 17 +----------------\n diff.h | 19 ++++++++++++++++++-\n 2 files changed, 19 insertions(+), 17 deletions(-)\n\ndiff --git a/diff.c b/diff.c\nindex 74283d9..7c073c2 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -1460,21 +1460,6 @@ static char *pprint_rename(const char *a, const char *b)\n \treturn strbuf_detach(&name, NULL);\n }\n \n-struct diffstat_t {\n-\tint nr;\n-\tint alloc;\n-\tstruct diffstat_file {\n-\t\tchar *from_name;\n-\t\tchar *name;\n-\t\tchar *print_name;\n-\t\tunsigned is_unmerged:1;\n-\t\tunsigned is_binary:1;\n-\t\tunsigned is_renamed:1;\n-\t\tunsigned is_interesting:1;\n-\t\tuintmax_t added, deleted;\n-\t} **files;\n-};\n-\n static struct diffstat_file *diffstat_add(struct diffstat_t *diffstat,\n \t\t\t\t\t  const char *name_a,\n \t\t\t\t\t  const char *name_b)\n@@ -4310,7 +4295,7 @@ static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o)\n \trun_diff(p, o);\n }\n \n-static void diff_flush_stat(struct diff_filepair *p, struct diff_options *o,\n+void diff_flush_stat(struct diff_filepair *p, struct diff_options *o,\n \t\t\t    struct diffstat_t *diffstat)\n {\n \tif (diff_unmodified_pair(p))\ndiff --git a/diff.h b/diff.h\nindex 5be1ee7..4cdc72d 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -188,6 +188,21 @@ struct diff_options {\n \tint diff_path_counter;\n };\n \n+struct diffstat_t {\n+\tint nr;\n+\tint alloc;\n+\tstruct diffstat_file {\n+\t\tchar *from_name;\n+\t\tchar *name;\n+\t\tchar *print_name;\n+\t\tunsigned is_unmerged:1;\n+\t\tunsigned is_binary:1;\n+\t\tunsigned is_renamed:1;\n+\t\tunsigned is_interesting:1;\n+\t\tuintmax_t added, deleted;\n+\t} **files;\n+};\n+\n enum color_diff {\n \tDIFF_RESET = 0,\n \tDIFF_CONTEXT = 1,\n@@ -206,7 +221,6 @@ const char *diff_get_color(int diff_use_color, enum color_diff ix);\n \n const char *diff_line_prefix(struct diff_options *);\n \n-\n extern const char mime_boundary_leader[];\n \n extern struct combine_diff_path *diff_tree_paths(\n@@ -262,6 +276,9 @@ extern void diff_change(struct diff_options *,\n \n extern struct diff_filepair *diff_unmerge(struct diff_options *, const char *path);\n \n+void diff_flush_stat(struct diff_filepair *p, struct diff_options *o,\n+\t\t\t    struct diffstat_t *diffstat);\n+\n #define DIFF_SETUP_REVERSE      \t1\n #define DIFF_SETUP_USE_CACHE\t\t2\n #define DIFF_SETUP_USE_SIZE_CACHE\t4\n-- \n2.7.4 (Apple Git-66)\n\n"},{"id":"319879","messageId":"1494907234-28903-3-git-send-email-bnmvco@gmail.com","threadId":"45977","inReplyTo":"1494907234-28903-1-git-send-email-bnmvco@gmail.com","subject":"[PATCH v2 2/4] add--helper: create builtin helper for interactive add","fromName":"Daniel Ferreira","fromEmail":"bnmvco@gmail.com","sentAt":"2017-05-16T04:00:32Z","receivedAt":"2017-05-16T04:01:04Z","isPatch":true,"sender":{"key":"bnmvco@gmail.com","avatar":"https://avatars.githubusercontent.com/u/735397?v=4"},"body":"Create a builtin helper for git-add--interactive, which right now is not\nable to do anything.\n\nThis is the first step in an effort to convert git-add--interactive.perl\nto a C builtin, in search for better portability, expressibility and\nperformance (specially on non-POSIX systems like Windows).\n\nAdditionally, an eventual complete port of git-add--interactive would\nremove the last \"big\" Git script to have Perl as a dependency, allowing\nmost Git users to have a NOPERL build running without big losses.\n\nSigned-off-by: Daniel Ferreira <bnmvco@gmail.com>\n---\n .gitignore            | 1 +\n Makefile              | 1 +\n builtin.h             | 1 +\n builtin/add--helper.c | 6 ++++++\n git.c                 | 1 +\n 5 files changed, 10 insertions(+)\n create mode 100644 builtin/add--helper.c\n\ndiff --git a/.gitignore b/.gitignore\nindex 833ef3b..11cec05 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -11,6 +11,7 @@\n /git\n /git-add\n /git-add--interactive\n+/git-add--helper\n /git-am\n /git-annotate\n /git-apply\ndiff --git a/Makefile b/Makefile\nindex e35542e..b7f49b6 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -873,6 +873,7 @@ LIB_OBJS += xdiff-interface.o\n LIB_OBJS += zlib.o\n \n BUILTIN_OBJS += builtin/add.o\n+BUILTIN_OBJS += builtin/add--helper.o\n BUILTIN_OBJS += builtin/am.o\n BUILTIN_OBJS += builtin/annotate.o\n BUILTIN_OBJS += builtin/apply.o\ndiff --git a/builtin.h b/builtin.h\nindex 9e4a898..85b4c55 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -30,6 +30,7 @@ extern int textconv_object(const char *path, unsigned mode, const struct object_\n extern int is_builtin(const char *s);\n \n extern int cmd_add(int argc, const char **argv, const char *prefix);\n+extern int cmd_add__helper(int argc, const char **argv, const char *prefix);\n extern int cmd_am(int argc, const char **argv, const char *prefix);\n extern int cmd_annotate(int argc, const char **argv, const char *prefix);\n extern int cmd_apply(int argc, const char **argv, const char *prefix);\ndiff --git a/builtin/add--helper.c b/builtin/add--helper.c\nnew file mode 100644\nindex 0000000..6a97f0e\n--- /dev/null\n+++ b/builtin/add--helper.c\n@@ -0,0 +1,6 @@\n+#include \"builtin.h\"\n+\n+int cmd_add__helper(int argc, const char **argv, const char *prefix)\n+{\n+\treturn 0;\n+}\ndiff --git a/git.c b/git.c\nindex 8ff44f0..47ee257 100644\n--- a/git.c\n+++ b/git.c\n@@ -391,6 +391,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)\n \n static struct cmd_struct commands[] = {\n \t{ \"add\", cmd_add, RUN_SETUP | NEED_WORK_TREE },\n+\t{ \"add--helper\", cmd_add__helper, RUN_SETUP | NEED_WORK_TREE },\n \t{ \"am\", cmd_am, RUN_SETUP | NEED_WORK_TREE },\n \t{ \"annotate\", cmd_annotate, RUN_SETUP },\n \t{ \"apply\", cmd_apply, RUN_SETUP_GENTLY },\n-- \n2.7.4 (Apple Git-66)\n\n"},{"id":"319880","messageId":"1494907234-28903-4-git-send-email-bnmvco@gmail.com","threadId":"45977","inReplyTo":"1494907234-28903-1-git-send-email-bnmvco@gmail.com","subject":"[PATCH v2 3/4] add--helper: implement interactive status command","fromName":"Daniel Ferreira","fromEmail":"bnmvco@gmail.com","sentAt":"2017-05-16T04:00:33Z","receivedAt":"2017-05-16T04:01:08Z","isPatch":true,"sender":{"key":"bnmvco@gmail.com","avatar":"https://avatars.githubusercontent.com/u/735397?v=4"},"body":"Implement add--interactive's status command in the add--helper builtin.\nIt prints a numstat comparing changed files between a) the worktree and\nthe index; b) the index and the HEAD.\n\nTo do so, we use run_diff_index() and run_diff_files() to get changed\nfiles, use the diffstat API on them to get the numstat and use a\ncombination of a hashmap and qsort() to print the result in\nO(n) + O(n lg n) complexity.\n\nThis is the first add--interactive command implemented in C of those\nanticipated by 6cbc52d (\"add--helper: create builtin helper for\ninteractive add\", 2017-05-15).\n\nSigned-off-by: Daniel Ferreira <bnmvco@gmail.com>\n---\n builtin/add--helper.c | 279 ++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 279 insertions(+)\n\ndiff --git a/builtin/add--helper.c b/builtin/add--helper.c\nindex 6a97f0e..f6d35bf 100644\n--- a/builtin/add--helper.c\n+++ b/builtin/add--helper.c\n@@ -1,6 +1,285 @@\n #include \"builtin.h\"\n+#include \"color.h\"\n+#include \"diff.h\"\n+#include \"diffcore.h\"\n+#include \"hashmap.h\"\n+#include \"revision.h\"\n+\n+#define HEADER_INDENT \"      \"\n+\n+enum collection_phase {\n+\tWORKTREE,\n+\tINDEX\n+};\n+\n+struct file_stat {\n+\tstruct hashmap_entry ent;\n+\tstruct {\n+\t\tuintmax_t added, deleted;\n+\t} index, worktree;\n+\tchar name[FLEX_ARRAY];\n+};\n+\n+struct collection_status {\n+\tenum collection_phase phase;\n+\n+\tconst char *reference;\n+\tstruct pathspec pathspec;\n+\n+\tstruct hashmap file_map;\n+};\n+\n+static int use_color = -1;\n+enum color_add_i {\n+\tCOLOR_PROMPT,\n+\tCOLOR_HEADER,\n+\tCOLOR_HELP,\n+\tCOLOR_ERROR\n+};\n+\n+static char colors[][COLOR_MAXLEN] = {\n+\tGIT_COLOR_BOLD_BLUE, /* Prompt */\n+\tGIT_COLOR_BOLD,      /* Header */\n+\tGIT_COLOR_BOLD_RED,  /* Help */\n+\tGIT_COLOR_BOLD_RED   /* Error */\n+};\n+\n+static const char *get_color(enum color_add_i ix)\n+{\n+\tif (want_color(use_color))\n+\t\treturn colors[ix];\n+\treturn \"\";\n+}\n+\n+static int parse_color_slot(const char *slot)\n+{\n+\tif (!strcasecmp(slot, \"prompt\"))\n+\t\treturn COLOR_PROMPT;\n+\tif (!strcasecmp(slot, \"header\"))\n+\t\treturn COLOR_HEADER;\n+\tif (!strcasecmp(slot, \"help\"))\n+\t\treturn COLOR_HELP;\n+\tif (!strcasecmp(slot, \"error\"))\n+\t\treturn COLOR_ERROR;\n+\n+\treturn -1;\n+}\n+\n+static int add_i_config(const char *var,\n+\t\tconst char *value, void *cbdata)\n+{\n+\tconst char *name;\n+\n+\tif (!strcmp(var, \"color.interactive\")) {\n+\t\tuse_color = git_config_colorbool(var, value);\n+\t\treturn 0;\n+\t}\n+\n+\tif (skip_prefix(var, \"color.interactive\", &name)) {\n+\t\tint slot = parse_color_slot(name);\n+\t\tif (slot < 0)\n+\t\t\treturn 0;\n+\t\tif (!value)\n+\t\t\treturn config_error_nonbool(var);\n+\t\treturn color_parse(value, colors[slot]);\n+\t}\n+\n+\treturn git_default_config(var, value, cbdata);\n+}\n+\n+static int hash_cmp(const void *entry, const void *entry_or_key,\n+ \t\t\t      const void *keydata)\n+{\n+ \tconst struct file_stat *e1 = entry, *e2 = entry_or_key;\n+ \tconst char *name = keydata ? keydata : e2->name;\n+\n+\treturn strcmp(e1->name, name);\n+}\n+\n+static int alphabetical_cmp(const void *a, const void *b)\n+{\n+\tstruct file_stat *f1 = *((struct file_stat **)a);\n+\tstruct file_stat *f2 = *((struct file_stat **)b);\n+\n+\treturn strcmp(f1->name, f2->name);\n+}\n+\n+static void collect_changes_cb(struct diff_queue_struct *q,\n+\t\t\t\t\t struct diff_options *options,\n+\t\t\t\t\t void *data)\n+{\n+\tstruct collection_status *s = data;\n+\tstruct diffstat_t stat = { 0 };\n+\tint i;\n+\n+\tif (!q->nr)\n+\t\treturn;\n+\n+\tfor (i = 0; i < q->nr; i++) {\n+\t\tstruct diff_filepair *p;\n+\t\tp = q->queue[i];\n+\t\tdiff_flush_stat(p, options, &stat);\n+\t}\n+\n+\tfor (i = 0; i < stat.nr; i++) {\n+\t\tstruct file_stat *entry;\n+\t\tconst char *name = stat.files[i]->name;\n+\t\tunsigned int hash = strhash(name);\n+\n+\t\tentry = hashmap_get_from_hash(&s->file_map, hash, name);\n+\t\tif (!entry) {\n+\t\t\tFLEX_ALLOC_STR(entry, name, name);\n+\t\t\thashmap_entry_init(entry, hash);\n+\t\t\thashmap_add(&s->file_map, entry);\n+\t\t}\n+\n+\t\tif (s->phase == WORKTREE) {\n+\t\t\tentry->worktree.added = stat.files[i]->added;\n+\t\t\tentry->worktree.deleted = stat.files[i]->deleted;\n+\t\t} else if (s->phase == INDEX) {\n+\t\t\tentry->index.added = stat.files[i]->added;\n+\t\t\tentry->index.deleted = stat.files[i]->deleted;\n+\t\t}\n+\t}\n+}\n+\n+static void collect_changes_worktree(struct collection_status *s)\n+{\n+\tstruct rev_info rev;\n+\n+\ts->phase = WORKTREE;\n+\n+\tinit_revisions(&rev, NULL);\n+\tsetup_revisions(0, NULL, &rev, NULL);\n+\n+\trev.max_count = 0;\n+\n+\trev.diffopt.output_format = DIFF_FORMAT_CALLBACK;\n+\trev.diffopt.format_callback = collect_changes_cb;\n+\trev.diffopt.format_callback_data = s;\n+\n+\trun_diff_files(&rev, 0);\n+}\n+\n+static void collect_changes_index(struct collection_status *s)\n+{\n+\tstruct rev_info rev;\n+\tstruct setup_revision_opt opt = { 0 };\n+\n+\ts->phase = INDEX;\n+\n+\tinit_revisions(&rev, NULL);\n+\topt.def = s->reference;\n+\tsetup_revisions(0, NULL, &rev, &opt);\n+\n+\trev.diffopt.output_format = DIFF_FORMAT_CALLBACK;\n+\trev.diffopt.format_callback = collect_changes_cb;\n+\trev.diffopt.format_callback_data = s;\n+\n+\trun_diff_index(&rev, 1);\n+}\n+\n+static void list_modified_into_status(struct collection_status *s)\n+{\n+\tcollect_changes_worktree(s);\n+\tcollect_changes_index(s);\n+}\n+\n+static void print_modified(void)\n+{\n+\tint i = 0;\n+\tstruct collection_status s;\n+\t/* TRANSLATORS: you can adjust this to align \"git add -i\" status menu */\n+\tconst char *modified_fmt = _(\"%12s %12s %s\");\n+\tconst char *header_color = get_color(COLOR_HEADER);\n+\tunsigned char sha1[20];\n+\n+\tstruct hashmap_iter iter;\n+\tstruct file_stat **files;\n+\tstruct file_stat *entry;\n+\n+\tif (read_cache() < 0)\n+\t\treturn;\n+\n+\ts.reference = !get_sha1(\"HEAD\", sha1) ? \"HEAD\": EMPTY_TREE_SHA1_HEX;\n+\thashmap_init(&s.file_map, hash_cmp, 0);\n+\tlist_modified_into_status(&s);\n+\n+\tif (s.file_map.size < 1) {\n+\t\tprintf(\"\\n\");\n+\t\treturn;\n+\t}\n+\n+\tprintf(HEADER_INDENT);\n+\tcolor_fprintf(stdout, header_color, modified_fmt, _(\"staged\"),\n+\t\t\t_(\"unstaged\"), _(\"path\"));\n+\tprintf(\"\\n\");\n+\n+\thashmap_iter_init(&s.file_map, &iter);\n+\n+\tfiles = xcalloc(s.file_map.size, sizeof(struct file_stat *));\n+\twhile ((entry = hashmap_iter_next(&iter))) {\n+\t\tfiles[i++] = entry;\n+\t}\n+\tQSORT(files, s.file_map.size, alphabetical_cmp);\n+\n+\tfor (i = 0; i < s.file_map.size; i++) {\n+\t\tstruct file_stat *f = files[i];\n+\n+\t\tchar worktree_changes[50];\n+\t\tchar index_changes[50];\n+\n+\t\tif (f->worktree.added || f->worktree.deleted)\n+\t\t\tsnprintf(worktree_changes, 50, \"+%ju/-%ju\", f->worktree.added,\n+\t\t\t\t\tf->worktree.deleted);\n+\t\telse\n+\t\t\tsnprintf(worktree_changes, 50, \"%s\", _(\"nothing\"));\n+\n+\t\tif (f->index.added || f->index.deleted)\n+\t\t\tsnprintf(index_changes, 50, \"+%ju/-%ju\", f->index.added,\n+\t\t\t\t\tf->index.deleted);\n+\t\telse\n+\t\t\tsnprintf(index_changes, 50, \"%s\", _(\"unchanged\"));\n+\n+\t\tprintf(\" %2d: \", i + 1);\n+\t\tprintf(modified_fmt, index_changes, worktree_changes, f->name);\n+\t\tprintf(\"\\n\");\n+\t}\n+\tprintf(\"\\n\");\n+\n+\tfree(files);\n+}\n+\n+static const char * const builtin_add_helper_usage[] = {\n+\tN_(\"git add-interactive--helper <command>\"),\n+\tNULL\n+};\n+\n+enum cmd_mode {\n+\tDEFAULT = 0,\n+\tSTATUS\n+};\n \n int cmd_add__helper(int argc, const char **argv, const char *prefix)\n {\n+\tenum cmd_mode mode = DEFAULT;\n+\n+\tstruct option options[] = {\n+\t\tOPT_CMDMODE(0, \"status\", &mode,\n+\t\t\t N_(\"print status information with diffstat\"), STATUS),\n+\t\tOPT_END()\n+\t};\n+\n+\tgit_config(add_i_config, NULL);\n+\targc = parse_options(argc, argv, NULL, options,\n+\t\t\t     builtin_add_helper_usage,\n+\t\t\t     PARSE_OPT_KEEP_ARGV0);\n+\n+\tif (mode == STATUS)\n+\t\tprint_modified();\n+\telse\n+\t\tusage_with_options(builtin_add_helper_usage,\n+\t\t\t\t   options);\n+\n \treturn 0;\n }\n-- \n2.7.4 (Apple Git-66)\n\n"},{"id":"319881","messageId":"1494907234-28903-5-git-send-email-bnmvco@gmail.com","threadId":"45977","inReplyTo":"1494907234-28903-1-git-send-email-bnmvco@gmail.com","subject":"[PATCH v2 4/4] add--interactive: use add-interactive--helper for status_cmd","fromName":"Daniel Ferreira","fromEmail":"bnmvco@gmail.com","sentAt":"2017-05-16T04:00:34Z","receivedAt":"2017-05-16T04:01:10Z","isPatch":true,"sender":{"key":"bnmvco@gmail.com","avatar":"https://avatars.githubusercontent.com/u/735397?v=4"},"body":"Call the newly introduced git-add-interactive--helper builtin on\nstatus_cmd() instead of relying on git-add--interactive's Perl\nfunctions to build print the numstat.\n\nSigned-off-by: Daniel Ferreira <bnmvco@gmail.com>\n---\n git-add--interactive.perl | 4 +---\n 1 file changed, 1 insertion(+), 3 deletions(-)\n\ndiff --git a/git-add--interactive.perl b/git-add--interactive.perl\nindex 709a5f6..8c192bf 100755\n--- a/git-add--interactive.perl\n+++ b/git-add--interactive.perl\n@@ -632,9 +632,7 @@ EOF\n }\n \n sub status_cmd {\n-\tlist_and_choose({ LIST_ONLY => 1, HEADER => $status_head },\n-\t\t\tlist_modified());\n-\tprint \"\\n\";\n+\tsystem(qw(git add--helper --status));\n }\n \n sub say_n_paths {\n-- \n2.7.4 (Apple Git-66)\n\n"},{"id":"319886","messageId":"xmqqinl12z5d.fsf@gitster.mtv.corp.google.com","threadId":"45977","inReplyTo":"1494907234-28903-4-git-send-email-bnmvco@gmail.com","subject":"Re: [PATCH v2 3/4] add--helper: implement interactive status command","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-16T04:39:42Z","receivedAt":"2017-05-16T04:39:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Ferreira <bnmvco@gmail.com> writes:\n\n> +\tif (!q->nr)\n> +\t\treturn;\n> +\n> +\tfor (i = 0; i < q->nr; i++) {\n> +\t\tstruct diff_filepair *p;\n> +\t\tp = q->queue[i];\n> +\t\tdiff_flush_stat(p, options, &stat);\n> +\t}\n\nCommenting just on the part that interacts with the diff machinery,\nwithout/before carefully reading the remainder of the patches.\n\nI suspect that refactoring this part out of diff_flush() into a\nhelper function \"compute_diffstat()\", like this:\n\ndiff --git a/diff.c b/diff.c\nindex 74283d9001..a42ff42e92 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -4770,12 +4770,7 @@ void diff_flush(struct diff_options *options)\n \t    dirstat_by_line) {\n \t\tstruct diffstat_t diffstat;\n \n-\t\tmemset(&diffstat, 0, sizeof(struct diffstat_t));\n-\t\tfor (i = 0; i < q->nr; i++) {\n-\t\t\tstruct diff_filepair *p = q->queue[i];\n-\t\t\tif (check_pair_status(p))\n-\t\t\t\tdiff_flush_stat(p, options, &diffstat);\n-\t\t}\n+\t\tcompute_diffstat(&options, &diffstat);\n \t\tif (output_format & DIFF_FORMAT_NUMSTAT)\n \t\t\tshow_numstat(&diffstat, options);\n \t\tif (output_format & DIFF_FORMAT_DIFFSTAT)\n\nand then exporting that function and \"struct diffstat_t\" to your\nhelper, may make it a better API, rather than having the callers to\ncall diff_flush_stat() for each and every path.\n\n"},{"id":"364086","messageId":"f29f31a2-4e89-7ae8-26ee-12aba67cee10@gmail.com","threadId":"45977","inReplyTo":"1494907234-28903-1-git-send-email-bnmvco@gmail.com","subject":"Re: [PATCH v2 0/4] Port git-add--interactive.perl:status_cmd to C","fromName":"Slavica Djukic","fromEmail":"slavicadj.ip2018@gmail.com","sentAt":"2018-11-26T17:18:09Z","receivedAt":"2018-11-26T17:18:16Z","isPatch":true,"sender":{"key":"slavicadj.ip2018@gmail.com","avatar":null},"body":"Hi Daniel,\n\nOn 16-May-17 6:00 AM, Daniel Ferreira wrote:\n> This is the second version of a patch series to start porting\n> git-add--interactive from Perl to C.\n>\n> Series:\n> v1: https://public-inbox.org/git/1494009820-2090-1-git-send-email-bnmvco@gmail.com/\n>\n> Travis CI build: https://travis-ci.org/theiostream/git/builds/232669894\n>\n> I have applied most of the changes suggested by Johannes and Ã†var (thank\n> you!). The one exception was Johannes' request to make this a WIP patch\n> series with a sort-of \"design\" of what's next to come. I did not do\n> this because I still have no clue...! I'll begin experimenting on\n> update_cmd() to see if I gain some insight on this issue that I could\n> bring to this series. I do think this would be a good idea, though! :)\n\n\nI am Slavica Đukic, Outreachy intern for Git (Dec-March 2018/19 round).\n\nProject I'll be working on is \"Turn git add -i to built-in\".\n\nWould you mind if I use your work so far as head start?\n\n\n>\n> -- Daniel.\n>\n> Daniel Ferreira (4):\n>    diff: export diffstat interface\n>    add--helper: create builtin helper for interactive add\n>    add--helper: implement interactive status command\n>    add--interactive: use add-interactive--helper for status_cmd\n>\n>   .gitignore                |   1 +\n>   Makefile                  |   1 +\n>   builtin.h                 |   1 +\n>   builtin/add--helper.c     | 285 ++++++++++++++++++++++++++++++++++++++++++++++\n>   diff.c                    |  17 +--\n>   diff.h                    |  19 +++-\n>   git-add--interactive.perl |   4 +-\n>   git.c                     |   1 +\n>   8 files changed, 309 insertions(+), 20 deletions(-)\n>   create mode 100644 builtin/add--helper.c\n>\n> --\n> 2.7.4 (Apple Git-66)\n>\n>\n>\nThank you,\nSlavica\n"}]}