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

Commit f7858ad

Browse files
committed
Merge branch 'jk/status-porcelain-z-b'
"git status --porcelain" ignored "--branch" option by mistake. The output for "git status --branch -z" was also incorrect and did not terminate the record for the current branch name with NUL as asked. By Jeff King via Jeff King * jk/status-porcelain-z-b: status: refactor colopts handling status: respect "-b" for porcelain format status: fix null termination with "-b" status: refactor null_termination option commit: refactor option parsing
2 parents 1652867 + 4d2292e commit f7858ad

File tree

5 files changed

+110
-95
lines changed

5 files changed

+110
-95
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: 71 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
8989
static int no_post_rewrite, allow_empty_message;
9090
static char *untracked_files_arg, *force_date, *ignore_submodule_arg;
9191
static char *sign_commit;
92-
static unsigned int colopts;
9392

9493
/*
9594
* The default commit message cleanup mode will remove the lines
@@ -111,13 +110,11 @@ static int show_ignored_in_status;
111110
static const char *only_include_assumed;
112111
static struct strbuf message = STRBUF_INIT;
113112

114-
static int null_termination;
115113
static enum {
116114
STATUS_FORMAT_LONG,
117115
STATUS_FORMAT_SHORT,
118116
STATUS_FORMAT_PORCELAIN
119117
} status_format = STATUS_FORMAT_LONG;
120-
static int status_show_branch;
121118

122119
static int opt_parse_m(const struct option *opt, const char *arg, int unset)
123120
{
@@ -131,59 +128,6 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset)
131128
return 0;
132129
}
133130

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-
187131
static void determine_whence(struct wt_status *s)
188132
{
189133
if (file_exists(git_path("MERGE_HEAD")))
@@ -501,10 +445,10 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
501445

502446
switch (status_format) {
503447
case STATUS_FORMAT_SHORT:
504-
wt_shortstatus_print(s, null_termination, status_show_branch);
448+
wt_shortstatus_print(s);
505449
break;
506450
case STATUS_FORMAT_PORCELAIN:
507-
wt_porcelain_print(s, null_termination);
451+
wt_porcelain_print(s);
508452
break;
509453
case STATUS_FORMAT_LONG:
510454
wt_status_print(s);
@@ -1037,15 +981,15 @@ static const char *read_commit_message(const char *name)
1037981
}
1038982

1039983
static int parse_and_validate_options(int argc, const char *argv[],
984+
const struct option *options,
1040985
const char * const usage[],
1041986
const char *prefix,
1042987
struct commit *current_head,
1043988
struct wt_status *s)
1044989
{
1045990
int f = 0;
1046991

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

1050994
if (force_author && !strchr(force_author, '>'))
1051995
force_author = find_author_by_nickname(force_author);
@@ -1130,7 +1074,7 @@ static int parse_and_validate_options(int argc, const char *argv[],
11301074
if (all && argc > 0)
11311075
die(_("Paths with -a does not make sense."));
11321076

1133-
if (null_termination && status_format == STATUS_FORMAT_LONG)
1077+
if (s->null_termination && status_format == STATUS_FORMAT_LONG)
11341078
status_format = STATUS_FORMAT_PORCELAIN;
11351079
if (status_format != STATUS_FORMAT_LONG)
11361080
dry_run = 1;
@@ -1176,7 +1120,7 @@ static int git_status_config(const char *k, const char *v, void *cb)
11761120
struct wt_status *s = cb;
11771121

11781122
if (!prefixcmp(k, "column."))
1179-
return git_column_config(k, v, "status", &colopts);
1123+
return git_column_config(k, v, "status", &s->colopts);
11801124
if (!strcmp(k, "status.submodulesummary")) {
11811125
int is_bool;
11821126
s->submodule_summary = git_config_bool_or_int(k, v, &is_bool);
@@ -1219,19 +1163,19 @@ static int git_status_config(const char *k, const char *v, void *cb)
12191163

12201164
int cmd_status(int argc, const char **argv, const char *prefix)
12211165
{
1222-
struct wt_status s;
1166+
static struct wt_status s;
12231167
int fd;
12241168
unsigned char sha1[20];
12251169
static struct option builtin_status_options[] = {
12261170
OPT__VERBOSE(&verbose, "be verbose"),
12271171
OPT_SET_INT('s', "short", &status_format,
12281172
"show status concisely", STATUS_FORMAT_SHORT),
1229-
OPT_BOOLEAN('b', "branch", &status_show_branch,
1173+
OPT_BOOLEAN('b', "branch", &s.show_branch,
12301174
"show branch information"),
12311175
OPT_SET_INT(0, "porcelain", &status_format,
12321176
"machine-readable output",
12331177
STATUS_FORMAT_PORCELAIN),
1234-
OPT_BOOLEAN('z', "null", &null_termination,
1178+
OPT_BOOLEAN('z', "null", &s.null_termination,
12351179
"terminate entries with NUL"),
12361180
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg,
12371181
"mode",
@@ -1242,7 +1186,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
12421186
{ OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, "when",
12431187
"ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)",
12441188
PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
1245-
OPT_COLUMN(0, "column", &colopts, "list untracked files in columns"),
1189+
OPT_COLUMN(0, "column", &s.colopts, "list untracked files in columns"),
12461190
OPT_END(),
12471191
};
12481192

@@ -1256,10 +1200,9 @@ int cmd_status(int argc, const char **argv, const char *prefix)
12561200
argc = parse_options(argc, argv, prefix,
12571201
builtin_status_options,
12581202
builtin_status_usage, 0);
1259-
finalize_colopts(&colopts, -1);
1260-
s.colopts = colopts;
1203+
finalize_colopts(&s.colopts, -1);
12611204

1262-
if (null_termination && status_format == STATUS_FORMAT_LONG)
1205+
if (s.null_termination && status_format == STATUS_FORMAT_LONG)
12631206
status_format = STATUS_FORMAT_PORCELAIN;
12641207

12651208
handle_untracked_files_arg(&s);
@@ -1284,10 +1227,10 @@ int cmd_status(int argc, const char **argv, const char *prefix)
12841227

12851228
switch (status_format) {
12861229
case STATUS_FORMAT_SHORT:
1287-
wt_shortstatus_print(&s, null_termination, status_show_branch);
1230+
wt_shortstatus_print(&s);
12881231
break;
12891232
case STATUS_FORMAT_PORCELAIN:
1290-
wt_porcelain_print(&s, null_termination);
1233+
wt_porcelain_print(&s);
12911234
break;
12921235
case STATUS_FORMAT_LONG:
12931236
s.verbose = verbose;
@@ -1422,6 +1365,60 @@ static int run_rewrite_hook(const unsigned char *oldsha1,
14221365

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

@@ -1441,6 +1437,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
14411437
wt_status_prepare(&s);
14421438
git_config(git_commit_config, &s);
14431439
determine_whence(&s);
1440+
s.colopts = 0;
14441441

14451442
if (get_sha1("HEAD", sha1))
14461443
current_head = NULL;
@@ -1449,7 +1446,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
14491446
if (!current_head || parse_commit(current_head))
14501447
die(_("could not parse HEAD commit"));
14511448
}
1452-
argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
1449+
argc = parse_and_validate_options(argc, argv, builtin_commit_options,
1450+
builtin_commit_usage,
14531451
prefix, current_head, &s);
14541452
if (dry_run)
14551453
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
'

0 commit comments

Comments
 (0)