@tienne/gestalt 0.68.0 → 0.70.0
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.
- package/CLAUDE.md +10 -2
- package/README.md +1 -0
- package/dist/package.json +2 -1
- package/dist/plugin/review-agents/quality-reviewer/AGENT.md +1 -1
- package/dist/plugin/review-agents/writing-reviewer/AGENT.md +2 -2
- package/dist/plugin/role-agents/humanize-monolith/AGENT.md +89 -11
- package/dist/plugin/skills/local-pr/SKILL.md +201 -0
- package/dist/plugin/skills/pr/SKILL.md +73 -4
- package/dist/plugin/skills/review/SKILL.md +190 -18
- package/dist/plugin/skills/review-reply/SKILL.md +144 -7
- package/dist/src/cli/commands/humanize-check.d.ts +2 -0
- package/dist/src/cli/commands/humanize-check.d.ts.map +1 -1
- package/dist/src/cli/commands/humanize-check.js +11 -5
- package/dist/src/cli/commands/humanize-check.js.map +1 -1
- package/dist/src/cli/commands/humanize-scan.d.ts +23 -0
- package/dist/src/cli/commands/humanize-scan.d.ts.map +1 -0
- package/dist/src/cli/commands/humanize-scan.js +30 -0
- package/dist/src/cli/commands/humanize-scan.js.map +1 -0
- package/dist/src/cli/commands/pr.d.ts +133 -0
- package/dist/src/cli/commands/pr.d.ts.map +1 -0
- package/dist/src/cli/commands/pr.js +489 -0
- package/dist/src/cli/commands/pr.js.map +1 -0
- package/dist/src/cli/index.d.ts.map +1 -1
- package/dist/src/cli/index.js +96 -0
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/core/config.d.ts.map +1 -1
- package/dist/src/core/config.js +4 -3
- package/dist/src/core/config.js.map +1 -1
- package/dist/src/core/home.d.ts +20 -0
- package/dist/src/core/home.d.ts.map +1 -0
- package/dist/src/core/home.js +52 -0
- package/dist/src/core/home.js.map +1 -0
- package/dist/src/core/types.d.ts +38 -0
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/core/version.d.ts.map +1 -1
- package/dist/src/core/version.js +4 -7
- package/dist/src/core/version.js.map +1 -1
- package/dist/src/events/store.d.ts +32 -0
- package/dist/src/events/store.d.ts.map +1 -1
- package/dist/src/events/store.js +68 -3
- package/dist/src/events/store.js.map +1 -1
- package/dist/src/humanize/check.d.ts +75 -7
- package/dist/src/humanize/check.d.ts.map +1 -1
- package/dist/src/humanize/check.js +241 -30
- package/dist/src/humanize/check.js.map +1 -1
- package/dist/src/humanize/detectors.d.ts.map +1 -1
- package/dist/src/humanize/detectors.js +7 -8
- package/dist/src/humanize/detectors.js.map +1 -1
- package/dist/src/humanize/index.d.ts +3 -2
- package/dist/src/humanize/index.d.ts.map +1 -1
- package/dist/src/humanize/index.js +3 -2
- package/dist/src/humanize/index.js.map +1 -1
- package/dist/src/humanize/rules.d.ts +12 -0
- package/dist/src/humanize/rules.d.ts.map +1 -1
- package/dist/src/humanize/rules.js +4 -0
- package/dist/src/humanize/rules.js.map +1 -1
- package/dist/src/humanize/scan.d.ts +24 -0
- package/dist/src/humanize/scan.d.ts.map +1 -0
- package/dist/src/humanize/scan.js +65 -0
- package/dist/src/humanize/scan.js.map +1 -0
- package/dist/src/local-pr/engine.d.ts +176 -0
- package/dist/src/local-pr/engine.d.ts.map +1 -0
- package/dist/src/local-pr/engine.js +373 -0
- package/dist/src/local-pr/engine.js.map +1 -0
- package/dist/src/local-pr/git.d.ts +190 -0
- package/dist/src/local-pr/git.d.ts.map +1 -0
- package/dist/src/local-pr/git.js +580 -0
- package/dist/src/local-pr/git.js.map +1 -0
- package/dist/src/local-pr/index.d.ts +6 -0
- package/dist/src/local-pr/index.d.ts.map +1 -0
- package/dist/src/local-pr/index.js +8 -0
- package/dist/src/local-pr/index.js.map +1 -0
- package/dist/src/local-pr/policy.d.ts +77 -0
- package/dist/src/local-pr/policy.d.ts.map +1 -0
- package/dist/src/local-pr/policy.js +80 -0
- package/dist/src/local-pr/policy.js.map +1 -0
- package/dist/src/local-pr/registry.d.ts +79 -0
- package/dist/src/local-pr/registry.d.ts.map +1 -0
- package/dist/src/local-pr/registry.js +307 -0
- package/dist/src/local-pr/registry.js.map +1 -0
- package/dist/src/local-pr/repository.d.ts +67 -0
- package/dist/src/local-pr/repository.d.ts.map +1 -0
- package/dist/src/local-pr/repository.js +251 -0
- package/dist/src/local-pr/repository.js.map +1 -0
- package/dist/src/local-pr/types.d.ts +151 -0
- package/dist/src/local-pr/types.d.ts.map +1 -0
- package/dist/src/local-pr/types.js +9 -0
- package/dist/src/local-pr/types.js.map +1 -0
- package/dist/src/local-pr-web/engine.d.ts +24 -0
- package/dist/src/local-pr-web/engine.d.ts.map +1 -0
- package/dist/src/local-pr-web/engine.js +112 -0
- package/dist/src/local-pr-web/engine.js.map +1 -0
- package/dist/src/local-pr-web/html-generator.d.ts +24 -0
- package/dist/src/local-pr-web/html-generator.d.ts.map +1 -0
- package/dist/src/local-pr-web/html-generator.js +385 -0
- package/dist/src/local-pr-web/html-generator.js.map +1 -0
- package/dist/src/local-pr-web/index.d.ts +5 -0
- package/dist/src/local-pr-web/index.d.ts.map +1 -0
- package/dist/src/local-pr-web/index.js +5 -0
- package/dist/src/local-pr-web/index.js.map +1 -0
- package/dist/src/local-pr-web/server.d.ts +126 -0
- package/dist/src/local-pr-web/server.d.ts.map +1 -0
- package/dist/src/local-pr-web/server.js +394 -0
- package/dist/src/local-pr-web/server.js.map +1 -0
- package/dist/src/local-pr-web/types.d.ts +11 -0
- package/dist/src/local-pr-web/types.d.ts.map +1 -0
- package/dist/src/local-pr-web/types.js +2 -0
- package/dist/src/local-pr-web/types.js.map +1 -0
- package/dist/src/mcp/schemas.d.ts +79 -4
- package/dist/src/mcp/schemas.d.ts.map +1 -1
- package/dist/src/mcp/schemas.js +80 -2
- package/dist/src/mcp/schemas.js.map +1 -1
- package/dist/src/mcp/server.d.ts.map +1 -1
- package/dist/src/mcp/server.js +13 -2
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/mcp/tools/pr.d.ts +5 -0
- package/dist/src/mcp/tools/pr.d.ts.map +1 -0
- package/dist/src/mcp/tools/pr.js +165 -0
- package/dist/src/mcp/tools/pr.js.map +1 -0
- package/dist/src/mcp/tools/review-passthrough.d.ts.map +1 -1
- package/dist/src/mcp/tools/review-passthrough.js +264 -15
- package/dist/src/mcp/tools/review-passthrough.js.map +1 -1
- package/dist/src/memory/user-profile-store.d.ts.map +1 -1
- package/dist/src/memory/user-profile-store.js +3 -4
- package/dist/src/memory/user-profile-store.js.map +1 -1
- package/dist/src/review/context-collector.d.ts +1 -1
- package/dist/src/review/context-collector.js +1 -1
- package/dist/src/review/passthrough-engine.d.ts +1 -0
- package/dist/src/review/passthrough-engine.d.ts.map +1 -1
- package/dist/src/review/passthrough-engine.js +7 -2
- package/dist/src/review/passthrough-engine.js.map +1 -1
- package/dist/src/spec/text-based-spec-generator.d.ts.map +1 -1
- package/dist/src/spec/text-based-spec-generator.js +5 -2
- package/dist/src/spec/text-based-spec-generator.js.map +1 -1
- package/package.json +2 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/review-agents/quality-reviewer/AGENT.md +1 -1
- package/plugin/review-agents/writing-reviewer/AGENT.md +2 -2
- package/plugin/role-agents/humanize-monolith/AGENT.md +89 -11
- package/plugin/skills/local-pr/SKILL.md +201 -0
- package/plugin/skills/pr/SKILL.md +73 -4
- package/plugin/skills/review/SKILL.md +190 -18
- package/plugin/skills/review-reply/SKILL.md +144 -7
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdirSync } from 'node:fs';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
import { EventStore } from '../events/store.js';
|
|
5
|
+
import * as git from './git.js';
|
|
6
|
+
import { unresolvedCount } from './policy.js';
|
|
7
|
+
import { PrEvent, PullRequestRepository } from './repository.js';
|
|
8
|
+
import { PR_AGGREGATE } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* 로컬 PR을 만들고 굴린다.
|
|
11
|
+
*
|
|
12
|
+
* 상태 전이 규칙이 여기 산다. 승인 게이트는 없어서 승인 없이 머지할 수 있다.
|
|
13
|
+
* 대신 그 시점의 미해결 스레드 수를 이벤트에 남겨 나중에 되짚게 한다.
|
|
14
|
+
*/
|
|
15
|
+
export class LocalPrEngine {
|
|
16
|
+
repoRoot;
|
|
17
|
+
store;
|
|
18
|
+
repo;
|
|
19
|
+
constructor(repoRoot, store) {
|
|
20
|
+
this.repoRoot = repoRoot;
|
|
21
|
+
if (store) {
|
|
22
|
+
this.store = store;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const dbPath = git.reviewsDbPath(repoRoot);
|
|
26
|
+
mkdirSync(dirname(dbPath), { recursive: true });
|
|
27
|
+
this.store = new EventStore(dbPath);
|
|
28
|
+
}
|
|
29
|
+
this.repo = new PullRequestRepository(this.store);
|
|
30
|
+
}
|
|
31
|
+
/** 저장소를 닫는다. PR을 닫는 closePr과 헷갈리지 않게 이름을 갈라뒀다 */
|
|
32
|
+
dispose() {
|
|
33
|
+
this.store.close();
|
|
34
|
+
}
|
|
35
|
+
// ─── 조회 ────────────────────────────────────────────────
|
|
36
|
+
get(prId) {
|
|
37
|
+
return this.repo.reconstruct(prId);
|
|
38
|
+
}
|
|
39
|
+
list(status) {
|
|
40
|
+
return status ? this.repo.reconstructByStatus(status) : this.repo.reconstructAll();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 상태별 PR 개수.
|
|
44
|
+
*
|
|
45
|
+
* 개수만 필요한 자리가 PR을 다 접지 않게 한다 — 웹 UI의 레포 배지가 레포마다
|
|
46
|
+
* `list('open')`을 부르느라 화면 한 번에 전체 재생이 레포 수만큼 돌았다.
|
|
47
|
+
*/
|
|
48
|
+
countByStatus() {
|
|
49
|
+
return this.repo.countByStatus();
|
|
50
|
+
}
|
|
51
|
+
diff(prId) {
|
|
52
|
+
const pr = this.require(prId);
|
|
53
|
+
return git.diff(this.repoRoot, pr.baseSha, pr.headSha);
|
|
54
|
+
}
|
|
55
|
+
changedFiles(prId) {
|
|
56
|
+
const pr = this.require(prId);
|
|
57
|
+
return git.changedFiles(this.repoRoot, pr.baseSha, pr.headSha);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* PR head를 임시 워크트리로 떼어 놓고 그 경로를 준다.
|
|
61
|
+
*
|
|
62
|
+
* 리뷰어가 코드를 깨서 테스트가 잡는지 보려면 실물 파일이 필요하다. diff만으로는
|
|
63
|
+
* 못 하는 검증이다. 닫히거나 머지된 PR도 떼어낼 수 있게 열림 여부는 안 본다 —
|
|
64
|
+
* 머지된 뒤에 "그때 그 코드가 맞았나"를 되짚는 자리가 있다.
|
|
65
|
+
*/
|
|
66
|
+
checkout(prId) {
|
|
67
|
+
const pr = this.require(prId);
|
|
68
|
+
if (!git.commitExists(this.repoRoot, pr.headSha)) {
|
|
69
|
+
throw new PrError(`head 커밋이 이 레포에 없다: ${pr.headSha.slice(0, 8)}`, 3);
|
|
70
|
+
}
|
|
71
|
+
return git.checkoutPrHead(this.repoRoot, prId, pr.headSha);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 떼어 놓은 워크트리를 지운다.
|
|
75
|
+
*
|
|
76
|
+
* 지킬 변경이 있으면 지우지 않고 그 사실을 돌려준다. 부르는 쪽은 결과의 `status`로
|
|
77
|
+
* 갈래를 탄다. PR head를 함께 넘겨야 그 자리에서 쌓은 커밋을 가려낼 수 있다.
|
|
78
|
+
*/
|
|
79
|
+
removeCheckout(prId, options = {}) {
|
|
80
|
+
const pr = this.require(prId);
|
|
81
|
+
return git.removePrCheckout(this.repoRoot, prId, { ...options, headSha: pr.headSha });
|
|
82
|
+
}
|
|
83
|
+
// ─── 생성과 갱신 ─────────────────────────────────────────
|
|
84
|
+
create(input) {
|
|
85
|
+
const baseRef = input.base ?? 'main';
|
|
86
|
+
const headRev = input.head ?? 'HEAD';
|
|
87
|
+
const headSha = git.resolveSha(this.repoRoot, headRev);
|
|
88
|
+
const baseSha = git.mergeBase(this.repoRoot, baseRef, headSha);
|
|
89
|
+
if (baseSha === headSha) {
|
|
90
|
+
throw new PrError('head가 base와 같다. 리뷰할 변경이 없다', 4);
|
|
91
|
+
}
|
|
92
|
+
const prId = randomUUID().slice(0, 8);
|
|
93
|
+
const headRef = input.head ?? git.currentBranch(this.repoRoot);
|
|
94
|
+
// 이벤트보다 ref를 먼저 붙인다. 사이에 죽어도 커밋은 살아 있다
|
|
95
|
+
git.pinRefs(this.repoRoot, prId, baseSha, headSha);
|
|
96
|
+
// 여기서 전역 레포 목록에 등록하지 않는다. 이 자리는 MCP `ges_pr`의 repoRoot로
|
|
97
|
+
// 이어져 있어서 등록하면 도구 호출 한 번이 인증 없는 웹 UI가 열어 줄 레포를 영구히
|
|
98
|
+
// 늘린다. 목록에 넣는 건 사람이 그 레포에서 `pr serve`를 띄울 때다
|
|
99
|
+
// → src/local-pr/registry.ts 머리말
|
|
100
|
+
this.store.append(PR_AGGREGATE, prId, PrEvent.CREATED, {
|
|
101
|
+
title: input.title,
|
|
102
|
+
body: input.body ?? '',
|
|
103
|
+
author: input.author,
|
|
104
|
+
baseSha,
|
|
105
|
+
headSha,
|
|
106
|
+
headRef,
|
|
107
|
+
baseRef,
|
|
108
|
+
});
|
|
109
|
+
return this.require(prId);
|
|
110
|
+
}
|
|
111
|
+
/** head를 지금 커밋으로 옮긴다. 코멘트는 그대로 붙어 있다. 본문만 고치려면 `edit`이다 */
|
|
112
|
+
update(prId, head) {
|
|
113
|
+
const pr = this.requireOpen(prId);
|
|
114
|
+
const headSha = git.resolveSha(this.repoRoot, head ?? pr.headRef ?? 'HEAD');
|
|
115
|
+
if (headSha === pr.headSha) {
|
|
116
|
+
throw new PrError('head가 그대로다. 옮길 것이 없다', 4);
|
|
117
|
+
}
|
|
118
|
+
git.pinRefs(this.repoRoot, prId, pr.baseSha, headSha);
|
|
119
|
+
this.store.append(PR_AGGREGATE, prId, PrEvent.UPDATED, {
|
|
120
|
+
headSha,
|
|
121
|
+
headRef: head ?? pr.headRef,
|
|
122
|
+
});
|
|
123
|
+
return this.require(prId);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* 제목과 본문을 고친다. head는 그대로다.
|
|
127
|
+
*
|
|
128
|
+
* `update`와 갈라 둔 자리다. `update`는 "고쳐서 다시 올렸다"라 head가 안 움직이면
|
|
129
|
+
* 거절하고 움직이면 `changes_requested`를 `open`으로 되돌린다. 본문 오타 수정은
|
|
130
|
+
* 둘 다 틀리다 — 옮길 head가 없어서 거절당하고 억지로 태우면 리뷰어가 내린 판정이
|
|
131
|
+
* 글자 하나 고쳤다고 풀린다. 그래서 `pr.edited`를 따로 낸다.
|
|
132
|
+
*
|
|
133
|
+
* 라운드도 안 는다. 새 라운드를 여는 건 `request_changes` 판정 하나뿐이다.
|
|
134
|
+
*
|
|
135
|
+
* 고칠 것을 안 주거나 지금 값과 같으면 던진다. 아무 일도 안 하는 이벤트를 남기면
|
|
136
|
+
* 이력에 "누가 뭘 고쳤다"는 줄이 서는데 정작 달라진 게 없다.
|
|
137
|
+
*
|
|
138
|
+
* 머지되거나 닫힌 PR은 못 고친다. 리뷰가 끝난 기록이라 그 시점 본문이 그대로
|
|
139
|
+
* 남아야 판단을 되짚을 수 있다.
|
|
140
|
+
*/
|
|
141
|
+
edit(prId, changes, by) {
|
|
142
|
+
const pr = this.requireOpen(prId);
|
|
143
|
+
// 빈 제목을 받으면 머지 커밋 메시지가 `Merge local PR <id>:`로 나간다. 머지한
|
|
144
|
+
// 뒤에는 되돌릴 수 없는 유일한 자리라 도메인에서 막는다 — CLI와 MCP가 함께 지난다
|
|
145
|
+
if (changes.title !== undefined && changes.title.trim() === '') {
|
|
146
|
+
throw new PrError('제목을 비울 수 없어요', 1);
|
|
147
|
+
}
|
|
148
|
+
const title = changes.title !== undefined && changes.title !== pr.title ? changes.title : undefined;
|
|
149
|
+
const body = changes.body !== undefined && changes.body !== pr.body ? changes.body : undefined;
|
|
150
|
+
if (title === undefined && body === undefined) {
|
|
151
|
+
throw new PrError('고칠 것이 없다. 지금 제목·본문과 같거나 아무것도 안 줬다', 4);
|
|
152
|
+
}
|
|
153
|
+
this.store.append(PR_AGGREGATE, prId, PrEvent.EDITED, {
|
|
154
|
+
by,
|
|
155
|
+
...(title !== undefined ? { title } : {}),
|
|
156
|
+
...(body !== undefined ? { body } : {}),
|
|
157
|
+
});
|
|
158
|
+
return this.require(prId);
|
|
159
|
+
}
|
|
160
|
+
// ─── 코멘트 ──────────────────────────────────────────────
|
|
161
|
+
/**
|
|
162
|
+
* 코멘트 여러 개를 한 번에 붙인다.
|
|
163
|
+
*
|
|
164
|
+
* `comment`를 N번 부르면 하나마다 PR 전체를 두 번 재생한다 — 앞에서 상태를 얻고
|
|
165
|
+
* 뒤에서 돌려주느라 그렇다. 재생 대상 이벤트도 붙일수록 늘어서 총 비용이 개수의
|
|
166
|
+
* 제곱으로 커진다. 리뷰 합의를 옮기는 자리는 수십에서 수백 개라 그 자리를 밟는다.
|
|
167
|
+
*
|
|
168
|
+
* 상태는 한 번만 접고 이벤트만 이어 붙인다. `onPosted`는 하나 쓸 때마다 그 입력의
|
|
169
|
+
* 인덱스로 부른다 — 중간에 던져도 어디까지 썼는지가 부르는 쪽에 남아야 재시도가
|
|
170
|
+
* 다시 안 쓴다. 부르는 쪽은 이 인덱스로 재개 지점을 잡는다. 자기 카운터를 따로
|
|
171
|
+
* 올리면 두 계산이 갈릴 때 재개 지점이 밀려 코멘트가 겹치거나 빠진다.
|
|
172
|
+
*/
|
|
173
|
+
commentMany(prId, inputs, onPosted) {
|
|
174
|
+
const pr = this.requireOpen(prId);
|
|
175
|
+
inputs.forEach((input, i) => {
|
|
176
|
+
const commentId = randomUUID().slice(0, 8);
|
|
177
|
+
this.store.append(PR_AGGREGATE, prId, PrEvent.COMMENT_ADDED, {
|
|
178
|
+
commentId,
|
|
179
|
+
author: input.author,
|
|
180
|
+
path: input.path,
|
|
181
|
+
line: input.line ?? null,
|
|
182
|
+
body: input.body,
|
|
183
|
+
threadId: commentId,
|
|
184
|
+
headSha: pr.headSha,
|
|
185
|
+
...(input.marker ? { marker: input.marker } : {}),
|
|
186
|
+
});
|
|
187
|
+
onPosted?.(i);
|
|
188
|
+
});
|
|
189
|
+
return this.require(prId);
|
|
190
|
+
}
|
|
191
|
+
comment(prId, input) {
|
|
192
|
+
const pr = this.requireOpen(prId);
|
|
193
|
+
let threadId;
|
|
194
|
+
const commentId = randomUUID().slice(0, 8);
|
|
195
|
+
if (input.replyTo) {
|
|
196
|
+
const parent = pr.comments.find((c) => c.id === input.replyTo);
|
|
197
|
+
if (!parent)
|
|
198
|
+
throw new PrError(`코멘트를 못 찾았다: ${input.replyTo}`, 3);
|
|
199
|
+
threadId = parent.threadId;
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
threadId = commentId;
|
|
203
|
+
}
|
|
204
|
+
this.store.append(PR_AGGREGATE, prId, PrEvent.COMMENT_ADDED, {
|
|
205
|
+
commentId,
|
|
206
|
+
author: input.author,
|
|
207
|
+
path: input.path,
|
|
208
|
+
line: input.line ?? null,
|
|
209
|
+
body: input.body,
|
|
210
|
+
threadId,
|
|
211
|
+
headSha: pr.headSha,
|
|
212
|
+
...(input.marker ? { marker: input.marker } : {}),
|
|
213
|
+
});
|
|
214
|
+
return this.require(prId);
|
|
215
|
+
}
|
|
216
|
+
resolve(prId, commentId, by) {
|
|
217
|
+
const pr = this.requireOpen(prId);
|
|
218
|
+
if (!pr.comments.some((c) => c.id === commentId)) {
|
|
219
|
+
throw new PrError(`코멘트를 못 찾았다: ${commentId}`, 3);
|
|
220
|
+
}
|
|
221
|
+
this.store.append(PR_AGGREGATE, prId, PrEvent.COMMENT_RESOLVED, { commentId, by });
|
|
222
|
+
return this.require(prId);
|
|
223
|
+
}
|
|
224
|
+
// ─── 판정 ────────────────────────────────────────────────
|
|
225
|
+
review(prId, input) {
|
|
226
|
+
const pr = this.requireOpen(prId);
|
|
227
|
+
this.store.append(PR_AGGREGATE, prId, PrEvent.REVIEW_SUBMITTED, {
|
|
228
|
+
reviewId: randomUUID().slice(0, 8),
|
|
229
|
+
reviewer: input.reviewer,
|
|
230
|
+
verdict: input.verdict,
|
|
231
|
+
summary: input.summary,
|
|
232
|
+
headSha: pr.headSha,
|
|
233
|
+
});
|
|
234
|
+
return this.require(prId);
|
|
235
|
+
}
|
|
236
|
+
// ─── 마무리 ──────────────────────────────────────────────
|
|
237
|
+
merge(prId, by, options = {}) {
|
|
238
|
+
const pr = this.requireOpen(prId);
|
|
239
|
+
const { mergeSha } = git.mergeIntoBase(this.repoRoot, {
|
|
240
|
+
prId,
|
|
241
|
+
baseRef: pr.baseRef ?? 'main',
|
|
242
|
+
headSha: pr.headSha,
|
|
243
|
+
title: pr.title,
|
|
244
|
+
});
|
|
245
|
+
this.store.append(PR_AGGREGATE, prId, PrEvent.MERGED, {
|
|
246
|
+
by,
|
|
247
|
+
mergeSha,
|
|
248
|
+
unresolvedCount: unresolvedCount(pr),
|
|
249
|
+
});
|
|
250
|
+
if (options.deleteBranch && pr.headRef) {
|
|
251
|
+
try {
|
|
252
|
+
git.deleteBranch(this.repoRoot, pr.headRef);
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
// 이미 없거나 다른 워크트리가 잡고 있다. 머지는 끝났으니 넘어간다
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return this.require(prId);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* 붙잡아 둘 이유가 끝난 ref를 놓는다.
|
|
262
|
+
*
|
|
263
|
+
* `refs/gestalt/` 아래는 지금까지 단조 증가만 했다. 머지된 PR도 base와 head를
|
|
264
|
+
* 영구 보유한다. `--force` 한 바퀴마다 체크아웃 자국도 한 칸씩 더 쌓인다. 지우는
|
|
265
|
+
* 명령도 만료도 없어서 오래 쓴 레포일수록 `for-each-ref`가 느려지고 `git gc`가
|
|
266
|
+
* 놓지 못하는 객체가 늘어난다.
|
|
267
|
+
*
|
|
268
|
+
* 무엇을 놓는지는 "놓아도 커밋이 안 사라지는가"로 가른다.
|
|
269
|
+
*
|
|
270
|
+
* - **머지된 PR의 base와 head**를 놓는다. 머지 커밋이 base 브랜치 이력에 둘을
|
|
271
|
+
* 모두 넣었으므로 ref를 놓아도 되짚을 수 있다. `unpinRefs`가 닫힌 PR의 base에
|
|
272
|
+
* 대해 이미 쓰는 근거와 같다. 그래도 놓기 전에 head가 정말 base 이력에 있는지
|
|
273
|
+
* 확인한다 — 머지 뒤 누가 base를 되돌렸으면 그 근거가 깨진다. 그때는 안 놓고
|
|
274
|
+
* 이유를 돌려준다.
|
|
275
|
+
* - **닫힌 PR은 아무것도 안 놓는다.** head를 붙잡아 두기로 한 결정이 그대로다.
|
|
276
|
+
* 닫힌 PR도 `checkout`으로 떼어낸다고 약속했다.
|
|
277
|
+
* - **체크아웃 자국(`refs/gestalt/pr-checkout/...`)은 기본으로 안 놓는다.** 그건
|
|
278
|
+
* 어느 이력에도 안 들어간 워크트리 전용 커밋이라 놓으면 영영 사라진다.
|
|
279
|
+
* `checkouts`로 뜻을 밝혔을 때, 그리고 그 PR이 이미 머지되거나 닫혀 리뷰가
|
|
280
|
+
* 끝났을 때만 놓는다.
|
|
281
|
+
*
|
|
282
|
+
* `dryRun`이면 무엇을 놓을지만 돌려주고 손대지 않는다.
|
|
283
|
+
*
|
|
284
|
+
* 지금 붙어 있는 ref를 먼저 한 번에 모아 놓고 PR을 훑는다. 붙어 있지도 않은 ref를
|
|
285
|
+
* 놓았다고 세지 않으려는 게 첫째 이유고 — 머지 PR의 base는 close 경로에서 이미
|
|
286
|
+
* 놓였을 수 있다 — 그 집합을 게이트로 쓰면 버려질 PR에 프로세스를 안 태우는 게
|
|
287
|
+
* 둘째다. 뒤에서 거르면 결과만 같고 스폰은 다 나간다. 놓을 게 하나도 없는 두 번째
|
|
288
|
+
* prune이 첫 번째와 똑같이 비쌌던 이유다.
|
|
289
|
+
*
|
|
290
|
+
* 체크아웃 자국도 이 집합에서 접두사로 걸러 낸다. PR마다 `for-each-ref`를 띄우면
|
|
291
|
+
* 이미 뽑아 둔 목록을 PR 수만큼 다시 뽑는 셈이다.
|
|
292
|
+
*
|
|
293
|
+
* 붙은 ref가 하나도 없는 머지 PR은 `kept`에도 안 올린다. 놓을 게 없으면 근거가
|
|
294
|
+
* 깨졌는지 물을 일도 없다 — "놓을 만했지만 남긴 PR"에 남길 것 자체가 없다.
|
|
295
|
+
*/
|
|
296
|
+
prune(options = {}) {
|
|
297
|
+
const released = [];
|
|
298
|
+
const kept = [];
|
|
299
|
+
const existing = new Set([
|
|
300
|
+
...git.refsUnder(this.repoRoot, git.PR_REF_ROOT),
|
|
301
|
+
...git.refsUnder(this.repoRoot, git.CHECKOUT_REF_ROOT),
|
|
302
|
+
]);
|
|
303
|
+
for (const pr of this.repo.reconstructAll()) {
|
|
304
|
+
if (pr.status === 'merged') {
|
|
305
|
+
const pinned = [`${git.PR_REF_ROOT}/${pr.id}/base`, `${git.PR_REF_ROOT}/${pr.id}/head`];
|
|
306
|
+
const attached = pinned.filter((ref) => existing.has(ref));
|
|
307
|
+
if (attached.length > 0) {
|
|
308
|
+
const baseRef = pr.baseRef ?? 'main';
|
|
309
|
+
if (git.isAncestor(this.repoRoot, pr.headSha, baseRef)) {
|
|
310
|
+
released.push(...attached);
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
kept.push({
|
|
314
|
+
prId: pr.id,
|
|
315
|
+
reason: `머지된 뒤 base ${baseRef}가 되돌아가 head가 그 이력에 없다`,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (options.checkouts && (pr.status === 'merged' || pr.status === 'closed')) {
|
|
321
|
+
const prefix = `${git.CHECKOUT_REF_ROOT}/${pr.id}/`;
|
|
322
|
+
for (const ref of existing) {
|
|
323
|
+
if (ref.startsWith(prefix))
|
|
324
|
+
released.push(ref);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// 확인과 삭제 사이에 base가 되돌아가면 근거가 깨진 채로 놓는다. 그 사이를 막지 않은
|
|
329
|
+
// 건 잃는 게 ref뿐이어서다 — 커밋은 reflog에 남고 PR 기록에 sha가 있어 되살린다
|
|
330
|
+
if (!options.dryRun) {
|
|
331
|
+
for (const ref of released)
|
|
332
|
+
git.deleteRef(this.repoRoot, ref);
|
|
333
|
+
}
|
|
334
|
+
return { released, kept, dryRun: options.dryRun === true };
|
|
335
|
+
}
|
|
336
|
+
closePr(prId, by, reason = '') {
|
|
337
|
+
const pr = this.requireOpen(prId);
|
|
338
|
+
this.store.append(PR_AGGREGATE, prId, PrEvent.CLOSED, { by, reason });
|
|
339
|
+
// base ref만 놓는다. head를 놓으면 닫힌 PR의 커밋이 gc에 수거돼 checkout도 diff도
|
|
340
|
+
// 죽는데, checkout은 닫힌 PR도 떼어낸다고 약속한 자리다
|
|
341
|
+
git.unpinRefs(this.repoRoot, prId);
|
|
342
|
+
return this.require(pr.id);
|
|
343
|
+
}
|
|
344
|
+
// ─── 안쪽 ────────────────────────────────────────────────
|
|
345
|
+
require(prId) {
|
|
346
|
+
const pr = this.repo.reconstruct(prId);
|
|
347
|
+
if (!pr)
|
|
348
|
+
throw new PrError(`PR을 못 찾았다: ${prId}`, 3);
|
|
349
|
+
return pr;
|
|
350
|
+
}
|
|
351
|
+
requireOpen(prId) {
|
|
352
|
+
const pr = this.require(prId);
|
|
353
|
+
if (pr.status === 'merged' || pr.status === 'closed') {
|
|
354
|
+
throw new PrError(`이미 ${pr.status} 상태다: ${prId}`, 4);
|
|
355
|
+
}
|
|
356
|
+
return pr;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* 종료 코드를 달고 다니는 오류.
|
|
361
|
+
*
|
|
362
|
+
* 부르는 쪽이 에이전트라 stdout을 안 읽고도 갈래를 타야 한다.
|
|
363
|
+
* 3은 못 찾음, 4는 상태 충돌이다.
|
|
364
|
+
*/
|
|
365
|
+
export class PrError extends Error {
|
|
366
|
+
exitCode;
|
|
367
|
+
constructor(message, exitCode) {
|
|
368
|
+
super(message);
|
|
369
|
+
this.exitCode = exitCode;
|
|
370
|
+
this.name = 'PrError';
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/local-pr/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
export declare function gitCommonDir(repoRoot: string): string;
|
|
2
|
+
/**
|
|
3
|
+
* PR 저장소 경로. 본체 git 디렉토리 옆에 둔다.
|
|
4
|
+
*
|
|
5
|
+
* 워크트리 어디서 불러도 같은 파일을 가리켜야 목록이 갈라지지 않는다.
|
|
6
|
+
*/
|
|
7
|
+
export declare function reviewsDbPath(repoRoot: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* PR 커밋을 붙잡아 두는 ref의 뿌리.
|
|
10
|
+
*
|
|
11
|
+
* 이름을 리터럴로 여러 자리에 적으면 하나를 고칠 때 나머지가 남는다. 붙이는 자리와
|
|
12
|
+
* 놓는 자리와 훑는 자리가 이미 셋이라 상수로 둔다.
|
|
13
|
+
*/
|
|
14
|
+
export declare const PR_REF_ROOT = "refs/gestalt/pr";
|
|
15
|
+
/** `--force`로 지울 때 워크트리 전용 커밋을 붙잡아 둘 ref의 뿌리 */
|
|
16
|
+
export declare const CHECKOUT_REF_ROOT = "refs/gestalt/pr-checkout";
|
|
17
|
+
export declare function resolveSha(repoRoot: string, rev: string): string;
|
|
18
|
+
/** 두 갈래가 갈라진 지점. PR의 base가 된다 */
|
|
19
|
+
export declare function mergeBase(repoRoot: string, base: string, head: string): string;
|
|
20
|
+
/** 지금 올라타 있는 브랜치 이름. detached HEAD면 null */
|
|
21
|
+
export declare function currentBranch(repoRoot: string): string | null;
|
|
22
|
+
/**
|
|
23
|
+
* PR의 커밋을 ref로 붙잡는다.
|
|
24
|
+
*
|
|
25
|
+
* 워커가 브랜치를 지우거나 리베이스해도 이 ref가 커밋을 잡고 있어 diff가 산다.
|
|
26
|
+
* GitHub이 `refs/pull/N/head`를 두는 것과 같은 이유다. 붙잡지 않으면 gc가
|
|
27
|
+
* 수거해 간 뒤 PR이 빈 껍데기가 된다.
|
|
28
|
+
*/
|
|
29
|
+
export declare function pinRefs(repoRoot: string, prId: string, baseSha: string, headSha: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* 붙잡아 둔 ref를 놓는다.
|
|
32
|
+
*
|
|
33
|
+
* **head는 안 놓는다.** PR을 닫아도 그 커밋은 되짚을 수 있어야 한다 — `checkout`이
|
|
34
|
+
* 닫힌 PR도 떼어낸다고 약속한다. 그게 "그때 그 코드가 맞았나"를 나중에 보는 자리다.
|
|
35
|
+
* head까지 놓으면 브랜치도 지워진 PR은 gc가 한 번 돌고 나서 빈 껍데기가 된다.
|
|
36
|
+
*
|
|
37
|
+
* base만 놓는 이유는 그 커밋이 base 브랜치 이력에 이미 들어 있어서다. 놓아도 안 사라진다.
|
|
38
|
+
*/
|
|
39
|
+
export declare function unpinRefs(repoRoot: string, prId: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* diff 계열은 셋 다 config에 적힌 외부 필터를 끄고 부른다.
|
|
42
|
+
*
|
|
43
|
+
* `diff.external`과 `diff.<드라이버>.textconv`는 git이 실행하는 외부 명령이다.
|
|
44
|
+
* 이 셋은 인증 없는 웹 서버의 요청 경로에서 돈다. 켜져 있으면 출력이 통합 diff가
|
|
45
|
+
* 아니게 되는데, 이 값을 읽는 쪽(웹 UI, 리뷰 에이전트)은 전부 통합 diff를 기대한다. 끄는 게 보안이자 정확성이다.
|
|
46
|
+
*/
|
|
47
|
+
export declare function diff(repoRoot: string, baseSha: string, headSha: string): string;
|
|
48
|
+
export declare function changedFiles(repoRoot: string, baseSha: string, headSha: string): string[];
|
|
49
|
+
export declare function diffStat(repoRoot: string, baseSha: string, headSha: string): string;
|
|
50
|
+
export interface MergeResult {
|
|
51
|
+
mergeSha: string;
|
|
52
|
+
/** 임시 워크트리에서 합쳤는지. 곧장 합쳤으면 false다 */
|
|
53
|
+
viaWorktree: boolean;
|
|
54
|
+
}
|
|
55
|
+
export interface WorktreeEntry {
|
|
56
|
+
path: string;
|
|
57
|
+
/** 이 워크트리가 올라타 있는 브랜치. detached면 null */
|
|
58
|
+
branch: string | null;
|
|
59
|
+
}
|
|
60
|
+
/** 이 레포에 딸린 워크트리 목록 */
|
|
61
|
+
export declare function worktrees(repoRoot: string): WorktreeEntry[];
|
|
62
|
+
/**
|
|
63
|
+
* 이 브랜치를 올라타고 있는 워크트리. 없으면 null.
|
|
64
|
+
*
|
|
65
|
+
* `known`을 주면 목록을 다시 안 구한다. `worktree list`는 프로세스를 하나 띄우는데
|
|
66
|
+
* 체크아웃 한 번에 이 목록을 보는 자리가 여럿이라 진입점에서 한 번 구해 돌린다.
|
|
67
|
+
*/
|
|
68
|
+
export declare function worktreeOn(repoRoot: string, branch: string, known?: WorktreeEntry[]): WorktreeEntry | null;
|
|
69
|
+
export declare function isClean(repoRoot: string): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* PR의 head를 base 브랜치에 병합한다.
|
|
72
|
+
*
|
|
73
|
+
* 부르는 쪽이 base로 옮겨 타지 않아도 되게 임시 워크트리에서 합치고 브랜치 ref만
|
|
74
|
+
* 옮긴다. 워커가 자기 워크트리에 그대로 있는 채로 머지할 수 있다.
|
|
75
|
+
*
|
|
76
|
+
* **base가 다른 워크트리에 체크아웃돼 있으면 ref를 밀지 않는다.** 그쪽은 파일이 옛
|
|
77
|
+
* 상태인데 HEAD만 움직인다. 그러면 그 워크트리의 `git status`가 머지로 들어온 변경을
|
|
78
|
+
* 전부 미커밋 삭제로 잡는다.
|
|
79
|
+
* 그 자리에서 직접 머지하도록 돌려보낸다.
|
|
80
|
+
*
|
|
81
|
+
* ref는 옛 값을 함께 넘겨 옮긴다. 여기서 base를 읽은 뒤 update-ref를 부르기 전에
|
|
82
|
+
* 다른 손이 base를 옮겼으면 git이 거부한다 — 그 사이에 낀 남의 커밋을 덮지 않는다.
|
|
83
|
+
*/
|
|
84
|
+
export declare function mergeIntoBase(repoRoot: string, input: {
|
|
85
|
+
prId: string;
|
|
86
|
+
baseRef: string;
|
|
87
|
+
headSha: string;
|
|
88
|
+
title: string;
|
|
89
|
+
}): MergeResult;
|
|
90
|
+
export declare function deleteBranch(repoRoot: string, branch: string): void;
|
|
91
|
+
/** 이 커밋이 아직 살아 있는가. ref가 안 붙었으면 gc가 가져갈 수 있다 */
|
|
92
|
+
export declare function commitExists(repoRoot: string, sha: string): boolean;
|
|
93
|
+
/** `checkoutPrHead`가 떼어 놓은 워크트리 */
|
|
94
|
+
export interface PrCheckout {
|
|
95
|
+
path: string;
|
|
96
|
+
/** 이번 호출이 새로 뗐으면 true. 이미 있어서 그대로 돌려줬으면 false */
|
|
97
|
+
created: boolean;
|
|
98
|
+
headSha: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* PR 리뷰용 워크트리가 놓일 자리.
|
|
102
|
+
*
|
|
103
|
+
* 공용 git 디렉토리 아래에 둔다. `.git/`은 워킹 트리가 아니라서 추적 안 되는
|
|
104
|
+
* 디렉토리가 리뷰 중인 diff에 섞이지 않는다 — 레포 안을 피해 tmp로 갔던 원래 이유가
|
|
105
|
+
* 여기서는 안 생긴다.
|
|
106
|
+
*
|
|
107
|
+
* tmp를 안 쓰는 이유는 둘이다. 공유 /tmp를 쓰는 호스트에서는 이 경로가 예측 가능해서
|
|
108
|
+
* 남이 먼저 그 자리를 만들어 두면 리뷰 중인 소스가 남의 소유 디렉토리에 풀린다.
|
|
109
|
+
* 그리고 tmp 경로는 TMPDIR를 타므로 뗄 때와 지울 때 환경이 다르면 값이 갈린다.
|
|
110
|
+
*
|
|
111
|
+
* repoRoot와 prId만으로 정해져서 리뷰어가 경로를 안 적어놨어도 지울 때 같은 값이
|
|
112
|
+
* 다시 나온다. 공용 git 디렉토리가 이미 레포마다 갈리므로 해시 칸도 필요 없다.
|
|
113
|
+
*/
|
|
114
|
+
export declare function prCheckoutPath(repoRoot: string, prId: string): string;
|
|
115
|
+
/**
|
|
116
|
+
* PR head를 임시 워크트리로 떼어 놓는다.
|
|
117
|
+
*
|
|
118
|
+
* 리뷰어가 코드를 일부러 깨서 테스트가 잡는지 보려면 PR head가 실물 파일로 있어야
|
|
119
|
+
* 한다. 리뷰어 자신의 워크트리는 자기 브랜치를 올라타고 있어 그 코드가 없다.
|
|
120
|
+
*
|
|
121
|
+
* `--detach`로 뗀다. 브랜치를 체크아웃하면 그 브랜치를 이미 올라탄 워크트리와
|
|
122
|
+
* 부딪힌다. mergeIntoBase가 임시 워크트리에서 같은 선택을 한 이유와 같다.
|
|
123
|
+
*
|
|
124
|
+
* 같은 PR을 두 번 부르면 있는 워크트리를 그대로 돌려준다. 리뷰어가 거기서 하던
|
|
125
|
+
* 작업을 날리지 않는다. 그 자리가 이미 워크트리로 등록돼 있는지를 먼저 본다. 등록만
|
|
126
|
+
* 남고 속이 깨졌으면 치운 뒤 다시 뗀다. 어느 갈래로 가든 한 PR에 워크트리는 하나다.
|
|
127
|
+
*/
|
|
128
|
+
export declare function checkoutPrHead(repoRoot: string, prId: string, headSha: string): PrCheckout;
|
|
129
|
+
/**
|
|
130
|
+
* 안 지운 이유를 식별자로 가른다.
|
|
131
|
+
*
|
|
132
|
+
* `reason`은 사람이 읽을 산문이라 부르는 쪽이 부분 문자열로 긁으면 문장을 손볼 때마다
|
|
133
|
+
* 깨진다. 갈래는 이 값으로 탄다.
|
|
134
|
+
*
|
|
135
|
+
* - `removed` 지웠다
|
|
136
|
+
* - `absent` 지울 자리가 없었다 (정리의 목표가 이미 이뤄진 상태다)
|
|
137
|
+
* - `dirty` 커밋 안 된 변경이 있어 일부러 안 지웠다
|
|
138
|
+
* - `diverged` 여기서 커밋한 변경이 있어 일부러 안 지웠다
|
|
139
|
+
* - `stale` 워크트리 등록이 끊기고 디렉토리만 남아, 안을 읽을 수 없어 안 지웠다
|
|
140
|
+
*
|
|
141
|
+
* `stale`을 `dirty`에 얹지 않는 이유는 둘이 다른 상태여서다. `dirty`는 안을 읽어서
|
|
142
|
+
* 커밋 안 된 변경을 확인한 것이고 `stale`은 읽을 방법이 없어 판단을 미룬 것이다.
|
|
143
|
+
* 부르는 쪽은 이 값으로 갈래를 타므로 같은 코드를 주면 "고칠 게 있으니 커밋해라"와
|
|
144
|
+
* "지난 정리가 끊겼으니 안을 확인해라"가 한 갈래로 뭉개진다.
|
|
145
|
+
*/
|
|
146
|
+
export type CheckoutRemovalStatus = 'removed' | 'absent' | 'dirty' | 'diverged' | 'stale';
|
|
147
|
+
export interface CheckoutRemoval {
|
|
148
|
+
path: string;
|
|
149
|
+
removed: boolean;
|
|
150
|
+
status: CheckoutRemovalStatus;
|
|
151
|
+
/** 안 지웠으면 그 이유. 지웠으면 null */
|
|
152
|
+
reason: string | null;
|
|
153
|
+
/** 사라질 뻔한 커밋을 붙잡아 둔 ref. 그런 커밋이 없었으면 null */
|
|
154
|
+
savedRef: string | null;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* 떼어 놓은 워크트리를 지운다.
|
|
158
|
+
*
|
|
159
|
+
* **지울 만하지 않으면 지우지 않는다.** 리뷰어가 뮤테이션 검증 중이면 그 워크트리는
|
|
160
|
+
* 일부러 깨놓은 코드다. 여기서 날리면 무엇을 어떻게 깼는지가 사라진다. 두 갈래를 막는다.
|
|
161
|
+
*
|
|
162
|
+
* - 커밋 안 된 변경 (`dirty`)
|
|
163
|
+
* - 여기서 커밋했는데 어느 ref도 안 품은 커밋 (`diverged`) — 떼어낸 자리는 detached
|
|
164
|
+
* HEAD라 브랜치 ref가 없고 워크트리 전용 reflog도 함께 죽는다. `git status`는
|
|
165
|
+
* 깨끗하다고 답하므로 미커밋 검사만으로는 이 손실이 안 걸린다.
|
|
166
|
+
*
|
|
167
|
+
* 어느 쪽이든 왜 안 지웠는지 돌려준다. 정말 버릴 참이면 `force`로 다시 부른다. 그때도
|
|
168
|
+
* ref가 안 품은 커밋은 `refs/gestalt/pr-checkout/<prId>/<sha 앞 8자>`로 붙잡아 두고 지운다 —
|
|
169
|
+
* 막는 것과 지우게 두는 것 사이에서, 되돌릴 실마리를 남기는 쪽을 골랐다. 리뷰어가 검증
|
|
170
|
+
* 중간을 커밋해 두는 건 있을 법한 흐름이라 `--force` 한 번에 영영 잃게 둘 수 없다.
|
|
171
|
+
*
|
|
172
|
+
* git이 추적하지 않기로 한 파일(.gitignore에 걸린 node_modules 등)은 변경으로
|
|
173
|
+
* 세지 않는다. `git status --porcelain`이 이미 그것들을 뺀 목록을 준다.
|
|
174
|
+
*/
|
|
175
|
+
export declare function removePrCheckout(repoRoot: string, prId: string, options?: {
|
|
176
|
+
force?: boolean;
|
|
177
|
+
headSha?: string;
|
|
178
|
+
}): CheckoutRemoval;
|
|
179
|
+
/**
|
|
180
|
+
* 이 뿌리 아래 붙어 있는 ref 이름.
|
|
181
|
+
*
|
|
182
|
+
* 패턴에 슬래시를 붙여 넘긴다. `refs/gestalt/pr`은 `refs/gestalt/pr-checkout`의
|
|
183
|
+
* 접두사이기도 해서, 슬래시 없이 훑으면 체크아웃 자국까지 딸려 온다.
|
|
184
|
+
*/
|
|
185
|
+
export declare function refsUnder(repoRoot: string, root: string): string[];
|
|
186
|
+
/** 이 커밋이 저 갈래의 이력에 들어 있는가. 들어 있으면 ref를 놓아도 안 사라진다 */
|
|
187
|
+
export declare function isAncestor(repoRoot: string, sha: string, rev: string): boolean;
|
|
188
|
+
/** ref를 놓는다. 이미 없으면 놓을 것도 없다 */
|
|
189
|
+
export declare function deleteRef(repoRoot: string, ref: string): void;
|
|
190
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../../src/local-pr/git.ts"],"names":[],"mappings":"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"}
|