Sync with 'maint'
[gitweb.git] / builtin / fetch.c
index 564705555b897bde0a1a2c3fad3c1f1b39903b53..bd7a10164f4fed8aeb6e8148e2ae8c0a793e7ee0 100644 (file)
@@ -30,7 +30,11 @@ enum {
        TAGS_SET = 2
 };
 
-static int all, append, dry_run, force, keep, multiple, prune, update_head_ok, verbosity;
+static int fetch_prune_config = -1; /* unspecified */
+static int prune = -1; /* unspecified */
+#define PRUNE_BY_DEFAULT 0 /* do we prune by default? */
+
+static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosity;
 static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
 static int tags = TAGS_DEFAULT, unshallow;
 static const char *depth;
@@ -55,30 +59,39 @@ static int option_parse_recurse_submodules(const struct option *opt,
        return 0;
 }
 
+static int git_fetch_config(const char *k, const char *v, void *cb)
+{
+       if (!strcmp(k, "fetch.prune")) {
+               fetch_prune_config = git_config_bool(k, v);
+               return 0;
+       }
+       return 0;
+}
+
 static struct option builtin_fetch_options[] = {
        OPT__VERBOSITY(&verbosity),
-       OPT_BOOLEAN(0, "all", &all,
-                   N_("fetch from all remotes")),
-       OPT_BOOLEAN('a', "append", &append,
-                   N_("append to .git/FETCH_HEAD instead of overwriting")),
+       OPT_BOOL(0, "all", &all,
+                N_("fetch from all remotes")),
+       OPT_BOOL('a', "append", &append,
+                N_("append to .git/FETCH_HEAD instead of overwriting")),
        OPT_STRING(0, "upload-pack", &upload_pack, N_("path"),
                   N_("path to upload pack on remote end")),
        OPT__FORCE(&force, N_("force overwrite of local branch")),
-       OPT_BOOLEAN('m', "multiple", &multiple,
-                   N_("fetch from multiple remotes")),
+       OPT_BOOL('m', "multiple", &multiple,
+                N_("fetch from multiple remotes")),
        OPT_SET_INT('t', "tags", &tags,
                    N_("fetch all tags and associated objects"), TAGS_SET),
        OPT_SET_INT('n', NULL, &tags,
                    N_("do not fetch all tags (--no-tags)"), TAGS_UNSET),
-       OPT_BOOLEAN('p', "prune", &prune,
-                   N_("prune remote-tracking branches no longer on remote")),
+       OPT_BOOL('p', "prune", &prune,
+                N_("prune remote-tracking branches no longer on remote")),
        { OPTION_CALLBACK, 0, "recurse-submodules", NULL, N_("on-demand"),
                    N_("control recursive fetching of submodules"),
                    PARSE_OPT_OPTARG, option_parse_recurse_submodules },
-       OPT_BOOLEAN(0, "dry-run", &dry_run,
-                   N_("dry run")),
-       OPT_BOOLEAN('k', "keep", &keep, N_("keep downloaded pack")),
-       OPT_BOOLEAN('u', "update-head-ok", &update_head_ok,
+       OPT_BOOL(0, "dry-run", &dry_run,
+                N_("dry run")),
+       OPT_BOOL('k', "keep", &keep, N_("keep downloaded pack")),
+       OPT_BOOL('u', "update-head-ok", &update_head_ok,
                    N_("allow updating of HEAD ref")),
        OPT_BOOL(0, "progress", &progress, N_("force progress reporting")),
        OPT_STRING(0, "depth", &depth, N_("depth"),
@@ -249,7 +262,8 @@ static int s_update_ref(const char *action,
                rla = default_rla.buf;
        snprintf(msg, sizeof(msg), "%s: %s", rla, action);
        lock = lock_any_ref_for_update(ref->name,
-                                      check_old ? ref->old_sha1 : NULL, 0);
+                                      check_old ? ref->old_sha1 : NULL,
+                                      0, NULL);
        if (!lock)
                return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT :
                                          STORE_REF_ERROR_OTHER;
@@ -816,7 +830,10 @@ static int do_fetch(struct transport *transport,
                goto cleanup;
        }
        if (prune) {
-               /* If --tags was specified, pretend the user gave us the canonical tags refspec */
+               /*
+                * If --tags was specified, pretend that the user gave us
+                * the canonical tags refspec
+                */
                if (tags == TAGS_SET) {
                        const char *tags_str = "refs/tags/*:refs/tags/*";
                        struct refspec *tags_refspec, *refspec;
@@ -913,7 +930,7 @@ static void add_options_to_argv(struct argv_array *argv)
 {
        if (dry_run)
                argv_array_push(argv, "--dry-run");
-       if (prune)
+       if (prune > 0)
                argv_array_push(argv, "--prune");
        if (update_head_ok)
                argv_array_push(argv, "--update-head-ok");
@@ -981,6 +998,17 @@ static int fetch_one(struct remote *remote, int argc, const char **argv)
                    "remote name from which new revisions should be fetched."));
 
        gtransport = prepare_transport(remote);
+
+       if (prune < 0) {
+               /* no command line request */
+               if (0 <= gtransport->remote->prune)
+                       prune = gtransport->remote->prune;
+               else if (0 <= fetch_prune_config)
+                       prune = fetch_prune_config;
+               else
+                       prune = PRUNE_BY_DEFAULT;
+       }
+
        if (argc > 0) {
                int j = 0;
                refs = xcalloc(argc + 1, sizeof(const char *));
@@ -1030,6 +1058,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
        for (i = 1; i < argc; i++)
                strbuf_addf(&default_rla, " %s", argv[i]);
 
+       git_config(git_fetch_config, NULL);
+
        argc = parse_options(argc, argv, prefix,
                             builtin_fetch_options, builtin_fetch_usage, 0);