Merge branch 'rj/advice-delete-branch-not-fully-merged'

The error message given when "git branch -d branch" fails due to
commits unique to the branch has been split into an error and a new
conditional advice message.

* rj/advice-delete-branch-not-fully-merged:
  branch: make the advice to force-deleting a conditional one
  advice: fix an unexpected leading space
  advice: sort the advice related lists
This commit is contained in:
Junio C Hamano
2024-01-26 08:54:45 -08:00
4 changed files with 100 additions and 96 deletions

View File

@ -4,27 +4,59 @@ advice.*::
can tell Git that you do not need help by setting these to 'false': can tell Git that you do not need help by setting these to 'false':
+ +
-- --
addEmbeddedRepo::
Advice on what to do when you've accidentally added one
git repo inside of another.
addEmptyPathspec::
Advice shown if a user runs the add command without providing
the pathspec parameter.
addIgnoredFile::
Advice shown if a user attempts to add an ignored file to
the index.
amWorkDir::
Advice that shows the location of the patch file when
linkgit:git-am[1] fails to apply it.
ambiguousFetchRefspec:: ambiguousFetchRefspec::
Advice shown when a fetch refspec for multiple remotes maps to Advice shown when a fetch refspec for multiple remotes maps to
the same remote-tracking branch namespace and causes branch the same remote-tracking branch namespace and causes branch
tracking set-up to fail. tracking set-up to fail.
checkoutAmbiguousRemoteBranchName::
Advice shown when the argument to
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
checked out. See the `checkout.defaultRemote`
configuration variable for how to set a given remote
to be used by default in some situations where this
advice would be printed.
commitBeforeMerge::
Advice shown when linkgit:git-merge[1] refuses to
merge to avoid overwriting local changes.
detachedHead::
Advice shown when you used
linkgit:git-switch[1] or linkgit:git-checkout[1]
to move to the detached HEAD state, to instruct how to
create a local branch after the fact.
diverging::
Advice shown when a fast-forward is not possible.
fetchShowForcedUpdates:: fetchShowForcedUpdates::
Advice shown when linkgit:git-fetch[1] takes a long time Advice shown when linkgit:git-fetch[1] takes a long time
to calculate forced updates after ref updates, or to warn to calculate forced updates after ref updates, or to warn
that the check is disabled. that the check is disabled.
pushUpdateRejected:: forceDeleteBranch::
Set this variable to 'false' if you want to disable Advice shown when a user tries to delete a not fully merged
'pushNonFFCurrent', 'pushNonFFMatching', 'pushAlreadyExists', branch without the force option set.
'pushFetchFirst', 'pushNeedsForce', and 'pushRefNeedsUpdate' ignoredHook::
simultaneously. Advice shown if a hook is ignored because the hook is not
pushNonFFCurrent:: set as executable.
Advice shown when linkgit:git-push[1] fails due to a implicitIdentity::
non-fast-forward update to the current branch. Advice on how to set your identity configuration when
pushNonFFMatching:: your information is guessed from the system username and
Advice shown when you ran linkgit:git-push[1] and pushed domain name.
'matching refs' explicitly (i.e. you used ':', or nestedTag::
specified a refspec that isn't your current branch) and Advice shown if a user attempts to recursively tag a tag object.
it resulted in a non-fast-forward error.
pushAlreadyExists:: pushAlreadyExists::
Shown when linkgit:git-push[1] rejects an update that Shown when linkgit:git-push[1] rejects an update that
does not qualify for fast-forwarding (e.g., a tag.) does not qualify for fast-forwarding (e.g., a tag.)
@ -37,6 +69,18 @@ advice.*::
tries to overwrite a remote ref that points at an tries to overwrite a remote ref that points at an
object that is not a commit-ish, or make the remote object that is not a commit-ish, or make the remote
ref point at an object that is not a commit-ish. ref point at an object that is not a commit-ish.
pushNonFFCurrent::
Advice shown when linkgit:git-push[1] fails due to a
non-fast-forward update to the current branch.
pushNonFFMatching::
Advice shown when you ran linkgit:git-push[1] and pushed
'matching refs' explicitly (i.e. you used ':', or
specified a refspec that isn't your current branch) and
it resulted in a non-fast-forward error.
pushRefNeedsUpdate::
Shown when linkgit:git-push[1] rejects a forced update of
a branch when its remote-tracking ref has updates that we
do not have locally.
pushUnqualifiedRefname:: pushUnqualifiedRefname::
Shown when linkgit:git-push[1] gives up trying to Shown when linkgit:git-push[1] gives up trying to
guess based on the source and destination refs what guess based on the source and destination refs what
@ -44,10 +88,23 @@ advice.*::
we can still suggest that the user push to either we can still suggest that the user push to either
refs/heads/* or refs/tags/* based on the type of the refs/heads/* or refs/tags/* based on the type of the
source object. source object.
pushRefNeedsUpdate:: pushUpdateRejected::
Shown when linkgit:git-push[1] rejects a forced update of Set this variable to 'false' if you want to disable
a branch when its remote-tracking ref has updates that we 'pushNonFFCurrent', 'pushNonFFMatching', 'pushAlreadyExists',
do not have locally. 'pushFetchFirst', 'pushNeedsForce', and 'pushRefNeedsUpdate'
simultaneously.
resetNoRefresh::
Advice to consider using the `--no-refresh` option to
linkgit:git-reset[1] when the command takes more than 2 seconds
to refresh the index after reset.
resolveConflict::
Advice shown by various commands when conflicts
prevent the operation from being performed.
rmHints::
In case of failure in the output of linkgit:git-rm[1],
show directions on how to proceed from the current state.
sequencerInUse::
Advice shown when a sequencer command is already in progress.
skippedCherryPicks:: skippedCherryPicks::
Shown when linkgit:git-rebase[1] skips a commit that has already Shown when linkgit:git-rebase[1] skips a commit that has already
been cherry-picked onto the upstream branch. been cherry-picked onto the upstream branch.
@ -68,76 +125,22 @@ advice.*::
Advise to consider using the `-u` option to linkgit:git-status[1] Advise to consider using the `-u` option to linkgit:git-status[1]
when the command takes more than 2 seconds to enumerate untracked when the command takes more than 2 seconds to enumerate untracked
files. files.
commitBeforeMerge::
Advice shown when linkgit:git-merge[1] refuses to
merge to avoid overwriting local changes.
resetNoRefresh::
Advice to consider using the `--no-refresh` option to
linkgit:git-reset[1] when the command takes more than 2 seconds
to refresh the index after reset.
resolveConflict::
Advice shown by various commands when conflicts
prevent the operation from being performed.
sequencerInUse::
Advice shown when a sequencer command is already in progress.
implicitIdentity::
Advice on how to set your identity configuration when
your information is guessed from the system username and
domain name.
detachedHead::
Advice shown when you used
linkgit:git-switch[1] or linkgit:git-checkout[1]
to move to the detached HEAD state, to instruct how to
create a local branch after the fact.
suggestDetachingHead::
Advice shown when linkgit:git-switch[1] refuses to detach HEAD
without the explicit `--detach` option.
checkoutAmbiguousRemoteBranchName::
Advice shown when the argument to
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
checked out. See the `checkout.defaultRemote`
configuration variable for how to set a given remote
to be used by default in some situations where this
advice would be printed.
amWorkDir::
Advice that shows the location of the patch file when
linkgit:git-am[1] fails to apply it.
rmHints::
In case of failure in the output of linkgit:git-rm[1],
show directions on how to proceed from the current state.
addEmbeddedRepo::
Advice on what to do when you've accidentally added one
git repo inside of another.
ignoredHook::
Advice shown if a hook is ignored because the hook is not
set as executable.
waitingForEditor::
Print a message to the terminal whenever Git is waiting for
editor input from the user.
nestedTag::
Advice shown if a user attempts to recursively tag a tag object.
submoduleAlternateErrorStrategyDie:: submoduleAlternateErrorStrategyDie::
Advice shown when a submodule.alternateErrorStrategy option Advice shown when a submodule.alternateErrorStrategy option
configured to "die" causes a fatal error. configured to "die" causes a fatal error.
submodulesNotUpdated:: submodulesNotUpdated::
Advice shown when a user runs a submodule command that fails Advice shown when a user runs a submodule command that fails
because `git submodule update --init` was not run. because `git submodule update --init` was not run.
addIgnoredFile:: suggestDetachingHead::
Advice shown if a user attempts to add an ignored file to Advice shown when linkgit:git-switch[1] refuses to detach HEAD
the index. without the explicit `--detach` option.
addEmptyPathspec::
Advice shown if a user runs the add command without providing
the pathspec parameter.
updateSparsePath:: updateSparsePath::
Advice shown when either linkgit:git-add[1] or linkgit:git-rm[1] Advice shown when either linkgit:git-add[1] or linkgit:git-rm[1]
is asked to update index entries outside the current sparse is asked to update index entries outside the current sparse
checkout. checkout.
diverging:: waitingForEditor::
Advice shown when a fast-forward is not possible. Print a message to the terminal whenever Git is waiting for
editor input from the user.
worktreeAddOrphan:: worktreeAddOrphan::
Advice shown when a user tries to create a worktree from an Advice shown when a user tries to create a worktree from an
invalid reference, to instruct how to create a new unborn invalid reference, to instruct how to create a new unborn

View File

@ -40,14 +40,14 @@ static struct {
[ADVICE_ADD_EMBEDDED_REPO] = { "addEmbeddedRepo", 1 }, [ADVICE_ADD_EMBEDDED_REPO] = { "addEmbeddedRepo", 1 },
[ADVICE_ADD_EMPTY_PATHSPEC] = { "addEmptyPathspec", 1 }, [ADVICE_ADD_EMPTY_PATHSPEC] = { "addEmptyPathspec", 1 },
[ADVICE_ADD_IGNORED_FILE] = { "addIgnoredFile", 1 }, [ADVICE_ADD_IGNORED_FILE] = { "addIgnoredFile", 1 },
[ADVICE_AM_WORK_DIR] = { "amWorkDir", 1 },
[ADVICE_AMBIGUOUS_FETCH_REFSPEC] = { "ambiguousFetchRefspec", 1 }, [ADVICE_AMBIGUOUS_FETCH_REFSPEC] = { "ambiguousFetchRefspec", 1 },
[ADVICE_AM_WORK_DIR] = { "amWorkDir", 1 },
[ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] = { "checkoutAmbiguousRemoteBranchName", 1 }, [ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] = { "checkoutAmbiguousRemoteBranchName", 1 },
[ADVICE_COMMIT_BEFORE_MERGE] = { "commitBeforeMerge", 1 }, [ADVICE_COMMIT_BEFORE_MERGE] = { "commitBeforeMerge", 1 },
[ADVICE_DETACHED_HEAD] = { "detachedHead", 1 }, [ADVICE_DETACHED_HEAD] = { "detachedHead", 1 },
[ADVICE_SUGGEST_DETACHING_HEAD] = { "suggestDetachingHead", 1 },
[ADVICE_DIVERGING] = { "diverging", 1 }, [ADVICE_DIVERGING] = { "diverging", 1 },
[ADVICE_FETCH_SHOW_FORCED_UPDATES] = { "fetchShowForcedUpdates", 1 }, [ADVICE_FETCH_SHOW_FORCED_UPDATES] = { "fetchShowForcedUpdates", 1 },
[ADVICE_FORCE_DELETE_BRANCH] = { "forceDeleteBranch", 1 },
[ADVICE_GRAFT_FILE_DEPRECATED] = { "graftFileDeprecated", 1 }, [ADVICE_GRAFT_FILE_DEPRECATED] = { "graftFileDeprecated", 1 },
[ADVICE_IGNORED_HOOK] = { "ignoredHook", 1 }, [ADVICE_IGNORED_HOOK] = { "ignoredHook", 1 },
[ADVICE_IMPLICIT_IDENTITY] = { "implicitIdentity", 1 }, [ADVICE_IMPLICIT_IDENTITY] = { "implicitIdentity", 1 },
@ -56,15 +56,12 @@ static struct {
[ADVICE_PUSH_ALREADY_EXISTS] = { "pushAlreadyExists", 1 }, [ADVICE_PUSH_ALREADY_EXISTS] = { "pushAlreadyExists", 1 },
[ADVICE_PUSH_FETCH_FIRST] = { "pushFetchFirst", 1 }, [ADVICE_PUSH_FETCH_FIRST] = { "pushFetchFirst", 1 },
[ADVICE_PUSH_NEEDS_FORCE] = { "pushNeedsForce", 1 }, [ADVICE_PUSH_NEEDS_FORCE] = { "pushNeedsForce", 1 },
[ADVICE_PUSH_REF_NEEDS_UPDATE] = { "pushRefNeedsUpdate", 1 },
/* make this an alias for backward compatibility */
[ADVICE_PUSH_UPDATE_REJECTED_ALIAS] = { "pushNonFastForward", 1 },
[ADVICE_PUSH_NON_FF_CURRENT] = { "pushNonFFCurrent", 1 }, [ADVICE_PUSH_NON_FF_CURRENT] = { "pushNonFFCurrent", 1 },
[ADVICE_PUSH_NON_FF_MATCHING] = { "pushNonFFMatching", 1 }, [ADVICE_PUSH_NON_FF_MATCHING] = { "pushNonFFMatching", 1 },
[ADVICE_PUSH_REF_NEEDS_UPDATE] = { "pushRefNeedsUpdate", 1 },
[ADVICE_PUSH_UNQUALIFIED_REF_NAME] = { "pushUnqualifiedRefName", 1 }, [ADVICE_PUSH_UNQUALIFIED_REF_NAME] = { "pushUnqualifiedRefName", 1 },
[ADVICE_PUSH_UPDATE_REJECTED] = { "pushUpdateRejected", 1 }, [ADVICE_PUSH_UPDATE_REJECTED] = { "pushUpdateRejected", 1 },
[ADVICE_PUSH_UPDATE_REJECTED_ALIAS] = { "pushNonFastForward", 1 }, /* backwards compatibility */
[ADVICE_RESET_NO_REFRESH_WARNING] = { "resetNoRefresh", 1 }, [ADVICE_RESET_NO_REFRESH_WARNING] = { "resetNoRefresh", 1 },
[ADVICE_RESOLVE_CONFLICT] = { "resolveConflict", 1 }, [ADVICE_RESOLVE_CONFLICT] = { "resolveConflict", 1 },
[ADVICE_RM_HINTS] = { "rmHints", 1 }, [ADVICE_RM_HINTS] = { "rmHints", 1 },
@ -74,8 +71,9 @@ static struct {
[ADVICE_STATUS_AHEAD_BEHIND_WARNING] = { "statusAheadBehindWarning", 1 }, [ADVICE_STATUS_AHEAD_BEHIND_WARNING] = { "statusAheadBehindWarning", 1 },
[ADVICE_STATUS_HINTS] = { "statusHints", 1 }, [ADVICE_STATUS_HINTS] = { "statusHints", 1 },
[ADVICE_STATUS_U_OPTION] = { "statusUoption", 1 }, [ADVICE_STATUS_U_OPTION] = { "statusUoption", 1 },
[ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE] = { "submoduleAlternateErrorStrategyDie", 1 },
[ADVICE_SUBMODULES_NOT_UPDATED] = { "submodulesNotUpdated", 1 }, [ADVICE_SUBMODULES_NOT_UPDATED] = { "submodulesNotUpdated", 1 },
[ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE] = { "submoduleAlternateErrorStrategyDie", 1 },
[ADVICE_SUGGEST_DETACHING_HEAD] = { "suggestDetachingHead", 1 },
[ADVICE_UPDATE_SPARSE_PATH] = { "updateSparsePath", 1 }, [ADVICE_UPDATE_SPARSE_PATH] = { "updateSparsePath", 1 },
[ADVICE_WAITING_FOR_EDITOR] = { "waitingForEditor", 1 }, [ADVICE_WAITING_FOR_EDITOR] = { "waitingForEditor", 1 },
[ADVICE_WORKTREE_ADD_ORPHAN] = { "worktreeAddOrphan", 1 }, [ADVICE_WORKTREE_ADD_ORPHAN] = { "worktreeAddOrphan", 1 },

View File

@ -10,18 +10,18 @@ struct string_list;
* Add the new config variable to Documentation/config/advice.txt. * Add the new config variable to Documentation/config/advice.txt.
* Call advise_if_enabled to print your advice. * Call advise_if_enabled to print your advice.
*/ */
enum advice_type { enum advice_type {
ADVICE_ADD_EMBEDDED_REPO, ADVICE_ADD_EMBEDDED_REPO,
ADVICE_ADD_EMPTY_PATHSPEC, ADVICE_ADD_EMPTY_PATHSPEC,
ADVICE_ADD_IGNORED_FILE, ADVICE_ADD_IGNORED_FILE,
ADVICE_AM_WORK_DIR,
ADVICE_AMBIGUOUS_FETCH_REFSPEC, ADVICE_AMBIGUOUS_FETCH_REFSPEC,
ADVICE_AM_WORK_DIR,
ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME, ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME,
ADVICE_COMMIT_BEFORE_MERGE, ADVICE_COMMIT_BEFORE_MERGE,
ADVICE_DETACHED_HEAD, ADVICE_DETACHED_HEAD,
ADVICE_DIVERGING, ADVICE_DIVERGING,
ADVICE_SUGGEST_DETACHING_HEAD,
ADVICE_FETCH_SHOW_FORCED_UPDATES, ADVICE_FETCH_SHOW_FORCED_UPDATES,
ADVICE_FORCE_DELETE_BRANCH,
ADVICE_GRAFT_FILE_DEPRECATED, ADVICE_GRAFT_FILE_DEPRECATED,
ADVICE_IGNORED_HOOK, ADVICE_IGNORED_HOOK,
ADVICE_IMPLICIT_IDENTITY, ADVICE_IMPLICIT_IDENTITY,
@ -32,23 +32,24 @@ struct string_list;
ADVICE_PUSH_NEEDS_FORCE, ADVICE_PUSH_NEEDS_FORCE,
ADVICE_PUSH_NON_FF_CURRENT, ADVICE_PUSH_NON_FF_CURRENT,
ADVICE_PUSH_NON_FF_MATCHING, ADVICE_PUSH_NON_FF_MATCHING,
ADVICE_PUSH_UNQUALIFIED_REF_NAME,
ADVICE_PUSH_UPDATE_REJECTED_ALIAS,
ADVICE_PUSH_UPDATE_REJECTED,
ADVICE_PUSH_REF_NEEDS_UPDATE, ADVICE_PUSH_REF_NEEDS_UPDATE,
ADVICE_PUSH_UNQUALIFIED_REF_NAME,
ADVICE_PUSH_UPDATE_REJECTED,
ADVICE_PUSH_UPDATE_REJECTED_ALIAS,
ADVICE_RESET_NO_REFRESH_WARNING, ADVICE_RESET_NO_REFRESH_WARNING,
ADVICE_RESOLVE_CONFLICT, ADVICE_RESOLVE_CONFLICT,
ADVICE_RM_HINTS, ADVICE_RM_HINTS,
ADVICE_SEQUENCER_IN_USE, ADVICE_SEQUENCER_IN_USE,
ADVICE_SET_UPSTREAM_FAILURE, ADVICE_SET_UPSTREAM_FAILURE,
ADVICE_SKIPPED_CHERRY_PICKS,
ADVICE_STATUS_AHEAD_BEHIND_WARNING, ADVICE_STATUS_AHEAD_BEHIND_WARNING,
ADVICE_STATUS_HINTS, ADVICE_STATUS_HINTS,
ADVICE_STATUS_U_OPTION, ADVICE_STATUS_U_OPTION,
ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE,
ADVICE_SUBMODULES_NOT_UPDATED, ADVICE_SUBMODULES_NOT_UPDATED,
ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE,
ADVICE_SUGGEST_DETACHING_HEAD,
ADVICE_UPDATE_SPARSE_PATH, ADVICE_UPDATE_SPARSE_PATH,
ADVICE_WAITING_FOR_EDITOR, ADVICE_WAITING_FOR_EDITOR,
ADVICE_SKIPPED_CHERRY_PICKS,
ADVICE_WORKTREE_ADD_ORPHAN, ADVICE_WORKTREE_ADD_ORPHAN,
}; };

View File

@ -24,6 +24,7 @@
#include "ref-filter.h" #include "ref-filter.h"
#include "worktree.h" #include "worktree.h"
#include "help.h" #include "help.h"
#include "advice.h"
#include "commit-reach.h" #include "commit-reach.h"
static const char * const builtin_branch_usage[] = { static const char * const builtin_branch_usage[] = {
@ -190,9 +191,10 @@ static int check_branch_commit(const char *branchname, const char *refname,
return -1; return -1;
} }
if (!force && !branch_merged(kinds, branchname, rev, head_rev)) { if (!force && !branch_merged(kinds, branchname, rev, head_rev)) {
error(_("the branch '%s' is not fully merged.\n" error(_("the branch '%s' is not fully merged"), branchname);
"If you are sure you want to delete it, " advise_if_enabled(ADVICE_FORCE_DELETE_BRANCH,
"run 'git branch -D %s'"), branchname, branchname); _("If you are sure you want to delete it, "
"run 'git branch -D %s'"), branchname);
return -1; return -1;
} }
return 0; return 0;