Ubuntu Suomen keskustelualueet

Ubuntun käyttö => Ohjelmointi, palvelimet ja muu edistyneempi käyttö => Aiheen aloitti: Sami Lehtinen - 11.11.26 - klo:16.34

Otsikko: Vcopy (versioning copy)
Kirjoitti: Sami Lehtinen - 11.11.26 - klo:16.34
Vcopy (versioning copy) - Paljon on ollut keskustelua ei-teknisten käyttäjien kesken siitä, miten hankalaksi versioitu kopiointi esimerkiksi ulkoiselle medialle tai verkkojaolle on tehty, tai että palautus vaatii jonkinlaista kikkailua. Tässä Vcopyn viimeisin dokumentaatio. Ohjelma on vielä alfa-vaiheessa, mutta siksi otankin palautetta dokumentaation perusteella. Ohjelma toimii tällä hetkellä dokumentaation mukaisesti, mutta en ole julkaissut sitä, vaan olen jakanut sen vain muutamalle (hikiselle) nörtille.

Jos joku jaksaa lukea ja tulee palautetta mieleen, saa laittaa tulemaan. Laitan jakoon, kun tuntuu, että suunnitelma on oikea ja ohjelma on testattu kattavasti erilaisilla testitapauksilla virtuaalikoneissa.

Toki ohjelmat kuten Borg, Restic, Duplicati ym. toimivat. Mutta palautus niiden avulla ei aina ole niin selkeää tai suoraviivaista.

VCOPY(1)                         User Commands                        VCOPY(1)

NAME
       vcopy - directly browseable, zero-link, multi-platform backup and sync
               tool with historical versioning

SYNOPSIS
       vcopy [OPTIONS] [SOURCES... DEST] [COMMAND]
       vcopy manual [--markdown]
       vcopy --manual | --manual-markdown

DESCRIPTION
       vcopy is a zero-dependency, static CLI backup and filesystem
       synchronization tool written in pure Rust. It creates directly
       browseable, uncompressed filesystem mirrors on external drives and
       non-snapshotting filesystems (exFAT, FAT32, NTFS, ext4, APFS) while
       preserving a full point-in-time historical change record.

       The binary embeds its complete documentation in both plain text and
       Markdown formats, allowing complete standalone operation without
       external documentation files or packages.

QUICK START & SIMPLE EXAMPLES
       Usage first! The following examples demonstrate common backup tasks:

   1. Basic Single Directory Backup
       Syncs /home/user/documents into /mnt/usb/backup:

           $ vcopy /home/user/documents /mnt/usb/backup

       Live files are directly browseable at /mnt/usb/backup/documents/ as
       regular, uncompressed files. Historical snapshots are archived under
       .version-history/.

   2. Multiple Sources
       Pass multiple source directories or files positionally or with the
       -s / --sources flag:

       Positional syntax (destination is always the final argument):
           $ vcopy /home/user/docs /home/user/photos /home/user/music /mnt/usb/backup

       In the destination mirror, distinct top-level source folders are kept:
           /mnt/usb/backup/
           |-- docs/
           |-- photos/
           `-- music/

       Using explicit -s / --sources and -d / --dest flags:
           $ vcopy -s /home/user/docs -s /home/user/photos -d /mnt/usb/backup

       Reading source paths from files, wildcards, or stdin (-f / --paths-from):
           # Read paths from a list file (one per line, # for comments)
           $ vcopy -f project_paths.txt -d /mnt/usb/backup

           # Read paths matching file glob patterns
           $ vcopy -f "backups_*.txt" -d /mnt/usb/backup

           # Pipe paths directly from find via standard input ('-')
           $ find /home/user/code -name "*.rs" | vcopy -f - -d /mnt/usb/backup

   3. Numbered Versions in a Flat Directory (--flatten)
       When you want all files in a single flat directory without nested
       subfolders (ideal for flat USB drives, camera card ingests, or single-
       folder cloud buckets), use --flatten.

       Every file is placed directly in the destination root. Historical
       revisions receive monotonic numbered version suffixes (.v0, .v1, ...):

           $ vcopy --flatten /home/user/docs /home/user/photos /mnt/usb/backup

       Destination layout with numbered versions:
           /mnt/usb/backup/
           |-- report.pdf                     # Current live version (latest)
           |-- report.v0.pdf                  # Oldest historical version (v0)
           |-- report.v1.pdf                  # Second historical version (v1)
           |-- photo.jpg                      # Current live photo
           |-- photo.v0.jpg                   # Prior version of photo
           |-- notes_from_docs.txt            # Stem collision disambiguated
           |-- notes_from_photos.txt          # Stem collision disambiguated
           |-- notes_from_photos.v0.txt       # Historical version of notes
           |-- .version-history.lock          # Advisory concurrency lock
           |-- .version-history.baseline.json # Live state manifest & checksums
           `-- .version-history.manifest.jsonl# Append-only snapshot ledger

   4. Zero-Obfuscation Configuration Files (-c / --config)
       No separate manual or syntax to learn! A configuration file uses the
       exact same command-line flags and parameters you type in the terminal:

           $ vcopy -c backup.conf

       Direct CLI arguments format (backup.conf):
           # backup.conf - exact same flags as the command line!
           --sources /home/user/documents
           --sources /home/user/photos
           --dest /mnt/usb/backup
           --flatten
           --preserve-permissions
           --keep-daily 7
           --keep-weekly 4

       Simple key-value format (backup.conf):
           dest = /mnt/usb/backup
           sources = /home/user/documents, /home/user/photos
           flatten = true
           preserve-permissions = true
           keep-daily = 7
           keep-weekly = 4

       TOML format (backup.toml):
           dest = "/mnt/usb/backup"
           sources = ["/home/user/documents", "/home/user/photos"]
           flatten = true
           preserve-permissions = true
           keep-daily = 7
           keep-weekly = 4

   5. Listing Snapshots
       View historical snapshots, transfer metrics, and file change counts:

           $ vcopy list /mnt/usb/backup

       Output:
           Snapshot                   Copied     Modified   Deleted    Transferred   
           ---------------------------------------------------------------------------
           2026-11-09_083000          142        0          0          12491024 bytes
           2026-11-09_091500          3          12         1          452010 bytes   
           2026-11-09_100000 (live)   0          0          0          0 bytes       

   6. Point-in-Time Restore
       Restore files to an exact prior snapshot or the latest mirror:

           # Restore latest live mirror
           $ vcopy restore /mnt/usb/backup /tmp/restored

           # Restore files as they existed at a specific snapshot timestamp
           $ vcopy restore --target-time 2026-11-09_083000 /mnt/usb/backup /tmp/restored

           # Restore with POSIX permissions and Windows readonly attributes
           $ vcopy restore -p --target-time 2026-11-09_083000 /mnt/usb/backup /tmp/restored

   7. Retention & Snapshot Pruning
       Prune old snapshots using count limits or GFS schedules:

           # Retain only the newest 5 snapshots
           $ vcopy prune -n 5 /mnt/usb/backup

           # Retain 24 hourly, 7 daily, 4 weekly, 12 monthly, and 1 yearly snapshots
           $ vcopy prune --keep-hourly 24 --keep-daily 7 --keep-weekly 4 /mnt/usb/backup

           # Dry run: preview which snapshots would be deleted without writing
           $ vcopy prune -n 5 --dry-run -v /mnt/usb/backup

OPTIONS
   Core Options:
       -s, --sources <PATH>
              Explicit source directory or file. Can be specified multiple
              times or comma-separated. Alias: --source.

       -d, --dest <PATH>
              Destination backup directory. Overrides positional destination.
              Alias: --destination.

       -f, --paths-from <PATTERN_OR_STDIN>
              Read source paths from a text file, glob pattern (e.g. backups*),
              or stdin ('-'). Can be specified multiple times.
              Aliases: --files-from, --sources-from.

       -c, --config <FILE>
              Path to configuration file. Accepts direct CLI arguments format,
              plain key-value, TOML, or JSON.

       --flatten
              Single-directory flat mode: stores all live and historical files
              directly in destination root using .v0, .v1 version numbers.

       -p, --preserve-permissions
              Record POSIX mode bits (Unix) and readonly attributes (Windows)
              in manifests and restore them on compatible filesystems.

       --dry-run
              Simulate execution and display planned operations without
              modifying the filesystem.

       -v, --verbose
              Enable detailed output listing every copied, modified, and
              deleted file.

       --target-time <TIMESTAMP>
              Target snapshot timestamp (YYYY-MM-DD_HHMMSS or prefix) or
              'latest' for restore.

       --manual, --man
              Print this complete user manual in ASCII / man-page format.

       --manual-markdown, --manual-md, --markdown
              Print this complete user manual in Markdown format.

   Retention Policy Options (GFS & Count):
       -n, --max-versions <N>
              Retain only the newest N snapshots (overrides GFS).

       --keep-hourly <N>
              Number of hourly snapshot buckets to retain (default: 24).

       --keep-daily <N>
              Number of daily snapshot buckets to retain (default: 7).

       --keep-weekly <N>
              Number of weekly snapshot buckets to retain (default: 4).

       --keep-monthly <N>
              Number of monthly snapshot buckets to retain (default: 12).

       --keep-yearly <N>
              Number of yearly snapshot buckets to retain (default: 1).

SUBCOMMANDS
       auto   (Default when no subcommand is given)
              Create backup snapshot and automatically prune old versions.

       create
              Create a new backup snapshot without running retention pruning.

       restore
              Restore files from destination to a target directory.

       list   List all snapshots in destination with summary statistics.

       prune  Manually prune snapshots according to retention rules.

       manual
              Display the user manual. Add --markdown for Markdown output.

STORAGE MODES
   1. Hierarchical Snapshot Mode (Default)
       The live mirror is stored in <dest>/ exactly matching the source.
       When a file changes, the older version is displaced into a timestamped
       directory under .version-history/<YYYY-MM-DD_HHMMSS>/.

   2. Single-Directory Flat Mode (--flatten)
       All files are kept in the destination root folder:
       - Numbered versions: <stem>.v0.<ext>, <stem>.v1.<ext>, ...
       - Collision disambiguation: <stem>_from_<source>.<ext>
       - Metadata: .version-history.baseline.json,
                   .version-history.manifest.jsonl,
                   .version-history.lock
       - Automatic orphan scan recovery if metadata files are missing.

SYSTEM INVARIANTS & SAFETY GUARANTEES
       1. Zero Links: Never creates or follows hardlinks, symlinks, or block
          reflinks. Destination mirrors are 100% portable across FAT32, exFAT,
          NTFS, ext4, and cloud drives.
       2. Directly Browseable: All live files and historical versions are raw,
          uncompressed files readable directly in standard OS file managers.
       3. Atomic Staging Writes: Writes to .<file>.tmp.<pid>.<id> and atomically
          renames into place to avoid partial file corruption.
       4. Nanosecond Timestamps & SIMD CRC32: Preserves nanosecond modification
          timestamps and CRC32 checksums to eliminate FAT/exFAT 2s drift.
       5. Reverse-Delta Pruning Consolidation: Pruning intermediate snapshots
          migrates displaced files into the preceding kept snapshot before
          removal, preventing data loss across restore points.
       6. Resilient Advisory Locking: Non-blocking .lock with PID file fallback.

EXIT STATUS
       0      Success.
       1      Fatal error (e.g. invalid arguments, path collision, I/O error).

AUTHORS & LICENSE
       Written by Sami Lehtinen <noreply@sami-lehtinen.net>.
       Licensed under the Zero-Clause BSD (0BSD) License.
       Repository: https://github.com/samilehtinen/vcopy