fetch: make the --prune-tags work with <url>
authorÆvar Arnfjörð Bjarmason <avarab@gmail.com>
Fri, 9 Feb 2018 20:32:16 +0000 (20:32 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 9 Feb 2018 21:10:13 +0000 (13:10 -0800)
Make the new --prune-tags option work properly when git-fetch is
invoked with a <url> parameter instead of a <remote name>
parameter.

This change is split off from the introduction of --prune-tags due to
the relative complexity of munging the incoming argv, which is easier
to review as a separate change.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-fetch.txt
builtin/fetch.c
t/t5510-fetch.sh
index af12310f757f6a074012071807afc7224e76dd4e..e3199355978880b21668bc1aff0e42f610c02bd6 100644 (file)
@@ -175,24 +175,15 @@ It's reasonable to e.g. configure `fetch.pruneTags=true` in
 run, without making every invocation of `git fetch` without `--prune`
 an error.
 
-Another special case of `--prune-tags` is that
-`refs/tags/*:refs/tags/*` will not be implicitly provided if an URL is
-being fetched. I.e.:
-
-------------------------------------------------
-$ git fetch <url> --prune --prune-tags
-------------------------------------------------
-
-Will prune no tags, as opposed to:
+Pruning tags with `--prune-tags` also works when fetching a URL
+instead of a named remote. These will all prune tags not found on
+origin:
 
 ------------------------------------------------
 $ git fetch origin --prune --prune-tags
-------------------------------------------------
-
-To prune tags given a URL supply the refspec explicitly:
-
-------------------------------------------------
-$ git fetch <url> --prune 'refs/tags/*:refs/tags/*'
+$ git fetch origin --prune 'refs/tags/*:refs/tags/*'
+$ git fetch <url of origin> --prune --prune-tags
+$ git fetch <url of origin> --prune 'refs/tags/*:refs/tags/*'
 ------------------------------------------------
 
 OUTPUT
index 55a0fc37be5dab4989de55deb90d69f9c34184c4..c96f17a9a3c39d9f66439b7ca12e649c46a20a76 100644 (file)
@@ -1283,7 +1283,10 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, int pru
        static const char **refs = NULL;
        struct refspec *refspec;
        int ref_nr = 0;
+       int j = 0;
        int exit_code;
+       int maybe_prune_tags;
+       int remote_via_config = remote_is_configured(remote, 0);
 
        if (!remote)
                die(_("No remote repository specified.  Please, specify either a URL or a\n"
@@ -1311,13 +1314,21 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, int pru
                        prune_tags = PRUNE_TAGS_BY_DEFAULT;
        }
 
-       if (prune_tags_ok && prune_tags && remote_is_configured(remote, 0))
+       maybe_prune_tags = prune_tags_ok && prune_tags;
+       if (maybe_prune_tags && remote_via_config)
                add_prune_tags_to_fetch_refspec(remote);
 
+       if (argc > 0 || (maybe_prune_tags && !remote_via_config)) {
+               size_t nr_alloc = st_add3(argc, maybe_prune_tags, 1);
+               refs = xcalloc(nr_alloc, sizeof(const char *));
+               if (maybe_prune_tags) {
+                       refs[j++] = xstrdup("refs/tags/*:refs/tags/*");
+                       ref_nr++;
+               }
+       }
+
        if (argc > 0) {
-               int j = 0;
                int i;
-               refs = xcalloc(st_add(argc, 1), sizeof(const char *));
                for (i = 0; i < argc; i++) {
                        if (!strcmp(argv[i], "tag")) {
                                i++;
index 227dd70b7b966b1b73106262d7bf1593d343532f..dce237130286c448359ab34f9a7b5cf0c3d8d50e 100755 (executable)
@@ -738,18 +738,15 @@ test_configured_prune unset unset unset true pruned  kept \
        "--prune origin +refs/heads/*:refs/remotes/origin/*"
 
 # Pruning that also takes place if a file:// url replaces a named
-# remote, with the exception of --prune-tags on the command-line
-# (arbitrary limitation).
-#
-# However, because there's no implicit
+# remote. However, because there's no implicit
 # +refs/heads/*:refs/remotes/origin/* refspec and supplying it on the
 # command-line negates --prune-tags, the branches will not be pruned.
 test_configured_prune_type unset unset unset unset kept   kept   "origin --prune-tags" "name"
 test_configured_prune_type unset unset unset unset kept   kept   "origin --prune-tags" "link"
 test_configured_prune_type unset unset unset unset pruned pruned "origin --prune --prune-tags" "name"
-test_configured_prune_type unset unset unset unset kept   kept   "origin --prune --prune-tags" "link"
+test_configured_prune_type unset unset unset unset kept   pruned "origin --prune --prune-tags" "link"
 test_configured_prune_type unset unset unset unset pruned pruned "--prune --prune-tags origin" "name"
-test_configured_prune_type unset unset unset unset kept   kept   "--prune --prune-tags origin" "link"
+test_configured_prune_type unset unset unset unset kept   pruned "--prune --prune-tags origin" "link"
 test_configured_prune_type unset unset true  unset pruned pruned "--prune origin" "name"
 test_configured_prune_type unset unset true  unset kept   pruned "--prune origin" "link"
 test_configured_prune_type unset unset unset true  pruned pruned "--prune origin" "name"
@@ -761,8 +758,9 @@ test_configured_prune_type unset  true true  unset kept   pruned "origin" "link"
 test_configured_prune_type unset  true unset true  pruned pruned "origin" "name"
 test_configured_prune_type unset  true unset true  kept   pruned "origin" "link"
 
-# Interaction between --prune-tags and no "fetch" config in the remote
-# at all.
+# When all remote.origin.fetch settings are deleted a --prune
+# --prune-tags still implicitly supplies refs/tags/*:refs/tags/* so
+# tags, but not tracking branches, will be deleted.
 test_expect_success 'remove remote.origin.fetch "one"' '
        (
                cd one &&
@@ -770,7 +768,7 @@ test_expect_success 'remove remote.origin.fetch "one"' '
        )
 '
 test_configured_prune_type unset unset unset unset kept pruned "origin --prune --prune-tags" "name"
-test_configured_prune_type unset unset unset unset kept kept   "origin --prune --prune-tags" "link"
+test_configured_prune_type unset unset unset unset kept pruned "origin --prune --prune-tags" "link"
 
 test_expect_success 'all boundary commits are excluded' '
        test_commit base &&