]> git.ipfire.org Git - thirdparty/git.git/blobdiff - builtin/fetch.c
Merge branch 'en/fetch-negotiation-default-fix'
[thirdparty/git.git] / builtin / fetch.c
index 5f06b21f8e97c5459fdb558302c5b9b95e99eee8..6f5e157863923da28c6394cc86f359abb97f9e01 100644 (file)
@@ -76,6 +76,7 @@ static struct transport *gtransport;
 static struct transport *gsecondary;
 static const char *submodule_prefix = "";
 static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
+static int recurse_submodules_cli = RECURSE_SUBMODULES_DEFAULT;
 static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;
 static int shown_url = 0;
 static struct refspec refmap = REFSPEC_INIT_FETCH;
@@ -167,7 +168,7 @@ static struct option builtin_fetch_options[] = {
                 N_("prune remote-tracking branches no longer on remote")),
        OPT_BOOL('P', "prune-tags", &prune_tags,
                 N_("prune local tags no longer on remote and clobber changed tags")),
-       OPT_CALLBACK_F(0, "recurse-submodules", &recurse_submodules, N_("on-demand"),
+       OPT_CALLBACK_F(0, "recurse-submodules", &recurse_submodules_cli, N_("on-demand"),
                    N_("control recursive fetching of submodules"),
                    PARSE_OPT_OPTARG, option_fetch_parse_recurse_submodules),
        OPT_BOOL(0, "dry-run", &dry_run,
@@ -1609,12 +1610,14 @@ static int do_fetch(struct transport *transport,
                 * don't care whether --tags was specified.
                 */
                if (rs->nr) {
-                       prune_refs(rs, ref_map, transport->url);
+                       retcode = prune_refs(rs, ref_map, transport->url);
                } else {
-                       prune_refs(&transport->remote->fetch,
-                                  ref_map,
-                                  transport->url);
+                       retcode = prune_refs(&transport->remote->fetch,
+                                            ref_map,
+                                            transport->url);
                }
+               if (retcode != 0)
+                       retcode = 1;
        }
        if (fetch_and_consume_refs(transport, ref_map, worktrees)) {
                free_refs(ref_map);
@@ -2019,6 +2022,28 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 
        argc = parse_options(argc, argv, prefix,
                             builtin_fetch_options, builtin_fetch_usage, 0);
+
+       if (recurse_submodules_cli != RECURSE_SUBMODULES_DEFAULT)
+               recurse_submodules = recurse_submodules_cli;
+
+       if (negotiate_only) {
+               switch (recurse_submodules_cli) {
+               case RECURSE_SUBMODULES_OFF:
+               case RECURSE_SUBMODULES_DEFAULT:
+                       /*
+                        * --negotiate-only should never recurse into
+                        * submodules. Skip it by setting recurse_submodules to
+                        * RECURSE_SUBMODULES_OFF.
+                        */
+                       recurse_submodules = RECURSE_SUBMODULES_OFF;
+                       break;
+
+               default:
+                       die(_("options '%s' and '%s' cannot be used together"),
+                           "--negotiate-only", "--recurse-submodules");
+               }
+       }
+
        if (recurse_submodules != RECURSE_SUBMODULES_OFF) {
                int *sfjc = submodule_fetch_jobs_config == -1
                            ? &submodule_fetch_jobs_config : NULL;
@@ -2029,7 +2054,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
        }
 
        if (negotiate_only && !negotiation_tip.nr)
-               die(_("--negotiate-only needs one or more --negotiate-tip=*"));
+               die(_("--negotiate-only needs one or more --negotiation-tip=*"));
 
        if (deepen_relative) {
                if (deepen_relative < 0)
@@ -2100,7 +2125,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
                        gtransport->smart_options->acked_commits = &acked_commits;
                } else {
                        warning(_("protocol does not support --negotiate-only, exiting"));
-                       return 1;
+                       result = 1;
+                       goto cleanup;
                }
                if (server_options.nr)
                        gtransport->server_options = &server_options;
@@ -2156,7 +2182,16 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
                strvec_clear(&options);
        }
 
-       string_list_clear(&list, 0);
+       /*
+        * Skip irrelevant tasks because we know objects were not
+        * fetched.
+        *
+        * NEEDSWORK: as a future optimization, we can return early
+        * whenever objects were not fetched e.g. if we already have all
+        * of them.
+        */
+       if (negotiate_only)
+               goto cleanup;
 
        prepare_repo_settings(the_repository);
        if (fetch_write_commit_graph > 0 ||
@@ -2175,5 +2210,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
        if (enable_auto_gc)
                run_auto_maintenance(verbosity < 0);
 
+ cleanup:
+       string_list_clear(&list, 0);
        return result;
 }