-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Currently, every gib backup run generates a brand new file tree, fully reflecting the current state of the filesystem — including deletions.
This is correct for full snapshots, but it limits an important use case:
incremental backups that inherit the tree of a previous backup, preserving historical files even if they were deleted locally.
We should support creating a backup that extends a previous one instead of redefining the tree from scratch.
Proposal
Introduce a new flag:
--parent [backup_hash]
This flag tells gib backup to inherit the file tree from another backup, identified by its hash.
Behavior
- Non-interactive usage (string value)
gib backup --parent <backup_hash>
The new backup inherits the tree from the parent backup.
The filesystem is scanned normally, but:
New files are added
Modified files are updated
Deleted local files are NOT removed from the tree
The resulting backup behaves like an incremental extension of the parent.
This must work normally in JSON an interactive modes.
- Interactive usage (boolean flag)
gib backup --parent
When --parent is passed without a value:
In interactive mode, show a selector:
Displays previous backups (hash + message)
User selects one as the parent
In JSON mode, this must error (see below).
- JSON mode validation (important)
If JSON mode is enabled:
gib backup --mode json --parent
➡️ This must error, because there is no way to prompt the user.
Suggested error message:
--parent requires a backup hash when used in JSON mode
However, this must be valid:
gib backup --json --parent abcd1234
Tree inheritance semantics (core concept)
When --parent is used, the new backup:
Starts with the exact tree of the parent backup
Applies only:
New files found on disk
Content changes to existing files
Never removes entries from the inherited tree, even if:
Files were deleted locally
Directories no longer exist on disk
In other words:
--parent disables deletion semantics and makes the backup purely additive + mutative.
Example
Backup 1 (initial)
Filesystem at time T1:
a.txt
b.txt
gib backup
➡️ Backup 1 tree:
a.txt
b.txt
Filesystem changes
At time T2:
a.txt deleted
b.txt deleted
c.txt created
Backup 2 with parent
gib backup --parent <hash_of_backup_1>
➡️ Backup 2 tree becomes:
a.txt (inherited)
b.txt (inherited)
c.txt (new)
a.txt and b.txt remain accessible via restore
No deletions are recorded
Storage efficiency is preserved via deduplication (already implemented)
Why this matters
Enables true incremental backups
Prevents accidental loss of historical files
Works perfectly with chunk-level deduplication
Keeps restore semantics flexible (especially with --only)
Summary of rules
--parent → valid in all modes
--parent (boolean):
✅ interactive mode → prompt user to select parent backup
❌ JSON mode → error
Using --parent:
Inherits full tree from parent
Applies only additions and modifications
Never removes files from the tree
Always update the refcount of each chunk in the parent tree by increment 1 (for new and inherited chunks)