summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/config/advice.txt6
-rw-r--r--Documentation/config/status.txt5
-rw-r--r--advice.c2
-rw-r--r--advice.h1
-rw-r--r--builtin/commit.c19
-rwxr-xr-xt/t6040-tracking-info.sh31
-rwxr-xr-xt/t7064-wtstatus-pv2.sh8
-rw-r--r--wt-status.c17
8 files changed, 88 insertions, 1 deletions
diff --git a/Documentation/config/advice.txt b/Documentation/config/advice.txt
index d5fd05ce81..0103faa417 100644
--- a/Documentation/config/advice.txt
+++ b/Documentation/config/advice.txt
@@ -37,6 +37,12 @@ advice.*::
we can still suggest that the user push to either
refs/heads/* or refs/tags/* based on the type of the
source object.
+ statusAheadBehind::
+ Shown when linkgit:git-status[1] computes the ahead/behind
+ counts for a local ref compared to its remote tracking ref,
+ and that calculation takes longer than expected. Will not
+ appear if `status.aheadBehind` is false or the option
+ `--no-ahead-behind` is given.
statusHints::
Show directions on how to proceed from the current
state in the output of linkgit:git-status[1], in
diff --git a/Documentation/config/status.txt b/Documentation/config/status.txt
index ed72fa7dae..0fc704ab80 100644
--- a/Documentation/config/status.txt
+++ b/Documentation/config/status.txt
@@ -12,6 +12,11 @@ status.branch::
Set to true to enable --branch by default in linkgit:git-status[1].
The option --no-branch takes precedence over this variable.
+status.aheadBehind::
+ Set to true to enable `--ahead-behind` and false to enable
+ `--no-ahead-behind` by default in linkgit:git-status[1] for
+ non-porcelain status formats. Defaults to true.
+
status.displayCommentPrefix::
If set to true, linkgit:git-status[1] will insert a comment
prefix before each output line (starting with
diff --git a/advice.c b/advice.c
index b04709bfec..2d330d2b75 100644
--- a/advice.c
+++ b/advice.c
@@ -12,6 +12,7 @@ int advice_push_needs_force = 1;
int advice_push_unqualified_ref_name = 1;
int advice_status_hints = 1;
int advice_status_u_option = 1;
+int advice_status_ahead_behind_warning = 1;
int advice_commit_before_merge = 1;
int advice_reset_quiet_warning = 1;
int advice_resolve_conflict = 1;
@@ -68,6 +69,7 @@ static struct {
{ "pushUnqualifiedRefName", &advice_push_unqualified_ref_name },
{ "statusHints", &advice_status_hints },
{ "statusUoption", &advice_status_u_option },
+ { "statusAheadBehindWarning", &advice_status_ahead_behind_warning },
{ "commitBeforeMerge", &advice_commit_before_merge },
{ "resetQuiet", &advice_reset_quiet_warning },
{ "resolveConflict", &advice_resolve_conflict },
diff --git a/advice.h b/advice.h
index e50f02cdfe..c86de9b9b8 100644
--- a/advice.h
+++ b/advice.h
@@ -12,6 +12,7 @@ extern int advice_push_needs_force;
extern int advice_push_unqualified_ref_name;
extern int advice_status_hints;
extern int advice_status_u_option;
+extern int advice_status_ahead_behind_warning;
extern int advice_commit_before_merge;
extern int advice_reset_quiet_warning;
extern int advice_resolve_conflict;
diff --git a/builtin/commit.c b/builtin/commit.c
index 851b257867..3b561c2a75 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1078,9 +1078,11 @@ static const char *read_commit_message(const char *name)
static struct status_deferred_config {
enum wt_status_format status_format;
int show_branch;
+ enum ahead_behind_flags ahead_behind;
} status_deferred_config = {
STATUS_FORMAT_UNSPECIFIED,
- -1 /* unspecified */
+ -1, /* unspecified */
+ AHEAD_BEHIND_UNSPECIFIED,
};
static void finalize_deferred_config(struct wt_status *s)
@@ -1107,6 +1109,17 @@ static void finalize_deferred_config(struct wt_status *s)
if (s->show_branch < 0)
s->show_branch = 0;
+ /*
+ * If the user did not give a "--[no]-ahead-behind" command
+ * line argument *AND* we will print in a human-readable format
+ * (short, long etc.) then we inherit from the status.aheadbehind
+ * config setting. In all other cases (and porcelain V[12] formats
+ * in particular), we inherit _FULL for backwards compatibility.
+ */
+ if (use_deferred_config &&
+ s->ahead_behind_flags == AHEAD_BEHIND_UNSPECIFIED)
+ s->ahead_behind_flags = status_deferred_config.ahead_behind;
+
if (s->ahead_behind_flags == AHEAD_BEHIND_UNSPECIFIED)
s->ahead_behind_flags = AHEAD_BEHIND_FULL;
}
@@ -1246,6 +1259,10 @@ static int git_status_config(const char *k, const char *v, void *cb)
status_deferred_config.show_branch = git_config_bool(k, v);
return 0;
}
+ if (!strcmp(k, "status.aheadbehind")) {
+ status_deferred_config.ahead_behind = git_config_bool(k, v);
+ return 0;
+ }
if (!strcmp(k, "status.showstash")) {
s->show_stash = git_config_bool(k, v);
return 0;
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
index 716283b274..febf63f28a 100755
--- a/t/t6040-tracking-info.sh
+++ b/t/t6040-tracking-info.sh
@@ -160,6 +160,19 @@ test_expect_success 'status -s -b --no-ahead-behind (diverged from upstream)' '
'
cat >expect <<\EOF
+## b1...origin/master [different]
+EOF
+
+test_expect_success 'status.aheadbehind=false status -s -b (diverged from upstream)' '
+ (
+ cd test &&
+ git checkout b1 >/dev/null &&
+ git -c status.aheadbehind=false status -s -b | head -1
+ ) >actual &&
+ test_i18ncmp expect actual
+'
+
+cat >expect <<\EOF
On branch b1
Your branch and 'origin/master' have diverged,
and have 1 and 1 different commits each, respectively.
@@ -174,6 +187,15 @@ test_expect_success 'status --long --branch' '
test_i18ncmp expect actual
'
+test_expect_success 'status --long --branch' '
+ (
+ cd test &&
+ git checkout b1 >/dev/null &&
+ git -c status.aheadbehind=true status --long -b | head -3
+ ) >actual &&
+ test_i18ncmp expect actual
+'
+
cat >expect <<\EOF
On branch b1
Your branch and 'origin/master' refer to different commits.
@@ -188,6 +210,15 @@ test_expect_success 'status --long --branch --no-ahead-behind' '
test_i18ncmp expect actual
'
+test_expect_success 'status.aheadbehind=false status --long --branch' '
+ (
+ cd test &&
+ git checkout b1 >/dev/null &&
+ git -c status.aheadbehind=false status --long -b | head -2
+ ) >actual &&
+ test_i18ncmp expect actual
+'
+
cat >expect <<\EOF
## b5...brokenbase [gone]
EOF
diff --git a/t/t7064-wtstatus-pv2.sh b/t/t7064-wtstatus-pv2.sh
index 11eccc231a..537787e598 100755
--- a/t/t7064-wtstatus-pv2.sh
+++ b/t/t7064-wtstatus-pv2.sh
@@ -445,6 +445,14 @@ test_expect_success 'verify --[no-]ahead-behind with V2 format' '
EOF
git status --ahead-behind --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual &&
+
+ # Confirm that "status.aheadbehind" DOES NOT work on V2 format.
+ git -c status.aheadbehind=false status --porcelain=v2 --branch --untracked-files=all >actual &&
+ test_cmp expect actual &&
+
+ # Confirm that "status.aheadbehind" DOES NOT work on V2 format.
+ git -c status.aheadbehind=true status --porcelain=v2 --branch --untracked-files=all >actual &&
test_cmp expect actual
)
'
diff --git a/wt-status.c b/wt-status.c
index dd5270647e..7d776f8a97 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -19,6 +19,8 @@
#include "lockfile.h"
#include "sequencer.h"
+#define AB_DELAY_WARNING_IN_MS (2 * 1000)
+
static const char cut_line[] =
"------------------------ >8 ------------------------\n";
@@ -1097,14 +1099,29 @@ static void wt_longstatus_print_tracking(struct wt_status *s)
struct branch *branch;
char comment_line_string[3];
int i;
+ uint64_t t_begin = 0;
assert(s->branch && !s->is_initial);
if (!skip_prefix(s->branch, "refs/heads/", &branch_name))
return;
branch = branch_get(branch_name);
+
+ t_begin = getnanotime();
+
if (!format_tracking_info(branch, &sb, s->ahead_behind_flags))
return;
+ if (advice_status_ahead_behind_warning &&
+ s->ahead_behind_flags == AHEAD_BEHIND_FULL) {
+ uint64_t t_delta_in_ms = (getnanotime() - t_begin) / 1000000;
+ if (t_delta_in_ms > AB_DELAY_WARNING_IN_MS) {
+ strbuf_addf(&sb, _("\n"
+ "It took %.2f seconds to compute the branch ahead/behind values.\n"
+ "You can use '--no-ahead-behind' to avoid this.\n"),
+ t_delta_in_ms / 1000.0);
+ }
+ }
+
i = 0;
if (s->display_comment_prefix) {
comment_line_string[i++] = comment_line_char;