Subject: [PATCH v5 00/17] document & test fetch pruning & add fetch.pruneTags

From: Ævar Arnfjörð Bjarmason <[email-masked]>
Date: Fri, 9 Feb 2018 20:31:59 +0000

Here's a v5 (correct subject line this time!). Many thanks to Eric for
a thorough review.

I'll spare you the per-patch changelog. These are all minor commit
message / doc / comment wording changes, with the exception of making
a bit of the test code better, and adding a \n for grep
portability. tbdiff at the end.

Ævar Arnfjörð Bjarmason (17):
  fetch: don't redundantly NULL something calloc() gave us
  fetch: trivially refactor assignment to ref_nr
  fetch: stop accessing "remote" variable indirectly
  remote: add a macro for "refs/tags/*:refs/tags/*"
  fetch tests: refactor in preparation for testing tag pruning
  fetch tests: re-arrange arguments for future readability
  fetch tests: add a tag to be deleted to the pruning tests
  fetch tests: test --prune and refspec interaction
  fetch tests: double quote a variable for interpolation
  fetch tests: expand case/esac for later change
  fetch tests: fetch <url> <spec> as well as fetch [<remote>]
  git fetch doc: add a new section to explain the ins & outs of pruning
  git remote doc: correct dangerous lies about what prune does
  git-fetch & config doc: link to the new PRUNING section
  fetch tests: add scaffolding for the new fetch.pruneTags
  fetch: add a --prune-tags option and fetch.pruneTags config
  fetch: make the --prune-tags work with <url>

 Documentation/config.txt               |  20 ++-
 Documentation/fetch-options.txt        |  17 ++-
 Documentation/git-fetch.txt            |  87 ++++++++++++
 Documentation/git-remote.txt           |  14 +-
 builtin/fetch.c                        |  54 ++++++--
 contrib/completion/git-completion.bash |   2 +-
 remote.c                               |  15 +++
 remote.h                               |   5 +
 t/t5510-fetch.sh                       | 238 +++++++++++++++++++++++++++------
 9 files changed, 391 insertions(+), 61 deletions(-)

tbdiff:

 1: da0992d97c =  1: da0992d97c fetch: don't redundantly NULL something calloc() gave us
 2: c781d18a29 !  2: 899430a3b2 fetch: trivially refactor assignment to ref_nr
    @@ -7,8 +7,8 @@
         "j" is, and "j" is only incremented in that loop, so this change isn't
         a logic error.
         
    -    This change makes a subsequent change which splits the incrementing of
    -    "ref_nr" into two blocks.
    +    This change simplifies a subsequent change, which will split the
    +    incrementing of "ref_nr" into two blocks.
         
         Signed-off-by: Ævar Arnfjörð Bjarmason <[email-masked]>
     
 3: 1203ef6e35 =  3: 98e3a28bdf fetch: stop accessing "remote" variable indirectly
 4: 1d7956c444 =  4: 384c1fc318 remote: add a macro for "refs/tags/*:refs/tags/*"
 5: a0dc3eb024 =  5: ec92777861 fetch tests: refactor in preparation for testing tag pruning
 6: 7ed1561e3d =  6: 1c23526223 fetch tests: re-arrange arguments for future readability
 7: 6dbf0e688d =  7: 59abe07b71 fetch tests: add a tag to be deleted to the pruning tests
 8: 9fc3589793 =  8: af7acef671 fetch tests: test --prune and refspec interaction
 9: a4487f9389 =  9: cb72187362 fetch tests: double quote a variable for interpolation
10: b8c07e2d42 = 10: 300c1c0985 fetch tests: expand case/esac for later change
11: 6341131ee0 ! 11: 550e7df594 fetch tests: fetch <url> <spec> as well as fetch [<remote>]
    @@ -60,15 +60,12 @@
     -	test_expect_success "prune fetch.prune=$1 remote.origin.prune=$2${5:+ $5}; branch:$3 tag:$4" '
     +	mode=$6
     +
    -+	if ! test -e prune-type-setup-done
    ++	if test -z "$cmdline_setup"
     +	then
    -+		test_expect_success 'prune_type setup' '
    -+			git -C one config remote.origin.url >one.remote-url &&
    -+			git -C one config remote.origin.fetch >one.remote-fetch &&
    -+			remote_url="file://$(cat one.remote-url)" &&
    -+			remote_fetch="$(cat one.remote-fetch)" &&
    -+			cmdline_setup="\"$remote_url\" \"$remote_fetch\"" &&
    -+			touch prune-type-setup-done
    ++		test_expect_success 'setup cmdline_setup variable for subsequent test' '
    ++			remote_url="file://$(git -C one config remote.origin.url)" &&
    ++			remote_fetch="$(git -C one config remote.origin.fetch)" &&
    ++			cmdline_setup="\"$remote_url\" \"$remote_fetch\""
     +		'
     +	fi
     +
12: 824c3ed4c1 ! 12: 273f4c603f git fetch doc: add a new section to explain the ins & outs of pruning
    @@ -32,7 +32,7 @@
     +<commit>` needlessly verbose, as well as impacting anything else
     +that'll work with the complete set of known references.
     +
    -+These remote tracking references can be deleted as a one-off with
    ++These remote-tracking references can be deleted as a one-off with
     +either of:
     +
     +------------------------------------------------
    @@ -44,13 +44,13 @@
     +------------------------------------------------
     +
     +To prune references as part of your normal workflow without needing to
    -+remember to run that set `fetch.prune` globally, or
    ++remember to run that, set `fetch.prune` globally, or
     +`remote.<name>.prune` per-remote in the config. See
     +linkgit:git-config[1].
     +
     +Here's where things get tricky and more specific. The pruning feature
     +doesn't actually care about branches, instead it'll prune local <->
    -+remote references as a function of the refspec of the remote (see
    ++remote-references as a function of the refspec of the remote (see
     +`<refspec>` and <<CRTB,CONFIGURED REMOTE-TRACKING BRANCHES>> above).
     +
     +Therefore if the refspec for the remote includes
13: 59de997172 ! 13: ada313b523 git remote doc: correct dangerous lies about what prune does
    @@ -11,7 +11,7 @@
         oldest version I could be bothered to test).
         
         E.g. if "refs/tags/*:refs/tags/*" is explicitly set in the refspec of
    -    the remote it'll delete all local tags <name> doesn't know about.
    +    the remote, it'll delete all local tags <name> doesn't know about.
         
         Instead, briefly give the reader just enough of a hint that this
         option might constitute a shotgun aimed at their foot, and point them
    @@ -36,11 +36,11 @@
     -These stale branches have already been removed from the remote repository
     -referenced by <name>, but are still locally available in
     -"remotes/<name>".
    -+Deletes stale references associated with <name>. By default stale
    -+remote-tracking branches under <name>, but depending on global
    -+configuration and the configuration of the remote we might even prune
    -+local tags that haven't been pushed there. Equivalent to `git fetch
    -+--prune <name>`, except that no new references will be fetched.
    ++Deletes stale references associated with <name>. By default, stale
    ++remote-tracking branches under <name> are deleted, but depending on
    ++global configuration and the configuration of the remote we might even
    ++prune local tags that haven't been pushed there. Equivalent to `git
    ++fetch --prune <name>`, except that no new references will be fetched.
     ++
     +See the PRUNING section of linkgit:git-fetch[1] for what it'll prune
     +depending on various configuration.
14: 5dfc9177bb = 14: eeb9102d9f git-fetch & config doc: link to the new PRUNING section
15: fc0890eb9c ! 15: 6c1facccda fetch tests: add scaffolding for the new fetch.pruneTags
    @@ -28,7 +28,7 @@
     +	cmdline=$7
     +	mode=$8
      
    - 	if ! test -e prune-type-setup-done
    + 	if test -z "$cmdline_setup"
      	then
     @@
      		cmdline="$new_cmdline"
16: 03b1393ea2 ! 16: 1d8d6e29fc fetch: add a --prune-tags option and fetch.pruneTags config
    @@ -1,9 +1,10 @@
     Author: Ævar Arnfjörð Bjarmason <[email-masked]>
     
    -    fetch: add a --fetch-prune option and fetch.pruneTags config
    -    
    -    Add a --fetch-prune option to git-fetch, along with fetch.pruneTags
    -    config option. This allows for doing any of:
    +    fetch: add a --prune-tags option and fetch.pruneTags config
    +    
    +    Add a --prune-tags option to git-fetch, along with fetch.pruneTags
    +    config option and a -P shorthand (-p is --prune). This allows for
    +    doing any of:
         
             git fetch -p -P
             git fetch --prune --prune-tags
    @@ -366,7 +367,7 @@
     +		if test "$fetch_prune_tags" = 'true' ||
     +		   test "$remote_origin_prune_tags" = 'true'
     +		then
    -+			if ! printf '%s' "$cmdline" | grep -q refs/remotes/origin/
    ++			if ! printf '%s' "$cmdline\n" | grep -q refs/remotes/origin/
     +			then
     +				new_cmdline="$new_cmdline refs/tags/*:refs/tags/*"
     +			fi
    @@ -396,7 +397,7 @@
     +test_configured_prune false true  false true  pruned pruned ""
     +test_configured_prune true  false true  false kept   kept   ""
     +
    -+# When --prune-tags is supplied it's ignored if an explict refspec is
    ++# When --prune-tags is supplied it's ignored if an explicit refspec is
     +# given, same for the configuration options.
     +test_configured_prune unset unset unset unset pruned kept \
     +	"--prune --prune-tags origin +refs/heads/*:refs/remotes/origin/*"
    @@ -405,13 +406,15 @@
     +test_configured_prune unset unset unset true pruned  kept \
     +	"--prune origin +refs/heads/*:refs/remotes/origin/*"
     +
    -+# Pruning that also takes place if s!origin!<file:// url of remote>!,
    -+# or otherwise uses the file://-specific codepath. However, because
    -+# there's no implicit +refs/heads/*:refs/remotes/origin/* refspec and
    -+# supplying it on the command-line negate --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"
    ++# 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
    ++# +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 pruned pruned "--prune --prune-tags origin" "name"
    @@ -427,9 +430,8 @@
     +test_configured_prune_type unset  true unset true  pruned pruned "origin" "name"
     +test_configured_prune_type unset  true unset true  kept   pruned "origin" "link"
     +
    -+# 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.
    ++# Interaction between --prune-tags and no "fetch" config in the remote
    ++# at all.
     +test_expect_success 'remove remote.origin.fetch "one"' '
     +	(
     +		cd one &&
17: f0dca21626 ! 17: ddcd576c5c fetch: make the --prune-tags work with <url>
    @@ -1,6 +1,6 @@
     Author: Ævar Arnfjörð Bjarmason <[email-masked]>
     
    -    fetch: make the --fetch-prune work with <url>
    +    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>
    @@ -91,8 +91,18 @@
     --- a/t/t5510-fetch.sh
     +++ b/t/t5510-fetch.sh
     @@
    - 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"
    + 	"--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"
    @@ -103,6 +113,18 @@
      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"
     @@
    + 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 &&
    +@@
      	)
      '
      test_configured_prune_type unset unset unset unset kept pruned "origin --prune --prune-tags" "name"

-- 
2.15.1.424.g9478a66081