Skip to content

Implement Git LFS backup and restore support - #5

Merged
yakupyigit merged 2 commits into
mainfrom
claude/laughing-lovelace-l84k95
Oct 14, 2026
Merged

yakupyigit merged 2 commits into
mainfrom
claude/laughing-lovelace-l84k95

Conversation

@yakupyigit

Copy link
Copy Markdown
Contributor

Completes Phase 4 by adding full Git LFS object backup and restore functionality.

Summary

Repositories using Git LFS now have their LFS objects backed up alongside the git bundle. Each snapshot includes an lfs.tar archive (when LFS objects exist) and a manifest field tracking its size. Restoration follows the documented process: clone the bundle, extract the tar into .git/lfs/objects, and run git lfs checkout.

Key Changes

Core LFS operations (src/core/lfs.ts):

  • fetchLfs(): Runs git lfs fetch --all origin in the mirror to download all LFS objects
  • hasLfsObjects(): Detects whether the mirror contains any LFS objects (recursive directory scan)
  • createLfsTar(): Creates a portable tar archive of lfs/objects and returns its byte size

Backup workflow (src/core/run.ts):

  • LFS fetch and tar creation only occur when a new snapshot is needed (refs changed)
  • LFS processing is skipped for wikis (only applies to repositories)
  • lfsTarBytes added to manifest when LFS objects exist
  • LFS tar passed to putSnapshot() alongside bundle and manifest

Prerequisites and configuration (src/commands/backup.ts):

  • New checkLfs() function verifies git-lfs is installed before backup starts
  • Fails with exit code 2 and helpful message (install link + --no-lfs option) if missing
  • Check is skipped when --no-lfs flag or GHBACKUP_LFS=false environment variable is set
  • BackupInput.lfs boolean controls whether LFS processing is enabled

Testing:

  • Unit tests (test/unit/lfs.test.ts): hasLfsObjects() and fetchLfs() behavior
  • Integration tests (test/integration/lfs.test.ts): Full backup→restore cycle with LFS files
    • Uses local file-based LFS transfer (lfs.url=file:// + lfs.standalonetransferagent=lfs-standalone-file) to avoid needing an LFS server
    • Verifies restored LFS file content matches original via SHA256
    • Tests --no-lfs flag, unchanged refs optimization, and wiki exclusion
  • Command tests (test/unit/commands.test.ts): Prerequisite check and flag behavior

CI/CD (.github/workflows/ci.yml):

  • Ensures git-lfs is installed on Ubuntu runners before tests run

Documentation:

  • Phase 4 marked complete in plans/faz-04-lfs.md
  • Architecture updated in plans/mimari.md with LFS workflow details
  • Remaining manual verification task documented (real GitHub LFS repo restoration)

Implementation Details

LFS objects are fetched only when snapshot creation is triggered (when refs change), avoiding unnecessary LFS operations on unchanged repositories. The tar archive preserves the lfs/objects/ directory structure needed for git lfs checkout to work correctly. Manifest includes lfsTarBytes only when LFS objects exist, keeping manifests clean for non-LFS repositories.

https://claude.ai/code/session_0197EtXcoZj4YJKStpAyaxJH

Fetch all LFS objects into the mirror when a new snapshot is due, pack
lfs/objects into <stamp>.lfs.tar with the tar package and record its size
in the manifest. Fail fast with exit 2 when git-lfs is missing unless LFS is
disabled. Wikis and unchanged repositories skip LFS entirely.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_0197EtXcoZj4YJKStpAyaxJH
@yakupyigit
yakupyigit merged commit 8ebc29b into main Oct 14, 2026
4 checks passed
@yakupyigit
yakupyigit deleted the claude/laughing-lovelace-l84k95 branch November 4, 2026 02:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants