roll wt_status_state into wt_status and populate in the collect phase

Status variables were initialized in the collect phase and some variables were later freed in the print functions. A "struct wt_status" used to be sufficient for the output phase to work. It was designed to be filled in the collect phase and consumed in the output phase, but over time some fields were added and output phase started filling the fields. A "struct wt_status_state" that was used in other codepaths turned out to be useful in the "git status" output. This is not tied to "struct wt_status", so filling in the collect phase was not consistently followed. Move the status state structure variables into the status state structure and populate them in the collect functions. Create a new function to free the buffers that were being freed in the print function. Call this new function in commit.c where both the collect and print functions were being called. Based on a patch suggestion by Junio C Hamano. [1] [1] https://public-inbox.org/git/xmqqr2i5ueg4.fsf@gitster-ct.c.googlers.com/ Signed-off-by: Stephen P. Smith <ischis2@cox.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Stephen P. Smith committed Sep 30, 2018 at 07:12 UTC 73ba5d78b4e5d96b2c521e3d0a2ec86c26a2d25b
3 files changed +82 -93
builtin/commit.c
+3
@@ -506,6 +506,7 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
506
507 wt_status_collect(s);
508 wt_status_print(s);
509 + wt_status_collect_free_buffers(s);
510
511 return s->committable;
512 }
@@ -1388,6 +1389,8 @@ int cmd_status(int argc, const char **argv, const char *prefix)
1389 s.prefix = prefix;
1390
1391 wt_status_print(&s);
1392 + wt_status_collect_free_buffers(&s);
1393 +
1394 return 0;
1395 }
1396
wt-status.c
+59 -75
@@ -744,21 +744,25 @@ static int has_unmerged(struct wt_status *s)
744
745 void wt_status_collect(struct wt_status *s)
746 {
747 - struct wt_status_state state;
747 wt_status_collect_changes_worktree(s);
749 -
748 if (s->is_initial)
749 wt_status_collect_changes_initial(s);
750 else
751 wt_status_collect_changes_index(s);
752 wt_status_collect_untracked(s);
753
756 - memset(&state, 0, sizeof(state));
757 - wt_status_get_state(&state, s->branch && !strcmp(s->branch, "HEAD"));
758 - if (state.merge_in_progress && !has_unmerged(s))
754 + wt_status_get_state(&s->state, s->branch && !strcmp(s->branch, "HEAD"));
755 + if (s->state.merge_in_progress && !has_unmerged(s))
756 s->committable = 1;
757 }
758
759 +void wt_status_collect_free_buffers(struct wt_status *s)
760 +{
761 + free(s->state.branch);
762 + free(s->state.onto);
763 + free(s->state.detached_from);
764 +}
765 +
766 static void wt_longstatus_print_unmerged(struct wt_status *s)
767 {
768 int shown_header = 0;
@@ -1087,8 +1091,7 @@ static void wt_longstatus_print_tracking(struct wt_status *s)
1091 }
1092
1093 static void show_merge_in_progress(struct wt_status *s,
1090 - struct wt_status_state *state,
1091 - const char *color)
1094 + const char *color)
1095 {
1096 if (has_unmerged(s)) {
1097 status_printf_ln(s, color, _("You have unmerged paths."));
@@ -1109,16 +1112,15 @@ static void show_merge_in_progress(struct wt_status *s,
1112 }
1113
1114 static void show_am_in_progress(struct wt_status *s,
1112 - struct wt_status_state *state,
1115 const char *color)
1116 {
1117 status_printf_ln(s, color,
1118 _("You are in the middle of an am session."));
1117 - if (state->am_empty_patch)
1119 + if (s->state.am_empty_patch)
1120 status_printf_ln(s, color,
1121 _("The current patch is empty."));
1122 if (s->hints) {
1121 - if (!state->am_empty_patch)
1123 + if (!s->state.am_empty_patch)
1124 status_printf_ln(s, color,
1125 _(" (fix conflicts and then run \"git am --continue\")"));
1126 status_printf_ln(s, color,
@@ -1242,10 +1244,9 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)
1244 }
1245
1246 static void show_rebase_information(struct wt_status *s,
1245 - struct wt_status_state *state,
1246 - const char *color)
1247 + const char *color)
1248 {
1248 - if (state->rebase_interactive_in_progress) {
1249 + if (s->state.rebase_interactive_in_progress) {
1250 int i;
1251 int nr_lines_to_show = 2;
1252
@@ -1296,28 +1297,26 @@ static void show_rebase_information(struct wt_status *s,
1297 }
1298
1299 static void print_rebase_state(struct wt_status *s,
1299 - struct wt_status_state *state,
1300 - const char *color)
1300 + const char *color)
1301 {
1302 - if (state->branch)
1302 + if (s->state.branch)
1303 status_printf_ln(s, color,
1304 _("You are currently rebasing branch '%s' on '%s'."),
1305 - state->branch,
1306 - state->onto);
1305 + s->state.branch,
1306 + s->state.onto);
1307 else
1308 status_printf_ln(s, color,
1309 _("You are currently rebasing."));
1310 }
1311
1312 static void show_rebase_in_progress(struct wt_status *s,
1313 - struct wt_status_state *state,
1314 - const char *color)
1313 + const char *color)
1314 {
1315 struct stat st;
1316
1318 - show_rebase_information(s, state, color);
1317 + show_rebase_information(s, color);
1318 if (has_unmerged(s)) {
1320 - print_rebase_state(s, state, color);
1319 + print_rebase_state(s, color);
1320 if (s->hints) {
1321 status_printf_ln(s, color,
1322 _(" (fix conflicts and then run \"git rebase --continue\")"));
@@ -1326,17 +1325,18 @@ static void show_rebase_in_progress(struct wt_status *s,
1325 status_printf_ln(s, color,
1326 _(" (use \"git rebase --abort\" to check out the original branch)"));
1327 }
1329 - } else if (state->rebase_in_progress || !stat(git_path_merge_msg(the_repository), &st)) {
1330 - print_rebase_state(s, state, color);
1328 + } else if (s->state.rebase_in_progress ||
1329 + !stat(git_path_merge_msg(the_repository), &st)) {
1330 + print_rebase_state(s, color);
1331 if (s->hints)
1332 status_printf_ln(s, color,
1333 _(" (all conflicts fixed: run \"git rebase --continue\")"));
1334 } else if (split_commit_in_progress(s)) {
1335 - if (state->branch)
1335 + if (s->state.branch)
1336 status_printf_ln(s, color,
1337 _("You are currently splitting a commit while rebasing branch '%s' on '%s'."),
1338 - state->branch,
1339 - state->onto);
1338 + s->state.branch,
1339 + s->state.onto);
1340 else
1341 status_printf_ln(s, color,
1342 _("You are currently splitting a commit during a rebase."));
@@ -1344,11 +1344,11 @@ static void show_rebase_in_progress(struct wt_status *s,
1344 status_printf_ln(s, color,
1345 _(" (Once your working directory is clean, run \"git rebase --continue\")"));
1346 } else {
1347 - if (state->branch)
1347 + if (s->state.branch)
1348 status_printf_ln(s, color,
1349 _("You are currently editing a commit while rebasing branch '%s' on '%s'."),
1350 - state->branch,
1351 - state->onto);
1350 + s->state.branch,
1351 + s->state.onto);
1352 else
1353 status_printf_ln(s, color,
1354 _("You are currently editing a commit during a rebase."));
@@ -1363,11 +1363,10 @@ static void show_rebase_in_progress(struct wt_status *s,
1363 }
1364
1365 static void show_cherry_pick_in_progress(struct wt_status *s,
1366 - struct wt_status_state *state,
1367 - const char *color)
1366 + const char *color)
1367 {
1368 status_printf_ln(s, color, _("You are currently cherry-picking commit %s."),
1370 - find_unique_abbrev(&state->cherry_pick_head_oid, DEFAULT_ABBREV));
1369 + find_unique_abbrev(&s->state.cherry_pick_head_oid, DEFAULT_ABBREV));
1370 if (s->hints) {
1371 if (has_unmerged(s))
1372 status_printf_ln(s, color,
@@ -1382,11 +1381,10 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
1381 }
1382
1383 static void show_revert_in_progress(struct wt_status *s,
1385 - struct wt_status_state *state,
1386 - const char *color)
1384 + const char *color)
1385 {
1386 status_printf_ln(s, color, _("You are currently reverting commit %s."),
1389 - find_unique_abbrev(&state->revert_head_oid, DEFAULT_ABBREV));
1387 + find_unique_abbrev(&s->state.revert_head_oid, DEFAULT_ABBREV));
1388 if (s->hints) {
1389 if (has_unmerged(s))
1390 status_printf_ln(s, color,
@@ -1401,13 +1399,12 @@ static void show_revert_in_progress(struct wt_status *s,
1399 }
1400
1401 static void show_bisect_in_progress(struct wt_status *s,
1404 - struct wt_status_state *state,
1405 - const char *color)
1402 + const char *color)
1403 {
1407 - if (state->branch)
1404 + if (s->state.branch)
1405 status_printf_ln(s, color,
1406 _("You are currently bisecting, started from branch '%s'."),
1410 - state->branch);
1407 + s->state.branch);
1408 else
1409 status_printf_ln(s, color,
1410 _("You are currently bisecting."));
@@ -1581,48 +1578,45 @@ void wt_status_get_state(struct wt_status_state *state,
1578 wt_status_get_detached_from(state);
1579 }
1580
1584 -static void wt_longstatus_print_state(struct wt_status *s,
1585 - struct wt_status_state *state)
1581 +static void wt_longstatus_print_state(struct wt_status *s)
1582 {
1583 const char *state_color = color(WT_STATUS_HEADER, s);
1584 + struct wt_status_state *state = &s->state;
1585 +
1586 if (state->merge_in_progress)
1589 - show_merge_in_progress(s, state, state_color);
1587 + show_merge_in_progress(s, state_color);
1588 else if (state->am_in_progress)
1591 - show_am_in_progress(s, state, state_color);
1589 + show_am_in_progress(s, state_color);
1590 else if (state->rebase_in_progress || state->rebase_interactive_in_progress)
1593 - show_rebase_in_progress(s, state, state_color);
1591 + show_rebase_in_progress(s, state_color);
1592 else if (state->cherry_pick_in_progress)
1595 - show_cherry_pick_in_progress(s, state, state_color);
1593 + show_cherry_pick_in_progress(s, state_color);
1594 else if (state->revert_in_progress)
1597 - show_revert_in_progress(s, state, state_color);
1595 + show_revert_in_progress(s, state_color);
1596 if (state->bisect_in_progress)
1599 - show_bisect_in_progress(s, state, state_color);
1597 + show_bisect_in_progress(s, state_color);
1598 }
1599
1600 static void wt_longstatus_print(struct wt_status *s)
1601 {
1602 const char *branch_color = color(WT_STATUS_ONBRANCH, s);
1603 const char *branch_status_color = color(WT_STATUS_HEADER, s);
1606 - struct wt_status_state state;
1607 -
1608 - memset(&state, 0, sizeof(state));
1609 - wt_status_get_state(&state,
1610 - s->branch && !strcmp(s->branch, "HEAD"));
1604
1605 if (s->branch) {
1606 const char *on_what = _("On branch ");
1607 const char *branch_name = s->branch;
1608 if (!strcmp(branch_name, "HEAD")) {
1609 branch_status_color = color(WT_STATUS_NOBRANCH, s);
1617 - if (state.rebase_in_progress || state.rebase_interactive_in_progress) {
1618 - if (state.rebase_interactive_in_progress)
1610 + if (s->state.rebase_in_progress ||
1611 + s->state.rebase_interactive_in_progress) {
1612 + if (s->state.rebase_interactive_in_progress)
1613 on_what = _("interactive rebase in progress; onto ");
1614 else
1615 on_what = _("rebase in progress; onto ");
1622 - branch_name = state.onto;
1623 - } else if (state.detached_from) {
1624 - branch_name = state.detached_from;
1625 - if (state.detached_at)
1616 + branch_name = s->state.onto;
1617 + } else if (s->state.detached_from) {
1618 + branch_name = s->state.detached_from;
1619 + if (s->state.detached_at)
1620 on_what = _("HEAD detached at ");
1621 else
1622 on_what = _("HEAD detached from ");
@@ -1639,10 +1633,7 @@ static void wt_longstatus_print(struct wt_status *s)
1633 wt_longstatus_print_tracking(s);
1634 }
1635
1642 - wt_longstatus_print_state(s, &state);
1643 - free(state.branch);
1644 - free(state.onto);
1645 - free(state.detached_from);
1636 + wt_longstatus_print_state(s);
1637
1638 if (s->is_initial) {
1639 status_printf_ln(s, color(WT_STATUS_HEADER, s), "%s", "");
@@ -1946,13 +1937,9 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
1937 struct branch *branch;
1938 const char *base;
1939 const char *branch_name;
1949 - struct wt_status_state state;
1940 int ab_info, nr_ahead, nr_behind;
1941 char eol = s->null_termination ? '\0' : '\n';
1942
1953 - memset(&state, 0, sizeof(state));
1954 - wt_status_get_state(&state, s->branch && !strcmp(s->branch, "HEAD"));
1955 -
1943 fprintf(s->fp, "# branch.oid %s%c",
1944 (s->is_initial ? "(initial)" : sha1_to_hex(s->sha1_commit)),
1945 eol);
@@ -1963,10 +1950,11 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
1950 if (!strcmp(s->branch, "HEAD")) {
1951 fprintf(s->fp, "# branch.head %s%c", "(detached)", eol);
1952
1966 - if (state.rebase_in_progress || state.rebase_interactive_in_progress)
1967 - branch_name = state.onto;
1968 - else if (state.detached_from)
1969 - branch_name = state.detached_from;
1953 + if (s->state.rebase_in_progress ||
1954 + s->state.rebase_interactive_in_progress)
1955 + branch_name = s->state.onto;
1956 + else if (s->state.detached_from)
1957 + branch_name = s->state.detached_from;
1958 else
1959 branch_name = "";
1960 } else {
@@ -2000,10 +1988,6 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s)
1988 }
1989 }
1990 }
2003 -
2004 - free(state.branch);
2005 - free(state.onto);
2006 - free(state.detached_from);
1991 }
1992
1993 /*
wt-status.h
+20 -18
@@ -64,6 +64,24 @@ enum wt_status_format {
64 STATUS_FORMAT_UNSPECIFIED
65 };
66
67 +struct wt_status_state {
68 + int merge_in_progress;
69 + int am_in_progress;
70 + int am_empty_patch;
71 + int rebase_in_progress;
72 + int rebase_interactive_in_progress;
73 + int cherry_pick_in_progress;
74 + int bisect_in_progress;
75 + int revert_in_progress;
76 + int detached_at;
77 + char *branch;
78 + char *onto;
79 + char *detached_from;
80 + struct object_id detached_oid;
81 + struct object_id revert_head_oid;
82 + struct object_id cherry_pick_head_oid;
83 +};
84 +
85 struct wt_status {
86 int is_initial;
87 char *branch;
@@ -93,6 +111,7 @@ struct wt_status {
111 int rename_score;
112 int rename_limit;
113 enum wt_status_format status_format;
114 + struct wt_status_state state;
115 unsigned char sha1_commit[GIT_MAX_RAWSZ]; /* when not Initial */
116
117 /* These are computed during processing of the individual sections */
@@ -107,29 +126,12 @@ struct wt_status {
126 uint32_t untracked_in_ms;
127 };
128
110 -struct wt_status_state {
111 - int merge_in_progress;
112 - int am_in_progress;
113 - int am_empty_patch;
114 - int rebase_in_progress;
115 - int rebase_interactive_in_progress;
116 - int cherry_pick_in_progress;
117 - int bisect_in_progress;
118 - int revert_in_progress;
119 - int detached_at;
120 - char *branch;
121 - char *onto;
122 - char *detached_from;
123 - struct object_id detached_oid;
124 - struct object_id revert_head_oid;
125 - struct object_id cherry_pick_head_oid;
126 -};
127 -
129 size_t wt_status_locate_end(const char *s, size_t len);
130 void wt_status_add_cut_line(FILE *fp);
131 void wt_status_prepare(struct wt_status *s);
132 void wt_status_print(struct wt_status *s);
133 void wt_status_collect(struct wt_status *s);
134 +void wt_status_collect_free_buffers(struct wt_status *s);
135 void wt_status_get_state(struct wt_status_state *state, int get_detached_from);
136 int wt_status_check_rebase(const struct worktree *wt,
137 struct wt_status_state *state);