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
the template shown when writing commit messages in
linkgit:git-commit[1], and in the help message shown
- by linkgit:git-checkout[1] when switching branch.
+ by linkgit:git-switch[1] or
+ linkgit:git-checkout[1] when switching branch.
statusUoption::
Advise to consider using the `-u` option to linkgit:git-status[1]
when the command takes more than 2 seconds to enumerate untracked
your information is guessed from the system username and
domain name.
detachedHead::
- Advice shown when you used linkgit:git-checkout[1] to
- move to the detach HEAD state, to instruct how to create
- a local branch after the fact.
+ Advice shown when you used
+ linkgit:git-switch[1] or linkgit:git-checkout[1]
+ to move to the detach HEAD state, to instruct how to
+ create a local branch after the fact.
checkoutAmbiguousRemoteBranchName::
Advice shown when the argument to
- linkgit:git-checkout[1] ambiguously resolves to a
+ linkgit:git-checkout[1] and linkgit:git-switch[1]
+ ambiguously resolves to a
remote tracking branch on more than one remote in
situations where an unambiguous argument would have
otherwise caused a remote-tracking branch to be
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;
{ "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 },
void detach_advice(const char *new_name)
{
const char *fmt =
- _("Note: checking out '%s'.\n\n"
+ _("Note: switching to '%s'.\n"
+ "\n"
"You are in 'detached HEAD' state. You can look around, make experimental\n"
"changes and commit them, and you can discard any commits you make in this\n"
- "state without impacting any branches by performing another checkout.\n\n"
+ "state without impacting any branches by switching back to a branch.\n"
+ "\n"
"If you want to create a new branch to retain commits you create, you may\n"
- "do so (now or later) by using -b with the checkout command again. Example:\n\n"
- " git checkout -b <new-branch-name>\n\n");
+ "do so (now or later) by using -c with the switch command. Example:\n"
+ "\n"
+ " git switch -c <new-branch-name>\n"
+ "\n"
+ "Or undo this operation with:\n"
+ "\n"
+ " git switch -\n"
+ "\n"
+ "Turn off this advice by setting config variable advice.detachedHead to false\n\n");
fprintf(stderr, fmt, new_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)
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;
}
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;
die("%s", err.buf);
}
- sequencer_post_commit_cleanup(the_repository);
+ sequencer_post_commit_cleanup(the_repository, 0);
unlink(git_path_merge_head(the_repository));
unlink(git_path_merge_msg(the_repository));
unlink(git_path_merge_mode(the_repository));
if (commit_index_files())
die(_("repository has been updated, but unable to write\n"
"new_index file. Check that disk is not full and quota is\n"
- "not exceeded, and then \"git reset HEAD\" to recover."));
+ "not exceeded, and then \"git restore --staged :/\" to recover."));
- if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0))
- write_commit_graph_reachable(get_object_directory(), 0, 0);
+ if (git_env_bool(GIT_TEST_COMMIT_GRAPH, 0) &&
+ write_commit_graph_reachable(get_object_directory(), 0))
+ return 1;
repo_rerere(the_repository, 0);
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
#include "lockfile.h"
#include "sequencer.h"
+ #define AB_DELAY_WARNING_IN_MS (2 * 1000)
+
static const char cut_line[] =
"------------------------ >8 ------------------------\n";
return;
if (s->whence != FROM_COMMIT)
;
- else if (!s->is_initial)
- status_printf_ln(s, c, _(" (use \"git reset %s <file>...\" to unstage)"), s->reference);
- else
+ else if (!s->is_initial) {
+ if (!strcmp(s->reference, "HEAD"))
+ status_printf_ln(s, c,
+ _(" (use \"git restore --staged <file>...\" to unstage)"));
+ else
+ status_printf_ln(s, c,
+ _(" (use \"git restore --source=%s --staged <file>...\" to unstage)"),
+ s->reference);
+ } else
status_printf_ln(s, c, _(" (use \"git rm --cached <file>...\" to unstage)"));
if (!both_deleted) {
return;
if (s->whence != FROM_COMMIT)
; /* NEEDSWORK: use "git reset --unresolve"??? */
- else if (!s->is_initial)
- status_printf_ln(s, c, _(" (use \"git reset %s <file>...\" to unstage)"), s->reference);
- else
+ else if (!s->is_initial) {
+ if (!strcmp(s->reference, "HEAD"))
+ status_printf_ln(s, c
+ , _(" (use \"git restore --staged <file>...\" to unstage)"));
+ else
+ status_printf_ln(s, c,
+ _(" (use \"git restore --source=%s --staged <file>...\" to unstage)"),
+ s->reference);
+ } else
status_printf_ln(s, c, _(" (use \"git rm --cached <file>...\" to unstage)"));
status_printf_ln(s, c, "%s", "");
}
status_printf_ln(s, c, _(" (use \"git add <file>...\" to update what will be committed)"));
else
status_printf_ln(s, c, _(" (use \"git add/rm <file>...\" to update what will be committed)"));
- status_printf_ln(s, c, _(" (use \"git checkout -- <file>...\" to discard changes in working directory)"));
+ status_printf_ln(s, c, _(" (use \"git restore <file>...\" to discard changes in working directory)"));
if (has_dirty_submodules)
status_printf_ln(s, c, _(" (commit or discard the untracked or modified content in submodules)"));
status_printf_ln(s, c, "%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;
} else if (s->state.detached_from) {
branch_name = s->state.detached_from;
if (s->state.detached_at)
- on_what = _("HEAD detached at ");
+ on_what = HEAD_DETACHED_AT;
else
- on_what = _("HEAD detached from ");
+ on_what = HEAD_DETACHED_FROM;
} else {
branch_name = "";
on_what = _("Not currently on any branch.");