Skip to content

Repository files navigation

Checkpoint

A Linux utility for creating, managing, and restoring timestamped snapshots of directories. Designed for developers, system administrators, and DevOps engineers who need reliable recovery points during iterative development and system configuration changes.

Overview

Checkpoint bridges the gap between informal backup practices and enterprise-grade snapshot management by providing simple commands for complex operations. Create recovery points before risky changes, track development progress through organized snapshots, and quickly restore when needed—all while maintaining security and automation compatibility.

Key Benefits

  • Development Safety: Create quick recovery points before risky code changes
  • Visual Change Tracking: Compare differences between snapshots to understand evolution
  • Flexible Recovery: Restore entire directories or specific file patterns
  • Linux-Native: Targets Bash 5.2+ with GNU coreutils (Ubuntu/Debian and similar)
  • Automation Ready: Works reliably in CI/CD pipelines and scripts
  • Non-Root Friendly: Works seamlessly for regular users with smart directory defaults

Core Features

  • Smart Snapshots: Creates timestamped backups with automatic exclusions
  • Intelligent Defaults: Automatically selects appropriate backup directories based on user privileges
  • Atomic Operations: Ensures backup integrity with temporary directories and atomic rename
  • Concurrency Protection: Lockfile mechanism prevents data corruption from parallel operations
  • Powerful Comparison: Visualizes differences between snapshots with color-coded output
  • Flexible Restoration: Supports complete or selective file recovery with preview mode
  • Space Optimization: Automatic hardlinking between versions (via rsync --link-dest) to minimize disk usage and keep incremental checkpoints sub-second
  • Backup Rotation: Manages history by count or age for automatic cleanup
  • Automation Support: Non-interactive operation with timeout safeguards
  • Smart Privilege Handling: Detects whether the backup directory is writable and advises sudo when needed (never escalates on its own)

Installation

Install

git clone https://github.com/Open-Technology-Foundation/checkpoint
cd checkpoint
sudo make install

make install places:

File Destination
checkpoint /usr/local/bin/checkpoint (mode 755)
chkpoint symlink to checkpoint in the same directory
checkpoint.1 /usr/local/share/man/man1/ (then mandb -q)
checkpoint.bash_completion /etc/bash_completion.d/checkpoint (+ chkpoint symlink)

Installation is verified automatically at the end of the run.

Make Targets

Target Action
install Install all files (default PREFIX=/usr/local)
uninstall Remove everything install created
check Verify checkpoint and chkpoint resolve in PATH
deps Report missing required commands; run automatically before install
test Run the BATS test suite
lint Run shellcheck
help List targets and variables (default target)

A bare make prints help — it never modifies the system.

Install Locations

Override any path with a standard variable:

# User-local install, no sudo
make PREFIX=~/.local COMPDIR=~/.local/share/bash-completion/completions install

# Staged install for packaging (skips PATH verification and mandb)
make DESTDIR=/tmp/pkg install
Variable Default
PREFIX /usr/local
BINDIR $(PREFIX)/bin
MANDIR $(PREFIX)/share/man/man1
COMPDIR /etc/bash_completion.d
DESTDIR (empty)

Source paths are anchored to the Makefile's own directory, so sudo make -f /path/to/checkpoint/Makefile install works from any working directory.

Manual Install (no git)

# Download script and make executable
curl -fsSL https://raw.githubusercontent.com/Open-Technology-Foundation/checkpoint/main/checkpoint -o checkpoint
chmod +x checkpoint
sudo cp checkpoint /usr/local/bin/
sudo ln -sf checkpoint /usr/local/bin/chkpoint

# Install man page
curl -fsSL https://raw.githubusercontent.com/Open-Technology-Foundation/checkpoint/main/checkpoint.1 -o checkpoint.1
sudo cp checkpoint.1 /usr/local/share/man/man1/
sudo mandb

# Install bash completion
curl -fsSL https://raw.githubusercontent.com/Open-Technology-Foundation/checkpoint/main/checkpoint.bash_completion -o checkpoint.bash_completion
sudo cp checkpoint.bash_completion /etc/bash_completion.d/checkpoint

Uninstall

sudo make uninstall

Requirements

Core Dependencies (required):

  • rsync - File synchronization
  • find - File discovery
  • stat - File metadata

Optional Dependencies:

  • delta or colordiff - Enhanced diff visualization

Quick Start

For Non-Root Users

# Create checkpoint of current directory (backs up to ~/.checkpoint/)
checkpoint

# Backup a specific directory
checkpoint ~/my-project

# Use custom backup location
checkpoint -d ~/backups/project ~/my-project

# Set default backup directory for all operations
export CHECKPOINT_BACKUP_DIR=~/my-backups
checkpoint ~/my-project

Basic Operations

# Create checkpoint of current directory
checkpoint

# Create checkpoint with descriptive name
checkpoint -s "before-refactor"

# List all checkpoints
checkpoint --list

# Restore latest checkpoint
checkpoint --restore

# Compare current files with checkpoint
checkpoint --restore --diff

Usage Examples

Development Workflow

# Before major changes
checkpoint -s "pre-api-refactor"

# Compare with previous state
checkpoint --restore --diff

# Restore if needed
checkpoint --restore --from 20250430_091429

System Administration

# Backup configuration before updates
sudo checkpoint -d /var/backups/system /etc

# Web server configuration checkpoint
checkpoint -s "ssl-optimization" /etc/nginx

# Compare configuration changes
checkpoint --from 20250430_091429 --compare-with 20250430_101530 --detailed

Selective Operations

# Restore only specific files
checkpoint --restore --files "*.js" --files "docs/*.md"

# Dry run to preview changes
checkpoint --restore --dry-run

# Custom backup location
checkpoint -d ~/backups/myproject

# Exclude specific patterns
checkpoint --exclude "node_modules/" --exclude "*.log"

Backup Management

# Automatic rotation: keep only 5 most recent
checkpoint --keep 5

# Age-based rotation: remove backups older than 30 days
checkpoint --age 30

# Prune without creating new backup
checkpoint --prune-only --keep 3

Concurrency Protection

Checkpoint includes a lockfile mechanism to prevent data corruption from concurrent operations:

# Normal operation (locking enabled by default)
checkpoint

# Disable locking (DANGEROUS - allows concurrent operations)
checkpoint --no-lock

# Set custom lock timeout (default: 300 seconds)
checkpoint --lock-timeout 60

# Force removal of stale locks
checkpoint --force-unlock

The locking mechanism:

  • Prevents multiple checkpoint instances from operating on the same backup directory
  • Automatically detects and removes stale locks from crashed processes
  • Can be disabled for special use cases (use with caution)

Command Reference

Core Options

Option Description
-d, --backup-dir DIR Custom backup location (default: context-dependent)
-s, --suffix SUF Add descriptive suffix to checkpoint name
--no-hardlink Do not hardlink to previous backup (full copy)
--hardlink Hardlink unchanged files to previous backup (default)
-q, --quiet Minimal output (just backup path)
-v, --verbose Detailed output with progress (default)
-l, --list List existing checkpoints with sizes
-x, --exclude PATTERN Additional exclusion pattern (repeatable)
--cross-mounts Recurse into mounted filesystems (default: stay on one filesystem)
-V, --version Print version and exit
-h, --help Display help

Backup Management

Option Description
-k, --keep N Keep only N most recent backups
--age DAYS Remove backups older than DAYS days
-p, --prune-only Only prune backups without creating new one
--no-sudo Hard-error on an unwritable backup dir instead of advising sudo
--no-lock Disable lockfile mechanism (DANGEROUS)
--lock-timeout N Lock acquisition timeout in seconds (default: 300)
--force-unlock Force removal of stale locks

Restore and Compare

Option Description
-r, --restore Restore from checkpoint
-f, --from ID Source checkpoint (defaults to most recent)
-t, --to DIR Target restore directory (defaults to original)
-n, --dry-run Preview changes without making them
--diff Show differences between current files and checkpoint
--compare-with ID Compare two checkpoints
--detailed Show file content differences in comparison
--files PATTERN Select specific files/patterns (repeatable)

Automation Integration

Environment Variables

# Set default backup directory for all operations
export CHECKPOINT_BACKUP_DIR=~/my-backups

# Skip interactive prompts
export CHECKPOINT_AUTO_CONFIRM=1

Note (v1.8.0): a restore into a non-empty target now refuses in a non-interactive context unless CHECKPOINT_AUTO_CONFIRM=1 is set (or --dry-run is used). This is a fail-safe: previously a non-TTY restore would silently overwrite. Scripted restores must set CHECKPOINT_AUTO_CONFIRM=1.

CI/CD Examples

# GitHub Actions / GitLab CI
- name: Create Checkpoint
  run: CHECKPOINT_AUTO_CONFIRM=1 checkpoint -s "build-${GITHUB_RUN_NUMBER}"

# Jenkins Pipeline
stage('Backup') {
    steps {
        sh 'CHECKPOINT_AUTO_CONFIRM=1 checkpoint -s "build-${BUILD_NUMBER}"'
    }
}

# Cron job for regular backups
0 2 * * * CHECKPOINT_AUTO_CONFIRM=1 /usr/local/bin/checkpoint -d /var/backups/nightly /home/user/project

Timeout Protection

All interactive prompts have built-in timeouts (auto-answer "no"/"N" on expiry):

  • Directory creation: 30 seconds
  • Restore overwrite confirmation: 30 seconds

Backup Directory Locations

Smart Directory Selection

Checkpoint intelligently selects backup directories based on your user context:

User Type Default Location Example
Root/sudo /var/backups/FULL/PATH/ /var/backups/home/user/myproject/
Regular user ~/.checkpoint/FULL/PATH/ ~/.checkpoint/home/user/myproject/
Custom $CHECKPOINT_BACKUP_DIR/FULL/PATH/ ~/backups/home/user/myproject/

The full canonical source path (with leading / stripped) is used as the subdirectory, preventing collisions when backing up different directories with the same basename.

Privilege Management

Checkpoint never runs sudo itself. It checks whether the backup directory is writable and acts accordingly:

  • Writability Detection: Determines whether the current user can write to the backup directory
  • Non-Root Friendly: Regular users can backup to any writable directory without sudo
  • Advice, Not Escalation: When the directory needs root, checkpoint exits with guidance to re-run under sudo (or pick a writable directory)
  • Explicit Control: Use --no-sudo to turn an unwritable backup directory into an immediate error instead of advising sudo
# Force non-root operation
checkpoint --no-sudo ~/myproject

# Let checkpoint decide (recommended)
checkpoint ~/myproject

Default Exclusions

These patterns are automatically excluded from all backups:

  • .gudang/, temp/, .temp/, tmp/ directories
  • Temporary files: *~ and ~*
  • The backup directory itself, when it sits inside the source tree (prevents recursion). A backup directory outside the source needs no exclusion.

Checkpoint's own working directories — .tmp.* (atomic operation temporaries) and .checkpoint.lock/ (concurrency locks) — live inside the backup directory, so the rule above covers them. They are not separately excluded: if such a directory exists in your source tree it will be snapshotted like any other file. Add --exclude '.tmp.*' if that matters to you.

Add further patterns with -x/--exclude (repeatable); they are passed straight to rsync.

Storage and Performance

Space Efficiency

With hardlinking enabled (the default), checkpoint can achieve 90%+ space savings between similar versions by sharing identical files. Because rsync --link-dest links unchanged files during the transfer, that data is never re-read or re-written: an incremental checkpoint of a 5.9 GB tree completes in under half a second. Example:

# First backup: 100MB
checkpoint -s "v1.0"

# Second backup: Only changed files use additional space
checkpoint -s "v1.1"  # Might only use 5MB additional space

Atomic Operations

Checkpoint uses atomic operations to ensure backup integrity:

  • Temporary Directory: Backups are created in a .tmp.* directory first
  • Atomic Rename: Only after all operations succeed is the backup renamed to its final name
  • Automatic Cleanup: Temporary directories are removed on interruption or failure
  • No Partial States: You'll never see incomplete or corrupted backups

This means:

  • Interrupted backups leave no trace
  • Concurrent operations are safe (with locking enabled)
  • Backup directories appear instantaneously when complete
  • Failed operations are automatically cleaned up

Performance Characteristics

  • Backup Speed: Limited by rsync performance and storage I/O
  • Comparison Speed: Byte-level file comparison (cmp) with optional pattern filtering
  • Scalability: Handles projects from small configs to large codebases
  • Memory Usage: Minimal footprint, primarily shell variables

Development

Testing

# Lint and test via the Makefile
make lint                              # shellcheck
make test                              # full suite with summary

# Or directly
shellcheck checkpoint
bcscheck checkpoint                    # BCS compliance
./run_all_tests.sh                     # all suites with summary
bats tests/*.bats                      # all suites, raw TAP

# Run individual test suites (97 tests total across 8 files)
bats tests/test_checkpoint.bats        # Core functionality (25 tests)
bats tests/test_low_findings.bats      # Low-severity + BCS review regressions (16 tests)
bats tests/test_medium_findings.bats   # Medium-severity review regressions (13 tests)
bats tests/test_high_findings.bats     # High-severity review regressions (10 tests)
bats tests/test_locking.bats           # Concurrency protection (10 tests)
bats tests/test_nonroot.bats           # Non-root user operations (9 tests)
bats tests/test_linkdest.bats          # --link-dest incremental backup path (8 tests)
bats tests/test_atomic.bats            # Atomic operations (6 tests)

# Run specific test by name
bats tests/test_checkpoint.bats -f "backup creation"

# Verbose testing
bats -v tests/test_checkpoint.bats

One test in test_nonroot.bats skips depending on the UID the suite runs under, so a clean run reports 96 passed / 1 skipped.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make changes following existing code style:
    • 2-space indentation (never tabs)
    • set -euo pipefail error handling
    • Use [[ for conditionals, (( )) for arithmetic
    • UPPER_CASE for global variables, lowercase for local variables
    • Comprehensive function documentation headers
    • BATS tests for new functionality
    • End all scripts with #fin marker
  4. Run make lint (must pass without errors)
  5. Run make test (all tests must pass)
  6. Submit pull request

Troubleshooting

Common Issues

Permission Denied: Back up to a writable directory (e.g. under $HOME), or re-run with sudo for a root-owned backup location. --no-sudo makes an unwritable target a hard error instead of advising sudo.

Insufficient Disk Space: Check available space in backup directory before large operations.

Command Not Found: Ensure all required dependencies (rsync, find, stat) are installed.

Failed to Acquire Lock: Another checkpoint process may be running. Use --force-unlock to remove stale locks from crashed processes, or wait for the other operation to complete.

Comparing with Checkpoints

# Compare with source to check differences
checkpoint --restore --diff

Security

  • Input Validation: Strict pattern matching prevents injection attacks
  • Path Protection: Prevents directory traversal attacks
  • Privilege Management: Never self-escalates; advises sudo only when the backup directory needs it

License

This project is licensed under the GPL-3.0 License - see the LICENSE file for details.

Version

Current version: 1.9.1

Recent Features

Packaging (post-1.9.1) - install.sh retired for a BCS1212 Makefile

install.sh has been removed. Installation is now sudo make install, against a Makefile conforming to BCS1212 (install/uninstall/check/test/help, PREFIX/BINDIR/MANDIR/COMPDIR/DESTDIR, install(1) throughout, and all: help so a bare make cannot modify the system).

Three behavioural differences from the retired installer:

  • No remote one-liner. curl … install.sh | bash is gone; clone the repository, or follow Manual Install for a git-free download.
  • No package-manager invocation. The installer ran apt-get/dnf/pacman/ apk/brew to pull in rsync, findutils and coreutils. The deps target only reports what is missing and the command to fix it; it never installs. It runs automatically before install.
  • Completions move to /etc/bash_completion.d (the BCS1212 default) from /usr/share/bash-completion/completions. make uninstall clears both paths, so an installation predating this change leaves nothing behind.

The script itself is unchanged, so checkpoint --version still reports 1.9.1.

v1.9.1 - Selective-pattern correctness and BCS hardening

Two behavioural fixes:

  • --compare-with --files now selects the same files as --diff --files. Checkpoint-to-checkpoint comparison still enumerated with find -path "*PATTERN*", which matches substrings of the whole path: a --files '*.js' comparison also pulled in app.json and notes.js.bak. Both viewers now share one _select_by_patterns() helper that enumerates through rsync's own filter engine using the same --include/--exclude arguments a selective restore uses, so preview and restore cannot disagree.
  • Restore file count is correct above 999 files. rsync --stats comma-groups its counts (1,500) irrespective of locale, and the parser took the last run of digits — reporting 500 for a 1500-file restore. At exactly 1000 files it parsed as 0, which additionally triggered the spurious "No files matched the requested pattern(s)" warning on a restore that had in fact moved everything.

Robustness:

  • Temporary scratch directory is now reclaimed on interrupt. The scratch directory used to enumerate --files patterns was function-local and therefore invisible to the EXIT/SIGINT cleanup trap; a signal delivered during enumeration leaked it into /tmp.

Standards compliance (no behavioural change): -- separators before all variable-derived pathname operands (BCS1005), $EPOCHSECONDS and printf '%(…)T' in place of date(1) forks (BCS1213), ||: for || true (BCS0606), and removal of ~110 comments that merely restated the following statement (BCS1202). ShellCheck-clean; 97 tests passing.

v1.9.0 - Incremental backups via rsync --link-dest

Backups are now incremental. Unchanged files are hardlinked to the previous checkpoint during the rsync transfer rather than being copied in full and deduplicated afterwards by a separate hardlink(1) content-hash pass over both trees. The old scheme made three passes over the data (a du precheck, a full copy, then a hash walk of the new and previous checkpoint); the new one makes a single pass and never re-reads or re-writes unchanged data.

Measured on a 5.9 GB / 34,337-file source:

before after
first checkpoint (no predecessor) 12.8 s 13.3 s
subsequent checkpoint (steady state) 22.9 s 0.48 s

This matters for callers on a deadline — notably pre-commit or pre-destructive-command hooks, where the old steady-state cost could exceed a 30-second budget on a large repository and abort the snapshot precisely when it was most needed.

Behavioural notes:

  • hardlink(1) is no longer a dependency. --hardlink previously failed with exit 18 if the binary was absent; it now always works, and hardlinking is enabled by default regardless of what is installed. --no-hardlink still opts out and forces full copies.
  • Linking is by rsync's quick check (size + mtime), not content hash. A file whose permissions or timestamps changed but whose contents did not will now be stored as a fresh copy where the old content-hash pass would have deduplicated it. The old pass also skipped files under 1 KB entirely, so small files are deduplicated better than before.
  • The disk-space precheck is skipped for incremental backups. A du of the whole source measures the wrong quantity when only a delta will be written (over-estimating by orders of magnitude) and costs a full recursive walk to do it. A genuine ENOSPC is still surfaced by rsync, and the atomic temp directory plus cleanup trap remove any partial backup.

v1.8.0 - Audit Remediation (58 findings)

Breaking changes (intentional, fail-safe defaults):

  • Restore refuses to overwrite non-interactively (H1): a restore into a non-empty target now dies unless CHECKPOINT_AUTO_CONFIRM=1 is set (or --dry-run is used), instead of silently overwriting on a non-TTY stdin. Scripted restores must now opt in with CHECKPOINT_AUTO_CONFIRM=1.
  • Backups stay on one filesystem by default (M2): a mount point inside the source is no longer pulled into the snapshot (rsync --one-file-system). The new --cross-mounts flag restores the old recurse-across-mounts behavior.

Locking subsystem hardened against TOCTOU races (H2, H3, H4, M5): atomic rename-then-remove reclamation, a grace window for pid-less locks being populated, cross-host pid safety (a foreign-host lock is judged by age, not a local kill -0), and release_lock no longer deletes a lock it cannot prove it owns.

Restore and preview correctness (M3, L4, L5): the --diff preview is driven by rsync's own filter engine so it always matches what restore transfers; an ambiguous --from prefix is rejected instead of silently resolving to the newest match.

Option parsing (M1, M4): bundled short options with attached arguments parse correctly (-k5-k 5); option values may begin with a dash.

Installer and tests: install.sh set -e discipline repaired (SC2155, inherit_errexit), a new --completion-dir flag, false-coverage tests removed (phantom-function and divergent-copy tests), and the whole suite is now shellcheck-clean. Suite at 87 tests; bcscheck reports 0 core-tier errors.

v1.7.8 - Messaging Refactor (BCS0703)

  • _msg redesigned: the core messaging function now takes the icon as its first argument and owns its stderr redirect, replacing FUNCNAME introspection and per-caller >&2. Output is byte-identical; this clears the remaining bcscheck recommended-tier finding on the messaging layer

v1.7.7 - BCS Refactor and Documentation Accuracy

  • _detect_diff_tool hardened (BCS0202): the diff-tool detector returns its result through explicit local -n namerefs instead of dynamic scoping into caller locals, clearing the lone bcscheck core-tier finding
  • Documentation synced to behavior: corrected the privilege-handling docs (checkpoint never self-escalates — it detects writability and advises sudo), removed a fabricated prompt timeout, refreshed the test inventory (7 suites / 74 tests), documented -k, and expanded the manpage EXIT STATUS to the full set of codes

v1.7.6 - Critical Review Low-Severity Fixes

  • Hardlinking matches its documented default: when the hardlink tool is installed it is auto-enabled (the docs always said "default if available"); --no-hardlink still opts out
  • Honest restore file counts: a restore reports the number of files rsync actually transferred (parsed from --stats), not a count of everything already in the target; a selective restore that matches nothing now warns instead of silently "succeeding"
  • Editor-backup files no longer mis-reported by diff: _should_skip now matches *~/~* as filename globs against the basename, so --diff/--compare-with stop flagging excluded editor-backup files as "only in source"
  • --list survives an unreadable checkpoint: the per-checkpoint du is guarded, so one permission-denied directory no longer aborts the whole listing under set -e
  • Disk-space check hardened: check_disk_space uses single-line POSIX df -P (a long, wrapped device name no longer mis-parses the Available column) and guards both du and df
  • Diff/compare documented as viewers: --help and the manpage now state that --diff/--compare-with always exit 0, whether or not differences are found

v1.7.5 - Critical Review Medium-Severity Fixes

  • Stale-lock recovery hardened: A lock with an empty or non-positive PID is now reclaimed instead of being treated as alive (kill -0 0 targets the caller's own process group and would otherwise block backups for up to 24h)
  • Prune and restore now lock: --prune-only and --restore acquire the backup-directory lock, so they no longer race a concurrent backup (which could delete a checkpoint mid-restore or mid-hardlink)
  • Dotfile-only restore targets confirmed: The overwrite confirmation now detects hidden-file-only targets (.git, .env, …) instead of treating them as empty and silently overwriting
  • Manpage corrected: Fixed the false .gudang default-storage claim in DESCRIPTION and synced the manpage version with the script

v1.7.4 - Critical Review Security and Data-Safety Fixes

  • Lock arithmetic injection fixed: Lock PID/timestamp files are now read as strings and integer-validated before use, instead of being assigned to declare -i variables (which arithmetic-evaluate — and thus execute — embedded command substitutions)
  • Quiet mode no longer skips restore confirmation: The overwrite-confirmation safety gate now runs regardless of -q; only its informational output is suppressed
  • Checkpoint-ID path traversal blocked: --from/--compare-with reject ids containing path separators or .., and resolution is constrained to real TIMESTAMP_PATTERN checkpoints (never .tmp.* or the lock dir)
  • Selective restore descends into subdirectories: --files 'docs/*.md' now restores matching files in nested directories (added --include=*/)
  • Timestamp collisions no longer corrupt backups: A same-second/reused-suffix name now gets a unique -N suffix and mv -T is used, instead of silently nesting the new backup inside the existing checkpoint and reporting stale data as success
  • Lock read no longer crashes on a missing timestamp file: The timestamp read is guarded so a partial lock no longer aborts the script under errexit
  • Restore/compare no longer abort via SIGPIPE: Checkpoint resolution uses mapfile instead of find | sort -r | head, which could make sort die on a closed pipe with large checkpoint counts

v1.7.1 - BCS Compliance and Bug Fixes

  • UPPER_CASE globals: All 23 global configuration variables renamed to UPPER_CASE convention for clear distinction from local variables
  • Stream separation: Status messages now routed to stderr via messaging functions; only data output (backup paths, list output) goes to stdout
  • New success() function: Completes the messaging system (info, success, warn, error)
  • Bug fix: Fixed backup_timestamp unreachable guard in prune_backups() under inherit_errexit
  • Performance: Replaced 6 external basename calls with ${var##*/} parameter expansion
  • Arithmetic fix: Replaced -gt in [[ ]] with (( )) for BCS0501 compliance

v1.7.0 - Simplification

  • Removed unused features: Removed --debug, --verify, --metadata, and --remote options
  • Reduced codebase: Cut ~970 lines of unused code for easier maintenance
  • Simplified CLI: Fewer options, clearer purpose

v1.6.1 - Documentation and Tooling

  • Comprehensive manpage: Full Unix manpage with all 35+ options documented
  • Enhanced bash completion: Dynamic checkpoint ID completion for restore/compare operations
  • Script documentation: All scripts updated with headers, usage docs, and #fin markers
  • Installer improvements: Now installs manpage and bash completion automatically
  • Fixed test scripts: Corrected corrupted shebangs and BCS compliance issues

v1.6.0 - Code Quality and Standards Compliance

  • Full BASH-CODING-STANDARD.md compliance: Refactored entire codebase to meet strict coding standards
  • Enhanced messaging system: New standardized output functions with visual indicators (✓ for success, ✗ for errors)
  • Improved variable handling: Proper type declarations for all variables (integers, arrays, strings)
  • Better error handling: Consistent error codes and messaging throughout
  • Verification improvements: Fixed file exclusion handling during backup verification
  • Code modernization: Updated arithmetic operations, fixed shellcheck warnings, improved quoting

v1.5.0 - Atomic Operations

  • Implemented atomic backup operations using temporary directories
  • Added automatic cleanup of interrupted operations
  • Ensured backup integrity with atomic rename after completion
  • Applied atomic pattern to both local and remote operations

v1.4.0 - Concurrency Protection

  • Added lockfile mechanism to prevent concurrent operations
  • Implemented PID-based lock ownership verification
  • Added stale lock detection and automatic cleanup
  • Introduced --no-lock, --lock-timeout, and --force-unlock options

For detailed version history, see the commit log or check checkpoint --version.

About

A simple, reliable utility for creating codebase snapshots (checkpoints) during development.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages