status: add optional stash count information

Introduce '--show-stash' and its configuration option 'status.showStash' to allow git-status to show information about currently stashed entries. Signed-off-by: Liam Beguin <liambeguin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Liam Beguin committed Jun 17, 2017 at 18:30 UTC c1b5d0194b98bd3d0acc9cec7070808fbbe6a740
6 files changed +71
Documentation/config.txt
+5
@@ -2992,6 +2992,11 @@ status.displayCommentPrefix::
2992 behavior of linkgit:git-status[1] in Git 1.8.4 and previous.
2993 Defaults to false.
2994
2995 +status.showStash::
2996 + If set to true, linkgit:git-status[1] will display the number of
2997 + entries currently stashed away.
2998 + Defaults to false.
2999 +
3000 status.showUntrackedFiles::
3001 By default, linkgit:git-status[1] and linkgit:git-commit[1] show
3002 files which are not currently tracked by Git. Directories which
Documentation/git-status.txt
+3
@@ -32,6 +32,9 @@ OPTIONS
32 --branch::
33 Show the branch and tracking info even in short-format.
34
35 +--show-stash::
36 + Show the number of entries currently stashed away.
37 +
38 --porcelain[=<version>]::
39 Give the output in an easy-to-parse format for scripts.
40 This is similar to the short output, but will remain stable
builtin/commit.c
+6
@@ -1295,6 +1295,10 @@ static int git_status_config(const char *k, const char *v, void *cb)
1295 status_deferred_config.show_branch = git_config_bool(k, v);
1296 return 0;
1297 }
1298 + if (!strcmp(k, "status.showstash")) {
1299 + s->show_stash = git_config_bool(k, v);
1300 + return 0;
1301 + }
1302 if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
1303 s->use_color = git_config_colorbool(k, v);
1304 return 0;
@@ -1343,6 +1347,8 @@ int cmd_status(int argc, const char **argv, const char *prefix)
1347 N_("show status concisely"), STATUS_FORMAT_SHORT),
1348 OPT_BOOL('b', "branch", &s.show_branch,
1349 N_("show branch information")),
1350 + OPT_BOOL(0, "show-stash", &s.show_stash,
1351 + N_("show stash information")),
1352 { OPTION_CALLBACK, 0, "porcelain", &status_format,
1353 N_("version"), N_("machine-readable output"),
1354 PARSE_OPT_OPTARG, opt_parse_porcelain },
t/t7508-status.sh
+32
@@ -1608,4 +1608,36 @@ test_expect_success 'git commit -m will commit a staged but ignored submodule' '
1608 git config -f .gitmodules --remove-section submodule.subname
1609 '
1610
1611 +test_expect_success 'show stash info with "--show-stash"' '
1612 + git reset --hard &&
1613 + git stash clear &&
1614 + echo 1 >file &&
1615 + git add file &&
1616 + git stash &&
1617 + git status >expected_default &&
1618 + git status --show-stash >expected_with_stash &&
1619 + test_i18ngrep "^Your stash currently has 1 entry$" expected_with_stash
1620 +'
1621 +
1622 +test_expect_success 'no stash info with "--show-stash --no-show-stash"' '
1623 + git status --show-stash --no-show-stash >expected_without_stash &&
1624 + test_cmp expected_default expected_without_stash
1625 +'
1626 +
1627 +test_expect_success '"status.showStash=false" weaker than "--show-stash"' '
1628 + git -c status.showStash=false status --show-stash >actual &&
1629 + test_cmp expected_with_stash actual
1630 +'
1631 +
1632 +test_expect_success '"status.showStash=true" weaker than "--no-show-stash"' '
1633 + git -c status.showStash=true status --no-show-stash >actual &&
1634 + test_cmp expected_without_stash actual
1635 +'
1636 +
1637 +test_expect_success 'no additionnal info if no stash entries' '
1638 + git stash clear &&
1639 + git -c status.showStash=true status >actual &&
1640 + test_cmp expected_without_stash actual
1641 +'
1642 +
1643 test_done
wt-status.c
+24
@@ -137,6 +137,7 @@ void wt_status_prepare(struct wt_status *s)
137 s->untracked.strdup_strings = 1;
138 s->ignored.strdup_strings = 1;
139 s->show_branch = -1; /* unspecified */
140 + s->show_stash = 0;
141 s->display_comment_prefix = 0;
142 }
143
@@ -801,6 +802,27 @@ static void wt_longstatus_print_changed(struct wt_status *s)
802 wt_longstatus_print_trailer(s);
803 }
804
805 +static int stash_count_refs(struct object_id *ooid, struct object_id *noid,
806 + const char *email, timestamp_t timestamp, int tz,
807 + const char *message, void *cb_data)
808 +{
809 + int *c = cb_data;
810 + (*c)++;
811 + return 0;
812 +}
813 +
814 +static void wt_longstatus_print_stash_summary(struct wt_status *s)
815 +{
816 + int stash_count = 0;
817 +
818 + for_each_reflog_ent("refs/stash", stash_count_refs, &stash_count);
819 + if (stash_count > 0)
820 + status_printf_ln(s, GIT_COLOR_NORMAL,
821 + Q_("Your stash currently has %d entry",
822 + "Your stash currently has %d entries", stash_count),
823 + stash_count);
824 +}
825 +
826 static void wt_longstatus_print_submodule_summary(struct wt_status *s, int uncommitted)
827 {
828 struct child_process sm_summary = CHILD_PROCESS_INIT;
@@ -1642,6 +1664,8 @@ static void wt_longstatus_print(struct wt_status *s)
1664 } else
1665 printf(_("nothing to commit, working tree clean\n"));
1666 }
1667 + if(s->show_stash)
1668 + wt_longstatus_print_stash_summary(s);
1669 }
1670
1671 static void wt_shortstatus_unmerged(struct string_list_item *it,
wt-status.h
+1
@@ -77,6 +77,7 @@ struct wt_status {
77 unsigned colopts;
78 int null_termination;
79 int show_branch;
80 + int show_stash;
81 int hints;
82
83 enum wt_status_format status_format;