gitundo 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gitundo-0.1.0/LICENSE +21 -0
- gitundo-0.1.0/PKG-INFO +360 -0
- gitundo-0.1.0/README.md +327 -0
- gitundo-0.1.0/pyproject.toml +63 -0
- gitundo-0.1.0/setup.cfg +4 -0
- gitundo-0.1.0/src/gitundo/__init__.py +31 -0
- gitundo-0.1.0/src/gitundo/__main__.py +8 -0
- gitundo-0.1.0/src/gitundo/cli.py +583 -0
- gitundo-0.1.0/src/gitundo/core.py +949 -0
- gitundo-0.1.0/src/gitundo/py.typed +0 -0
- gitundo-0.1.0/src/gitundo.egg-info/PKG-INFO +360 -0
- gitundo-0.1.0/src/gitundo.egg-info/SOURCES.txt +18 -0
- gitundo-0.1.0/src/gitundo.egg-info/dependency_links.txt +1 -0
- gitundo-0.1.0/src/gitundo.egg-info/entry_points.txt +2 -0
- gitundo-0.1.0/src/gitundo.egg-info/requires.txt +4 -0
- gitundo-0.1.0/src/gitundo.egg-info/top_level.txt +1 -0
- gitundo-0.1.0/tests/test_autowrap_integration.py +111 -0
- gitundo-0.1.0/tests/test_restore.py +113 -0
- gitundo-0.1.0/tests/test_selectors_tags_guard.py +253 -0
- gitundo-0.1.0/tests/test_snapshot.py +179 -0
gitundo-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 gitundo contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
gitundo-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gitundo
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The undo button git never had. Automatic safety-net snapshots for any git repo.
|
|
5
|
+
Author: gitundo contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/xrchris7/gitundo
|
|
8
|
+
Project-URL: Repository, https://github.com/xrchris7/gitundo
|
|
9
|
+
Project-URL: Documentation, https://github.com/xrchris7/gitundo#readme
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/xrchris7/gitundo/issues
|
|
11
|
+
Keywords: git,undo,checkpoint,snapshot,backup,reset,recovery,developer-tools,cli,version-control
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Software Development :: Version Control
|
|
25
|
+
Classifier: Topic :: Utilities
|
|
26
|
+
Requires-Python: >=3.9
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
<div align="center">
|
|
35
|
+
|
|
36
|
+
# 🛟 gitundo
|
|
37
|
+
|
|
38
|
+
**The undo button git never had.**
|
|
39
|
+
|
|
40
|
+
Automatic safety‑net snapshots for any git repository — so you can never lose
|
|
41
|
+
work to `reset --hard`, `clean -fdx`, a bad rebase, or "oops I deleted it" again.
|
|
42
|
+
|
|
43
|
+
Zero dependencies · works in any repo · never touches your history.
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
pip install gitundo
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
[](https://pypi.org/project/gitundo/)
|
|
50
|
+
[](https://pypi.org/project/gitundo/)
|
|
51
|
+
[](LICENSE)
|
|
52
|
+
[](https://github.com/xrchris7/gitundo/actions)
|
|
53
|
+
[](https://marketplace.visualstudio.com/items?itemName=gitundo.gitundo)
|
|
54
|
+
|
|
55
|
+
[Features](#features) · [Quick start](#quick-start) · [Commands](#commands) ·
|
|
56
|
+
[Auto-guard](#the-auto-guard) · [How it works](#how-it-works) ·
|
|
57
|
+
[Recipes](#recipes) · [Comparison](#comparison) · [FAQ](#faq)
|
|
58
|
+
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## The one-paragraph pitch
|
|
64
|
+
|
|
65
|
+
Git only protects work you **commit**. Everything else — the half‑finished
|
|
66
|
+
refactor, the deleted file, the unstaged fix that took an hour — is one
|
|
67
|
+
`reset --hard` away from oblivion. gitundo is a safety net for exactly that:
|
|
68
|
+
|
|
69
|
+
* **`gitundo snap`** stores the entire current state of your working tree
|
|
70
|
+
(staged **and** unstaged **and** untracked) as a lightweight *checkpoint*.
|
|
71
|
+
* **`gitundo restore`** brings any checkpoint back — even files you deleted.
|
|
72
|
+
* The **auto-guard** (`gitundo autowrap`) snapshots automatically before
|
|
73
|
+
destructive commands like `git reset --hard` or `git clean -fdx`.
|
|
74
|
+
|
|
75
|
+
Checkpoints live on a hidden ref — `refs/gitundo/checkpoints` — so they are
|
|
76
|
+
**ordinary git objects**: deduplicated by git, visible in `git log`,
|
|
77
|
+
shareable, and safe. Your branches, commits, index and tags are never touched.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Features
|
|
82
|
+
|
|
83
|
+
| | |
|
|
84
|
+
|---|---|
|
|
85
|
+
| 📸 **Snapshot anything** | Staged, unstaged, *and* untracked files, deletions, symlinks, binaries. Ignored files and the stash are never captured. |
|
|
86
|
+
| 🪂 **Undo the un‑undoable** | Recover files destroyed by `reset --hard`, `clean -fdx`, `checkout -f`, bad merges, editor mishaps — even files that were never committed. |
|
|
87
|
+
| 🛡️ **Auto‑guard** | Optional shell wrapper that snapshots *before* clearly destructive git commands. You are always one command from a safety net. |
|
|
88
|
+
| 🏷️ **Tag & diff** | Name checkpoints (`gitundo tag demo-ready`), inspect exactly what each one saved (`gitundo diff`). |
|
|
89
|
+
| 🔒 **Zero‑invasion** | Only a hidden ref is ever written. The index, working tree, and history stay exactly as they were. |
|
|
90
|
+
| 🪶 **Zero dependencies** | Pure standard library. Works everywhere git works. |
|
|
91
|
+
| 🚿 **Prune** | `gitundo prune -k 50` keeps your latest 50 (+ tagged) and reclaims the rest. |
|
|
92
|
+
| 🧵 **Library + CLI** | Use it from your own scripts via `from gitundo import core`. |
|
|
93
|
+
| 🧑💻 **VS Code extension** | Official editor integration — sidebar checkpoints, one-click snapshot & restore, diff, tags and a live status bar (see [`extensions/vscode`](extensions/vscode)). |
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Quick start
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# 1. install
|
|
101
|
+
pip install gitundo # or: uv tool install gitundo / pipx install gitundo
|
|
102
|
+
|
|
103
|
+
# 2. snapshot whenever you reach a point you might want to return to
|
|
104
|
+
gitundo snap "before the big refactor"
|
|
105
|
+
|
|
106
|
+
# ...edit files, experiment, break things...
|
|
107
|
+
|
|
108
|
+
# 3. bring back the state from any snapshot
|
|
109
|
+
gitundo list # see what you've saved
|
|
110
|
+
gitundo restore # latest snapshot
|
|
111
|
+
gitundo restore 2 # two snapshots ago
|
|
112
|
+
gitundo restore before-the-big-refactor # by tag
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### The one-command setup you'll actually use
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
gitundo on # mark this repo as guarded
|
|
119
|
+
gitundo autowrap # install the shell wrapper (one time, per machine)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Editor integration (VS Code)
|
|
123
|
+
|
|
124
|
+
The official **gitundo extension** puts a 🛟 GitUndo view in your Activity Bar:
|
|
125
|
+
snapshot with one click, browse checkpoints, diff what each one saved, and
|
|
126
|
+
restore from the right-click menu — all without touching your commits.
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
git clone https://github.com/xrchris7/gitundo
|
|
130
|
+
cd gitundo/extensions/vscode
|
|
131
|
+
npm install && npm run package # -> gitundo-<version>.vsix
|
|
132
|
+
code --install-extension gitundo-0.1.0.vsix
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
(Needs the CLI installed: `pip install gitundo`.) Full details in
|
|
136
|
+
[`extensions/vscode/README.md`](extensions/vscode/README.md).
|
|
137
|
+
|
|
138
|
+
Now every time you run a destructive command, gitundo quietly saves a
|
|
139
|
+
checkpoint first:
|
|
140
|
+
|
|
141
|
+
```text
|
|
142
|
+
$ git reset --hard HEAD~3
|
|
143
|
+
gitundo snapshot before git reset --hard → 9f3a1c2
|
|
144
|
+
HEAD is now at 7b8c9d0 add feature
|
|
145
|
+
|
|
146
|
+
$ git clean -fdx
|
|
147
|
+
gitundo snapshot before git clean -dfx → 0e5d2b1
|
|
148
|
+
Removing build/cache/
|
|
149
|
+
|
|
150
|
+
# hours later — "wait, that reset was a mistake" →
|
|
151
|
+
$ gitundo restore
|
|
152
|
+
✔ restored working tree to latest (14 file(s) written, 0 removed)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Disable the guard at any moment with `export GITUNDO_DISABLE=1`.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Commands
|
|
160
|
+
|
|
161
|
+
| Command | What it does |
|
|
162
|
+
|---|---|
|
|
163
|
+
| `gitundo snap [msg] [-t TAG]` | Snapshot the current working state. |
|
|
164
|
+
| `gitundo list [-n N] [--tags]` | List checkpoints, newest first. |
|
|
165
|
+
| `gitundo restore [SEL] [--index] [--hard] [--delete-extraneous]` | Restore the working tree to a checkpoint. |
|
|
166
|
+
| `gitundo diff [SEL] [--from SEL] [--workdir]` | Show what a snapshot saved, or diff two snapshots. |
|
|
167
|
+
| `gitundo tag NAME [SEL]` / `gitundo untag [NAME]` | Give checkpoints readable names. |
|
|
168
|
+
| `gitundo prune -k N` | Delete old checkpoints (tagged ones survive). |
|
|
169
|
+
| `gitundo status` | Guard state + recent checkpoints + storage used. |
|
|
170
|
+
| `gitundo on` / `gitundo off` | Enable/disable the guard for this repo. |
|
|
171
|
+
| `gitundo autowrap [--uninstall]` | Install/remove the destructive-command shell wrapper. |
|
|
172
|
+
| `gitundo help` | Full command reference. |
|
|
173
|
+
|
|
174
|
+
**Selectors** — everywhere a checkpoint is expected:
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
latest | N (0 = latest, 1 = the one before…) | a tag name | an object-id prefix
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Full reference in [`docs/CLI.md`](docs/CLI.md).
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## The auto-guard
|
|
185
|
+
|
|
186
|
+
`gitundo autowrap` adds a tiny function to your `~/.bashrc` / `~/.zshrc` that
|
|
187
|
+
intercepts `git` and, **only when** the command is clearly destructive,
|
|
188
|
+
snapshots first, then runs your command normally (stdin/stdout/exit code all
|
|
189
|
+
inherited). Nothing else changes — `git status` is never slowed down.
|
|
190
|
+
|
|
191
|
+
Currently guarded: `git reset --hard`, `git clean -dfx`, `git checkout -f` /
|
|
192
|
+
`--` / `.`, `git restore`, `git rm`, `git branch -D`, `git update-ref`, plus
|
|
193
|
+
plain-shell `rm -rf`, `rmdir`, `shred`, `mv`/`cp`, `truncate`, `dd` and
|
|
194
|
+
in-place `sed -i`-style edits when run through the wrapped `git`.
|
|
195
|
+
|
|
196
|
+
> History operations like `merge`, `rebase`, `revert` and `cherry-pick` are
|
|
197
|
+
> deliberately **not** guarded: git's own reflog already protects them and they
|
|
198
|
+
> never delete uncommitted work — auto-snapshots would only add noise.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## How it works
|
|
203
|
+
|
|
204
|
+
Snapshots are plain commits hanging off a hidden ref:
|
|
205
|
+
|
|
206
|
+
```text
|
|
207
|
+
git commit ← the snapshot
|
|
208
|
+
tree f02a9… ← complete working state: tracked + untracked files as-is
|
|
209
|
+
author gitundo <gitundo@localhost> ← never impersonates you
|
|
210
|
+
message before-the-big-refactor (subject)
|
|
211
|
+
snapshot-of: a1b2c3d ← your HEAD at capture time
|
|
212
|
+
created-by: gitundo
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
refs/gitundo/checkpoints o3 → o2 → o1 → … (linear chain of snapshots)
|
|
217
|
+
refs/gitundo/tags/demo-ready → o2 (tags are lightweight refs)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Because a checkpoint is a real commit, git does the heavy lifting for you:
|
|
221
|
+
|
|
222
|
+
* **Deduplication is free.** Ten snapshots of an almost-unchanged repo add
|
|
223
|
+
only a few objects — identical file content is stored once, forever.
|
|
224
|
+
* **Restore never rewrites history.** It writes files back into your working
|
|
225
|
+
tree. Committed work is left alone (it's already safe).
|
|
226
|
+
* **You can inspect them with plain git:** `git log refs/gitundo/checkpoints`
|
|
227
|
+
and even push the ref to back your safety net up on a remote.
|
|
228
|
+
|
|
229
|
+
### Guarantees
|
|
230
|
+
|
|
231
|
+
* The working tree, index, branch refs and tags are **never modified** by
|
|
232
|
+
snapshot / list / diff.
|
|
233
|
+
* Restore **never deletes** files that exist only in commits newer than the
|
|
234
|
+
checkpoint, and never deletes untracked files (unless you pass
|
|
235
|
+
`--delete-extraneous`).
|
|
236
|
+
* Restore **never overwrites** a file with local edits — they are parked as
|
|
237
|
+
`*.gitundo-keep` and reported (pass `--hard` to overwrite instead).
|
|
238
|
+
* Snapshot commits are authored `gitundo`, so they are instantly
|
|
239
|
+
recognisable in `git log` and can never be mistaken for (or signed as) your
|
|
240
|
+
work.
|
|
241
|
+
* Every command degrades gracefully: if gitundo can't run, your git command
|
|
242
|
+
still runs.
|
|
243
|
+
|
|
244
|
+
### What gitundo deliberately is not
|
|
245
|
+
|
|
246
|
+
* Not a backup tool for `.git` itself, and it does not protect *committed*
|
|
247
|
+
history (reflog + remotes already do).
|
|
248
|
+
* Not a replacement for good commits — it *protects the stuff between them*.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Recipes
|
|
253
|
+
|
|
254
|
+
**Recover from `git clean -fdx`** (deleted untracked work):
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
gitundo snap # do this BEFORE you clean
|
|
258
|
+
git clean -fdx # ...or let the auto-guard snapshot for you
|
|
259
|
+
# hours later:
|
|
260
|
+
gitundo list
|
|
261
|
+
gitundo restore 0 # everything is back, as untracked files
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
**Undo a wrong `git reset --hard`** (uncommitted + committed work):
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
gitundo snap # before the reset
|
|
268
|
+
git reset --hard HEAD~5
|
|
269
|
+
gitundo restore # working tree is exactly what you snapshotted
|
|
270
|
+
git reset --hard <your branch tip> # then optionally re-point your branch
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**Branch experiments without fear:**
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
gitundo snap exp-start
|
|
277
|
+
git checkout -b experiment
|
|
278
|
+
# ... go wild ...
|
|
279
|
+
git checkout main
|
|
280
|
+
gitundo restore exp-start # clean tree exactly as you left it
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**Before an AI agent / co-pilot edits your repo:**
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
gitundo snap "before agent run"
|
|
287
|
+
# let the agent do its thing; if it trashes files, gitundo restore
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**In CI / scripts** (zero output unless something is wrong):
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
gitundo snap -t ${GITHUB_SHA} || true # snapshot, never fail the build
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
**As a library:**
|
|
297
|
+
|
|
298
|
+
```python
|
|
299
|
+
from gitundo import core
|
|
300
|
+
|
|
301
|
+
core.snapshot(path=".", message="deploy preflight", tag="pre-deploy")
|
|
302
|
+
cps = core.list_checkpoints()
|
|
303
|
+
core.restore(path=".", selector="pre-deploy")
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Comparison
|
|
309
|
+
|
|
310
|
+
| Tool | What it does | How gitundo differs |
|
|
311
|
+
|---|---|---|
|
|
312
|
+
| `git stash` | Temporarily shelves a *single* change set | Checkpoints stack: full history of every intermediate state, browseable & restorable by tag/number |
|
|
313
|
+
| reflog | Undoes *committed* operations | gitundo protects *uncommitted* state, which reflog can't |
|
|
314
|
+
| `ugit` / `gitjk` | Interactive recipe for reversing specific git commands | gitundo is automatic + non-interactive; snapshots include untracked files & deletions |
|
|
315
|
+
| `git-snap` | Manual snapshot to a side branch | gitundo: full undo cycle (snap → list → diff → restore), tags, guard, prune |
|
|
316
|
+
| `jj` / agents' checkpoints | Continuous op-log / per-session snapshots | gitundo rides on *your* plain git (no new VCS), opt-in per repo, no config |
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## FAQ
|
|
321
|
+
|
|
322
|
+
**Does it slow git down?** Only the commands you ask it to guard, and only for
|
|
323
|
+
the brief moment a checkpoint is written. Ordinary commands pass straight
|
|
324
|
+
through.
|
|
325
|
+
|
|
326
|
+
**Where does the data live?** In your repo's own `.git` object store, under
|
|
327
|
+
`refs/gitundo/`. There is no daemon, no database, nothing to corrupt
|
|
328
|
+
independently of git.
|
|
329
|
+
|
|
330
|
+
**Can I push checkpoints to a remote?** Yes — they're refs:
|
|
331
|
+
`git push origin refs/gitundo/checkpoints:refs/gitundo/checkpoints`.
|
|
332
|
+
|
|
333
|
+
**Is this safe for huge monorepos?** Snapshots reuse git's own content
|
|
334
|
+
addressing, so unchanged content costs almost nothing. Files larger than
|
|
335
|
+
~64 MB are skipped for byte-comparison during restore (still snapshotted).
|
|
336
|
+
|
|
337
|
+
**How do I reclaim space?** `gitundo prune -k 20`, then occasionally
|
|
338
|
+
`git gc --prune=now`.
|
|
339
|
+
|
|
340
|
+
**Where are my checkpointed files if the working tree is clean?** If a
|
|
341
|
+
snapshot captured nothing new, gitundo says so and stores nothing.
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Contributing
|
|
346
|
+
|
|
347
|
+
Contributions are very welcome — docs, tests, shell guards, integrations
|
|
348
|
+
(IDE, pre-commit, Git hooks), and more destructive-command patterns. See
|
|
349
|
+
[`CONTRIBUTING.md`](CONTRIBUTING.md). The codebase is intentionally small:
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
src/gitundo/core.py ~ the engine (snapshot, restore, diff, prune, guard)
|
|
353
|
+
src/gitundo/cli.py ~ the command-line interface
|
|
354
|
+
tests/ ~ 75+ tests against real throwaway git repositories
|
|
355
|
+
extensions/vscode/ ~ the official VS Code extension (sidebar, commands)
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## License
|
|
359
|
+
|
|
360
|
+
[MIT](LICENSE)
|