Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## Unreleased

### Changed
- Tightened README, CLI, crate, and landing-page language around what reflog-based recovery can and cannot do.
- Synced documented controls and feature lists with the current `0.3.0` behavior.

## [0.3.0] - 2026-04-10

### Added
- Search/filter mode for reflog entries.
- JSON export with `--export-json`.
- Full diff toggle in the diff panel.
- Relative/absolute timestamp toggle.
- Vim-style `gg` and `G` navigation.

## [0.2.4] - 2026-03-24

### Added
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name = "git-time-machine"
version = "0.3.0"
edition = "2021"
authors = ["Dinakar Sarbada <dinakars777@gmail.com>"]
description = "🕰️ A beautiful TUI to undo ANY git mistake in 3 seconds"
description = "🕰️ A visual TUI for browsing Git reflog and restoring reachable local history"
license = "MIT"
repository = "https://github.com/dinakars777/git-time-machine"
keywords = ["git", "tui", "undo", "reflog", "cli"]
Expand Down
81 changes: 48 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 🕰️ git-time-machine

> **Undo git mistakes in 3 seconds with a TUI**
> **Browse Git reflog visually and recover reachable local history with a TUI**

`git-time-machine` makes git reflog visual and interactive.

Expand All @@ -16,20 +16,20 @@
## ✨ The Problem

You just:
- 💥 Accidentally moved HEAD and lost track of your commits
- 🗑️ Deleted a branch you needed
- 🤦 Rebased wrong and broke everything
- 😱 Can't remember what you did 5 minutes ago
- 💥 Moved HEAD and need to find the previous state
- 🗑️ Deleted a local branch and need the last reachable commit
- 🤦 Ran several Git operations and cannot remember the sequence
- 😱 Need to inspect what changed before choosing a recovery point

**Current solution:** Dig through `git reflog`, copy cryptic hashes, pray you picked the right one.
**Current solution:** Read through `git reflog`, copy hashes, compare candidates, and run the right Git command manually.

**Better:** `git-time-machine` 🎯

## 🚀 Demo

![Demo GIF](demo.gif)

*Navigate your git history like a time traveler. One key to restore.*
*Navigate your local reflog, preview changes, and restore deliberately.*

## 📦 Installation

Expand All @@ -45,19 +45,17 @@ cd git-time-machine
cargo install --path .
```

### Homebrew (Coming Soon)
```bash
brew install git-time-machine
```

## 🎮 Usage

```bash
# Launch in any git repository
git-time-machine

# Show all reflog entries (default: last 50)
# Show up to 1000 reflog entries (default: last 50)
git-time-machine --all

# Export the current reflog view as JSON
git-time-machine --export-json
```

### Controls
Expand All @@ -66,15 +64,25 @@ git-time-machine --all
|-----|--------|
| `↑` / `k` | Move up |
| `↓` / `j` | Move down |
| `Enter` | Restore to selected state |
| `q` / `Esc` | Quit |
| `Home` / `End` | Jump to first/last entry |
| `gg` / `G` | Jump to first/last entry (vim-style) |
| `PgUp` / `PgDn` | Jump 10 entries |
| `Space` | Toggle diff panel |
| `d` | Switch between diff summary and full diff |
| `t` | Toggle relative/absolute timestamps |
| `/` | Search/filter commits by message |
| `Esc` | Clear active filter, or quit if no filter is active |
| `Enter` | Confirm restore to selected state |
| `q` | Quit |

## 🎯 Features

- ✅ **Visual Timeline** - See your entire git history at a glance
- ✅ **Visual Timeline** - See recent reflog entries at a glance
- ✅ **Relative Timestamps** - "5m ago", "2h ago", "yesterday"
- ✅ **One-Key Restore** - Press Enter, done
- ✅ **Vim Keybindings** - j/k navigation
- ✅ **Diff Preview** - Compare the selected entry before restoring
- ✅ **Search/Filter** - Filter commit messages with multi-word search
- ✅ **JSON Export** - Export the reflog timeline for automation
- ✅ **Vim Keybindings** - j/k and gg/G navigation
- ✅ **Beautiful TUI** - Built with Ratatui
- ✅ **Lightning Fast** - Written in Rust
- ✅ **Zero Config** - Just works
Expand All @@ -91,7 +99,7 @@ git-time-machine --all
git-time-machine
# Visually scan the timeline
# See "2h ago - before I started messing around"
# Press Enter, back to working state ✨
# Preview the diff, then press Enter if it is the right state
```

**Why not `git reflog`?** You'd need to:
Expand All @@ -112,7 +120,7 @@ git-time-machine
# Scroll through visual timeline
# See relative timestamps: "15m ago", "1h ago"
# Find the state you need
# Press Enter to restore
# Preview the diff, then press Enter to restore if it is the right state
```

**Why not `git reflog | grep`?** You'd need to:
Expand Down Expand Up @@ -160,52 +168,59 @@ git-time-machine
3. Hope you counted right
4. Manually re-apply commits if you messed up

## ⚠️ What Git-Time-Machine Cannot Fix
## ⚠️ Recovery Boundaries

`git-time-machine` is a reflog browser. It can only help with history that Git can still see locally.

- **Uncommitted Changes:** If you haven't committed or stashed your work, the reflog cannot see it. Accidentally running `git clean -fd` or wiping uncommitted files via `git reset --hard` is permanent.
- **Garbage Collected Commits:** By default, git periodically cleans up unreachable commits. If a commit has been permanently garbage-collected, it is gone forever.
| Situation | Can it help? | Notes |
|-----------|--------------|-------|
| You moved `HEAD` with reset, rebase, merge, amend, or checkout | Usually | If the target commit is still in the local reflog, you can inspect and restore it. |
| You deleted a local branch | Usually | If the branch tip is still reachable from your local reflog, you can find the commit hash and recreate the branch manually. |
| You force-pushed a remote branch | Sometimes | Only if the commits existed in your local clone before the force-push. It cannot recover commits that were never fetched locally. |
| You lost uncommitted, unstashed files | No | Git reflog tracks refs, not arbitrary working-tree file contents. |
| Git garbage-collected the commit | No | If Git has permanently removed the object, this tool cannot bring it back. |

## 🛠️ How It Works

`git-time-machine` is a wrapper around `git reflog` that:

1. Parses your reflog history
2. Displays it in an interactive TUI
3. Lets you preview and restore any state
3. Lets you preview and restore reachable local states
4. Executes `git reset --hard <hash>` when you press Enter

**It's just git under the hood** - no magic, no risk.
**It's just Git under the hood** - useful, but not magic. The restore action is destructive and should be confirmed only after previewing the target state.

## 🤔 Why Not Just Use Git Commands?

**You absolutely can!** But here's the reality:

| Task | With git commands | With git-time-machine |
|------|------------------|---------------------|
| Find state from "before I broke it" | `git reflog`, scan 50+ lines, guess hash, `git reset --hard <hash>`, hope it's right | Scroll, press Enter |
| Recover a deleted branch's commit hash | `git reflog --all \| grep branch-name`, find hash, `git checkout -b`, verify | `--all` flag, scroll, copy hash |
| Undo complex operation sequence | Remember exact commands, count commits, pick right reset flag | Visual timeline, click the "before" state |
| Explore "what if" scenarios | Multiple `git reset` attempts, risk losing more work | Navigate freely, restore is one keypress |
| Find state from "before I broke it" | `git reflog`, scan 50+ lines, guess hash, `git reset --hard <hash>`, hope it's right | Scroll, preview, confirm |
| Recover a deleted branch's commit hash | `git reflog`, search manually, find hash, `git checkout -b`, verify | Expanded reflog view, scroll, copy hash |
| Undo complex operation sequence | Remember exact commands, count commits, pick right reset flag | Visual timeline, select the "before" state |
| Explore "what if" scenarios | Multiple `git reset` attempts, risk losing more work | Navigate, preview, and confirm from one interface |

**git-time-machine doesn't replace git** - it makes reflog actually usable for humans who:
- Don't memorize commit hashes
- Don't want to grep through 200 lines of text
- Want to see their history visually
- Need to undo mistakes quickly without googling

Think of it as `git reflog` with a UI that doesn't require a PhD.
Think of it as `git reflog` with a visual interface for recovery decisions.

## 🤝 Contributing

Contributions welcome!

**Ideas for future versions:**
- [ ] Show file diffs inline
- [ ] Safer restore modes: soft reset, mixed reset, checkout preview
- [ ] "Panic mode" - undo last N minutes
- [ ] Branch visualization
- [ ] Stash recovery
- [ ] Search/filter commits
- [ ] Export timeline as JSON
- [ ] Copy selected commit hash to clipboard
- [ ] True all-ref reflog mode for deleted branch recovery

## 📝 License

Expand Down
51 changes: 26 additions & 25 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>git-time-machine - Undo ANY git mistake in 3 seconds</title>
<meta name="description" content="Visual git reflog TUI. Never lose work again. Navigate your git history like a time traveler with vim keybindings.">
<title>git-time-machine - Visual Git reflog recovery TUI</title>
<meta name="description" content="Visual Git reflog TUI for browsing reachable local history, previewing changes, and restoring deliberately.">
<link rel="stylesheet" href="style.css">
</head>
<body>
Expand All @@ -13,8 +13,8 @@
<div class="container">
<div class="hero-emoji">🕰️</div>
<h1>git-time-machine</h1>
<p class="tagline">Undo git mistakes in 3 seconds</p>
<p class="subtitle">Visual git reflog that makes sense.</p>
<p class="tagline">Browse Git reflog visually</p>
<p class="subtitle">Preview reachable local history before you restore.</p>

<div class="cta-buttons">
<button class="btn-primary" onclick="copyCommand()">
Expand All @@ -28,35 +28,35 @@ <h1>git-time-machine</h1>

<div class="demo-container">
<img src="demo.gif" alt="git-time-machine demo" class="demo-gif">
<p class="demo-caption">Navigate your git history like a time traveler. One key to restore.</p>
<p class="demo-caption">Navigate local reflog entries, preview changes, and restore deliberately.</p>
</div>
</div>
</section>

<!-- Problem Section -->
<section class="problem">
<div class="container">
<h2>You just broke everything</h2>
<h2>You need to recover a known-good state</h2>
<div class="problem-grid">
<div class="problem-card">
<div class="problem-icon">🔥</div>
<h3>Force pushed</h3>
<p>Lost commits you needed</p>
<h3>Moved HEAD</h3>
<p>Need the previous local state</p>
</div>
<div class="problem-card">
<div class="problem-icon">💥</div>
<h3>git reset --hard</h3>
<p>By accident, of course</p>
<p>And need to inspect what came before</p>
</div>
<div class="problem-card">
<div class="problem-icon">🗑️</div>
<h3>Deleted a branch</h3>
<p>The one you actually needed</p>
<p>Need the last reachable tip</p>
</div>
<div class="problem-card">
<div class="problem-icon">🤦</div>
<h3>Rebased wrong</h3>
<p>Everything is broken now</p>
<p>Need to compare recovery points</p>
</div>
</div>

Expand All @@ -74,15 +74,15 @@ <h3>Current solution:</h3>
</div>
<div class="terminal-line">$ # Which hash do I need? 🤷</div>
</div>
<p class="pain-point">Dig through cryptic hashes, guess which one is right, pray it works.</p>
<p class="pain-point">Read through reflog text, compare hashes manually, and make sure the target is still available locally.</p>
</div>
</div>
</section>

<!-- Solution Section -->
<section class="solution">
<div class="container">
<h2>Better: git-time-machine 🎯</h2>
<h2>Better: git-time-machine</h2>

<div class="comparison">
<div class="comparison-card bad">
Expand All @@ -94,17 +94,18 @@ <h3>❌ With git reflog</h3>
<li>Hope you picked the right one</li>
<li>Repeat if wrong</li>
</ol>
<p class="time">⏱️ 5-10 minutes + stress</p>
<p class="time">Manual and easy to misread</p>
</div>

<div class="comparison-card good">
<h3>✅ With git-time-machine</h3>
<ol>
<li>Run <code>git-time-machine</code></li>
<li>Scroll through visual timeline</li>
<li>Press Enter</li>
<li>Preview the diff</li>
<li>Press Enter after confirming</li>
</ol>
<p class="time">⏱️ 3 seconds</p>
<p class="time">Visual and deliberate</p>
</div>
</div>
</div>
Expand All @@ -118,7 +119,7 @@ <h2>Features</h2>
<div class="feature-card">
<div class="feature-icon">📊</div>
<h3>Visual Timeline</h3>
<p>See your git history at a glance</p>
<p>See recent reflog entries at a glance</p>
</div>
<div class="feature-card">
<div class="feature-icon">⏰</div>
Expand All @@ -127,13 +128,13 @@ <h3>Relative Timestamps</h3>
</div>
<div class="feature-card">
<div class="feature-icon">⚡</div>
<h3>One-Key Restore</h3>
<p>Press Enter, done. No copying hashes, no commands</p>
<h3>Diff Preview</h3>
<p>Inspect the selected state before restoring</p>
</div>
<div class="feature-card">
<div class="feature-icon">⌨️</div>
<h3>Vim Keybindings</h3>
<p>j/k navigation for the keyboard warriors</p>
<h3>Search and JSON</h3>
<p>Filter reflog messages or export entries for automation</p>
</div>
<div class="feature-card">
<div class="feature-icon">🎨</div>
Expand Down Expand Up @@ -220,7 +221,7 @@ <h3>From Source</h3>
<div class="usage-section">
<h3>Usage</h3>
<div class="code-block large">
<code># Launch in any git repository<br>git-time-machine<br><br># Show all reflog entries (default: last 50)<br>git-time-machine --all</code>
<code># Launch in any git repository<br>git-time-machine<br><br># Show up to 1000 reflog entries (default: last 50)<br>git-time-machine --all<br><br># Export reflog entries as JSON<br>git-time-machine --export-json</code>
</div>

<h3>Controls</h3>
Expand All @@ -242,7 +243,7 @@ <h3>Controls</h3>
</tr>
<tr>
<td><kbd>Enter</kbd></td>
<td>Restore to selected state</td>
<td>Confirm restore to selected state</td>
</tr>
<tr>
<td><kbd>q</kbd> / <kbd>Esc</kbd></td>
Expand All @@ -257,8 +258,8 @@ <h3>Controls</h3>
<!-- CTA Section -->
<section class="cta">
<div class="container">
<h2>Stop losing work</h2>
<p class="cta-subtext">Just git under the hood.</p>
<h2>Stop guessing at reflog hashes</h2>
<p class="cta-subtext">Just Git under the hood, with a visual recovery workflow.</p>
<div class="cta-buttons">
<button class="btn-primary large" onclick="copyCommand()">
<span class="btn-text">cargo install git-time-machine</span>
Expand Down
Loading
Loading