git-dup

May 4, 2026 · View on GitHub

Checkpoint a git subdirectory before handing it to an AI coding agent. Committed files plus all untracked/ignored files land in a timestamped sibling directory. The repo is never touched.

git-dup ./my-app
# → ../my-app-1746300000

The problem

LLM coding agents (Claude Code, OpenCode, Cursor, Aider, etc.) don't have a "regenerate" button. When one makes a mess of your codebase, the options are git checkout, manual undo, or hoping the agent's built-in revert works. None of those are great when:

  • The agent ran against a subdirectory of a monorepo
  • You had untracked files (build output, local data, node_modules) that aren't in git
  • The agent's built-in revert didn't fire or you're not using the built-in at all

git-dup gives you a complete before-snapshot in one command. If the agent's run goes wrong, the clean copy is already sitting one directory up.

Install

curl -fsSL https://raw.githubusercontent.com/yuis-ice/git-dup/main/git-dup -o ~/.local/bin/git-dup
chmod +x ~/.local/bin/git-dup

Or clone and symlink:

git clone https://github.com/yuis-ice/git-dup
ln -s "$PWD/git-dup/git-dup" ~/.local/bin/git-dup

Usage

git-dup <path> [options]

Options

FlagDefaultDescription
--commit <hash>HEADWhich commit to snapshot
--suffix <string>unix timestampSuffix on the new directory name
--no-ignoredfalseSkip untracked/ignored files (committed state only)
--progressfalseVerbose output
--dry-runShow what would happen, do nothing

Typical agentic workflow

# 1. Snapshot before the agent run
git-dup ./my-app

# 2. Let the agent do its thing
claude --dir ./my-app "refactor the auth module"

# 3. Agent made a mess — restore from snapshot
cp -r ../my-app-1746300000 ./my-app-recovered

Other examples

# Named checkpoint instead of a timestamp
git-dup ./my-app --suffix before-auth-refactor

# Committed state only (skip node_modules, build output, etc.)
git-dup ./my-app --no-ignored

# From a specific past commit
git-dup ./my-app --commit abc1234

# Dry run to see paths before committing
git-dup ./my-app --dry-run --progress

How it works

Two steps:

  1. git archive <commit>:<subpath> extracts the committed file tree — no .git directory, no working-tree modifications.
  2. git ls-files -z --others --exclude-standard --directory | rsync ... copies untracked and ignored files (node_modules, build artifacts, local data, .env, etc.) on top.

The original directory and git history are left completely alone.

Why not just cp -r?

cp -r copies everything including .git, which creates a broken nested repo. It also doesn't let you snapshot a past commit easily. git-dup is purpose-built for subdirectory snapshots.

Requirements

  • bash
  • git
  • rsync

Contributing

See CONTRIBUTING.md.

License

Apache 2.0 — see LICENSE.