Lab: Git LFS, recovery, and safe history repair

Outcome

Use a disposable repository to track a binary with Git LFS, inspect the committed pointer, recover a deleted file locally, and identify when a shared-history repair requires coordination. This lab never uses a real secret, a production remote, or an irreversible rewrite.

Before you begin

Create a throwaway local repository and install Git LFS from its official distribution or your package manager. Confirm it before proceeding:

git lfs install
git init azlearn-lfs && cd azlearn-lfs
git config user.name 'Training User'
git config user.email '[email protected]'

git-fat is historical/tool-selection context, not the path this lab uses. Use Git LFS where your Git host supports it; use a package registry or release asset when you need versioned distribution rather than source-tree storage.

Do

  1. Create a harmless binary-sized file and track its type before adding it:

    mkdir assets
    dd if=/dev/zero of=assets/demo.bin bs=1M count=2
    git lfs track '*.bin'
    git add .gitattributes assets/demo.bin
    git commit -m 'Add LFS training binary'
    git lfs ls-files
  2. Inspect what ordinary Git committed, rather than assuming it contains the binary:

    git show HEAD:assets/demo.bin
    git check-attr filter -- assets/demo.bin

    The committed content is an LFS pointer containing an object identifier and size. The LFS client resolves that pointer to the binary for a capable clone.

  3. If you use a disposable GitHub repository, push it and inspect both the LFS transfer output and the repository’s .gitattributes. Clone it into a second directory after temporarily disabling LFS smudging (GIT_LFS_SKIP_SMUDGE=1 git clone ...) to observe the pointer-only state. Re-enable LFS and run git lfs pull to fetch the object. Never perform this test against a repository you need.

Verify

Record the git lfs ls-files output, the committed pointer text, .gitattributes, and—if you used a remote—the fresh clone before and after git lfs pull. You should now understand that Git tracks a pointer while LFS stores the object separately; a collaborator without LFS cannot use the original binary merely because they cloned the repository.

Break and fix

  1. In a second disposable repository, commit a .bin file before running git lfs track. git lfs ls-files should omit it. Do not force-push a rewrite. Remove that local repository and repeat the correct sequence instead.
  2. Delete assets/demo.bin, stage and commit the deletion, then recover it with git restore --source=HEAD~1 -- assets/demo.bin. Verify the recovered file and commit it. This is local/safe recovery, not shared-history rewriting.
  3. Explain the response if a large file or secret already reached a shared remote: stop normal pushes, assess clones/forks and credential exposure, revoke any secret, follow the host’s history-removal procedure, coordinate a force-update, and require collaborators to reclone or repair. Removing a file in a new commit does not remove it from old commits.

Scenario practice

  1. Configure: A repository stores a 500 MB model artifact. Choose Git LFS, a package feed, or a release asset and state the consumer and retention requirement that drives your choice.
  2. Diagnose: A fresh clone displays pointer text instead of the binary. Which client capability and commands do you check before declaring the object lost?
  3. Distinguish: Contrast git restore/git revert with a history rewrite. Which is appropriate for an accidental deletion already pulled by other developers?

Clean up

Delete the two local training repositories. If you created a disposable remote, delete it only after confirming it contains no work you need. Do not assume deleting one LFS pointer immediately removes remote LFS storage; follow your host’s documented retention/removal process.

Sources and re-audit

Re-audit when host limits, LFS retention, or sensitive-data removal guidance changes.

Git · Repository scaling · Git path · All labs