Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 5410ae4

Browse files
committed
Merge branch 'jk/maint-status-porcelain-z-b' into HEAD
* jk/maint-status-porcelain-z-b: status: respect "-b" for porcelain format status: fix null termination with "-b" status: refactor null_termination option commit: refactor option parsing Conflicts: wt-status.h
2 parents a3935e6 + d4a6bf1 commit 5410ae4

File tree

5 files changed

+105
-89
lines changed

5 files changed

+105
-89
lines changed

Documentation/git-status.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ order is reversed (e.g 'from \-> to' becomes 'to from'). Second, a NUL
184184
and the terminating newline (but a space still separates the status
185185
field from the first filename). Third, filenames containing special
186186
characters are not specially formatted; no quoting or
187-
backslash-escaping is performed. Fourth, there is no branch line.
187+
backslash-escaping is performed.
188188

189189
CONFIGURATION
190190
-------------

builtin/commit.c

Lines changed: 67 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,11 @@ static int show_ignored_in_status;
111111
static const char *only_include_assumed;
112112
static struct strbuf message = STRBUF_INIT;
113113

114-
static int null_termination;
115114
static enum {
116115
STATUS_FORMAT_LONG,
117116
STATUS_FORMAT_SHORT,
118117
STATUS_FORMAT_PORCELAIN
119118
} status_format = STATUS_FORMAT_LONG;
120-
static int status_show_branch;
121119

122120
static int opt_parse_m(const struct option *opt, const char *arg, int unset)
123121
{
@@ -131,59 +129,6 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset)
131129
return 0;
132130
}
133131

134-
static struct option builtin_commit_options[] = {
135-
OPT__QUIET(&quiet, "suppress summary after successful commit"),
136-
OPT__VERBOSE(&verbose, "show diff in commit message template"),
137-
138-
OPT_GROUP("Commit message options"),
139-
OPT_FILENAME('F', "file", &logfile, "read message from file"),
140-
OPT_STRING(0, "author", &force_author, "author", "override author for commit"),
141-
OPT_STRING(0, "date", &force_date, "date", "override date for commit"),
142-
OPT_CALLBACK('m', "message", &message, "message", "commit message", opt_parse_m),
143-
OPT_STRING('c', "reedit-message", &edit_message, "commit", "reuse and edit message from specified commit"),
144-
OPT_STRING('C', "reuse-message", &use_message, "commit", "reuse message from specified commit"),
145-
OPT_STRING(0, "fixup", &fixup_message, "commit", "use autosquash formatted message to fixup specified commit"),
146-
OPT_STRING(0, "squash", &squash_message, "commit", "use autosquash formatted message to squash specified commit"),
147-
OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C/-c/--amend)"),
148-
OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
149-
OPT_FILENAME('t', "template", &template_file, "use specified template file"),
150-
OPT_BOOL('e', "edit", &edit_flag, "force edit of commit"),
151-
OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
152-
OPT_BOOLEAN(0, "status", &include_status, "include status in commit message template"),
153-
{ OPTION_STRING, 'S', "gpg-sign", &sign_commit, "key id",
154-
"GPG sign commit", PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
155-
/* end commit message options */
156-
157-
OPT_GROUP("Commit contents options"),
158-
OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
159-
OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
160-
OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
161-
OPT_BOOLEAN('p', "patch", &patch_interactive, "interactively add changes"),
162-
OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
163-
OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
164-
OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
165-
OPT_SET_INT(0, "short", &status_format, "show status concisely",
166-
STATUS_FORMAT_SHORT),
167-
OPT_BOOLEAN(0, "branch", &status_show_branch, "show branch information"),
168-
OPT_SET_INT(0, "porcelain", &status_format,
169-
"machine-readable output", STATUS_FORMAT_PORCELAIN),
170-
OPT_BOOLEAN('z', "null", &null_termination,
171-
"terminate entries with NUL"),
172-
OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
173-
OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"),
174-
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
175-
/* end commit contents options */
176-
177-
{ OPTION_BOOLEAN, 0, "allow-empty", &allow_empty, NULL,
178-
"ok to record an empty change",
179-
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
180-
{ OPTION_BOOLEAN, 0, "allow-empty-message", &allow_empty_message, NULL,
181-
"ok to record a change with an empty message",
182-
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
183-
184-
OPT_END()
185-
};
186-
187132
static void determine_whence(struct wt_status *s)
188133
{
189134
if (file_exists(git_path("MERGE_HEAD")))
@@ -501,10 +446,10 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
501446

502447
switch (status_format) {
503448
case STATUS_FORMAT_SHORT:
504-
wt_shortstatus_print(s, null_termination, status_show_branch);
449+
wt_shortstatus_print(s);
505450
break;
506451
case STATUS_FORMAT_PORCELAIN:
507-
wt_porcelain_print(s, null_termination);
452+
wt_porcelain_print(s);
508453
break;
509454
case STATUS_FORMAT_LONG:
510455
wt_status_print(s);
@@ -1037,15 +982,15 @@ static const char *read_commit_message(const char *name)
1037982
}
1038983

1039984
static int parse_and_validate_options(int argc, const char *argv[],
985+
const struct option *options,
1040986
const char * const usage[],
1041987
const char *prefix,
1042988
struct commit *current_head,
1043989
struct wt_status *s)
1044990
{
1045991
int f = 0;
1046992

1047-
argc = parse_options(argc, argv, prefix, builtin_commit_options, usage,
1048-
0);
993+
argc = parse_options(argc, argv, prefix, options, usage, 0);
1049994

1050995
if (force_author && !strchr(force_author, '>'))
1051996
force_author = find_author_by_nickname(force_author);
@@ -1130,7 +1075,7 @@ static int parse_and_validate_options(int argc, const char *argv[],
11301075
if (all && argc > 0)
11311076
die(_("Paths with -a does not make sense."));
11321077

1133-
if (null_termination && status_format == STATUS_FORMAT_LONG)
1078+
if (s->null_termination && status_format == STATUS_FORMAT_LONG)
11341079
status_format = STATUS_FORMAT_PORCELAIN;
11351080
if (status_format != STATUS_FORMAT_LONG)
11361081
dry_run = 1;
@@ -1219,19 +1164,19 @@ static int git_status_config(const char *k, const char *v, void *cb)
12191164

12201165
int cmd_status(int argc, const char **argv, const char *prefix)
12211166
{
1222-
struct wt_status s;
1167+
static struct wt_status s;
12231168
int fd;
12241169
unsigned char sha1[20];
12251170
static struct option builtin_status_options[] = {
12261171
OPT__VERBOSE(&verbose, "be verbose"),
12271172
OPT_SET_INT('s', "short", &status_format,
12281173
"show status concisely", STATUS_FORMAT_SHORT),
1229-
OPT_BOOLEAN('b', "branch", &status_show_branch,
1174+
OPT_BOOLEAN('b', "branch", &s.show_branch,
12301175
"show branch information"),
12311176
OPT_SET_INT(0, "porcelain", &status_format,
12321177
"machine-readable output",
12331178
STATUS_FORMAT_PORCELAIN),
1234-
OPT_BOOLEAN('z', "null", &null_termination,
1179+
OPT_BOOLEAN('z', "null", &s.null_termination,
12351180
"terminate entries with NUL"),
12361181
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
12371182
"mode",
@@ -1259,7 +1204,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
12591204
finalize_colopts(&colopts, -1);
12601205
s.colopts = colopts;
12611206

1262-
if (null_termination && status_format == STATUS_FORMAT_LONG)
1207+
if (s.null_termination && status_format == STATUS_FORMAT_LONG)
12631208
status_format = STATUS_FORMAT_PORCELAIN;
12641209

12651210
handle_untracked_files_arg(&s);
@@ -1284,10 +1229,10 @@ int cmd_status(int argc, const char **argv, const char *prefix)
12841229

12851230
switch (status_format) {
12861231
case STATUS_FORMAT_SHORT:
1287-
wt_shortstatus_print(&s, null_termination, status_show_branch);
1232+
wt_shortstatus_print(&s);
12881233
break;
12891234
case STATUS_FORMAT_PORCELAIN:
1290-
wt_porcelain_print(&s, null_termination);
1235+
wt_porcelain_print(&s);
12911236
break;
12921237
case STATUS_FORMAT_LONG:
12931238
s.verbose = verbose;
@@ -1422,6 +1367,60 @@ static int run_rewrite_hook(const unsigned char *oldsha1,
14221367

14231368
int cmd_commit(int argc, const char **argv, const char *prefix)
14241369
{
1370+
static struct wt_status s;
1371+
static struct option builtin_commit_options[] = {
1372+
OPT__QUIET(&quiet, "suppress summary after successful commit"),
1373+
OPT__VERBOSE(&verbose, "show diff in commit message template"),
1374+
1375+
OPT_GROUP("Commit message options"),
1376+
OPT_FILENAME('F', "file", &logfile, "read message from file"),
1377+
OPT_STRING(0, "author", &force_author, "author", "override author for commit"),
1378+
OPT_STRING(0, "date", &force_date, "date", "override date for commit"),
1379+
OPT_CALLBACK('m', "message", &message, "message", "commit message", opt_parse_m),
1380+
OPT_STRING('c', "reedit-message", &edit_message, "commit", "reuse and edit message from specified commit"),
1381+
OPT_STRING('C', "reuse-message", &use_message, "commit", "reuse message from specified commit"),
1382+
OPT_STRING(0, "fixup", &fixup_message, "commit", "use autosquash formatted message to fixup specified commit"),
1383+
OPT_STRING(0, "squash", &squash_message, "commit", "use autosquash formatted message to squash specified commit"),
1384+
OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C/-c/--amend)"),
1385+
OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
1386+
OPT_FILENAME('t', "template", &template_file, "use specified template file"),
1387+
OPT_BOOL('e', "edit", &edit_flag, "force edit of commit"),
1388+
OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
1389+
OPT_BOOLEAN(0, "status", &include_status, "include status in commit message template"),
1390+
{ OPTION_STRING, 'S', "gpg-sign", &sign_commit, "key id",
1391+
"GPG sign commit", PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
1392+
/* end commit message options */
1393+
1394+
OPT_GROUP("Commit contents options"),
1395+
OPT_BOOLEAN('a', "all", &all, "commit all changed files"),
1396+
OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"),
1397+
OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
1398+
OPT_BOOLEAN('p', "patch", &patch_interactive, "interactively add changes"),
1399+
OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
1400+
OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
1401+
OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
1402+
OPT_SET_INT(0, "short", &status_format, "show status concisely",
1403+
STATUS_FORMAT_SHORT),
1404+
OPT_BOOLEAN(0, "branch", &s.show_branch, "show branch information"),
1405+
OPT_SET_INT(0, "porcelain", &status_format,
1406+
"machine-readable output", STATUS_FORMAT_PORCELAIN),
1407+
OPT_BOOLEAN('z', "null", &s.null_termination,
1408+
"terminate entries with NUL"),
1409+
OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
1410+
OPT_BOOLEAN(0, "no-post-rewrite", &no_post_rewrite, "bypass post-rewrite hook"),
1411+
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1412+
/* end commit contents options */
1413+
1414+
{ OPTION_BOOLEAN, 0, "allow-empty", &allow_empty, NULL,
1415+
"ok to record an empty change",
1416+
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
1417+
{ OPTION_BOOLEAN, 0, "allow-empty-message", &allow_empty_message, NULL,
1418+
"ok to record a change with an empty message",
1419+
PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
1420+
1421+
OPT_END()
1422+
};
1423+
14251424
struct strbuf sb = STRBUF_INIT;
14261425
struct strbuf author_ident = STRBUF_INIT;
14271426
const char *index_file, *reflog_msg;
@@ -1431,7 +1430,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
14311430
struct commit_list *parents = NULL, **pptr = &parents;
14321431
struct stat statbuf;
14331432
int allow_fast_forward = 1;
1434-
struct wt_status s;
14351433
struct commit *current_head = NULL;
14361434
struct commit_extra_header *extra = NULL;
14371435

@@ -1449,7 +1447,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
14491447
if (!current_head || parse_commit(current_head))
14501448
die(_("could not parse HEAD commit"));
14511449
}
1452-
argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
1450+
argc = parse_and_validate_options(argc, argv, builtin_commit_options,
1451+
builtin_commit_usage,
14531452
prefix, current_head, &s);
14541453
if (dry_run)
14551454
return dry_run_commit(argc, argv, prefix, current_head, &s);

t/t7508-status.sh

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,15 @@ test_expect_success 'status -s -b' '
295295
296296
'
297297

298+
test_expect_success 'status -s -z -b' '
299+
tr "\\n" Q <expect >expect.q &&
300+
mv expect.q expect &&
301+
git status -s -z -b >output &&
302+
nul_to_q <output >output.q &&
303+
mv output.q output &&
304+
test_cmp expect output
305+
'
306+
298307
test_expect_success 'setup dir3' '
299308
mkdir dir3 &&
300309
: >dir3/untracked1 &&
@@ -671,9 +680,14 @@ test_expect_success 'status --porcelain ignores color.status' '
671680
git config --unset color.status
672681
git config --unset color.ui
673682

674-
test_expect_success 'status --porcelain ignores -b' '
683+
test_expect_success 'status --porcelain respects -b' '
675684
676685
git status --porcelain -b >output &&
686+
{
687+
echo "## master" &&
688+
cat expect
689+
} >tmp &&
690+
mv tmp expect &&
677691
test_cmp expect output
678692
679693
'

wt-status.c

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ void wt_status_print(struct wt_status *s)
801801
}
802802
}
803803

804-
static void wt_shortstatus_unmerged(int null_termination, struct string_list_item *it,
804+
static void wt_shortstatus_unmerged(struct string_list_item *it,
805805
struct wt_status *s)
806806
{
807807
struct wt_status_change_data *d = it->util;
@@ -817,7 +817,7 @@ static void wt_shortstatus_unmerged(int null_termination, struct string_list_ite
817817
case 7: how = "UU"; break; /* both modified */
818818
}
819819
color_fprintf(s->fp, color(WT_STATUS_UNMERGED, s), "%s", how);
820-
if (null_termination) {
820+
if (s->null_termination) {
821821
fprintf(stdout, " %s%c", it->string, 0);
822822
} else {
823823
struct strbuf onebuf = STRBUF_INIT;
@@ -828,7 +828,7 @@ static void wt_shortstatus_unmerged(int null_termination, struct string_list_ite
828828
}
829829
}
830830

831-
static void wt_shortstatus_status(int null_termination, struct string_list_item *it,
831+
static void wt_shortstatus_status(struct string_list_item *it,
832832
struct wt_status *s)
833833
{
834834
struct wt_status_change_data *d = it->util;
@@ -842,7 +842,7 @@ static void wt_shortstatus_status(int null_termination, struct string_list_item
842842
else
843843
putchar(' ');
844844
putchar(' ');
845-
if (null_termination) {
845+
if (s->null_termination) {
846846
fprintf(stdout, "%s%c", it->string, 0);
847847
if (d->head_path)
848848
fprintf(stdout, "%s%c", d->head_path, 0);
@@ -870,10 +870,10 @@ static void wt_shortstatus_status(int null_termination, struct string_list_item
870870
}
871871
}
872872

873-
static void wt_shortstatus_other(int null_termination, struct string_list_item *it,
873+
static void wt_shortstatus_other(struct string_list_item *it,
874874
struct wt_status *s, const char *sign)
875875
{
876-
if (null_termination) {
876+
if (s->null_termination) {
877877
fprintf(stdout, "%s %s%c", sign, it->string, 0);
878878
} else {
879879
struct strbuf onebuf = STRBUF_INIT;
@@ -913,8 +913,8 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
913913
if (s->is_initial)
914914
color_fprintf(s->fp, header_color, _("Initial commit on "));
915915
if (!stat_tracking_info(branch, &num_ours, &num_theirs)) {
916-
color_fprintf_ln(s->fp, branch_color_local,
917-
"%s", branch_name);
916+
color_fprintf(s->fp, branch_color_local, "%s", branch_name);
917+
fputc(s->null_termination ? '\0' : '\n', s->fp);
918918
return;
919919
}
920920

@@ -938,14 +938,15 @@ static void wt_shortstatus_print_tracking(struct wt_status *s)
938938
color_fprintf(s->fp, branch_color_remote, "%d", num_theirs);
939939
}
940940

941-
color_fprintf_ln(s->fp, header_color, "]");
941+
color_fprintf(s->fp, header_color, "]");
942+
fputc(s->null_termination ? '\0' : '\n', s->fp);
942943
}
943944

944-
void wt_shortstatus_print(struct wt_status *s, int null_termination, int show_branch)
945+
void wt_shortstatus_print(struct wt_status *s)
945946
{
946947
int i;
947948

948-
if (show_branch)
949+
if (s->show_branch)
949950
wt_shortstatus_print_tracking(s);
950951

951952
for (i = 0; i < s->change.nr; i++) {
@@ -955,28 +956,28 @@ void wt_shortstatus_print(struct wt_status *s, int null_termination, int show_br
955956
it = &(s->change.items[i]);
956957
d = it->util;
957958
if (d->stagemask)
958-
wt_shortstatus_unmerged(null_termination, it, s);
959+
wt_shortstatus_unmerged(it, s);
959960
else
960-
wt_shortstatus_status(null_termination, it, s);
961+
wt_shortstatus_status(it, s);
961962
}
962963
for (i = 0; i < s->untracked.nr; i++) {
963964
struct string_list_item *it;
964965

965966
it = &(s->untracked.items[i]);
966-
wt_shortstatus_other(null_termination, it, s, "??");
967+
wt_shortstatus_other(it, s, "??");
967968
}
968969
for (i = 0; i < s->ignored.nr; i++) {
969970
struct string_list_item *it;
970971

971972
it = &(s->ignored.items[i]);
972-
wt_shortstatus_other(null_termination, it, s, "!!");
973+
wt_shortstatus_other(it, s, "!!");
973974
}
974975
}
975976

976-
void wt_porcelain_print(struct wt_status *s, int null_termination)
977+
void wt_porcelain_print(struct wt_status *s)
977978
{
978979
s->use_color = 0;
979980
s->relative_paths = 0;
980981
s->prefix = NULL;
981-
wt_shortstatus_print(s, null_termination, 0);
982+
wt_shortstatus_print(s);
982983
}

0 commit comments

Comments
 (0)