Fixes#234 — repo-backups directory growing to 17GB+ due to a backward-compatibility trap where legacy configs silently resolve to "always backup" mode.
Fix backward-compat trap: backupBeforeSync: true (the mapper default) was silently mapping to "always" in resolveBackupStrategy, creating full git bundles on every sync. Now maps to "on-force-push" (smart backup) instead.
Fix UI round-trip regression: Legacy backupBeforeSync: false configs were being overwritten to "on-force-push" after any auto-save. mapDbToUiConfig now correctly preserves the "disabled" state.
Lower default retention: Reduced backupRetentionCount from 20 to 5 bundles per repo across all layers (schema, defaults, mapper, UI).
Add time-based retention: New backupRetentionDays field (default 30 days) deletes old bundles alongside count-based retention, with a safety net to always keep at least 1 bundle.
Expose retention days in UI: Added "Snapshot retention days" input to the backup settings form (was documented but missing from UI).
Add UI warning: "Always Backup" option now shows "(high disk usage)" in the description.
Update docs: FORCE_PUSH_PROTECTION.md updated with new defaults and backward-compat table.
Test plan
All 171 tests pass (2 test assertions updated for new behavior)
Production build succeeds
Verified legacy backupBeforeSync: false round-trip with direct mapper repro
Verified all 4 legacy config scenarios map correctly:
backupBeforeSync: false + no strategy → "disabled"
backupBeforeSync: true + no strategy → "on-force-push"
Explicit backupStrategy → preserved as-is
No fields at all → "on-force-push" (default)
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
## 📋 Pull Request Information
**Original PR:** https://github.com/RayLabsHQ/gitea-mirror/pull/235
**Author:** [@arunavo4](https://github.com/arunavo4)
**Created:** 3/18/2026
**Status:** ✅ Merged
**Merged:** 3/18/2026
**Merged by:** [@arunavo4](https://github.com/arunavo4)
**Base:** `main` ← **Head:** `fix/234-disk-space-backup-retention`
---
### 📝 Commits (2)
- [`3246b10`](https://github.com/RayLabsHQ/gitea-mirror/commit/3246b10e6f21da1a8f6d5f50abbc8e1ecdec2742) fix: prevent excessive disk usage from repo backups (#234)
- [`67e085f`](https://github.com/RayLabsHQ/gitea-mirror/commit/67e085f6c0729a6d3abcabe28425d06de73363c7) fix: preserve legacy backupBeforeSync:false on UI round-trip and expose retention days
### 📊 Changes
**10 files changed** (+94 additions, -23 deletions)
<details>
<summary>View changed files</summary>
📝 `docs/FORCE_PUSH_PROTECTION.md` (+6 -2)
📝 `src/components/config/ConfigTabs.tsx` (+2 -1)
📝 `src/components/config/GitHubConfigForm.tsx` (+26 -4)
📝 `src/lib/db/schema.ts` (+2 -1)
📝 `src/lib/gitea-enhanced.test.ts` (+1 -1)
📝 `src/lib/repo-backup.test.ts` (+2 -2)
📝 `src/lib/repo-backup.ts` (+44 -7)
📝 `src/lib/utils/config-defaults.ts` (+2 -1)
📝 `src/lib/utils/config-mapper.ts` (+8 -4)
📝 `src/types/config.ts` (+1 -0)
</details>
### 📄 Description
## Summary
Fixes #234 — repo-backups directory growing to 17GB+ due to a backward-compatibility trap where legacy configs silently resolve to "always backup" mode.
- **Fix backward-compat trap**: `backupBeforeSync: true` (the mapper default) was silently mapping to `"always"` in `resolveBackupStrategy`, creating full git bundles on every sync. Now maps to `"on-force-push"` (smart backup) instead.
- **Fix UI round-trip regression**: Legacy `backupBeforeSync: false` configs were being overwritten to `"on-force-push"` after any auto-save. `mapDbToUiConfig` now correctly preserves the `"disabled"` state.
- **Lower default retention**: Reduced `backupRetentionCount` from 20 to 5 bundles per repo across all layers (schema, defaults, mapper, UI).
- **Add time-based retention**: New `backupRetentionDays` field (default 30 days) deletes old bundles alongside count-based retention, with a safety net to always keep at least 1 bundle.
- **Expose retention days in UI**: Added "Snapshot retention days" input to the backup settings form (was documented but missing from UI).
- **Add UI warning**: "Always Backup" option now shows "(high disk usage)" in the description.
- **Update docs**: `FORCE_PUSH_PROTECTION.md` updated with new defaults and backward-compat table.
## Test plan
- [x] All 171 tests pass (2 test assertions updated for new behavior)
- [x] Production build succeeds
- [x] Verified legacy `backupBeforeSync: false` round-trip with direct mapper repro
- [x] Verified all 4 legacy config scenarios map correctly:
- `backupBeforeSync: false` + no strategy → `"disabled"`
- `backupBeforeSync: true` + no strategy → `"on-force-push"`
- Explicit `backupStrategy` → preserved as-is
- No fields at all → `"on-force-push"` (default)
---
<sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
📋 Pull Request Information
Original PR: https://github.com/RayLabsHQ/gitea-mirror/pull/235
Author: @arunavo4
Created: 3/18/2026
Status: ✅ Merged
Merged: 3/18/2026
Merged by: @arunavo4
Base:
main← Head:fix/234-disk-space-backup-retention📝 Commits (2)
3246b10fix: prevent excessive disk usage from repo backups (#234)67e085ffix: preserve legacy backupBeforeSync:false on UI round-trip and expose retention days📊 Changes
10 files changed (+94 additions, -23 deletions)
View changed files
📝
docs/FORCE_PUSH_PROTECTION.md(+6 -2)📝
src/components/config/ConfigTabs.tsx(+2 -1)📝
src/components/config/GitHubConfigForm.tsx(+26 -4)📝
src/lib/db/schema.ts(+2 -1)📝
src/lib/gitea-enhanced.test.ts(+1 -1)📝
src/lib/repo-backup.test.ts(+2 -2)📝
src/lib/repo-backup.ts(+44 -7)📝
src/lib/utils/config-defaults.ts(+2 -1)📝
src/lib/utils/config-mapper.ts(+8 -4)📝
src/types/config.ts(+1 -0)📄 Description
Summary
Fixes #234 — repo-backups directory growing to 17GB+ due to a backward-compatibility trap where legacy configs silently resolve to "always backup" mode.
backupBeforeSync: true(the mapper default) was silently mapping to"always"inresolveBackupStrategy, creating full git bundles on every sync. Now maps to"on-force-push"(smart backup) instead.backupBeforeSync: falseconfigs were being overwritten to"on-force-push"after any auto-save.mapDbToUiConfignow correctly preserves the"disabled"state.backupRetentionCountfrom 20 to 5 bundles per repo across all layers (schema, defaults, mapper, UI).backupRetentionDaysfield (default 30 days) deletes old bundles alongside count-based retention, with a safety net to always keep at least 1 bundle.FORCE_PUSH_PROTECTION.mdupdated with new defaults and backward-compat table.Test plan
backupBeforeSync: falseround-trip with direct mapper reprobackupBeforeSync: false+ no strategy →"disabled"backupBeforeSync: true+ no strategy →"on-force-push"backupStrategy→ preserved as-is"on-force-push"(default)🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.