b

bkp

v0.0.1tool

Standalone Odin CLI: timestamped file copies and .tgz directory backups with symlinks/hardlinks

0 stars0 forksAGPL-3.0updated 10 hours ago
Open repo

bkp

Standalone timestamped backups — files, folders, symlinks, hardlinks

License Odin Platforms Release


bkp is a small, dependency-free CLI for fast local backups. Point it at files or directories and get timestamped copies: plain files are duplicated beside the original; directories become a single .tgz (ustar + gzip) that preserves symlinks and hardlinks. Unpack with bkp -x or standard tar.

Written in Odin. Compression uses an embedded miniz (gzip level 1). No system zlib, pigz, or zip required at runtime.

Features

  • Timestamped file copiesnotes.txtnotes.txt.20260714120000 (like cp -p)
  • Directory archivesproject/project.20260714120000.tgz
  • Symlinks & hardlinks — stored correctly in the tar stream (not flattened as ZIP often is)
  • Extract modebkp -x archive.tgz [dest] restores files, dirs, and links safely
  • Parallel entities-j processes multiple top-level paths at once
  • Quiet stdout — only src -> dst lines; errors on stderr
  • Multi-arch releases — Linux amd64/arm64, macOS Apple Silicon, Windows amd64

Quick Start

Pre-built binary

Download from Releases, then:

chmod +x bkp-linux-amd64   # or the asset for your OS
./bkp-linux-amd64 notes.txt src/

Build from source

Requires Odin and a C compiler (cc / MSVC on Windows).

git clone https://github.com/macedot/bkp.git
cd bkp
make
./bkp

Usage

bkp [-j N] [-c N] <file|directory|pattern> ...
bkp -x <archive.tgz> [dest_dir]
Mode Behavior
File Copy to <path>.<timestamp>
Directory Pack to <path>.<timestamp>.tgz (ustar + gzip level 1)
-x Unpack .tgz / .tar.gz into dest_dir (default: .)
Flag Default Description
-j N CPU count Max paths to process in parallel
-c N CPU count Entry-prep workers while packing (gzip stream is serial)

No arguments prints usage and exits with code 2. Exit 1 if any path fails.

Stdout is only mapping lines:

src -> dst

Examples

# Backup a file and a tree
./bkp notes.txt src/

# Parallel jobs
./bkp -j 4 -c 8 data/*.csv project/

# Shell globs (or let bkp expand patterns)
./bkp 'logs/*.log'

# Extract
./bkp -x project.20260714120000.tgz restored/

# Compatible with system tar
tar -tzf project.20260714120000.tgz
tar -xzf project.20260714120000.tgz -C restored/

How it works

Input Output
Regular file Byte copy next to the source, suffix .<YYYYMMDDHHMMSS>
Directory Walk with lstat → ustar members (0 file, 5 dir, 2 symlink, 1 hardlink) → gzip → .tgz

Hardlinks share an inode: the first copy stores data; later names reference it. Symlinks store the link target, not the pointed-to content.

Extract rejects path traversal (.., absolute names) before writing under the destination.

Test

make test

Covers file copy, nested tree, symlink, hardlink, tar -tzf, and bkp -x.

Releases

Publishing a GitHub Release runs .github/workflows/release.yml and attaches:

Asset Platform
bkp-linux-amd64 Linux x86_64
bkp-linux-arm64 Linux ARM64
bkp-darwin-arm64 macOS Apple Silicon
bkp-windows-amd64.exe Windows x86_64

Layout

Path Role
src/ Odin sources (CLI, tar write/read, copy)
vendor/miniz.* Embedded DEFLATE / gzip
vendor/bkp_miniz_wrap.c Thin C API used from Odin
build/ Local objects / static lib (not tracked)
.github/workflows/ Multi-arch release builds

License

bkp is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).

Bundled miniz retains its own license (see vendor/MINIZ_LICENSE).

Package Info
Version
v0.0.1
License
AGPL-3.0
Author
@macedot
Type
tool
Forks
0
Created
11 hours ago
Updated
10 hours ago
Health
maintained
has releases
has readme
has license
Activity
last 56 weeks