Skip to content

DazzleTools/xormove

Repository files navigation

xormove

C++17 CMake 3.20+ vcpkg License: MIT GitHub release CI GitHub Discussions

Windows Linux macOS

Swap files between near-full disks without requiring temporary space.

Binary name: xmv (short for "xor-move")

The Problem

You have two disks, both nearly full. You want to move one file to the other disk, but need to keep all the files and can't delete anything. So you want to somehow swap a file from Disk2 to Disk1 and vice versa, but there is not enough space.

Disk1: FileA (10GB)     Disk2: FileB (8GB)
       Free: 2GB               Free: 3GB

Traditional copy fails - neither disk has enough free space to hold the other's file as a temporary copy.

The Solution

xormove uses the XOR swap algorithm to exchange file contents in-place, chunk by chunk:

A XOR B XOR A = B
A XOR B XOR B = A

By streaming chunks and XORing them together, xormove swaps the contents without needing extra disk space beyond a small buffer.

Features

  • Space-efficient: Only needs buffer space, not full file size
  • Integrity verification: Optional SHA-256 hash verification
  • Progress display: Track swap progress for large files
  • Cross-platform: Windows, Linux, macOS, BSD
  • Safe by default: Uses temp files with atomic rename

Installation

Download Pre-built Binaries (Recommended)

Download the latest release for your platform from the Releases page:

Platform Binary
Windows (x64) xmv-windows-x64.exe
Linux (x64) xmv-linux-x64
macOS (ARM64) xmv-macos-arm64

Place the binary somewhere in your PATH (e.g., C:\Windows on Windows, /usr/local/bin on Linux/macOS).

Build from Source

If you prefer to build from source:

Prerequisites:

Quick build:

# Windows
scripts\build-windows.cmd

# Linux/macOS
./scripts/build-unix.sh

For detailed build instructions, see the Building Guide.

Usage

# Basic file swap
xmv /path/to/fileA /path/to/fileB

# With integrity verification
xmv fileA fileB --verify

# With progress display
xmv fileA fileB --progress

# Preview without making changes
xmv fileA fileB --dry-run

# Verbose output with logging
xmv fileA fileB --verbose --log swap.log

# Secure mode (larger chunks, more thorough)
xmv fileA fileB --secure --verify

Path Preservation

xmv intelligently handles file destinations based on whether files are on the same or different drives:

Cross-drive swaps (default: REL) - Files move to the other drive, preserving their relative path:

xmv C:\backup\large.bin D:\archive\small.iso
# Result:
#   D:\backup\large.bin   (moved from C:, keeps relative path)
#   C:\archive\small.iso  (moved from D:, keeps relative path)

Same-drive swaps - Files swap locations via atomic renames (O(1) performance):

# Different folders: files swap to each other's directory
xmv C:\backup\fileA.txt C:\archive\fileB.txt
# Result:
#   C:\archive\fileA.txt  (A moved to B's folder)
#   C:\backup\fileB.txt   (B moved to A's folder)

# Same folder: files swap names
xmv C:\backup\fileA.txt C:\backup\fileB.txt
# Result:
#   C:\backup\fileA.txt   (now contains what was in fileB)
#   C:\backup\fileB.txt   (now contains what was in fileA)

Custom destinations - Override defaults with --1-to and --2-to:

# Move file1 to a specific folder
xmv C:\backup\large.bin D:\archive\small.iso --1-to D:\staging --yes mkdir

# Use the other file's folder structure
xmv C:\backup\fileA.txt D:\isos\fileB.txt --1-to SAME-AS-2 --2-to SAME-AS-1

Path Keywords

Keyword Description
REL Preserve relative path on target drive (default for cross-drive)
SAME Keep file at original location (swap contents only)
SAME-AS-1 Use file 1's folder structure
SAME-AS-2 Use file 2's folder structure
/path Explicit destination path

Auto-confirmation

Flag Description
--yes Auto-confirm safe actions (mkdir)
--yes mkdir Auto-create directories
--yes overwrite Auto-overwrite existing files
--yes all Auto-confirm all prompts

Options

Option Description
--secure Use larger chunk size (1MB vs 4KB)
--fast Minimal checking for speed
--verify SHA-256 verification after swap
--dry-run Preview operation without making changes
--verbose, -vb Detailed output
--log FILE Write to log file
--progress Display progress bar
--1-to DEST Destination for file 1 (see Path Preservation)
--2-to DEST Destination for file 2 (see Path Preservation)
--yes [ACTION] Auto-confirm prompts (mkdir, overwrite, all)

How It Works

  1. Pre-flight checks: Verify both files exist, check disk space
  2. Chunk streaming: Read matching chunks from both files
  3. XOR transformation: Apply XOR to swap chunk contents
  4. Safe write: Write to temporary files first
  5. Atomic swap: Rename temp files to final destinations
  6. Verification (optional): Hash check to confirm integrity

Use Cases

  • Embedded systems: Limited storage devices
  • Thumb drives: Reorganizing files on small USB drives
  • Archive management: Swapping large backup files
  • Disk cleanup: Moving files when space is tight

Dependencies

Managed via vcpkg:

  • Boost.Filesystem
  • Boost.Algorithm
  • Crypto++ (for SHA-256)
  • argparse

Development

Project Structure

xormove/
├── CMakeLists.txt      # Build configuration
├── vcpkg.json          # Dependency manifest
├── src/
│   └── xormove.cpp     # Main source
├── scripts/
│   ├── build-windows.cmd
│   └── build-unix.sh
└── tests/              # Test files

Building for Development

# Debug build
./scripts/build-unix.sh --debug

# Clean rebuild
./scripts/build-unix.sh --clean --debug

Contributions

Contributions are welcome! Please read our Contributing Guide for details.

Like the project?

"Buy Me A Coffee"

Acknowledgements

Part of the DazzleTools collection.

License

xormove, Copyright (C) 2025 Dustin Darcy (@djdarcy)

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

About

Swap files between disks using XOR operations - works even when disks are near full

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Sponsor this project

  •  

Packages

 
 
 

Contributors