Skip to content

pricci1/git-sift

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

31 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

git-sift

A CLI tool to automate syncing commits between git branches while filtering out experimental commits.

The Problem

Sometimes you want to track experimental or temporary changes in git without having them end up in your main codebase. Traditional solutions:

  • .gitignore - but you lose the changes entirely
  • Separate branch - but you lose the context and history with your real work

This tool lets you:

  1. Mark experimental commits with a prefix (default: remove-me:)
  2. Keep working normally on your dev branch
  3. Sync only the "real" commits to your target branch automatically

Installation

# Use directly with npx (no installation required)
npx git-sift --help

# Or install globally
npm install -g git-sift

# Or install as a dev dependency
npm install --save-dev git-sift

For development:

git clone <repo-url>
cd git-sift
bun install
bun link

Usage

Basic Workflow

  1. Work on your dev branch:
git checkout -b dev
git commit -m "feat: real feature"
git commit -m "remove-me: debug logging"
git commit -m "fix: important fix"
  1. First sync to master (use --force-checkpoint to start from beginning):
git-sift --target master --force-checkpoint
  1. Result: master gets "feat: real feature" and "fix: important fix", but not the debug logging. A checkpoint UUID is automatically added to both branches.

  2. Continue working on dev:

git checkout dev
git commit -m "feat: another feature"
git commit -m "remove-me: temporary code"
  1. Sync again (automatically picks up from last checkpoint):
git-sift --target master
  1. Result: Only the new commits since the last sync are transferred to master

⚠️ Important: Avoiding Rebase Conflicts

To prevent conflicts during sync, commits marked for removal should only modify files that are not touched by commits being kept.

For example:

  • Safe: A remove-me: commit adds debug logging to debug.js, while kept commits only modify feature.js
  • Risky: A remove-me: commit modifies utils.js, and a kept commit also modifies utils.js

When files overlap between filtered and kept commits, the cherry-pick process may encounter conflicts that require manual resolution. Structure your work to isolate experimental changes in separate files when possible.

Recommendation: Consider working on a fresh clone of your repository to avoid any risk of data loss.

Command Options

git-sift [options]

Options:

  • --target <branch> - Target branch to sync to (default: master)
  • --to-commit <hash> - Sync up to this commit (default: HEAD)
  • --tag <prefix> - Commit message prefix to filter (default: remove-me)
  • --resume - Resume after resolving conflicts
  • --force-checkpoint - Use first commit if no checkpoint found
  • --checkpoint <hash> - Use specific commit as checkpoint
  • --dry-run - Show what would be synced without making changes
  • --help - Show help

Examples

Preview what would be synced (dry run):

git-sift --dry-run
# Shows which commits would be synced and which would be filtered

Sync to main branch:

git-sift --target main

Use custom tag prefix:

# First sync with custom tag (use --force-checkpoint for first time)
git-sift --tag wip --target main --force-checkpoint
# Now commits like "wip: testing" will be filtered

# Subsequent syncs with the same tag
git-sift --tag wip --target main

Sync up to specific commit:

git-sift --to-commit abc123 --target main

Use a specific commit as checkpoint:

git-sift --checkpoint abc123 --target main

Resume after conflict:

# If sync encounters conflicts:
# 1. Resolve conflicts manually
# 2. Stage resolved files: git add <files>
# 3. Resume:
git-sift --resume

First-time sync (start from repository beginning):

# For the first sync on a repository, use --force-checkpoint
# to start from the very first commit
git-sift --target main --force-checkpoint
# After this, subsequent syncs will automatically use the checkpoint

How It Works

  1. Validation - Checks working directory is clean, you're not on target branch, and finds the checkpoint commit
  2. Analysis - Gets commits from checkpoint to current position, filters by tag prefix
  3. Transfer - Checks out target branch, cherry-picks filtered commits one by one
  4. Conflict Handling - If conflicts occur, saves state and pauses for manual resolution
  5. Finalization - Returns to dev branch and provides summary

Checkpoint System

The tool automatically manages checkpoints using git notes with random UUIDs. After each successful sync, a UUID is added as a note to the HEAD commit of both the target branch and the working branch. This UUID serves as a reference point for the next sync.

How it works:

  1. After a sync completes: A random UUID is automatically added as a git note (in the checkpoints namespace) to:

    • The HEAD commit on the target branch (e.g., master)
    • The HEAD commit on the working branch (e.g., dev)
  2. When starting a new sync: The tool:

    • Reads the UUID from the target branch's HEAD commit
    • Searches the working branch for the commit with the same UUID
    • Uses that commit as the starting point for the sync
    • Only syncs commits that come after the checkpoint

First-time usage (no checkpoint exists):

Use the --force-checkpoint flag to start syncing from the very first commit:

git-sift --target main --force-checkpoint

After the first sync completes, checkpoints are automatically managed for all future syncs.

Viewing checkpoints:

To see the checkpoint UUID on any commit:

git notes --ref=checkpoints show HEAD

When to use --force-checkpoint:

  • First time using git-sift on a repository
  • You want to re-sync the entire history
  • You need to reset the checkpoint system

Development

Install dependencies:

bun install

Run tests:

bun test

Run in dev mode:

bun run dev --help

Watch tests:

bun test --watch

Build for production:

bun run build

Test package before publishing:

bun run publish:dry

Publish to npm:

bun publish

The build process uses Bun's bundler to create a single optimized JavaScript file that includes all dependencies. The output is configured to run with Node.js (via the #!/usr/bin/env node shebang), making it compatible with npx and standard npm workflows.

Architecture

The project is organized into focused modules:

  • GitOperations - Wrapper around simple-git for all git operations (checkout, cherry-pick, commit lookup, git notes)
  • StateManager - Persists operation state to .git/git-sift-state.json for resume capability
  • CheckpointSync - Main orchestrator that runs the workflow phases
  • cli.ts - Command-line interface using Node's built-in parseArgs

Key Design Decisions

  1. Git Notes for Checkpoints - Uses git's built-in notes feature rather than tags or commit messages
  2. Stateful Resume - Saves progress to allow conflict resolution without losing context
  3. Cherry-pick Strategy - Preserves original commit metadata and allows selective syncing
  4. Zero Config - Works with sensible defaults, customizable when needed

Requirements

  • Bun runtime (tested with v1.3.1+)
  • Git repository

License

MIT

About

[AI generated] Remove commits strating with some tag

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors