Skip to content

Commit cf0fac2

Browse files
committed
feat: implement oops v0.1.0 with Git backend
- Single file versioning using Git bare repositories - Friendly commands: start, save, back, oops!, history, changes, now, done, files - Git-style aliases: track, commit, checkout, log, diff, status, untrack - Self-update via GitHub Releases (oops update) - Smart binary compression for non-compressed file types - GitHub Actions for CI and automated releases
1 parent 4613284 commit cf0fac2

32 files changed

Lines changed: 3552 additions & 48 deletions

.github/workflows/ci.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
name: Test
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v4
16+
17+
- name: Setup Go
18+
uses: actions/setup-go@v5
19+
with:
20+
go-version: '1.21'
21+
22+
- name: Run tests
23+
run: go test -v -race -coverprofile=coverage.out ./...
24+
25+
- name: Upload coverage
26+
uses: codecov/codecov-action@v4
27+
with:
28+
file: coverage.out
29+
continue-on-error: true
30+
31+
build:
32+
name: Build
33+
runs-on: ${{ matrix.os }}
34+
strategy:
35+
matrix:
36+
os: [ubuntu-latest, macos-latest, windows-latest]
37+
steps:
38+
- name: Checkout
39+
uses: actions/checkout@v4
40+
41+
- name: Setup Go
42+
uses: actions/setup-go@v5
43+
with:
44+
go-version: '1.21'
45+
46+
- name: Build
47+
run: go build -v .
48+
49+
- name: Test binary
50+
run: |
51+
./oops --version
52+
shell: bash

.github/workflows/release.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
build:
13+
name: Build
14+
runs-on: ubuntu-latest
15+
strategy:
16+
matrix:
17+
include:
18+
- goos: linux
19+
goarch: amd64
20+
- goos: linux
21+
goarch: arm64
22+
- goos: darwin
23+
goarch: amd64
24+
- goos: darwin
25+
goarch: arm64
26+
- goos: windows
27+
goarch: amd64
28+
29+
steps:
30+
- name: Checkout
31+
uses: actions/checkout@v4
32+
33+
- name: Setup Go
34+
uses: actions/setup-go@v5
35+
with:
36+
go-version: '1.21'
37+
38+
- name: Get version
39+
id: version
40+
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
41+
42+
- name: Build
43+
env:
44+
GOOS: ${{ matrix.goos }}
45+
GOARCH: ${{ matrix.goarch }}
46+
run: |
47+
VERSION=${{ steps.version.outputs.VERSION }}
48+
OUTPUT_NAME=oops-${{ matrix.goos }}-${{ matrix.goarch }}
49+
50+
if [ "${{ matrix.goos }}" = "windows" ]; then
51+
go build -ldflags "-X github.com/iyulab/oops/cmd.Version=${VERSION#v}" -o ${OUTPUT_NAME}.exe .
52+
zip ${OUTPUT_NAME}.zip ${OUTPUT_NAME}.exe
53+
else
54+
go build -ldflags "-X github.com/iyulab/oops/cmd.Version=${VERSION#v}" -o ${OUTPUT_NAME} .
55+
tar -czvf ${OUTPUT_NAME}.tar.gz ${OUTPUT_NAME}
56+
fi
57+
58+
- name: Upload artifact
59+
uses: actions/upload-artifact@v4
60+
with:
61+
name: oops-${{ matrix.goos }}-${{ matrix.goarch }}
62+
path: |
63+
*.zip
64+
*.tar.gz
65+
66+
release:
67+
name: Release
68+
needs: build
69+
runs-on: ubuntu-latest
70+
steps:
71+
- name: Download all artifacts
72+
uses: actions/download-artifact@v4
73+
with:
74+
path: artifacts
75+
merge-multiple: true
76+
77+
- name: List artifacts
78+
run: ls -la artifacts/
79+
80+
- name: Create Release
81+
uses: softprops/action-gh-release@v1
82+
with:
83+
files: artifacts/*
84+
generate_release_notes: true
85+
draft: false
86+
prerelease: ${{ contains(github.ref, '-') }}
87+
env:
88+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,24 @@
11
# local
2-
dev-docs/
2+
dev-docs/
3+
4+
# Binaries
5+
oops
6+
oops.exe
7+
build/
8+
9+
# IDE
10+
.idea/
11+
.vscode/
12+
*.swp
13+
*.swo
14+
15+
# OS
16+
.DS_Store
17+
Thumbs.db
18+
19+
# Test
20+
testdata/
21+
coverage.out
22+
23+
# Oops version storage
24+
.oops/

Makefile

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
.PHONY: build test clean release
2+
3+
VERSION ?= 0.1.0
4+
BINARY_NAME = oops
5+
BUILD_DIR = build
6+
7+
build:
8+
go build -o $(BINARY_NAME) .
9+
10+
test:
11+
go test ./... -v
12+
13+
clean:
14+
rm -rf $(BUILD_DIR) $(BINARY_NAME) $(BINARY_NAME).exe
15+
16+
release: clean
17+
mkdir -p $(BUILD_DIR)
18+
# Windows
19+
GOOS=windows GOARCH=amd64 go build -o $(BUILD_DIR)/$(BINARY_NAME)-windows-amd64.exe .
20+
# Linux
21+
GOOS=linux GOARCH=amd64 go build -o $(BUILD_DIR)/$(BINARY_NAME)-linux-amd64 .
22+
# macOS Intel
23+
GOOS=darwin GOARCH=amd64 go build -o $(BUILD_DIR)/$(BINARY_NAME)-darwin-amd64 .
24+
# macOS Apple Silicon
25+
GOOS=darwin GOARCH=arm64 go build -o $(BUILD_DIR)/$(BINARY_NAME)-darwin-arm64 .
26+
27+
install:
28+
go install .

README.md

Lines changed: 90 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Oops - Git-Style Single File Versioning
1+
# Oops - Simple File Versioning for Everyone 🎯
22

3-
**Familiar Git commands, simplified for single files.**
3+
**Oops! Made a mistake? No worries - you can always go back!**
44

5-
A single binary with zero dependencies. No Git, no Node.js, no runtime required.
5+
A single binary with zero runtime dependencies. Git-powered but Git-knowledge not required.
66

77
## Installation
88

@@ -12,92 +12,135 @@ go install github.com/iyulab/oops@latest
1212

1313
Or download from [GitHub Releases](https://github.com/iyulab/oops/releases).
1414

15+
> **Requires**: Git installed on your system
16+
1517
## Quick Start
1618

1719
```bash
18-
oops track config.txt # Start versioning
19-
vim config.txt # Edit with any editor
20-
oops commit "updated" # Save checkpoint
21-
oops diff # See changes
22-
oops checkout 1 # Go back if needed
20+
oops start essay.txt # 👀 Start versioning
21+
# ... write something ...
22+
oops save "first draft" # 📸 Save a snapshot
23+
# ... edit more ...
24+
oops save "added conclusion" # 📸 Save another
25+
oops history # 📜 View all snapshots
26+
oops oops! # ↩️ Made a mistake? Go back!
2327
```
2428

2529
## Commands
2630

31+
### Friendly Commands (Recommended)
32+
2733
| Command | Description |
2834
|---------|-------------|
29-
| `oops track <file>` | Start versioning (creates version 1) |
30-
| `oops commit [message]` | Create next version |
31-
| `oops checkout <version>` | Navigate to version (`-f` to force) |
32-
| `oops diff [version]` | Show changes |
33-
| `oops log` | Show version history |
34-
| `oops status` | Show current state |
35-
| `oops list` | List tracked files |
36-
| `oops untrack` | Stop tracking |
35+
| `oops start <file>` | 👀 Start versioning a file |
36+
| `oops save [message]` | 📸 Save a snapshot |
37+
| `oops back <N>` | ⏪ Go back to snapshot #N |
38+
| `oops oops!` | ↩️ Undo (restore last saved state) |
39+
| `oops history` | 📜 View all snapshots |
40+
| `oops changes` | 🔍 See what changed |
41+
| `oops now` | ℹ️ Show current status |
42+
| `oops files` | 📁 List tracked files |
43+
| `oops done` | 🗑️ Stop versioning |
44+
45+
### Developer Aliases
46+
47+
If you're familiar with Git, these work too:
48+
49+
| Friendly | Git-style |
50+
|----------|-----------|
51+
| `start` | `track` |
52+
| `save` | `commit` |
53+
| `back` | `checkout` |
54+
| `history` | `log` |
55+
| `changes` | `diff` |
56+
| `now` | `status` |
57+
| `done` | `untrack` |
3758

3859
## Examples
3960

4061
### Basic Workflow
4162

4263
```bash
43-
oops track notes.md # Version 1
44-
# ... edit ...
45-
oops commit "first draft" # Version 2
64+
oops start notes.md # Snapshot #1 created
65+
# ... write ...
66+
oops save "brain dump" # Snapshot #2
4667
# ... edit ...
47-
oops commit "revisions" # Version 3
68+
oops save "organized thoughts" # Snapshot #3
4869
```
4970

50-
### Compare Versions
71+
### Oops! Moments
5172

5273
```bash
53-
oops diff # Working file vs current version
54-
oops diff 1 # Working file vs version 1
55-
oops diff 1 3 # Version 1 vs version 3
74+
# Accidentally deleted important text?
75+
oops oops! # Restores to last saved state
76+
77+
# Want to see an older version?
78+
oops back 1 # Go to snapshot #1
79+
oops back 3 # Jump back to snapshot #3
5680
```
5781

58-
### Navigation
82+
### See What Changed
5983

6084
```bash
61-
oops log # See all versions
62-
oops checkout 2 # Jump to version 2
63-
oops checkout -f 1 # Force checkout (discard uncommitted changes)
85+
oops changes # Unsaved changes vs last snapshot
86+
oops changes 1 # Current vs snapshot #1
87+
oops changes 1 3 # Compare snapshot #1 and #3
6488
```
6589

66-
### Branching from Past
90+
### Check Status
6791

6892
```bash
69-
# At version 10, go back to version 2
70-
oops checkout 2
71-
# ... edit ...
72-
oops commit "new direction" # Creates version 11 (from v2)
93+
oops now
94+
# 📄 File: notes.md
95+
# 📍 Snapshot: #3 (latest)
96+
# ✏️ Status: Modified
97+
#
98+
# You have unsaved changes
99+
# oops save Save your changes
100+
# oops oops! Undo changes
73101
```
74102

75-
All versions preserved. No data loss.
76-
77103
## How It Works
78104

79-
Versions stored in `.oops/` alongside your file:
105+
Oops uses Git under the hood, but hides all the complexity:
80106

81107
```
82108
project/
83-
├── config.txt
109+
├── notes.md
84110
└── .oops/
85-
└── {hash}/
86-
├── meta.json
87-
└── versions/
88-
├── 1
89-
├── 2
90-
└── 3
111+
└── notes.md.git/ ← Git repository (hidden)
91112
```
92113

93-
Automatically added to `.gitignore` if present.
114+
- Each snapshot = Git commit + tag (v1, v2, v3...)
115+
- Full Git delta compression for storage efficiency
116+
- Works completely offline, no server needed
117+
- `.oops/` automatically added to `.gitignore`
94118

95119
## Use Cases
96120

97-
**Good for**: Config files, scripts, documentation, notes
121+
**Perfect for:**
122+
- 📝 Writers - essays, articles, manuscripts
123+
- 📊 Researchers - notes, data files
124+
- ⚙️ Config files - when you need quick rollback
125+
- 📋 Any single file you edit frequently
126+
127+
**For multi-file projects:** Use Git directly
128+
129+
## Comparison
130+
131+
| Feature | Oops | Git |
132+
|---------|------|-----|
133+
| Learning curve | 5 minutes | Hours |
134+
| Commands to learn | ~5 | ~20+ |
135+
| Single file focus || Multi-file |
136+
| Server required | No | Optional |
137+
| Storage efficiency | Git-level | Git |
138+
| Undo mistakes | `oops oops!` | `git checkout HEAD -- file` |
139+
140+
## Why "Oops"?
98141

99-
**Not for**: Multi-file projects, binary files, team collaboration → use Git
142+
Because everyone makes mistakes when editing files. With Oops, you can simply say "oops!" and go back to a safe state. No complex commands, no fear of losing work.
100143

101144
## License
102145

103-
MIT
146+
MIT

0 commit comments

Comments
 (0)