Skip to content

Commit 8085b4f

Browse files
committed
refactor: patch requests -> patchsets -> patches
Previously a patch request contained a series of patches. This worked great as an MVP but we are starting to see some issues with this impl. Previously the contrib and reviewer would push patches to git-pr similar to github pull requests. They all get merged into a single patchset. This mostly works until you want to start editing previous commits to keep the commit history tidy and relevant. For many workflows, going back to a previous commit and amending it to address feedback is desirable. This creates a new model, patchset, which is a mostly immutable container for patches. 1-to-many patch request to patchsets and 1-to-many patchset to patches. Think of these patchsets as revisions. This allows us to better organize collaboration and enable features like `git range-diff` to see changes between revisions. BREAKING CHANGE: sqlite dbs will have to be recreated as the new models are fundamentally different. Sorry for the inconvenience!
1 parent 8460ee0 commit 8085b4f

File tree

12 files changed

+763
-336
lines changed

12 files changed

+763
-336
lines changed

cli.go

+202-124
Large diffs are not rendered by default.

db.go

+83-53
Original file line numberDiff line numberDiff line change
@@ -42,35 +42,43 @@ type PatchRequest struct {
4242
LastUpdated string `db:"last_updated"`
4343
}
4444

45+
type Patchset struct {
46+
ID int64 `db:"id"`
47+
UserID int64 `db:"user_id"`
48+
PatchRequestID int64 `db:"patch_request_id"`
49+
Review bool `db:"review"`
50+
CreatedAt time.Time `db:"created_at"`
51+
}
52+
4553
// Patch is a database model for a single entry in a patchset.
4654
// This usually corresponds to a git commit.
4755
type Patch struct {
48-
ID int64 `db:"id"`
49-
UserID int64 `db:"user_id"`
50-
PatchRequestID int64 `db:"patch_request_id"`
51-
AuthorName string `db:"author_name"`
52-
AuthorEmail string `db:"author_email"`
53-
AuthorDate string `db:"author_date"`
54-
Title string `db:"title"`
55-
Body string `db:"body"`
56-
BodyAppendix string `db:"body_appendix"`
57-
CommitSha string `db:"commit_sha"`
58-
ContentSha string `db:"content_sha"`
59-
BaseCommitSha sql.NullString `db:"base_commit_sha"`
60-
Review bool `db:"review"`
61-
RawText string `db:"raw_text"`
62-
CreatedAt time.Time `db:"created_at"`
56+
ID int64 `db:"id"`
57+
UserID int64 `db:"user_id"`
58+
PatchsetID int64 `db:"patchset_id"`
59+
AuthorName string `db:"author_name"`
60+
AuthorEmail string `db:"author_email"`
61+
AuthorDate string `db:"author_date"`
62+
Title string `db:"title"`
63+
Body string `db:"body"`
64+
BodyAppendix string `db:"body_appendix"`
65+
CommitSha string `db:"commit_sha"`
66+
ContentSha string `db:"content_sha"`
67+
BaseCommitSha sql.NullString `db:"base_commit_sha"`
68+
RawText string `db:"raw_text"`
69+
CreatedAt time.Time `db:"created_at"`
6370
}
6471

6572
// EventLog is a event log for RSS or other notification systems.
6673
type EventLog struct {
67-
ID int64 `db:"id"`
68-
UserID int64 `db:"user_id"`
69-
RepoID string `db:"repo_id"`
70-
PatchRequestID int64 `db:"patch_request_id"`
71-
Event string `db:"event"`
72-
Data string `db:"data"`
73-
CreatedAt time.Time `db:"created_at"`
74+
ID int64 `db:"id"`
75+
UserID int64 `db:"user_id"`
76+
RepoID string `db:"repo_id"`
77+
PatchRequestID sql.NullInt64 `db:"patch_request_id"`
78+
PatchsetID sql.NullInt64 `db:"patchset_id"`
79+
Event string `db:"event"`
80+
Data string `db:"data"`
81+
CreatedAt time.Time `db:"created_at"`
7482
}
7583

7684
// DB is the interface for a pico/git database.
@@ -111,54 +119,76 @@ CREATE TABLE IF NOT EXISTS patch_requests (
111119
ON UPDATE CASCADE
112120
);
113121
114-
CREATE TABLE IF NOT EXISTS patches (
122+
CREATE TABLE IF NOT EXISTS patchsets (
115123
id INTEGER PRIMARY KEY AUTOINCREMENT,
116124
user_id INTEGER NOT NULL,
117125
patch_request_id INTEGER NOT NULL,
118-
author_name TEXT NOT NULL,
119-
author_email TEXT NOT NULL,
120-
author_date DATETIME NOT NULL,
121-
title TEXT NOT NULL,
122-
body TEXT NOT NULL,
123-
body_appendix TEXT NOT NULL,
124-
commit_sha TEXT NOT NULL,
125-
content_sha TEXT NOT NULL,
126126
review BOOLEAN NOT NULL DEFAULT false,
127-
raw_text TEXT NOT NULL,
128-
base_commit_sha TEXT,
129127
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
130-
CONSTRAINT pr_id_fk
131-
FOREIGN KEY(patch_request_id) REFERENCES patch_requests(id)
128+
CONSTRAINT patchset_user_id_fk
129+
FOREIGN KEY(user_id) REFERENCES app_users(id)
132130
ON DELETE CASCADE
133131
ON UPDATE CASCADE,
134-
CONSTRAINT patches_user_id_fk
135-
FOREIGN KEY(user_id) REFERENCES app_users(id)
132+
CONSTRAINT patchset_patch_request_id_fk
133+
FOREIGN KEY(patch_request_id) REFERENCES patch_requests(id)
136134
ON DELETE CASCADE
137135
ON UPDATE CASCADE
138136
);
139137
138+
CREATE TABLE IF NOT EXISTS patches (
139+
id INTEGER PRIMARY KEY AUTOINCREMENT,
140+
user_id INTEGER NOT NULL,
141+
patchset_id INTEGER NOT NULL,
142+
author_name TEXT NOT NULL,
143+
author_email TEXT NOT NULL,
144+
author_date DATETIME NOT NULL,
145+
title TEXT NOT NULL,
146+
body TEXT NOT NULL,
147+
body_appendix TEXT NOT NULL,
148+
commit_sha TEXT NOT NULL,
149+
content_sha TEXT NOT NULL,
150+
raw_text TEXT NOT NULL,
151+
base_commit_sha TEXT,
152+
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
153+
CONSTRAINT patches_user_id_fk
154+
FOREIGN KEY(user_id) REFERENCES app_users(id)
155+
ON DELETE CASCADE
156+
ON UPDATE CASCADE,
157+
CONSTRAINT patches_patchset_id_fk
158+
FOREIGN KEY(patchset_id) REFERENCES patchsets(id)
159+
ON DELETE CASCADE
160+
ON UPDATE CASCADE
161+
);
162+
140163
CREATE TABLE IF NOT EXISTS event_logs (
141-
id INTEGER PRIMARY KEY AUTOINCREMENT,
142-
user_id INTEGER NOT NULL,
143-
repo_id TEXT,
144-
patch_request_id INTEGER,
145-
event TEXT NOT NULL,
146-
data TEXT,
147-
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
148-
CONSTRAINT event_logs_pr_id_fk
149-
FOREIGN KEY(patch_request_id) REFERENCES patch_requests(id)
150-
ON DELETE CASCADE
151-
ON UPDATE CASCADE,
152-
CONSTRAINT event_logs_user_id_fk
153-
FOREIGN KEY(user_id) REFERENCES app_users(id)
154-
ON DELETE CASCADE
155-
ON UPDATE CASCADE
164+
id INTEGER PRIMARY KEY AUTOINCREMENT,
165+
user_id INTEGER NOT NULL,
166+
repo_id TEXT,
167+
patch_request_id INTEGER,
168+
patchset_id INTEGER,
169+
event TEXT NOT NULL,
170+
data TEXT,
171+
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
172+
CONSTRAINT event_logs_pr_id_fk
173+
FOREIGN KEY(patch_request_id) REFERENCES patch_requests(id)
174+
ON DELETE CASCADE
175+
ON UPDATE CASCADE,
176+
CONSTRAINT event_logs_patchset_id_fk
177+
FOREIGN KEY(patchset_id) REFERENCES patchsets(id)
178+
ON DELETE CASCADE
179+
ON UPDATE CASCADE,
180+
CONSTRAINT event_logs_user_id_fk
181+
FOREIGN KEY(user_id) REFERENCES app_users(id)
182+
ON DELETE CASCADE
183+
ON UPDATE CASCADE
156184
);
157185
`
158186

159187
var sqliteMigrations = []string{
160188
"", // migration #0 is reserved for schema initialization
161189
"ALTER TABLE patches ADD COLUMN base_commit_sha TEXT",
190+
`
191+
`,
162192
}
163193

164194
// Open opens a database connection.
@@ -199,7 +229,7 @@ func (db *DB) upgrade() error {
199229
return fmt.Errorf("git-pr (version %d) older than schema (version %d)", len(sqliteMigrations), version)
200230
}
201231

202-
tx, err := db.Begin()
232+
tx, err := db.Beginx()
203233
if err != nil {
204234
return err
205235
}

fixtures/single.diff

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
diff --git a/README.md b/README.md
2+
index 586bc0d..8f3a780 100644
3+
--- a/README.md
4+
+++ b/README.md
5+
@@ -1,3 +1,3 @@
6+
-# test
7+
+# Let's build an RNN
8+
9+
-testing git pr
10+
+This repo demonstrates building an RNN using `pytorch`
11+
diff --git a/train.py b/train.py
12+
new file mode 100644
13+
index 0000000..5c027f4
14+
--- /dev/null
15+
+++ b/train.py
16+
@@ -0,0 +1,2 @@
17+
+if __name__ == "__main__":
18+
+ print("train!")

fixtures/single.patch

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
From 59456574a0bfee9f71c91c13046173c820152346 Mon Sep 17 00:00:00 2001
2+
From: Eric Bower <[email protected]>
3+
Date: Wed, 3 Jul 2024 15:18:47 -0400
4+
Subject: [PATCH] feat: lets build an rnn
5+
6+
---
7+
README.md | 4 ++--
8+
train.py | 2 ++
9+
2 files changed, 4 insertions(+), 2 deletions(-)
10+
create mode 100644 train.py
11+
12+
diff --git a/README.md b/README.md
13+
index 586bc0d..8f3a780 100644
14+
--- a/README.md
15+
+++ b/README.md
16+
@@ -1,3 +1,3 @@
17+
-# test
18+
+# Let's build an RNN
19+
20+
-testing git pr
21+
+This repo demonstrates building an RNN using `pytorch`
22+
diff --git a/train.py b/train.py
23+
new file mode 100644
24+
index 0000000..5c027f4
25+
--- /dev/null
26+
+++ b/train.py
27+
@@ -0,0 +1,2 @@
28+
+if __name__ == "__main__":
29+
+ print("train!")
30+
--
31+
2.45.2

mdw.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package git
22

33
import (
4+
"fmt"
5+
46
"github.com/charmbracelet/ssh"
57
"github.com/charmbracelet/wish"
68
)
@@ -14,7 +16,7 @@ func GitPatchRequestMiddleware(be *Backend, pr GitPatchRequest) wish.Middleware
1416
err := cli.Run(margs)
1517
if err != nil {
1618
be.Logger.Error("error when running cli", "err", err)
17-
wish.Fatalln(sesh, err)
19+
wish.Fatalln(sesh, fmt.Errorf("err: %w", err))
1820
next(sesh)
1921
return
2022
}

0 commit comments

Comments
 (0)