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:
Junio C Hamano
2010-06-18 11:16:55 -07:00
5 changed files with 130 additions and 8 deletions

View File

@ -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
------------- -------------

View File

@ -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);

View File

@ -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:

View File

@ -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);
} }

View File

@ -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 */