Simplify git subtree management through declarative configuration with safe file extraction and validation capabilities.
- Declarative Configuration - Manage subtrees through a simple
subtree.yamlfile instead of remembering complex git commands - Atomic Operations - All subtree changes include configuration updates in single commits for perfect consistency
- Safe File Management - Extract files from subtrees with smart overwrite protection and validation
- Developer Experience - Intuitive CLI with clear error messages, dry-run modes, and helpful guidance
Note
Subtree CLI wraps git subtree with enhanced safety and convenience - your existing git history remains unchanged.
Important
You must be inside a Git repository to use Subtree CLI. The tool will not initialize repositories for you.
- Swift 6.0+ toolchain
- macOS 13+ or Linux (glibc 2.27+)
- Git installed and available on PATH
Add the following to your Package.swift dependencies:
dependencies: [ .package(url: "https://github.com/21-DOT-DEV/subtree.git", from: "1.0.0") ]Download pre-built binaries from GitHub Releases:
-
Download the appropriate binary for your platform:
subtree_1.0.0_macOS_arm64(Apple Silicon)subtree_1.0.0_macOS_x86_64(Intel Mac)subtree_1.0.0_linux_x86_64(Linux)subtree_1.0.0_linux_arm64(Linux ARM)
-
Make executable and add to PATH:
chmod +x subtree_1.0.0_macOS_arm64 mv subtree_1.0.0_macOS_arm64 /usr/local/bin/subtree
Use the artifact bundle for Swift Package Manager integration:
dependencies: [ .binaryTarget( name: "subtree", url: "https://github.com/21-DOT-DEV/subtree/releases/download/1.0.0/subtree.artifactbundle.zip", checksum: "..." ) ]git clone https://github.com/21-DOT-DEV/subtree.git cd subtree swift build -c release ./.build/release/subtree --helpCreate your first subtree.yaml configuration:
# Create minimal config in your git repository subtree init # π― Interactive setup with step-by-step guidance (TTY only) subtree init --interactiveTip
Start with --interactive mode to get familiar with the configuration format!
Add configured subtrees to your repository:
# Add a single subtree by name subtree add --name example-lib # Add with explicit overrides subtree add --name libfoo \ --remote https://github.com/example/libfoo.git \ --prefix Vendor/libfoo \ --ref main \ --no-squash # Add all configured subtrees subtree add --allManage subtree updates with various strategies:
# Report pending updates (no changes, exit 5 if updates available) subtree update # Apply updates (one commit per subtree on topic branch) subtree update --commit # Single commit with all updates on current branch subtree update --commit --single-commit --on-current # Dry run to preview changes subtree update --dry-run# Remove a configured subtree subtree remove --name example-libCopy files from subtrees to your repository:
Warning
Extract operations respect Git's tracking status - tracked files are protected unless you use --force.
# Ad-hoc file extraction with glob patterns subtree extract --name example-lib --from "docs/**/*.md" --to Docs/ # Multi-pattern extraction (009) - extract from multiple directories at once subtree extract --name mylib \ --from "include/**/*.h" \ --from "src/**/*.c" \ --to vendor/ # Multi-destination extraction (012) - fan-out to multiple locations subtree extract --name mylib \ --from "**/*.h" \ --to Lib/include/ \ --to Vendor/headers/ # Combined: multi-pattern + multi-destination (cartesian product) subtree extract --name mylib \ --from "*.h" --from "*.c" \ --to Lib/ --to Vendor/ # Brace expansion (011) - compact patterns with {alternatives} subtree extract --name mylib --from "*.{h,c,cpp}" --to Sources/ subtree extract --name mylib --from "{src,test}/*.swift" --to Sources/ # Brace expansion with embedded path separators (different directory depths) subtree extract --name crypto-lib \ --from "Sources/{PrettyBytes,SecureBytes,BoringSSL/RNG}.swift" \ --to Crypto/ # With exclusions (applies to all patterns) subtree extract --name mylib --from "src/**/*.c" --to Sources/ --exclude "**/test/**" # Save multi-destination mapping for future use subtree extract --name mylib --from "**/*.h" --to Lib/ --to Vendor/ --persist # Execute saved mappings from subtree.yaml subtree extract --name example-lib subtree extract --allRemove previously extracted files with checksum validation:
# Clean specific files (validates checksums before deletion) subtree extract --clean --name mylib --from "src/**/*.c" --to Sources/ # Clean from multiple destinations (012) subtree extract --clean --name mylib --from "**/*.h" --to Lib/ --to Vendor/ # Clean all saved mappings for a subtree subtree extract --clean --name mylib # Clean all mappings for all subtrees subtree extract --clean --all # Force clean modified files (skips checksum validation) subtree extract --clean --force --name mylib --from "*.c" --to Sources/Verify subtree integrity and synchronization:
# Offline validation against commit hash subtree validate # Validate specific subtree with pattern subtree validate --name example-lib --from "**/*.md" # Repair discrepancies subtree validate --repair # Include remote divergence check subtree validate --with-remote-
init- Initializesubtree.yamlconfiguration--import- Scan for existing git subtrees--interactive- Guided setup (TTY only)--force- Overwrite existing configuration
-
add- Add configured subtrees--name <name>- Add specific subtree--all- Add all configured subtrees- Override flags:
--remote,--prefix,--ref,--no-squash
-
update- Update subtrees with various strategies--name <name>- Update specific subtree--all- Update all subtrees--commit- Apply updates (default: report only)--mode <branch|tag|release>- Update strategy--branch <name>- Custom topic branch name--single-commit- Squash all updates into one commit--on-current- Apply updates to current branch--dry-run- Preview changes without applying--force- Override safety checks
-
remove- Remove configured subtrees--name <name>- Remove specific subtree
-
extract- Copy or clean files from subtrees--name <name>- Extract from specific subtree--from <pattern>- Source glob pattern (repeatable for multi-pattern)--to <path>- Destination path--exclude <pattern>- Exclude pattern (repeatable)--all- Execute all saved mappings--persist- Save mapping to subtree.yaml--force- Overwrite git-tracked files / force delete modified files--clean- Remove extracted files (validates checksums first)- Multi-destination: Use
--tomultiple times for fan-out extraction
-
validate- Verify subtree integrity--name <name>- Validate specific subtree--from <pattern>- Validate specific files--repair- Fix discrepancies--with-remote- Include remote comparison
- 0 - Success
- 1 - General error
- 2 - Invalid usage or configuration
- 3 - Git operation failure or not in Git repository
- 4 - Configuration file not found
- 5 - Updates available (report mode only)
subtree.yaml schema:
subtrees: - name: example-lib # Unique identifier remote: https://github.com/example/lib.git prefix: Sources/ThirdParty/ExampleLib branch: main squash: true # Default: true commit: 0123456789abcdef... # Latest known commit extractions: # File extraction mappings # Single pattern, single destination (legacy format) - from: "docs/**/*.md" to: Docs/ # Multi-pattern (009) - union extraction - from: - "include/**/*.h" - "src/**/*.c" to: vendor/ exclude: - "**/test/**" # Multi-destination (012) - fan-out to multiple locations - from: "**/*.h" to: - Lib/include/ - Vendor/headers/ # Combined: multi-pattern + multi-destination - from: - "*.h" - "*.c" to: - Lib/ - Vendor/| Platform | Architecture | Minimum Version | Status |
|---|---|---|---|
| macOS | arm64, x86_64 | 13.0+ | β Supported |
| Linux | x86_64, arm64 | glibc 2.27+ | β Supported |
| Windows | x86_64, arm64 | Windows 10+ | Future |
Dependencies:
- Swift 6.0+ toolchain
- Git (any recent version)
- ArgumentParser 1.6.1
- Yams 6.1.0
- swift-subprocess 0.1.0+
- SemanticVersion 0.5.1
We welcome contributions! Please see our Contributing Guidelines for details.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Run tests:
swift test - Make your changes following our coding standards
- Add tests for new functionality
- Submit a pull request
git clone https://github.com/21-DOT-DEV/subtree.git cd subtree swift build swift testThis project is licensed under the MIT License - see the LICENSE file for details.