fetch: make the --prune-tags work with <url>

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>

Ævar Arnfjörð Bjarmason committed Feb 9, 2018 at 20:32 UTC 6317972cff9b4df7a6cc666b08be7133ba81617c
3 files changed +27 -27
Documentation/git-fetch.txt
+6 -15
@@ -175,24 +175,15 @@ It's reasonable to e.g. configure `fetch.pruneTags=true` in
175 run, without making every invocation of `git fetch` without `--prune`
176 an error.
177
178 -Another special case of `--prune-tags` is that
179 -`refs/tags/*:refs/tags/*` will not be implicitly provided if an URL is
180 -being fetched. I.e.:
181 -
182 -------------------------------------------------
183 -$ git fetch <url> --prune --prune-tags
184 -------------------------------------------------
185 -
186 -Will prune no tags, as opposed to:
178 +Pruning tags with `--prune-tags` also works when fetching a URL
179 +instead of a named remote. These will all prune tags not found on
180 +origin:
181
182 ------------------------------------------------
183 $ git fetch origin --prune --prune-tags
190 -------------------------------------------------
191 -
192 -To prune tags given a URL supply the refspec explicitly:
193 -
194 -------------------------------------------------
195 -$ git fetch <url> --prune 'refs/tags/*:refs/tags/*'
184 +$ git fetch origin --prune 'refs/tags/*:refs/tags/*'
185 +$ git fetch <url of origin> --prune --prune-tags
186 +$ git fetch <url of origin> --prune 'refs/tags/*:refs/tags/*'
187 ------------------------------------------------
188
189 OUTPUT
builtin/fetch.c
+14 -3
@@ -1283,7 +1283,10 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, int pru
1283 static const char **refs = NULL;
1284 struct refspec *refspec;
1285 int ref_nr = 0;
1286 + int j = 0;
1287 int exit_code;
1288 + int maybe_prune_tags;
1289 + int remote_via_config = remote_is_configured(remote, 0);
1290
1291 if (!remote)
1292 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
1314 prune_tags = PRUNE_TAGS_BY_DEFAULT;
1315 }
1316
1314 - if (prune_tags_ok && prune_tags && remote_is_configured(remote, 0))
1317 + maybe_prune_tags = prune_tags_ok && prune_tags;
1318 + if (maybe_prune_tags && remote_via_config)
1319 add_prune_tags_to_fetch_refspec(remote);
1320
1321 + if (argc > 0 || (maybe_prune_tags && !remote_via_config)) {
1322 + size_t nr_alloc = st_add3(argc, maybe_prune_tags, 1);
1323 + refs = xcalloc(nr_alloc, sizeof(const char *));
1324 + if (maybe_prune_tags) {
1325 + refs[j++] = xstrdup("refs/tags/*:refs/tags/*");
1326 + ref_nr++;
1327 + }
1328 + }
1329 +
1330 if (argc > 0) {
1318 - int j = 0;
1331 int i;
1320 - refs = xcalloc(st_add(argc, 1), sizeof(const char *));
1332 for (i = 0; i < argc; i++) {
1333 if (!strcmp(argv[i], "tag")) {
1334 i++;
t/t5510-fetch.sh
+7 -9
@@ -738,18 +738,15 @@ test_configured_prune unset unset unset true pruned kept \
738 "--prune origin +refs/heads/*:refs/remotes/origin/*"
739
740 # Pruning that also takes place if a file:// url replaces a named
741 -# remote, with the exception of --prune-tags on the command-line
742 -# (arbitrary limitation).
743 -#
744 -# However, because there's no implicit
741 +# remote. However, because there's no implicit
742 # +refs/heads/*:refs/remotes/origin/* refspec and supplying it on the
743 # command-line negates --prune-tags, the branches will not be pruned.
744 test_configured_prune_type unset unset unset unset kept kept "origin --prune-tags" "name"
745 test_configured_prune_type unset unset unset unset kept kept "origin --prune-tags" "link"
746 test_configured_prune_type unset unset unset unset pruned pruned "origin --prune --prune-tags" "name"
750 -test_configured_prune_type unset unset unset unset kept kept "origin --prune --prune-tags" "link"
747 +test_configured_prune_type unset unset unset unset kept pruned "origin --prune --prune-tags" "link"
748 test_configured_prune_type unset unset unset unset pruned pruned "--prune --prune-tags origin" "name"
752 -test_configured_prune_type unset unset unset unset kept kept "--prune --prune-tags origin" "link"
749 +test_configured_prune_type unset unset unset unset kept pruned "--prune --prune-tags origin" "link"
750 test_configured_prune_type unset unset true unset pruned pruned "--prune origin" "name"
751 test_configured_prune_type unset unset true unset kept pruned "--prune origin" "link"
752 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"
758 test_configured_prune_type unset true unset true pruned pruned "origin" "name"
759 test_configured_prune_type unset true unset true kept pruned "origin" "link"
760
764 -# Interaction between --prune-tags and no "fetch" config in the remote
765 -# at all.
761 +# When all remote.origin.fetch settings are deleted a --prune
762 +# --prune-tags still implicitly supplies refs/tags/*:refs/tags/* so
763 +# tags, but not tracking branches, will be deleted.
764 test_expect_success 'remove remote.origin.fetch "one"' '
765 (
766 cd one &&
@@ -770,7 +768,7 @@ test_expect_success 'remove remote.origin.fetch "one"' '
768 )
769 '
770 test_configured_prune_type unset unset unset unset kept pruned "origin --prune --prune-tags" "name"
773 -test_configured_prune_type unset unset unset unset kept kept "origin --prune --prune-tags" "link"
771 +test_configured_prune_type unset unset unset unset kept pruned "origin --prune --prune-tags" "link"
772
773 test_expect_success 'all boundary commits are excluded' '
774 test_commit base &&