3 . "$(dirname "$0")/testlib.sh"
5 begin_test "prune unreferenced and old"
9 reponame="prune_unref_old"
10 setup_remote_repo "remote_$reponame"
12 clone_repo "remote_$reponame" "clone_$reponame"
14 git lfs track "*.dat" 2>&1 | tee track.log
15 grep "Tracking \"\*.dat\"" track.log
17 # generate content we'll use
18 content_unreferenced="To delete: unreferenced"
19 content_oldandpushed="To delete: pushed and too old"
20 content_oldandunchanged="Keep: pushed and created a while ago, but still current"
21 oid_unreferenced=$(calc_oid "$content_unreferenced")
22 oid_oldandpushed=$(calc_oid "$content_oldandpushed")
23 oid_oldandunchanged=$(calc_oid "$content_oldandunchanged")
24 content_retain1="Retained content 1"
25 content_retain2="Retained content 2"
26 oid_retain1=$(calc_oid "$content_retain1")
27 oid_retain2=$(calc_oid "$content_retain2")
30 # Remember for something to be 'too old' it has to appear on the MINUS side
31 # of the diff outside the prune window, i.e. it's not when it was introduced
32 # but when it disappeared from relevance. That's why changes to file1.dat on master
33 # from 7d ago are included even though the commit itself is outside of the window,
34 # that content of file1.dat was relevant until it was removed with a commit, inside the window
35 # think of it as windows of relevance that overlap until the content is replaced
37 # we also make sure we commit today on master so that the recent commits measured
38 # from latest commit on master tracks back from there
41 \"CommitDate\":\"$(get_date -20d)\",
43 {\"Filename\":\"old.dat\",\"Size\":${#content_oldandpushed}, \"Data\":\"$content_oldandpushed\"},
44 {\"Filename\":\"stillcurrent.dat\",\"Size\":${#content_oldandunchanged}, \"Data\":\"$content_oldandunchanged\"}]
47 \"CommitDate\":\"$(get_date -7d)\",
49 {\"Filename\":\"old.dat\",\"Size\":${#content_retain1}, \"Data\":\"$content_retain1\"}]
52 \"CommitDate\":\"$(get_date -4d)\",
53 \"NewBranch\":\"branch_to_delete\",
55 {\"Filename\":\"unreferenced.dat\",\"Size\":${#content_unreferenced}, \"Data\":\"$content_unreferenced\"}]
58 \"ParentBranches\":[\"master\"],
60 {\"Filename\":\"old.dat\",\"Size\":${#content_retain2}, \"Data\":\"$content_retain2\"}]
62 ]" | lfstest-testutils addcommits
64 git push origin master
65 git branch -D branch_to_delete
67 git config lfs.fetchrecentrefsdays 5
68 git config lfs.fetchrecentremoterefs true
69 git config lfs.fetchrecentcommitsdays 3
70 git config lfs.pruneoffsetdays 2
72 git lfs prune --dry-run --verbose 2>&1 | tee prune.log
74 grep "prune: 5 local object(s), 3 retained" prune.log
75 grep "prune: 2 file(s) would be pruned" prune.log
76 grep "$oid_oldandpushed" prune.log
77 grep "$oid_unreferenced" prune.log
79 assert_local_object "$oid_oldandpushed" "${#content_oldandpushed}"
80 assert_local_object "$oid_unreferenced" "${#content_unreferenced}"
82 refute_local_object "$oid_oldandpushed" "${#content_oldandpushed}"
83 refute_local_object "$oid_unreferenced" "${#content_unreferenced}"
84 assert_local_object "$oid_retain1" "${#content_retain1}"
85 assert_local_object "$oid_retain2" "${#content_retain2}"
87 # now only keep AT refs, no recents
88 git config lfs.fetchrecentcommitsdays 0
90 git lfs prune --verbose 2>&1 | tee prune.log
91 grep "prune: 3 local object(s), 2 retained" prune.log
92 grep "prune: Deleting objects: 100% (1/1), done" prune.log
93 grep "$oid_retain1" prune.log
94 refute_local_object "$oid_retain1"
95 assert_local_object "$oid_retain2" "${#content_retain2}"
99 begin_test "prune keep unpushed"
103 # need to set up many commits on each branch with old data so that would
104 # get deleted if it were not for unpushed status (heads would never be pruned but old changes would)
105 reponame="prune_keep_unpushed"
106 setup_remote_repo "remote_$reponame"
108 clone_repo "remote_$reponame" "clone_$reponame"
110 git lfs track "*.dat" 2>&1 | tee track.log
111 grep "Tracking \"\*.dat\"" track.log
114 content_keepunpushedhead1="Keep: unpushed HEAD 1"
115 content_keepunpushedhead2="Keep: unpushed HEAD 2"
116 content_keepunpushedhead3="Keep: unpushed HEAD 3"
117 content_keepunpushedbranch1="Keep: unpushed second branch 1"
118 content_keepunpushedbranch2="Keep: unpushed second branch 2"
119 content_keepunpushedbranch3="Keep: unpushed second branch 3"
120 oid_keepunpushedhead1=$(calc_oid "$content_keepunpushedhead1")
121 oid_keepunpushedhead2=$(calc_oid "$content_keepunpushedhead2")
122 oid_keepunpushedhead3=$(calc_oid "$content_keepunpushedhead3")
123 oid_keepunpushedbranch1=$(calc_oid "$content_keepunpushedbranch1")
124 oid_keepunpushedbranch2=$(calc_oid "$content_keepunpushedbranch2")
125 oid_keepunpushedbranch3=$(calc_oid "$content_keepunpushedbranch3")
126 oid_keepunpushedtagged1=$(calc_oid "$content_keepunpushedtagged1")
127 oid_keepunpushedtagged2=$(calc_oid "$content_keepunpushedtagged1")
131 \"CommitDate\":\"$(get_date -40d)\",
133 {\"Filename\":\"file.dat\",\"Size\":${#content_keepunpushedhead1}, \"Data\":\"$content_keepunpushedhead1\"}]
136 \"CommitDate\":\"$(get_date -31d)\",
137 \"ParentBranches\":[\"master\"],
138 \"NewBranch\":\"branch_unpushed\",
140 {\"Filename\":\"file.dat\",\"Size\":${#content_keepunpushedbranch1}, \"Data\":\"$content_keepunpushedbranch1\"}]
143 \"CommitDate\":\"$(get_date -16d)\",
145 {\"Filename\":\"file.dat\",\"Size\":${#content_keepunpushedbranch2}, \"Data\":\"$content_keepunpushedbranch2\"}]
148 \"CommitDate\":\"$(get_date -2d)\",
150 {\"Filename\":\"file.dat\",\"Size\":${#content_keepunpushedbranch3}, \"Data\":\"$content_keepunpushedbranch3\"}]
153 \"CommitDate\":\"$(get_date -21d)\",
154 \"ParentBranches\":[\"master\"],
156 {\"Filename\":\"file.dat\",\"Size\":${#content_keepunpushedhead2}, \"Data\":\"$content_keepunpushedhead2\"}]
159 \"CommitDate\":\"$(get_date -0d)\",
161 {\"Filename\":\"file.dat\",\"Size\":${#content_keepunpushedhead3}, \"Data\":\"$content_keepunpushedhead3\"}]
163 ]" | lfstest-testutils addcommits
165 git config lfs.fetchrecentrefsdays 5
166 git config lfs.fetchrecentremoterefs true
167 git config lfs.fetchrecentcommitsdays 0 # only keep AT refs, no recents
168 git config lfs.pruneoffsetdays 2
172 # Now push master and show that older versions on master will be removed
173 git push origin master
175 git lfs prune --verbose 2>&1 | tee prune.log
176 grep "prune: 6 local object(s), 4 retained" prune.log
177 grep "prune: Deleting objects: 100% (2/2), done" prune.log
178 grep "$oid_keepunpushedhead1" prune.log
179 grep "$oid_keepunpushedhead2" prune.log
180 refute_local_object "$oid_keepunpushedhead1"
181 refute_local_object "$oid_keepunpushedhead2"
183 # MERGE the secondary branch, delete the branch then push master, then make sure
184 # we delete the intermediate commits but also make sure they're on server
185 # resolve conflicts by taking other branch
186 git merge -Xtheirs branch_unpushed
187 git branch -D branch_unpushed
188 git lfs prune --dry-run
189 git push origin master
191 git lfs prune --verbose 2>&1 | tee prune.log
192 grep "prune: 4 local object(s), 1 retained" prune.log
193 grep "prune: Deleting objects: 100% (3/3), done" prune.log
194 grep "$oid_keepunpushedbranch1" prune.log
195 grep "$oid_keepunpushedbranch2" prune.log
196 grep "$oid_keepunpushedhead3" prune.log
197 refute_local_object "$oid_keepunpushedbranch1"
198 refute_local_object "$oid_keepunpushedbranch2"
199 # we used -Xtheirs so old head state is now obsolete, is the last state on branch
200 refute_local_object "$oid_keepunpushedhead3"
201 assert_server_object "remote_$reponame" "$oid_keepunpushedbranch1"
202 assert_server_object "remote_$reponame" "$oid_keepunpushedbranch2"
203 assert_server_object "remote_$reponame" "$oid_keepunpushedhead3"
208 begin_test "prune keep recent"
212 reponame="prune_recent"
213 setup_remote_repo "remote_$reponame"
215 clone_repo "remote_$reponame" "clone_$reponame"
217 git lfs track "*.dat" 2>&1 | tee track.log
218 grep "Tracking \"\*.dat\"" track.log
220 content_keephead="Keep: HEAD"
221 content_keeprecentbranch1tip="Keep: Recent branch 1 tip"
222 content_keeprecentbranch2tip="Keep: Recent branch 2 tip"
223 content_keeprecentcommithead="Keep: Recent commit on HEAD"
224 content_keeprecentcommitbranch1="Keep: Recent commit on recent branch 1"
225 content_keeprecentcommitbranch2="Keep: Recent commit on recent branch 2"
226 content_prunecommitoldbranch1="Prune: old commit on old branch"
227 content_prunecommitoldbranch2="Prune: old branch tip"
228 content_prunecommitbranch1="Prune: old commit on recent branch 1"
229 content_prunecommitbranch2="Prune: old commit on recent branch 2"
230 content_prunecommithead="Prune: old commit on HEAD"
231 oid_keephead=$(calc_oid "$content_keephead")
232 oid_keeprecentbranch1tip=$(calc_oid "$content_keeprecentbranch1tip")
233 oid_keeprecentbranch2tip=$(calc_oid "$content_keeprecentbranch2tip")
234 oid_keeprecentcommithead=$(calc_oid "$content_keeprecentcommithead")
235 oid_keeprecentcommitbranch1=$(calc_oid "$content_keeprecentcommitbranch1")
236 oid_keeprecentcommitbranch2=$(calc_oid "$content_keeprecentcommitbranch2")
237 oid_prunecommitoldbranch=$(calc_oid "$content_prunecommitoldbranch1")
238 oid_prunecommitoldbranch2=$(calc_oid "$content_prunecommitoldbranch2")
239 oid_prunecommitbranch1=$(calc_oid "$content_prunecommitbranch1")
240 oid_prunecommitbranch2=$(calc_oid "$content_prunecommitbranch2")
241 oid_prunecommithead=$(calc_oid "$content_prunecommithead")
244 # use a single file so each commit supercedes the last, if different files
245 # then history becomes harder to track
246 # Also note that when considering 'recent' when editing a single file, it means
247 # that the snapshot state overlapped; so the latest commit *before* the day
248 # that you're looking at, not just the commits on/after.
251 \"CommitDate\":\"$(get_date -50d)\",
253 {\"Filename\":\"file.dat\",\"Size\":${#content_prunecommithead}, \"Data\":\"$content_prunecommithead\"}]
256 \"CommitDate\":\"$(get_date -30d)\",
258 {\"Filename\":\"file.dat\",\"Size\":${#content_keeprecentcommithead}, \"Data\":\"$content_keeprecentcommithead\"}]
261 \"CommitDate\":\"$(get_date -8d)\",
262 \"NewBranch\":\"branch_old\",
264 {\"Filename\":\"file.dat\",\"Size\":${#content_prunecommitoldbranch1}, \"Data\":\"$content_prunecommitoldbranch1\"}]
267 \"CommitDate\":\"$(get_date -7d)\",
269 {\"Filename\":\"file.dat\",\"Size\":${#content_prunecommitoldbranch2}, \"Data\":\"$content_prunecommitoldbranch2\"}]
272 \"CommitDate\":\"$(get_date -9d)\",
273 \"ParentBranches\":[\"master\"],
274 \"NewBranch\":\"branch1\",
276 {\"Filename\":\"file.dat\",\"Size\":${#content_prunecommitbranch1}, \"Data\":\"$content_prunecommitbranch1\"}]
279 \"CommitDate\":\"$(get_date -8d)\",
281 {\"Filename\":\"file.dat\",\"Size\":${#content_keeprecentcommitbranch1}, \"Data\":\"$content_keeprecentcommitbranch1\"}]
284 \"CommitDate\":\"$(get_date -5d)\",
286 {\"Filename\":\"file.dat\",\"Size\":${#content_keeprecentbranch1tip}, \"Data\":\"$content_keeprecentbranch1tip\"}]
289 \"CommitDate\":\"$(get_date -17d)\",
290 \"ParentBranches\":[\"master\"],
291 \"NewBranch\":\"branch2\",
293 {\"Filename\":\"file.dat\",\"Size\":${#content_prunecommitbranch2}, \"Data\":\"$content_prunecommitbranch2\"}]
296 \"CommitDate\":\"$(get_date -10d)\",
298 {\"Filename\":\"file.dat\",\"Size\":${#content_keeprecentcommitbranch2}, \"Data\":\"$content_keeprecentcommitbranch2\"}]
301 \"CommitDate\":\"$(get_date -2d)\",
303 {\"Filename\":\"file.dat\",\"Size\":${#content_keeprecentbranch2tip}, \"Data\":\"$content_keeprecentbranch2tip\"}]
306 \"CommitDate\":\"$(get_date -1d)\",
307 \"ParentBranches\":[\"master\"],
309 {\"Filename\":\"file.dat\",\"Size\":${#content_keephead}, \"Data\":\"$content_keephead\"}]
311 ]" | lfstest-testutils addcommits
313 # keep refs for 6 days & any prev commit that overlaps 2 days before tip (recent + offset)
314 git config lfs.fetchrecentrefsdays 5
315 git config lfs.fetchrecentremoterefs true
316 git config lfs.fetchrecentcommitsdays 1
317 git config lfs.pruneoffsetdays 1
319 # push everything so that's not a reason to retain
320 git push origin master:master branch_old:branch_old branch1:branch1 branch2:branch2
323 git lfs prune --verbose 2>&1 | tee prune.log
324 grep "prune: 11 local object(s), 6 retained, done" prune.log
325 grep "prune: Deleting objects: 100% (5/5), done" prune.log
326 grep "$oid_prunecommitoldbranch" prune.log
327 grep "$oid_prunecommitoldbranch2" prune.log
328 grep "$oid_prunecommitbranch1" prune.log
329 grep "$oid_prunecommitbranch2" prune.log
330 grep "$oid_prunecommithead" prune.log
332 refute_local_object "$oid_prunecommitoldbranch"
333 refute_local_object "$oid_prunecommitoldbranch2"
334 refute_local_object "$oid_prunecommitbranch1"
335 refute_local_object "$oid_prunecommitbranch2"
336 refute_local_object "$oid_prunecommithead"
337 assert_local_object "$oid_keephead" "${#content_keephead}"
338 assert_local_object "$oid_keeprecentbranch1tip" "${#content_keeprecentbranch1tip}"
339 assert_local_object "$oid_keeprecentbranch2tip" "${#content_keeprecentbranch2tip}"
340 assert_local_object "$oid_keeprecentcommithead" "${#content_keeprecentcommithead}"
341 assert_local_object "$oid_keeprecentcommitbranch1" "${#content_keeprecentcommitbranch1}"
342 assert_local_object "$oid_keeprecentcommitbranch2" "${#content_keeprecentcommitbranch2}"
344 # now don't include any recent commits in fetch & hence don't retain
345 # still retain tips of branches
346 git config lfs.fetchrecentcommitsdays 0
347 git lfs prune --verbose 2>&1 | tee prune.log
348 grep "prune: 6 local object(s), 3 retained, done" prune.log
349 grep "prune: Deleting objects: 100% (3/3), done" prune.log
350 assert_local_object "$oid_keephead" "${#content_keephead}"
351 assert_local_object "$oid_keeprecentbranch1tip" "${#content_keeprecentbranch1tip}"
352 assert_local_object "$oid_keeprecentbranch2tip" "${#content_keeprecentbranch2tip}"
353 refute_local_object "$oid_keeprecentcommithead"
354 refute_local_object "$oid_keeprecentcommitbranch1"
355 refute_local_object "$oid_keeprecentcommitbranch2"
357 # now don't include any recent refs at all, only keep HEAD
358 git config lfs.fetchrecentrefsdays 0
359 git lfs prune --verbose 2>&1 | tee prune.log
360 grep "prune: 3 local object(s), 1 retained, done" prune.log
361 grep "prune: Deleting objects: 100% (2/2), done" prune.log
362 assert_local_object "$oid_keephead" "${#content_keephead}"
363 refute_local_object "$oid_keeprecentbranch1tip"
364 refute_local_object "$oid_keeprecentbranch2tip"
369 begin_test "prune remote tests"
373 reponame="prune_no_or_nonorigin_remote"
377 git lfs track "*.dat" 2>&1 | tee track.log
378 grep "Tracking \"\*.dat\"" track.log
382 \"CommitDate\":\"$(get_date -50d)\",
384 {\"Filename\":\"file.dat\",\"Size\":30}]
387 \"CommitDate\":\"$(get_date -40d)\",
389 {\"Filename\":\"file.dat\",\"Size\":28}]
392 \"CommitDate\":\"$(get_date -35d)\",
394 {\"Filename\":\"file.dat\",\"Size\":37}]
397 \"CommitDate\":\"$(get_date -25d)\",
399 {\"Filename\":\"file.dat\",\"Size\":42}]
401 ]" | lfstest-testutils addcommits
403 # set no recents so max ability to prune normally
404 git config lfs.fetchrecentrefsdays 0
405 git config lfs.fetchrecentremoterefs true
406 git config lfs.fetchrecentcommitsdays 0
407 git config lfs.pruneoffsetdays 1
409 # can never prune with no remote
410 git lfs prune --verbose 2>&1 | tee prune.log
411 grep "prune: 4 local object(s), 4 retained, done" prune.log
414 # also make sure nothing is pruned when remote is not origin
415 # create 2 remotes, neither of which is called origin & push to both
416 setup_remote_repo "remote1_$reponame"
417 setup_remote_repo "remote2_$reponame"
418 cd "$TRASHDIR/$reponame"
419 git remote add not_origin "$GITSERVER/remote1_$reponame"
420 git push not_origin master
422 git lfs prune --verbose 2>&1 | tee prune.log
423 grep "prune: 4 local object(s), 4 retained, done" prune.log
425 # now set the prune remote to be not_origin, should now prune
426 # do a dry run so we can also verify
427 git config lfs.pruneremotetocheck not_origin
429 git lfs prune --verbose --dry-run 2>&1 | tee prune.log
430 grep "prune: 4 local object(s), 1 retained, done" prune.log
431 grep "prune: 3 file(s) would be pruned" prune.log
438 begin_test "prune verify"
442 reponame="prune_verify"
443 setup_remote_repo "remote_$reponame"
445 clone_repo "remote_$reponame" "clone_$reponame"
447 git lfs track "*.dat" 2>&1 | tee track.log
448 grep "Tracking \"\*.dat\"" track.log
450 content_head="HEAD content"
451 content_commit3="Content for commit 3 (prune)"
452 content_commit2_failverify="Content for commit 2 (prune - fail verify)"
453 content_commit1="Content for commit 1 (prune)"
454 oid_head=$(calc_oid "$content_head")
455 oid_commit3=$(calc_oid "$content_commit3")
456 oid_commit2_failverify=$(calc_oid "$content_commit2_failverify")
457 oid_commit1=$(calc_oid "$content_commit1")
461 \"CommitDate\":\"$(get_date -50d)\",
463 {\"Filename\":\"file.dat\",\"Size\":${#content_commit1}, \"Data\":\"$content_commit1\"}]
466 \"CommitDate\":\"$(get_date -40d)\",
468 {\"Filename\":\"file.dat\",\"Size\":${#content_commit2_failverify}, \"Data\":\"$content_commit2_failverify\"}]
471 \"CommitDate\":\"$(get_date -35d)\",
473 {\"Filename\":\"file.dat\",\"Size\":${#content_commit3}, \"Data\":\"$content_commit3\"}]
476 \"CommitDate\":\"$(get_date -25d)\",
478 {\"Filename\":\"file.dat\",\"Size\":${#content_head}, \"Data\":\"$content_head\"}]
480 ]" | lfstest-testutils addcommits
482 # push all so no unpushed reason to not prune
483 git push origin master
485 # set no recents so max ability to prune normally
486 git config lfs.fetchrecentrefsdays 0
487 git config lfs.fetchrecentremoterefs true
488 git config lfs.fetchrecentcommitsdays 0
489 git config lfs.pruneoffsetdays 1
491 # confirm that it would prune with verify when no issues
492 git lfs prune --dry-run --verify-remote --verbose 2>&1 | tee prune.log
493 grep "prune: 4 local object(s), 1 retained, 3 verified with remote, done" prune.log
494 grep "prune: 3 file(s) would be pruned" prune.log
495 grep "$oid_commit3" prune.log
496 grep "$oid_commit2_failverify" prune.log
497 grep "$oid_commit1" prune.log
499 # delete one file on the server to make the verify fail
500 delete_server_object "remote_$reponame" "$oid_commit2_failverify"
501 # this should now fail
502 git lfs prune --verify-remote 2>&1 | tee prune.log
503 grep "prune: 4 local object(s), 1 retained, 2 verified with remote, done" prune.log
504 grep "missing on remote:" prune.log
505 grep "$oid_commit2_failverify" prune.log
506 # Nothing should have been deleted
507 assert_local_object "$oid_commit1" "${#content_commit1}"
508 assert_local_object "$oid_commit2_failverify" "${#content_commit2_failverify}"
509 assert_local_object "$oid_commit3" "${#content_commit3}"
511 # Now test with the global option
512 git config lfs.pruneverifyremotealways true
513 # no verify arg but should be pulled from global
514 git lfs prune 2>&1 | tee prune.log
515 grep "prune: 4 local object(s), 1 retained, 2 verified with remote, done" prune.log
516 grep "missing on remote:" prune.log
517 grep "$oid_commit2_failverify" prune.log
518 # Nothing should have been deleted
519 assert_local_object "$oid_commit1" "${#content_commit1}"
520 assert_local_object "$oid_commit2_failverify" "${#content_commit2_failverify}"
521 assert_local_object "$oid_commit3" "${#content_commit3}"
523 # now try overriding the global option
524 git lfs prune --no-verify-remote 2>&1 | tee prune.log
525 grep "prune: 4 local object(s), 1 retained, done" prune.log
526 grep "prune: Deleting objects: 100% (3/3), done" prune.log
527 # should now have been deleted
528 refute_local_object "$oid_commit1"
529 refute_local_object "$oid_commit2_failverify"
530 refute_local_object "$oid_commit3"
535 begin_test "prune verify large numbers of refs"
539 reponame="prune_verify_large"
540 setup_remote_repo "remote_$reponame"
542 clone_repo "remote_$reponame" "clone_$reponame"
544 git lfs track "*.dat" 2>&1 | tee track.log
545 grep "Tracking \"\*.dat\"" track.log
547 content_head="HEAD content"
548 content_commit1="Recent commit"
549 content_oldcommit="Old content"
550 oid_head=$(calc_oid "$content_head")
552 # Add two recent commits that should not be pruned
555 \"CommitDate\":\"$(get_date -50d)\",
557 {\"Filename\":\"file.dat\",\"Size\":${#content_oldcommit}, \"Data\":\"$(uuidgen)\"}]
560 \"CommitDate\":\"$(get_date -45d)\",
562 {\"Filename\":\"file.dat\",\"Size\":${#content_oldcommit}, \"Data\":\"$(uuidgen)\"}]
565 \"CommitDate\":\"$(get_date -2d)\",
567 {\"Filename\":\"file.dat\",\"Size\":${#content_commit1}, \"Data\":\"$content_commit1\"}]
570 \"CommitDate\":\"$(get_date -1d)\",
572 {\"Filename\":\"file.dat\",\"Size\":${#content_head}, \"Data\":\"$content_head\"}]
574 ]" | lfstest-testutils addcommits
576 # Generate a large number of refs to old commits make sure prune has a lot of data to read
577 git checkout $(git log --pretty=oneline master | tail -2 | awk '{print $1}' | head -1)
578 for i in $(seq 0 1000); do
583 # push all so no unpushed reason to not prune
584 # git push origin master
586 # set no recents so max ability to prune normally
587 git config lfs.fetchrecentrefsdays 3
588 git config lfs.fetchrecentremoterefs true
589 git config lfs.fetchrecentcommitsdays 3
590 git config lfs.pruneoffsetdays 3
592 # confirm that prune does not hang
593 git lfs prune --dry-run --verify-remote --verbose 2>&1 | tee prune.log