Skip to content

Commit cbc5c2f

Browse files
pks-tgitster
authored andcommitted
add-patch: split out struct interactive_options
The `struct add_p_opt` is reused both by our infra for "git add -p" and "git add -i". Users of `run_add_i()` for example are expected to pass `struct add_p_opt`. This is somewhat confusing and raises the question of which options apply to what part of the stack. But things are even more confusing than that: while callers are expected to pass in `struct add_p_opt`, these options ultimately get used to initialize a `struct add_i_state` that is used by both subsystems. So we are basically going full circle here. Refactor the code and split out a new `struct interactive_options` that hosts common options used by both. These options are then applied to a `struct interactive_config` that hosts common configuration. This refactoring doesn't yet fully detangle the two subsystems from one another, as we still end up calling `init_add_i_state()` in the "git add -p" subsystem. This will be fixed in a subsequent commit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 68b1491 commit cbc5c2f

File tree

10 files changed

+270
-239
lines changed

10 files changed

+270
-239
lines changed

add-interactive.c

Lines changed: 36 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include "git-compat-util.h"
44
#include "add-interactive.h"
55
#include "color.h"
6-
#include "config.h"
76
#include "diffcore.h"
87
#include "gettext.h"
98
#include "hash.h"
@@ -20,119 +19,18 @@
2019
#include "prompt.h"
2120
#include "tree.h"
2221

23-
static void init_color(struct repository *r, enum git_colorbool use_color,
24-
const char *section_and_slot, char *dst,
25-
const char *default_color)
26-
{
27-
char *key = xstrfmt("color.%s", section_and_slot);
28-
const char *value;
29-
30-
if (!want_color(use_color))
31-
dst[0] = '\0';
32-
else if (repo_config_get_value(r, key, &value) ||
33-
color_parse(value, dst))
34-
strlcpy(dst, default_color, COLOR_MAXLEN);
35-
36-
free(key);
37-
}
38-
39-
static enum git_colorbool check_color_config(struct repository *r, const char *var)
40-
{
41-
const char *value;
42-
enum git_colorbool ret;
43-
44-
if (repo_config_get_value(r, var, &value))
45-
ret = GIT_COLOR_UNKNOWN;
46-
else
47-
ret = git_config_colorbool(var, value);
48-
49-
/*
50-
* Do not rely on want_color() to fall back to color.ui for us. It uses
51-
* the value parsed by git_color_config(), which may not have been
52-
* called by the main command.
53-
*/
54-
if (ret == GIT_COLOR_UNKNOWN &&
55-
!repo_config_get_value(r, "color.ui", &value))
56-
ret = git_config_colorbool("color.ui", value);
57-
58-
return ret;
59-
}
60-
6122
void init_add_i_state(struct add_i_state *s, struct repository *r,
62-
struct add_p_opt *add_p_opt)
23+
struct interactive_options *opts)
6324
{
6425
s->r = r;
65-
s->context = -1;
66-
s->interhunkcontext = -1;
67-
68-
s->use_color_interactive = check_color_config(r, "color.interactive");
69-
70-
init_color(r, s->use_color_interactive, "interactive.header",
71-
s->header_color, GIT_COLOR_BOLD);
72-
init_color(r, s->use_color_interactive, "interactive.help",
73-
s->help_color, GIT_COLOR_BOLD_RED);
74-
init_color(r, s->use_color_interactive, "interactive.prompt",
75-
s->prompt_color, GIT_COLOR_BOLD_BLUE);
76-
init_color(r, s->use_color_interactive, "interactive.error",
77-
s->error_color, GIT_COLOR_BOLD_RED);
78-
strlcpy(s->reset_color_interactive,
79-
want_color(s->use_color_interactive) ? GIT_COLOR_RESET : "", COLOR_MAXLEN);
80-
81-
s->use_color_diff = check_color_config(r, "color.diff");
82-
83-
init_color(r, s->use_color_diff, "diff.frag", s->fraginfo_color,
84-
diff_get_color(s->use_color_diff, DIFF_FRAGINFO));
85-
init_color(r, s->use_color_diff, "diff.context", s->context_color,
86-
"fall back");
87-
if (!strcmp(s->context_color, "fall back"))
88-
init_color(r, s->use_color_diff, "diff.plain",
89-
s->context_color,
90-
diff_get_color(s->use_color_diff, DIFF_CONTEXT));
91-
init_color(r, s->use_color_diff, "diff.old", s->file_old_color,
92-
diff_get_color(s->use_color_diff, DIFF_FILE_OLD));
93-
init_color(r, s->use_color_diff, "diff.new", s->file_new_color,
94-
diff_get_color(s->use_color_diff, DIFF_FILE_NEW));
95-
strlcpy(s->reset_color_diff,
96-
want_color(s->use_color_diff) ? GIT_COLOR_RESET : "", COLOR_MAXLEN);
97-
98-
FREE_AND_NULL(s->interactive_diff_filter);
99-
repo_config_get_string(r, "interactive.difffilter",
100-
&s->interactive_diff_filter);
101-
102-
FREE_AND_NULL(s->interactive_diff_algorithm);
103-
repo_config_get_string(r, "diff.algorithm",
104-
&s->interactive_diff_algorithm);
105-
106-
if (!repo_config_get_int(r, "diff.context", &s->context))
107-
if (s->context < 0)
108-
die(_("%s cannot be negative"), "diff.context");
109-
if (!repo_config_get_int(r, "diff.interHunkContext", &s->interhunkcontext))
110-
if (s->interhunkcontext < 0)
111-
die(_("%s cannot be negative"), "diff.interHunkContext");
112-
113-
repo_config_get_bool(r, "interactive.singlekey", &s->use_single_key);
114-
if (s->use_single_key)
115-
setbuf(stdin, NULL);
116-
117-
if (add_p_opt->context != -1) {
118-
if (add_p_opt->context < 0)
119-
die(_("%s cannot be negative"), "--unified");
120-
s->context = add_p_opt->context;
121-
}
122-
if (add_p_opt->interhunkcontext != -1) {
123-
if (add_p_opt->interhunkcontext < 0)
124-
die(_("%s cannot be negative"), "--inter-hunk-context");
125-
s->interhunkcontext = add_p_opt->interhunkcontext;
126-
}
26+
interactive_config_init(&s->cfg, r, opts);
12727
}
12828

12929
void clear_add_i_state(struct add_i_state *s)
13030
{
131-
FREE_AND_NULL(s->interactive_diff_filter);
132-
FREE_AND_NULL(s->interactive_diff_algorithm);
31+
interactive_config_clear(&s->cfg);
13332
memset(s, 0, sizeof(*s));
134-
s->use_color_interactive = GIT_COLOR_UNKNOWN;
135-
s->use_color_diff = GIT_COLOR_UNKNOWN;
33+
interactive_config_clear(&s->cfg);
13634
}
13735

13836
/*
@@ -286,7 +184,7 @@ static void list(struct add_i_state *s, struct string_list *list, int *selected,
286184
return;
287185

288186
if (opts->header)
289-
color_fprintf_ln(stdout, s->header_color,
187+
color_fprintf_ln(stdout, s->cfg.header_color,
290188
"%s", opts->header);
291189

292190
for (i = 0; i < list->nr; i++) {
@@ -354,7 +252,7 @@ static ssize_t list_and_choose(struct add_i_state *s,
354252

355253
list(s, &items->items, items->selected, &opts->list_opts);
356254

357-
color_fprintf(stdout, s->prompt_color, "%s", opts->prompt);
255+
color_fprintf(stdout, s->cfg.prompt_color, "%s", opts->prompt);
358256
fputs(singleton ? "> " : ">> ", stdout);
359257
fflush(stdout);
360258

@@ -432,7 +330,7 @@ static ssize_t list_and_choose(struct add_i_state *s,
432330

433331
if (from < 0 || from >= items->items.nr ||
434332
(singleton && from + 1 != to)) {
435-
color_fprintf_ln(stderr, s->error_color,
333+
color_fprintf_ln(stderr, s->cfg.error_color,
436334
_("Huh (%s)?"), p);
437335
break;
438336
} else if (singleton) {
@@ -992,7 +890,7 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps,
992890
free(files->items.items[i].string);
993891
} else if (item->index.unmerged ||
994892
item->worktree.unmerged) {
995-
color_fprintf_ln(stderr, s->error_color,
893+
color_fprintf_ln(stderr, s->cfg.error_color,
996894
_("ignoring unmerged: %s"),
997895
files->items.items[i].string);
998896
free(item);
@@ -1014,9 +912,9 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps,
1014912
opts->prompt = N_("Patch update");
1015913
count = list_and_choose(s, files, opts);
1016914
if (count > 0) {
1017-
struct add_p_opt add_p_opt = {
1018-
.context = s->context,
1019-
.interhunkcontext = s->interhunkcontext,
915+
struct interactive_options opts = {
916+
.context = s->cfg.context,
917+
.interhunkcontext = s->cfg.interhunkcontext,
1020918
};
1021919
struct strvec args = STRVEC_INIT;
1022920
struct pathspec ps_selected = { 0 };
@@ -1028,7 +926,7 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps,
1028926
parse_pathspec(&ps_selected,
1029927
PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL,
1030928
PATHSPEC_LITERAL_PATH, "", args.v);
1031-
res = run_add_p(s->r, ADD_P_ADD, &add_p_opt, NULL, &ps_selected);
929+
res = run_add_p(s->r, ADD_P_ADD, &opts, NULL, &ps_selected);
1032930
strvec_clear(&args);
1033931
clear_pathspec(&ps_selected);
1034932
}
@@ -1064,10 +962,10 @@ static int run_diff(struct add_i_state *s, const struct pathspec *ps,
1064962
struct child_process cmd = CHILD_PROCESS_INIT;
1065963

1066964
strvec_pushl(&cmd.args, "git", "diff", "-p", "--cached", NULL);
1067-
if (s->context != -1)
1068-
strvec_pushf(&cmd.args, "--unified=%i", s->context);
1069-
if (s->interhunkcontext != -1)
1070-
strvec_pushf(&cmd.args, "--inter-hunk-context=%i", s->interhunkcontext);
965+
if (s->cfg.context != -1)
966+
strvec_pushf(&cmd.args, "--unified=%i", s->cfg.context);
967+
if (s->cfg.interhunkcontext != -1)
968+
strvec_pushf(&cmd.args, "--inter-hunk-context=%i", s->cfg.interhunkcontext);
1071969
strvec_pushl(&cmd.args, oid_to_hex(!is_initial ? &oid :
1072970
s->r->hash_algo->empty_tree), "--", NULL);
1073971
for (i = 0; i < files->items.nr; i++)
@@ -1085,39 +983,39 @@ static int run_help(struct add_i_state *s, const struct pathspec *ps UNUSED,
1085983
struct prefix_item_list *files UNUSED,
1086984
struct list_and_choose_options *opts UNUSED)
1087985
{
1088-
color_fprintf_ln(stdout, s->help_color, "status - %s",
986+
color_fprintf_ln(stdout, s->cfg.help_color, "status - %s",
1089987
_("show paths with changes"));
1090-
color_fprintf_ln(stdout, s->help_color, "update - %s",
988+
color_fprintf_ln(stdout, s->cfg.help_color, "update - %s",
1091989
_("add working tree state to the staged set of changes"));
1092-
color_fprintf_ln(stdout, s->help_color, "revert - %s",
990+
color_fprintf_ln(stdout, s->cfg.help_color, "revert - %s",
1093991
_("revert staged set of changes back to the HEAD version"));
1094-
color_fprintf_ln(stdout, s->help_color, "patch - %s",
992+
color_fprintf_ln(stdout, s->cfg.help_color, "patch - %s",
1095993
_("pick hunks and update selectively"));
1096-
color_fprintf_ln(stdout, s->help_color, "diff - %s",
994+
color_fprintf_ln(stdout, s->cfg.help_color, "diff - %s",
1097995
_("view diff between HEAD and index"));
1098-
color_fprintf_ln(stdout, s->help_color, "add untracked - %s",
996+
color_fprintf_ln(stdout, s->cfg.help_color, "add untracked - %s",
1099997
_("add contents of untracked files to the staged set of changes"));
1100998

1101999
return 0;
11021000
}
11031001

11041002
static void choose_prompt_help(struct add_i_state *s)
11051003
{
1106-
color_fprintf_ln(stdout, s->help_color, "%s",
1004+
color_fprintf_ln(stdout, s->cfg.help_color, "%s",
11071005
_("Prompt help:"));
1108-
color_fprintf_ln(stdout, s->help_color, "1 - %s",
1006+
color_fprintf_ln(stdout, s->cfg.help_color, "1 - %s",
11091007
_("select a single item"));
1110-
color_fprintf_ln(stdout, s->help_color, "3-5 - %s",
1008+
color_fprintf_ln(stdout, s->cfg.help_color, "3-5 - %s",
11111009
_("select a range of items"));
1112-
color_fprintf_ln(stdout, s->help_color, "2-3,6-9 - %s",
1010+
color_fprintf_ln(stdout, s->cfg.help_color, "2-3,6-9 - %s",
11131011
_("select multiple ranges"));
1114-
color_fprintf_ln(stdout, s->help_color, "foo - %s",
1012+
color_fprintf_ln(stdout, s->cfg.help_color, "foo - %s",
11151013
_("select item based on unique prefix"));
1116-
color_fprintf_ln(stdout, s->help_color, "-... - %s",
1014+
color_fprintf_ln(stdout, s->cfg.help_color, "-... - %s",
11171015
_("unselect specified items"));
1118-
color_fprintf_ln(stdout, s->help_color, "* - %s",
1016+
color_fprintf_ln(stdout, s->cfg.help_color, "* - %s",
11191017
_("choose all items"));
1120-
color_fprintf_ln(stdout, s->help_color, " - %s",
1018+
color_fprintf_ln(stdout, s->cfg.help_color, " - %s",
11211019
_("(empty) finish selecting"));
11221020
}
11231021

@@ -1152,7 +1050,7 @@ static void print_command_item(int i, int selected UNUSED,
11521050

11531051
static void command_prompt_help(struct add_i_state *s)
11541052
{
1155-
const char *help_color = s->help_color;
1053+
const char *help_color = s->cfg.help_color;
11561054
color_fprintf_ln(stdout, help_color, "%s", _("Prompt help:"));
11571055
color_fprintf_ln(stdout, help_color, "1 - %s",
11581056
_("select a numbered item"));
@@ -1163,7 +1061,7 @@ static void command_prompt_help(struct add_i_state *s)
11631061
}
11641062

11651063
int run_add_i(struct repository *r, const struct pathspec *ps,
1166-
struct add_p_opt *add_p_opt)
1064+
struct interactive_options *interactive_opts)
11671065
{
11681066
struct add_i_state s = { NULL };
11691067
struct print_command_item_data data = { "[", "]" };
@@ -1206,15 +1104,15 @@ int run_add_i(struct repository *r, const struct pathspec *ps,
12061104
->util = util;
12071105
}
12081106

1209-
init_add_i_state(&s, r, add_p_opt);
1107+
init_add_i_state(&s, r, interactive_opts);
12101108

12111109
/*
12121110
* When color was asked for, use the prompt color for
12131111
* highlighting, otherwise use square brackets.
12141112
*/
1215-
if (want_color(s.use_color_interactive)) {
1216-
data.color = s.prompt_color;
1217-
data.reset = s.reset_color_interactive;
1113+
if (want_color(s.cfg.use_color_interactive)) {
1114+
data.color = s.cfg.prompt_color;
1115+
data.reset = s.cfg.reset_color_interactive;
12181116
}
12191117
print_file_item_data.color = data.color;
12201118
print_file_item_data.reset = data.reset;

add-interactive.h

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,20 @@
22
#define ADD_INTERACTIVE_H
33

44
#include "add-patch.h"
5-
#include "color.h"
65

76
struct pathspec;
87
struct repository;
98

109
struct add_i_state {
1110
struct repository *r;
12-
enum git_colorbool use_color_interactive;
13-
enum git_colorbool use_color_diff;
14-
char header_color[COLOR_MAXLEN];
15-
char help_color[COLOR_MAXLEN];
16-
char prompt_color[COLOR_MAXLEN];
17-
char error_color[COLOR_MAXLEN];
18-
char reset_color_interactive[COLOR_MAXLEN];
19-
20-
char fraginfo_color[COLOR_MAXLEN];
21-
char context_color[COLOR_MAXLEN];
22-
char file_old_color[COLOR_MAXLEN];
23-
char file_new_color[COLOR_MAXLEN];
24-
char reset_color_diff[COLOR_MAXLEN];
25-
26-
int use_single_key;
27-
char *interactive_diff_filter, *interactive_diff_algorithm;
28-
int context, interhunkcontext;
11+
struct interactive_config cfg;
2912
};
3013

3114
void init_add_i_state(struct add_i_state *s, struct repository *r,
32-
struct add_p_opt *add_p_opt);
15+
struct interactive_options *opts);
3316
void clear_add_i_state(struct add_i_state *s);
3417

3518
int run_add_i(struct repository *r, const struct pathspec *ps,
36-
struct add_p_opt *add_p_opt);
19+
struct interactive_options *opts);
3720

3821
#endif

0 commit comments

Comments
 (0)