GIT-LFS-PRUNE(1)

๐Ÿฆ‹ NAME ๐Ÿฆ‹

okay so bestie, this is GIT-LFS-PRUNE(1) โ€” the page for git-lfs-prune, and its whole main-character job is to delete old LFS files from local storage โœจ๐Ÿ’–

๐ŸŽ€ SYNOPSIS ๐ŸŽ€

git lfs prune [options]

๐Ÿ”ฅ DESCRIPTION ๐Ÿ”ฅ

Deletes local copies of LFS files that are old, so you get disk space back. Prune literally enumerates every locally stored object, then deletes anything that is not referenced by at least ONE of these:

  • the current checkout
  • all existing stashes
  • a "recent branch"; see RECENT FILES
  • a "recent commit" on the current branch or recent branches; see RECENT FILES
  • a commit which has not been pushed; see UNPUSHED LFS FILES
  • any other worktree checkouts; see git-worktree(1)

In general terms, prune deletes files youโ€™re not currently using and that arenโ€™t "recent", as long as theyโ€™ve been pushed โ€” meaning the local copy is not the only one. Thatโ€™s the vibe check: if itโ€™s old, unused, and safely pushed, it can go ๐Ÿ‘‹

The reflog is not considered โ€” only commits. So LFS objects that are only referenced by orphaned commits are always deleted. No cap, thatโ€™s just how it is.

โš ๏ธ do not run git lfs prune if you have different repositories sharing the same custom storage directory; see git-lfs-config(5) for more details about the lfs.storage option. This is a serious โ€œbestie, donโ€™tโ€ moment ๐Ÿซถ

In your Git configuration or in a .lfsconfig file, you may set lfs.fetchexclude to a comma-separated list of paths. If lfs.fetchexclude is defined, then any Git LFS files whose paths match one in that list will be pruned unless they are referenced by a stash or an unpushed commit. Paths are matched using wildcard matching as per gitignore(5).

๐Ÿ’… OPTIONS ๐Ÿ’…

  • -d, --dry-run โ€” Donโ€™t actually delete anything, just report on what would have been done. Itโ€™s giving โ€œwindow shoppingโ€ energy ๐Ÿ›๏ธ
  • -f, --force โ€” Prune all objects except unpushed objects, including objects required for currently checked out refs. Implies --recent. Aggressive, iconic, be careful โœจ
  • --recent โ€” Prune even objects that would normally be preserved by the configuration options specified below in RECENT FILES.
  • -c, --verify-remote โ€” Contact the remote and check that copies of reachable files we would delete definitely exist before deleting. See VERIFY REMOTE. Extra safe, extra overhead ๐Ÿฆ‹
  • --no-verify-remote โ€” Disables remote verification if lfs.pruneverifyremotealways was enabled in settings. See VERIFY REMOTE.
  • --verify-unreachable โ€” When doing --verify-remote contact the remote and check unreachable objects as well. See VERIFY REMOTE.
  • --no-verify-unreachable โ€” Disables remote verification of unreachable files if lfs.pruneverifyunreachablealways was enabled in settings. See VERIFY REMOTE.
  • --when-unverified=<halt,continue> โ€” When --verify-remote cannot verify an object on the remote, either halt the execution or continue the deletion of verified objects. See VERIFY REMOTE.
  • -v, --verbose โ€” Report the full detail of what is/would be deleted. Spill the tea, prune edition โ˜•

๐ŸŒธ RECENT FILES ๐ŸŒธ

Prune wonโ€™t delete LFS files referenced by "recent" commits, in case you want to use them again without having to download. The definition of "recent" is derived from the one used by git-lfs-fetch(1) to download recent objects with the --recent option, with an offset of a number of days (default 3) to ensure that we always keep files you download for a few days. Itโ€™s literally a lil grace period, bestie ๐Ÿ’–

Here are the git-config(1) settings that control this behaviour:

  • lfs.pruneoffsetdays โ€” The number of extra days added to the fetch recent settings when using them to decide when to prune. So for a reference to be considered old enough to prune, it has to be this many days older than the oldest reference that would be downloaded via git lfs fetch --recent. Only used if the relevant fetch recent "days" setting is non-zero. Default 3 days.
  • lfs.fetchrecentrefsdays, lfs.fetchrecentremoterefs, lfs.fetchrecentcommitsdays โ€” These have the same meaning as git-lfs-fetch(1) with the --recent option, they are used as a base for the offset above. Anything which falls outside of this offsetted window is considered old enough to prune. If a day value is zero, that condition is not used at all to retain objects and they will be pruned.

๐Ÿš UNPUSHED LFS FILES ๐Ÿš

When the only copy of an LFS file is local, and it is still reachable from any reference, that file can never be pruned, regardless of how old it is. That file is main character energy and it stays ๐Ÿ‘‘

To determine whether an LFS file has been pushed, we check the difference between local refs and remote refs; where the local ref is ahead, any LFS files referenced in those commits is unpushed and will not be deleted. This works because the LFS pre-push hook always ensures that LFS files are pushed before the remote branch is updated.

See DEFAULT REMOTE, for which remote is considered "pushed" for pruning purposes.

๐Ÿงš VERIFY REMOTE ๐Ÿงš

The --verify-remote option calls the remote to ensure that any reachable LFS files to be deleted have copies on the remote before actually deleting them.

Usually the check performed by UNPUSHED LFS FILES is enough to determine that files have been pushed, but if you want to be extra sure at the expense of extra overhead you can make prune actually call the remote API and verify the presence of the files youโ€™re about to delete locally. See DEFAULT REMOTE for which remote is checked.

You can make this behaviour the default by setting lfs.pruneverifyremotealways to true.

In addition to the overhead of calling the remote, using this option also requires prune to distinguish between totally unreachable files (e.g. those that were added to the index but never committed, or referenced only by orphaned commits), and files which are still referenced, but by commits which are prunable. This makes the prune process take longer. Not gonna lie, itโ€™s thorough but itโ€™s not a quick little scroll ๐Ÿ˜ญ

If you want to verify unreachable objects as well, set the --verify-unreachable option.

You can check for unreachable objects by default by setting lfs.pruneverifyunreachablealways to true.

By default, --verify-remote halts execution if a file cannot be verified. Set --when-unverified=continue to not halt execution but continue deleting all objects that can be verified.

๐ŸŒˆ DEFAULT REMOTE ๐ŸŒˆ

When identifying UNPUSHED LFS FILES and performing VERIFY REMOTE, a single remote, origin, is normally used as the reference. This one remote is considered canonical; even if you use multiple remotes, you probably want to retain your local copies until theyโ€™ve made it to that remote. origin is used by default because that will usually be a main central repo, or your fork of it โ€” in both cases thatโ€™s a valid remote backup of your work. If origin doesnโ€™t exist then by default nothing will be pruned because everything is treated as "unpushed". Fr fr, no backup means no deletion ๐Ÿ’€

You can alter the remote via git config: lfs.pruneremotetocheck. Set this to a different remote name to check that one instead of origin.

โญ SEE ALSO โญ

git-lfs-fetch(1), gitignore(5).

Part of the git-lfs(1) suite.


xoxo, the GIT-LFS-PRUNE(1) footer bestie ๐Ÿ’– โ€” no extra source/version/date crumbs showed up on this page, just the manual name and all my love, so go forth and prune responsibly โœจ๐ŸŽ€

๐Ÿ“ฆ where this page comes from