diff --git a/commands/command_fetch.go b/commands/command_fetch.go index 2ea1685a..6114669e 100644 --- a/commands/command_fetch.go +++ b/commands/command_fetch.go @@ -19,6 +19,7 @@ var ( fetchExcludeArg string fetchRecentArg bool fetchAllArg bool + fetchPruneArg bool ) func fetchCommand(cmd *cobra.Command, args []string) { @@ -77,6 +78,12 @@ func fetchCommand(cmd *cobra.Command, args []string) { fetchRecent(refs, includePaths, excludePaths) } } + + if fetchPruneArg { + verify := lfs.Config.FetchPruneConfig().PruneVerifyRemoteAlways + // no dry-run or verbose options in fetch, assume false + prune(verify, false, false) + } } func init() { @@ -84,6 +91,7 @@ func init() { fetchCmd.Flags().StringVarP(&fetchExcludeArg, "exclude", "X", "", "Exclude a list of paths") fetchCmd.Flags().BoolVarP(&fetchRecentArg, "recent", "r", false, "Fetch recent refs & commits") fetchCmd.Flags().BoolVarP(&fetchAllArg, "all", "a", false, "Fetch all LFS files ever referenced") + fetchCmd.Flags().BoolVarP(&fetchPruneArg, "prune", "p", false, "After fetching, prune old data") RootCmd.AddCommand(fetchCmd) } diff --git a/docs/man/git-lfs-fetch.1.ronn b/docs/man/git-lfs-fetch.1.ronn index 437a1b25..fbdccd6b 100644 --- a/docs/man/git-lfs-fetch.1.ronn +++ b/docs/man/git-lfs-fetch.1.ronn @@ -30,6 +30,10 @@ This does not update the working copy. --include/--exclude. Ignores any globally configured include and exclude paths to ensure that all objects are downloaded. +* `--prune` `-p`: + Prune old and unreferenced objects after fetching, equivalent to running + `git lfs prune` afterwards. See git-lfs-prune(1) for more details. + ## INCLUDE AND EXCLUDE You can configure Git LFS to only fetch objects to satisfy references in certain @@ -132,7 +136,7 @@ What changes are considered 'recent' is based on a number of gitconfig options: ## SEE ALSO -git-lfs-checkout(1), git-lfs-pull(1). +git-lfs-checkout(1), git-lfs-pull(1), git-lfs-prune(1). Part of the git-lfs(1) suite. diff --git a/test/test-fetch.sh b/test/test-fetch.sh index 50ebe227..24f4631c 100755 --- a/test/test-fetch.sh +++ b/test/test-fetch.sh @@ -404,3 +404,58 @@ begin_test "fetch: outside git repository" grep "Not in a git repository" fetch.log ) end_test + +begin_test "fetch --prune" +( + set -e + + reponame="fetch_prune" + setup_remote_repo "remote_$reponame" + + clone_repo "remote_$reponame" "clone_$reponame" + + git lfs track "*.dat" 2>&1 | tee track.log + grep "Tracking \*.dat" track.log + + content_head="HEAD content" + content_commit2="Content for commit 2 (prune)" + content_commit1="Content for commit 1 (prune)" + oid_head=$(calc_oid "$content_head") + oid_commit2=$(calc_oid "$content_commit2") + oid_commit1=$(calc_oid "$content_commit1") + + echo "[ + { + \"CommitDate\":\"$(get_date -50d)\", + \"Files\":[ + {\"Filename\":\"file.dat\",\"Size\":${#content_commit1}, \"Data\":\"$content_commit1\"}] + }, + { + \"CommitDate\":\"$(get_date -35d)\", + \"Files\":[ + {\"Filename\":\"file.dat\",\"Size\":${#content_commit2}, \"Data\":\"$content_commit2\"}] + }, + { + \"CommitDate\":\"$(get_date -25d)\", + \"Files\":[ + {\"Filename\":\"file.dat\",\"Size\":${#content_head}, \"Data\":\"$content_head\"}] + } + ]" | lfstest-testutils addcommits + + # push all so no unpushed reason to not prune + git push origin master + + # set no recents so max ability to prune + git config lfs.fetchrecentrefsdays 0 + git config lfs.fetchrecentcommitsdays 0 + + # delete HEAD object to prove that we still download something + # also prune at the same time which will remove anything other than HEAD + delete_local_object "$oid_head" + git lfs fetch --prune + assert_local_object "$oid_head" "${#content_head}" + refute_local_object "$oid_commit1" + refute_local_object "$oid_commit2" + +) +end_test diff --git a/test/testhelpers.sh b/test/testhelpers.sh index a81ac513..bff0b8d6 100644 --- a/test/testhelpers.sh +++ b/test/testhelpers.sh @@ -46,6 +46,16 @@ refute_local_object() { fi } +# delete_local_object deletes the local storage for an oid +# $ delete_local_object "some-oid" +delete_local_object() { + local oid="$1" + local cfg=`git lfs env | grep LocalMediaDir` + local f="${cfg:14}/${oid:0:2}/${oid:2:2}/$oid" + rm "$f" +} + + # check that the object does not exist in the git lfs server. HTTP log is # written to http.log. JSON output is written to http.json. #