Merge branch 'mg/status-b'
* mg/status-b: Documentation+t5708: document and test status -s -b Show branch information in short output of git status
This commit is contained in:
@ -27,6 +27,10 @@ OPTIONS
|
|||||||
--short::
|
--short::
|
||||||
Give the output in the short-format.
|
Give the output in the short-format.
|
||||||
|
|
||||||
|
-b::
|
||||||
|
--branch::
|
||||||
|
Show the branch and tracking info even in short-format.
|
||||||
|
|
||||||
--porcelain::
|
--porcelain::
|
||||||
Give the output in a stable, easy-to-parse format for scripts.
|
Give the output in a stable, easy-to-parse format for scripts.
|
||||||
Currently this is identical to --short output, but is guaranteed
|
Currently this is identical to --short output, but is guaranteed
|
||||||
@ -120,6 +124,10 @@ Ignored files are not listed.
|
|||||||
? ? untracked
|
? ? untracked
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
|
||||||
|
If -b is used the short-format status is preceded by a line
|
||||||
|
|
||||||
|
## branchname tracking info
|
||||||
|
|
||||||
There is an alternate -z format recommended for machine parsing. In
|
There is an alternate -z format recommended for machine parsing. In
|
||||||
that format, the status field is the same, but some other things
|
that format, the status field is the same, but some other things
|
||||||
change. First, the '->' is omitted from rename entries and the field
|
change. First, the '->' is omitted from rename entries and the field
|
||||||
@ -128,7 +136,7 @@ order is reversed (e.g 'from -> to' becomes 'to from'). Second, a NUL
|
|||||||
and the terminating newline (but a space still separates the status
|
and the terminating newline (but a space still separates the status
|
||||||
field from the first filename). Third, filenames containing special
|
field from the first filename). Third, filenames containing special
|
||||||
characters are not specially formatted; no quoting or
|
characters are not specially formatted; no quoting or
|
||||||
backslash-escaping is performed.
|
backslash-escaping is performed. Fourth, there is no branch line.
|
||||||
|
|
||||||
CONFIGURATION
|
CONFIGURATION
|
||||||
-------------
|
-------------
|
||||||
|
@ -93,6 +93,7 @@ static enum {
|
|||||||
STATUS_FORMAT_SHORT,
|
STATUS_FORMAT_SHORT,
|
||||||
STATUS_FORMAT_PORCELAIN,
|
STATUS_FORMAT_PORCELAIN,
|
||||||
} status_format = STATUS_FORMAT_LONG;
|
} status_format = STATUS_FORMAT_LONG;
|
||||||
|
static int status_show_branch;
|
||||||
|
|
||||||
static int opt_parse_m(const struct option *opt, const char *arg, int unset)
|
static int opt_parse_m(const struct option *opt, const char *arg, int unset)
|
||||||
{
|
{
|
||||||
@ -134,6 +135,7 @@ static struct option builtin_commit_options[] = {
|
|||||||
OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
|
OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
|
||||||
OPT_SET_INT(0, "short", &status_format, "show status concisely",
|
OPT_SET_INT(0, "short", &status_format, "show status concisely",
|
||||||
STATUS_FORMAT_SHORT),
|
STATUS_FORMAT_SHORT),
|
||||||
|
OPT_BOOLEAN(0, "branch", &status_show_branch, "show branch information"),
|
||||||
OPT_SET_INT(0, "porcelain", &status_format,
|
OPT_SET_INT(0, "porcelain", &status_format,
|
||||||
"show porcelain output format", STATUS_FORMAT_PORCELAIN),
|
"show porcelain output format", STATUS_FORMAT_PORCELAIN),
|
||||||
OPT_BOOLEAN('z', "null", &null_termination,
|
OPT_BOOLEAN('z', "null", &null_termination,
|
||||||
@ -424,7 +426,7 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
|
|||||||
|
|
||||||
switch (status_format) {
|
switch (status_format) {
|
||||||
case STATUS_FORMAT_SHORT:
|
case STATUS_FORMAT_SHORT:
|
||||||
wt_shortstatus_print(s, null_termination);
|
wt_shortstatus_print(s, null_termination, status_show_branch);
|
||||||
break;
|
break;
|
||||||
case STATUS_FORMAT_PORCELAIN:
|
case STATUS_FORMAT_PORCELAIN:
|
||||||
wt_porcelain_print(s, null_termination);
|
wt_porcelain_print(s, null_termination);
|
||||||
@ -1036,6 +1038,8 @@ int cmd_status(int argc, const char **argv, const char *prefix)
|
|||||||
OPT__VERBOSE(&verbose),
|
OPT__VERBOSE(&verbose),
|
||||||
OPT_SET_INT('s', "short", &status_format,
|
OPT_SET_INT('s', "short", &status_format,
|
||||||
"show status concisely", STATUS_FORMAT_SHORT),
|
"show status concisely", STATUS_FORMAT_SHORT),
|
||||||
|
OPT_BOOLEAN('b', "branch", &status_show_branch,
|
||||||
|
"show branch information"),
|
||||||
OPT_SET_INT(0, "porcelain", &status_format,
|
OPT_SET_INT(0, "porcelain", &status_format,
|
||||||
"show porcelain output format",
|
"show porcelain output format",
|
||||||
STATUS_FORMAT_PORCELAIN),
|
STATUS_FORMAT_PORCELAIN),
|
||||||
@ -1088,7 +1092,7 @@ int cmd_status(int argc, const char **argv, const char *prefix)
|
|||||||
|
|
||||||
switch (status_format) {
|
switch (status_format) {
|
||||||
case STATUS_FORMAT_SHORT:
|
case STATUS_FORMAT_SHORT:
|
||||||
wt_shortstatus_print(&s, null_termination);
|
wt_shortstatus_print(&s, null_termination, status_show_branch);
|
||||||
break;
|
break;
|
||||||
case STATUS_FORMAT_PORCELAIN:
|
case STATUS_FORMAT_PORCELAIN:
|
||||||
wt_porcelain_print(&s, null_termination);
|
wt_porcelain_print(&s, null_termination);
|
||||||
|
@ -107,13 +107,32 @@ A dir2/added
|
|||||||
?? untracked
|
?? untracked
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
test_expect_success 'status -s (2)' '
|
test_expect_success 'status -s' '
|
||||||
|
|
||||||
git status -s >output &&
|
git status -s >output &&
|
||||||
test_cmp expect output
|
test_cmp expect output
|
||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
|
cat >expect <<\EOF
|
||||||
|
## master
|
||||||
|
M dir1/modified
|
||||||
|
A dir2/added
|
||||||
|
?? dir1/untracked
|
||||||
|
?? dir2/modified
|
||||||
|
?? dir2/untracked
|
||||||
|
?? expect
|
||||||
|
?? output
|
||||||
|
?? untracked
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'status -s -b' '
|
||||||
|
|
||||||
|
git status -s -b >output &&
|
||||||
|
test_cmp expect output
|
||||||
|
|
||||||
|
'
|
||||||
|
|
||||||
cat >expect <<EOF
|
cat >expect <<EOF
|
||||||
# On branch master
|
# On branch master
|
||||||
# Changes to be committed:
|
# Changes to be committed:
|
||||||
@ -436,6 +455,25 @@ test_expect_success 'status -s with color.status' '
|
|||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
|
cat >expect <<\EOF
|
||||||
|
## <GREEN>master<RESET>
|
||||||
|
<RED>M<RESET> dir1/modified
|
||||||
|
<GREEN>A<RESET> dir2/added
|
||||||
|
<BLUE>??<RESET> dir1/untracked
|
||||||
|
<BLUE>??<RESET> dir2/modified
|
||||||
|
<BLUE>??<RESET> dir2/untracked
|
||||||
|
<BLUE>??<RESET> expect
|
||||||
|
<BLUE>??<RESET> output
|
||||||
|
<BLUE>??<RESET> untracked
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test_expect_success 'status -s -b with color.status' '
|
||||||
|
|
||||||
|
git status -s -b | test_decode_color >output &&
|
||||||
|
test_cmp expect output
|
||||||
|
|
||||||
|
'
|
||||||
|
|
||||||
cat >expect <<\EOF
|
cat >expect <<\EOF
|
||||||
M dir1/modified
|
M dir1/modified
|
||||||
A dir2/added
|
A dir2/added
|
||||||
@ -469,6 +507,13 @@ test_expect_success 'status --porcelain ignores color.status' '
|
|||||||
git config --unset color.status
|
git config --unset color.status
|
||||||
git config --unset color.ui
|
git config --unset color.ui
|
||||||
|
|
||||||
|
test_expect_success 'status --porcelain ignores -b' '
|
||||||
|
|
||||||
|
git status --porcelain -b >output &&
|
||||||
|
test_cmp expect output
|
||||||
|
|
||||||
|
'
|
||||||
|
|
||||||
cat >expect <<\EOF
|
cat >expect <<\EOF
|
||||||
# On branch master
|
# On branch master
|
||||||
# Changes to be committed:
|
# Changes to be committed:
|
||||||
|
67
wt-status.c
67
wt-status.c
@ -9,6 +9,7 @@
|
|||||||
#include "quote.h"
|
#include "quote.h"
|
||||||
#include "run-command.h"
|
#include "run-command.h"
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
|
#include "refs.h"
|
||||||
|
|
||||||
static char default_wt_status_colors[][COLOR_MAXLEN] = {
|
static char default_wt_status_colors[][COLOR_MAXLEN] = {
|
||||||
GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */
|
GIT_COLOR_NORMAL, /* WT_STATUS_HEADER */
|
||||||
@ -17,6 +18,8 @@ static char default_wt_status_colors[][COLOR_MAXLEN] = {
|
|||||||
GIT_COLOR_RED, /* WT_STATUS_UNTRACKED */
|
GIT_COLOR_RED, /* WT_STATUS_UNTRACKED */
|
||||||
GIT_COLOR_RED, /* WT_STATUS_NOBRANCH */
|
GIT_COLOR_RED, /* WT_STATUS_NOBRANCH */
|
||||||
GIT_COLOR_RED, /* WT_STATUS_UNMERGED */
|
GIT_COLOR_RED, /* WT_STATUS_UNMERGED */
|
||||||
|
GIT_COLOR_GREEN, /* WT_STATUS_LOCAL_BRANCH */
|
||||||
|
GIT_COLOR_RED, /* WT_STATUS_REMOTE_BRANCH */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *color(int slot, struct wt_status *s)
|
static const char *color(int slot, struct wt_status *s)
|
||||||
@ -756,9 +759,69 @@ static void wt_shortstatus_other(int null_termination, struct string_list_item *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wt_shortstatus_print(struct wt_status *s, int null_termination)
|
static void wt_shortstatus_print_tracking(struct wt_status *s)
|
||||||
|
{
|
||||||
|
struct branch *branch;
|
||||||
|
const char *header_color = color(WT_STATUS_HEADER, s);
|
||||||
|
const char *branch_color_local = color(WT_STATUS_LOCAL_BRANCH, s);
|
||||||
|
const char *branch_color_remote = color(WT_STATUS_REMOTE_BRANCH, s);
|
||||||
|
|
||||||
|
const char *base;
|
||||||
|
const char *branch_name;
|
||||||
|
int num_ours, num_theirs;
|
||||||
|
|
||||||
|
color_fprintf(s->fp, color(WT_STATUS_HEADER, s), "## ");
|
||||||
|
|
||||||
|
if (!s->branch)
|
||||||
|
return;
|
||||||
|
branch_name = s->branch;
|
||||||
|
|
||||||
|
if (!prefixcmp(branch_name, "refs/heads/"))
|
||||||
|
branch_name += 11;
|
||||||
|
else if (!strcmp(branch_name, "HEAD")) {
|
||||||
|
branch_name = "HEAD (no branch)";
|
||||||
|
branch_color_local = color(WT_STATUS_NOBRANCH, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
branch = branch_get(s->branch + 11);
|
||||||
|
if (s->is_initial)
|
||||||
|
color_fprintf(s->fp, header_color, "Initial commit on ");
|
||||||
|
if (!stat_tracking_info(branch, &num_ours, &num_theirs)) {
|
||||||
|
color_fprintf_ln(s->fp, branch_color_local,
|
||||||
|
"%s", branch_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
base = branch->merge[0]->dst;
|
||||||
|
base = shorten_unambiguous_ref(base, 0);
|
||||||
|
color_fprintf(s->fp, branch_color_local, "%s", branch_name);
|
||||||
|
color_fprintf(s->fp, header_color, "...");
|
||||||
|
color_fprintf(s->fp, branch_color_remote, "%s", base);
|
||||||
|
|
||||||
|
color_fprintf(s->fp, header_color, " [");
|
||||||
|
if (!num_ours) {
|
||||||
|
color_fprintf(s->fp, header_color, "behind ");
|
||||||
|
color_fprintf(s->fp, branch_color_remote, "%d", num_theirs);
|
||||||
|
} else if (!num_theirs) {
|
||||||
|
color_fprintf(s->fp, header_color, "ahead ");
|
||||||
|
color_fprintf(s->fp, branch_color_local, "%d", num_ours);
|
||||||
|
} else {
|
||||||
|
color_fprintf(s->fp, header_color, "ahead ");
|
||||||
|
color_fprintf(s->fp, branch_color_local, "%d", num_ours);
|
||||||
|
color_fprintf(s->fp, header_color, ", behind ");
|
||||||
|
color_fprintf(s->fp, branch_color_remote, "%d", num_theirs);
|
||||||
|
}
|
||||||
|
|
||||||
|
color_fprintf_ln(s->fp, header_color, "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
void wt_shortstatus_print(struct wt_status *s, int null_termination, int show_branch)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (show_branch)
|
||||||
|
wt_shortstatus_print_tracking(s);
|
||||||
|
|
||||||
for (i = 0; i < s->change.nr; i++) {
|
for (i = 0; i < s->change.nr; i++) {
|
||||||
struct wt_status_change_data *d;
|
struct wt_status_change_data *d;
|
||||||
struct string_list_item *it;
|
struct string_list_item *it;
|
||||||
@ -789,5 +852,5 @@ void wt_porcelain_print(struct wt_status *s, int null_termination)
|
|||||||
s->use_color = 0;
|
s->use_color = 0;
|
||||||
s->relative_paths = 0;
|
s->relative_paths = 0;
|
||||||
s->prefix = NULL;
|
s->prefix = NULL;
|
||||||
wt_shortstatus_print(s, null_termination);
|
wt_shortstatus_print(s, null_termination, 0);
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ enum color_wt_status {
|
|||||||
WT_STATUS_UNTRACKED,
|
WT_STATUS_UNTRACKED,
|
||||||
WT_STATUS_NOBRANCH,
|
WT_STATUS_NOBRANCH,
|
||||||
WT_STATUS_UNMERGED,
|
WT_STATUS_UNMERGED,
|
||||||
|
WT_STATUS_LOCAL_BRANCH,
|
||||||
|
WT_STATUS_REMOTE_BRANCH,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum untracked_status_type {
|
enum untracked_status_type {
|
||||||
@ -43,7 +45,7 @@ struct wt_status {
|
|||||||
int submodule_summary;
|
int submodule_summary;
|
||||||
int show_ignored_files;
|
int show_ignored_files;
|
||||||
enum untracked_status_type show_untracked_files;
|
enum untracked_status_type show_untracked_files;
|
||||||
char color_palette[WT_STATUS_UNMERGED+1][COLOR_MAXLEN];
|
char color_palette[WT_STATUS_REMOTE_BRANCH+1][COLOR_MAXLEN];
|
||||||
|
|
||||||
/* These are computed during processing of the individual sections */
|
/* These are computed during processing of the individual sections */
|
||||||
int commitable;
|
int commitable;
|
||||||
@ -60,7 +62,7 @@ void wt_status_prepare(struct wt_status *s);
|
|||||||
void wt_status_print(struct wt_status *s);
|
void wt_status_print(struct wt_status *s);
|
||||||
void wt_status_collect(struct wt_status *s);
|
void wt_status_collect(struct wt_status *s);
|
||||||
|
|
||||||
void wt_shortstatus_print(struct wt_status *s, int null_termination);
|
void wt_shortstatus_print(struct wt_status *s, int null_termination, int show_branch);
|
||||||
void wt_porcelain_print(struct wt_status *s, int null_termination);
|
void wt_porcelain_print(struct wt_status *s, int null_termination);
|
||||||
|
|
||||||
#endif /* STATUS_H */
|
#endif /* STATUS_H */
|
||||||
|
Reference in New Issue
Block a user