summaryrefslogtreecommitdiff
path: root/builtin/push.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2020-10-27 22:09:49 (GMT)
committerJunio C Hamano <gitster@pobox.com>2020-10-27 22:09:49 (GMT)
commitde0a7effc86aadf6177fdcea52b5ae24c7a85911 (patch)
tree4c542ec9c7c2b29ad2d1c1329602bc47dc40c4c5 /builtin/push.c
parent52b8c8c7165987650bf873b878f20b14c33b268f (diff)
parent3b5bf96573b5773e64f7884607794c268b352992 (diff)
downloadgit-de0a7effc86aadf6177fdcea52b5ae24c7a85911.zip
git-de0a7effc86aadf6177fdcea52b5ae24c7a85911.tar.gz
git-de0a7effc86aadf6177fdcea52b5ae24c7a85911.tar.bz2
Merge branch 'sk/force-if-includes'
"git push --force-with-lease[=<ref>]" can easily be misused to lose commits unless the user takes good care of their own "git fetch". A new option "--force-if-includes" attempts to ensure that what is being force-pushed was created after examining the commit at the tip of the remote ref that is about to be force-replaced. * sk/force-if-includes: t, doc: update tests, reference for "--force-if-includes" push: parse and set flag for "--force-if-includes" push: add reflog check for "--force-if-includes"
Diffstat (limited to 'builtin/push.c')
-rw-r--r--builtin/push.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/builtin/push.c b/builtin/push.c
index 6da3a8e..03adb58 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -290,6 +290,12 @@ static const char message_advice_ref_needs_force[] =
"or update a remote ref to make it point at a non-commit object,\n"
"without using the '--force' option.\n");
+static const char message_advice_ref_needs_update[] =
+ N_("Updates were rejected because the tip of the remote-tracking\n"
+ "branch has been updated since the last checkout. You may want\n"
+ "to integrate those changes locally (e.g., 'git pull ...')\n"
+ "before forcing an update.\n");
+
static void advise_pull_before_push(void)
{
if (!advice_push_non_ff_current || !advice_push_update_rejected)
@@ -325,6 +331,13 @@ static void advise_ref_needs_force(void)
advise(_(message_advice_ref_needs_force));
}
+static void advise_ref_needs_update(void)
+{
+ if (!advice_push_ref_needs_update || !advice_push_update_rejected)
+ return;
+ advise(_(message_advice_ref_needs_update));
+}
+
static int push_with_options(struct transport *transport, struct refspec *rs,
int flags)
{
@@ -374,6 +387,8 @@ static int push_with_options(struct transport *transport, struct refspec *rs,
advise_ref_fetch_first();
} else if (reject_reasons & REJECT_NEEDS_FORCE) {
advise_ref_needs_force();
+ } else if (reject_reasons & REJECT_REF_NEEDS_UPDATE) {
+ advise_ref_needs_update();
}
return 1;
@@ -510,6 +525,12 @@ static int git_push_config(const char *k, const char *v, void *cb)
if (!v)
return config_error_nonbool(k);
return color_parse(v, push_colors[slot]);
+ } else if (!strcmp(k, "push.useforceifincludes")) {
+ if (git_config_bool(k, v))
+ *flags |= TRANSPORT_PUSH_FORCE_IF_INCLUDES;
+ else
+ *flags &= ~TRANSPORT_PUSH_FORCE_IF_INCLUDES;
+ return 0;
}
return git_default_config(k, v, NULL);
@@ -541,6 +562,9 @@ int cmd_push(int argc, const char **argv, const char *prefix)
OPT_CALLBACK_F(0, CAS_OPT_NAME, &cas, N_("<refname>:<expect>"),
N_("require old value of ref to be at this value"),
PARSE_OPT_OPTARG | PARSE_OPT_LITERAL_ARGHELP, parseopt_push_cas_option),
+ OPT_BIT(0, TRANS_OPT_FORCE_IF_INCLUDES, &flags,
+ N_("require remote updates to be integrated locally"),
+ TRANSPORT_PUSH_FORCE_IF_INCLUDES),
OPT_CALLBACK(0, "recurse-submodules", &recurse_submodules, "(check|on-demand|no)",
N_("control recursive pushing of submodules"), option_parse_recurse_submodules),
OPT_BOOL_F( 0 , "thin", &thin, N_("use thin pack"), PARSE_OPT_NOCOMPLETE),
@@ -625,6 +649,9 @@ int cmd_push(int argc, const char **argv, const char *prefix)
if ((flags & TRANSPORT_PUSH_ALL) && (flags & TRANSPORT_PUSH_MIRROR))
die(_("--all and --mirror are incompatible"));
+ if (!is_empty_cas(&cas) && (flags & TRANSPORT_PUSH_FORCE_IF_INCLUDES))
+ cas.use_force_if_includes = 1;
+
for_each_string_list_item(item, push_options)
if (strchr(item->string, '\n'))
die(_("push options must not have new line characters"));