gitcrumbs


Namegitcrumbs JSON
Version 0.1.1 PyPI version JSON
download
home_pageNone
SummaryTrack durable working-tree states for Git repos: snapshot, diff, restore, and auto-track stable changes.
upload_time2025-10-19 10:04:31
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT
keywords git cli developer-tools productivity snapshots version-control
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # gitcrumbs

_A tiny CLI tool that captures **durable working states** of your Git repo._  
It makes a snapshot **only when changes persist** (e.g., after you pause to test, or step away), and lets you **list**, **diff**, and **restore** those states without interfering with Git.

- **Zero friction**: works with your existing Git workflow.  
- **Lightweight**: uses Git’s object store and a small SQLite DB under `.git/gitcrumbs/`.  
- **Safe**: won’t change commits or refs.

---

## Why would I want this?

Sometimes you tweak code, run tests, tweak again… and only some of those transient edits “stick.” `gitcrumbs` records **stable** working trees so you can jump back to the exact files you had when something actually worked, even if you never committed.

Think of it as **temporary but reliable breadcrumbs** between commits.

---

## Install

The CLI is published as `gitcrumbs` on PyPI. You can install it system-wide and use it in any repo.

**Recommended (isolated CLIs):**
```bash
pipx install gitcrumbs
```

**Standard pip:**
```bash
python -m pip install gitcrumbs
```

> Requires Python 3.9+ and `git` on your PATH.

---

## Quick Start (2 minutes)

```bash
cd /path/to/your/repo

# 1) Prepare state storage under .git/gitcrumbs/
gitcrumbs init

# 2) Start the tracker: it snapshots only when you make changes and they last (dwell) for some time. Ctrl-C to stop
gitcrumbs track
# or
gitcrumbs track --interval 30 --dwell 90

# 3) See what has been captured
gitcrumbs timeline

# 4) Jump to an earlier/later working state
gitcrumbs previous  # alias: gitcrumbs p
gitcrumbs next  # alias: gitcrumbs n

# 5) Optional manual snapshot at any time
gitcrumbs snapshot
```

---

## Core ideas

- **Durable change**: a change that remains after a short wait (`--dwell`, e.g., 90s). Flapping edits don’t create noise.  
- **Snapshot**: a record of file states (tracked + untracked) at a moment in time, stored in `.git/gitcrumbs/gitcrumbs.db`.  
- **Anchoring on restore**: when you restore an old snapshot, `gitcrumbs` **does not** create a new one immediately. It **waits** until you make a new durable change, then records a fresh snapshot that’s linked back to the one you restored from.

---

## Everyday workflows

### 1) “I had it working 10 minutes ago…”
```bash
gitcrumbs timeline
gitcrumbs previous        # step back one snapshot
# run tests...
# If it works, you can diff or continue from here
```

### 2) Continuous capture while you work
```bash
gitcrumbs track --interval 15 --dwell 60
# Let this run in another terminal tab or tmux pane
```

### 3) Compare two states
```bash
gitcrumbs diff 12 15
# Shows added/deleted/modified files between snapshots #12 and #15
```

### 4) Restore an older snapshot
```bash
gitcrumbs restore 2
```

### 5) Remove gitcrumbs from a repo
```bash
gitcrumbs remove --dry-run   # see what would be deleted under .git/gitcrumbs
gitcrumbs remove --yes       # removes gitcrumbs from the current repo
```

---

## Commands (cheat sheet)

```text
gitcrumbs init
  Initialize .git/gitcrumbs/ (SQLite DB + config).

gitcrumbs track [--interval N] [--dwell M]
  Continuous tracker: snapshot only when the state changes and stays changed for M seconds.

gitcrumbs snapshot
  Create a snapshot right now.

gitcrumbs timeline
  Show all snapshots with timestamps, branch, and a short summary.

gitcrumbs status
  Show tracker status and the current cursor (baseline snapshot id).

gitcrumbs diff A B
  Summarize differences between snapshots A and B (added/deleted/modified paths).

gitcrumbs restore ID [--purge/--no-purge]
  Restore working files to snapshot ID. Default: --purge (remove extra files).

gitcrumbs next [--purge/--no-purge]      # alias: n
  Restore to the next snapshot after the current cursor (defaults to --purge).

gitcrumbs previous [--purge/--no-purge]  # alias: p
  Restore to the previous snapshot before the current cursor (defaults to --purge).

gitcrumbs remove [--dry-run] [--yes|-y]
  Delete .git/gitcrumbs (DB and metadata). Safe: does not affect Git commits/branches.
```

---

## How it works (a bit deeper)

- Uses Git plumbing commands (`ls-files`, `diff-files`, `hash-object`, `cat-file`) to compare the **real** working tree to the index/HEAD.  
- For tracked files, `gitcrumbs` fingerprints by **content hash**, not mtime/size (so restores don’t cause false deltas).  
- For untracked files, it records metadata + hashed content.  
- Snapshots live in SQLite; file bytes live in Git’s object store (efficient, deduplicated).  
- The tracker writes a tiny `tracker_state.json` so it knows when to anchor after restore and when to create the next snapshot.

---

## Safety & edge cases

- Works **before first commit** (unborn `HEAD`) and in **detached HEAD**.  
- Pauses during **merge/rebase** or when `.git/index.lock` exists.  
- On restore, if the saved branch no longer exists, it falls back to **detached** at the recorded commit.  
- Default restore is **purge on** for predictability; append `--no-purge` to keep extra files.

---

## Troubleshooting

- “`gitcrumbs` not found after installation” → If you used `pip install --user`, ensure `~/.local/bin` is on your PATH; or prefer `pipx`.  
- “No snapshots yet” → Start the tracker or run `gitcrumbs snapshot` manually.  
- “Snapshot created right after restore” → That should not happen with the anchoring logic. If it does, please open an issue with your `timeline` and steps.

---

## Contributing

Issues and PRs are welcome. If you hit an edge case, share a minimal repro.

---

## License

MIT

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "gitcrumbs",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "git, cli, developer-tools, productivity, snapshots, version-control",
    "author": null,
    "author_email": "Ertelek <contact.ertelek@yahoo.com>",
    "download_url": "https://files.pythonhosted.org/packages/f5/24/7f7c087b03fd5cf8cd6fc99d6ec0db294c05755a99574d09242c7198f3bd/gitcrumbs-0.1.1.tar.gz",
    "platform": null,
    "description": "# gitcrumbs\n\n_A tiny CLI tool that captures **durable working states** of your Git repo._  \nIt makes a snapshot **only when changes persist** (e.g., after you pause to test, or step away), and lets you **list**, **diff**, and **restore** those states without interfering with Git.\n\n- **Zero friction**: works with your existing Git workflow.  \n- **Lightweight**: uses Git\u2019s object store and a small SQLite DB under `.git/gitcrumbs/`.  \n- **Safe**: won\u2019t change commits or refs.\n\n---\n\n## Why would I want this?\n\nSometimes you tweak code, run tests, tweak again\u2026 and only some of those transient edits \u201cstick.\u201d `gitcrumbs` records **stable** working trees so you can jump back to the exact files you had when something actually worked, even if you never committed.\n\nThink of it as **temporary but reliable breadcrumbs** between commits.\n\n---\n\n## Install\n\nThe CLI is published as `gitcrumbs` on PyPI. You can install it system-wide and use it in any repo.\n\n**Recommended (isolated CLIs):**\n```bash\npipx install gitcrumbs\n```\n\n**Standard pip:**\n```bash\npython -m pip install gitcrumbs\n```\n\n> Requires Python 3.9+ and `git` on your PATH.\n\n---\n\n## Quick Start (2 minutes)\n\n```bash\ncd /path/to/your/repo\n\n# 1) Prepare state storage under .git/gitcrumbs/\ngitcrumbs init\n\n# 2) Start the tracker: it snapshots only when you make changes and they last (dwell) for some time. Ctrl-C to stop\ngitcrumbs track\n# or\ngitcrumbs track --interval 30 --dwell 90\n\n# 3) See what has been captured\ngitcrumbs timeline\n\n# 4) Jump to an earlier/later working state\ngitcrumbs previous  # alias: gitcrumbs p\ngitcrumbs next  # alias: gitcrumbs n\n\n# 5) Optional manual snapshot at any time\ngitcrumbs snapshot\n```\n\n---\n\n## Core ideas\n\n- **Durable change**: a change that remains after a short wait (`--dwell`, e.g., 90s). Flapping edits don\u2019t create noise.  \n- **Snapshot**: a record of file states (tracked + untracked) at a moment in time, stored in `.git/gitcrumbs/gitcrumbs.db`.  \n- **Anchoring on restore**: when you restore an old snapshot, `gitcrumbs` **does not** create a new one immediately. It **waits** until you make a new durable change, then records a fresh snapshot that\u2019s linked back to the one you restored from.\n\n---\n\n## Everyday workflows\n\n### 1) \u201cI had it working 10 minutes ago\u2026\u201d\n```bash\ngitcrumbs timeline\ngitcrumbs previous        # step back one snapshot\n# run tests...\n# If it works, you can diff or continue from here\n```\n\n### 2) Continuous capture while you work\n```bash\ngitcrumbs track --interval 15 --dwell 60\n# Let this run in another terminal tab or tmux pane\n```\n\n### 3) Compare two states\n```bash\ngitcrumbs diff 12 15\n# Shows added/deleted/modified files between snapshots #12 and #15\n```\n\n### 4) Restore an older snapshot\n```bash\ngitcrumbs restore 2\n```\n\n### 5) Remove gitcrumbs from a repo\n```bash\ngitcrumbs remove --dry-run   # see what would be deleted under .git/gitcrumbs\ngitcrumbs remove --yes       # removes gitcrumbs from the current repo\n```\n\n---\n\n## Commands (cheat sheet)\n\n```text\ngitcrumbs init\n  Initialize .git/gitcrumbs/ (SQLite DB + config).\n\ngitcrumbs track [--interval N] [--dwell M]\n  Continuous tracker: snapshot only when the state changes and stays changed for M seconds.\n\ngitcrumbs snapshot\n  Create a snapshot right now.\n\ngitcrumbs timeline\n  Show all snapshots with timestamps, branch, and a short summary.\n\ngitcrumbs status\n  Show tracker status and the current cursor (baseline snapshot id).\n\ngitcrumbs diff A B\n  Summarize differences between snapshots A and B (added/deleted/modified paths).\n\ngitcrumbs restore ID [--purge/--no-purge]\n  Restore working files to snapshot ID. Default: --purge (remove extra files).\n\ngitcrumbs next [--purge/--no-purge]      # alias: n\n  Restore to the next snapshot after the current cursor (defaults to --purge).\n\ngitcrumbs previous [--purge/--no-purge]  # alias: p\n  Restore to the previous snapshot before the current cursor (defaults to --purge).\n\ngitcrumbs remove [--dry-run] [--yes|-y]\n  Delete .git/gitcrumbs (DB and metadata). Safe: does not affect Git commits/branches.\n```\n\n---\n\n## How it works (a bit deeper)\n\n- Uses Git plumbing commands (`ls-files`, `diff-files`, `hash-object`, `cat-file`) to compare the **real** working tree to the index/HEAD.  \n- For tracked files, `gitcrumbs` fingerprints by **content hash**, not mtime/size (so restores don\u2019t cause false deltas).  \n- For untracked files, it records metadata + hashed content.  \n- Snapshots live in SQLite; file bytes live in Git\u2019s object store (efficient, deduplicated).  \n- The tracker writes a tiny `tracker_state.json` so it knows when to anchor after restore and when to create the next snapshot.\n\n---\n\n## Safety & edge cases\n\n- Works **before first commit** (unborn `HEAD`) and in **detached HEAD**.  \n- Pauses during **merge/rebase** or when `.git/index.lock` exists.  \n- On restore, if the saved branch no longer exists, it falls back to **detached** at the recorded commit.  \n- Default restore is **purge on** for predictability; append `--no-purge` to keep extra files.\n\n---\n\n## Troubleshooting\n\n- \u201c`gitcrumbs` not found after installation\u201d \u2192 If you used `pip install --user`, ensure `~/.local/bin` is on your PATH; or prefer `pipx`.  \n- \u201cNo snapshots yet\u201d \u2192 Start the tracker or run `gitcrumbs snapshot` manually.  \n- \u201cSnapshot created right after restore\u201d \u2192 That should not happen with the anchoring logic. If it does, please open an issue with your `timeline` and steps.\n\n---\n\n## Contributing\n\nIssues and PRs are welcome. If you hit an edge case, share a minimal repro.\n\n---\n\n## License\n\nMIT\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Track durable working-tree states for Git repos: snapshot, diff, restore, and auto-track stable changes.",
    "version": "0.1.1",
    "project_urls": {
        "Homepage": "https://github.com/ertelek/gitcrumbs",
        "Issues": "https://github.com/ertelek/gitcrumbs/issues",
        "Repository": "https://github.com/ertelek/gitcrumbs"
    },
    "split_keywords": [
        "git",
        " cli",
        " developer-tools",
        " productivity",
        " snapshots",
        " version-control"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7787bbe5862b19d704d023f4fb341024ffd494e14282e450d2e3b0d507c6ede7",
                "md5": "03a88930afaee04dc21c38544907b1a5",
                "sha256": "d7f1d1bfa06ac7c3212fc61e0e50487120fd86ead08de2d5ec0f8b1f2ac77d8d"
            },
            "downloads": -1,
            "filename": "gitcrumbs-0.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "03a88930afaee04dc21c38544907b1a5",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 12182,
            "upload_time": "2025-10-19T10:04:29",
            "upload_time_iso_8601": "2025-10-19T10:04:29.908749Z",
            "url": "https://files.pythonhosted.org/packages/77/87/bbe5862b19d704d023f4fb341024ffd494e14282e450d2e3b0d507c6ede7/gitcrumbs-0.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "f5247f7c087b03fd5cf8cd6fc99d6ec0db294c05755a99574d09242c7198f3bd",
                "md5": "08cc9e48f521f566006dd4282c184c26",
                "sha256": "58285c3ab26ca81d19227c8b4456c7044a8bc70322009225848382d29a9c51bf"
            },
            "downloads": -1,
            "filename": "gitcrumbs-0.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "08cc9e48f521f566006dd4282c184c26",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 14043,
            "upload_time": "2025-10-19T10:04:31",
            "upload_time_iso_8601": "2025-10-19T10:04:31.314228Z",
            "url": "https://files.pythonhosted.org/packages/f5/24/7f7c087b03fd5cf8cd6fc99d6ec0db294c05755a99574d09242c7198f3bd/gitcrumbs-0.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-19 10:04:31",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ertelek",
    "github_project": "gitcrumbs",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "gitcrumbs"
}
        
Elapsed time: 0.72638s