@unifan/pi-unifan-zh 1.0.28 → 1.0.30
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/AGENTS.md +3 -0
- package/README.md +1 -0
- package/README_zh.md +1 -0
- package/extensions/commit/index.ts +16 -3
- package/extensions/commit/package.json +1 -1
- package/extensions/commit/src/git.ts +29 -2
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -87,6 +87,9 @@ pi-unifan-zh/
|
|
|
87
87
|
* **网络抖动重试**:`runs.all` 并发调用必须包裹 `try-catch` 并在发生网络断连时自动延迟 800ms 重试一次。
|
|
88
88
|
* **门禁熔断保护**:门禁裁判长(Gate)发生异常时必须兜底捕获,**绝对不能抛出未捕获异常导致已完成的 Reviewer 成果丢失**。
|
|
89
89
|
|
|
90
|
+
### 6. 冲突解决原则
|
|
91
|
+
拉取或变基冲突时,严禁直接使用 ours/theirs 覆盖,必须根据双方修改对比与上下文解决冲突。
|
|
92
|
+
|
|
90
93
|
---
|
|
91
94
|
|
|
92
95
|
## 🚀 三、发版与发布指南(Release & Publish Workflow)
|
package/README.md
CHANGED
|
@@ -128,6 +128,7 @@ pi install npm:@unifan/pi-commit-zh
|
|
|
128
128
|
- **Strict ASCII Punctuation**: Parentheses `()` and colon `: ` strictly use ASCII half-width characters for CI / Commitlint compliance.
|
|
129
129
|
- **No Emoji**: Clean, professional plain text commit style.
|
|
130
130
|
- **Smart Auto-Rebase on Push**: In `/commit-push`, if remote contains unpulled commits, it automatically runs `git pull --rebase` and retries push, keeping a clean linear git history.
|
|
131
|
+
- **Smart Conflict Guidance**: If rebase conflicts occur, lists conflict files and enforces resolving by diff and context (never blindly using ours/theirs).
|
|
131
132
|
- **Unpushed Commits Sync**: Automatically pushes unpushed local commits even if the working tree is clean.
|
|
132
133
|
|
|
133
134
|
---
|
package/README_zh.md
CHANGED
|
@@ -133,6 +133,7 @@ pi install npm:@unifan/pi-commit-zh
|
|
|
133
133
|
- **严格半角英文标点**:括号 `()` 与冒号空格 `: ` 严格使用英文半角字符,确保 CI / Commitlint 正则解析合规。
|
|
134
134
|
- **严禁 Emoji**:保持严谨、专业的纯文本工程风格。
|
|
135
135
|
- **智能自动变基(Auto Rebase)**:在 `/commit-push` 时,若远端有别人先提交的代码被拒绝,**自动在后台执行 `git pull --rebase` 变基并自动重试推送**,Git 历史保持一条干净直线!
|
|
136
|
+
- **智能冲突引导**:变基遇冲突时列出冲突文件,提示严禁直接用 ours/theirs 覆盖,需按修改对比与上下文解决。
|
|
136
137
|
- **未推送提交自动同步**:即使当前工作区干净,若检测到本地有尚未 push 的历史 Commit,`/commit-push` 也会自动将其推送至远端!
|
|
137
138
|
|
|
138
139
|
---
|
|
@@ -131,7 +131,16 @@ export default function (pi: ExtensionAPI) {
|
|
|
131
131
|
display: true,
|
|
132
132
|
});
|
|
133
133
|
} else {
|
|
134
|
-
|
|
134
|
+
if (pushRes.hasConflict) {
|
|
135
|
+
notify("⚠️ 远端变基冲突:请对比修改与上下文解决冲突,严禁直接使用 ours/theirs。", "warning");
|
|
136
|
+
} else {
|
|
137
|
+
notify(`⚠️ 推送失败: ${pushRes.output}`, "error");
|
|
138
|
+
}
|
|
139
|
+
pi.sendMessage({
|
|
140
|
+
customType: "pi-commit-result",
|
|
141
|
+
content: `### ⚠️ 推送到远端未完成\n\n${pushRes.output}`,
|
|
142
|
+
display: true,
|
|
143
|
+
});
|
|
135
144
|
}
|
|
136
145
|
return;
|
|
137
146
|
}
|
|
@@ -172,8 +181,12 @@ export default function (pi: ExtensionAPI) {
|
|
|
172
181
|
notify(successMsg, "info");
|
|
173
182
|
pushText = `\n\n${successMsg}`;
|
|
174
183
|
} else {
|
|
175
|
-
|
|
176
|
-
|
|
184
|
+
if (pushRes.hasConflict) {
|
|
185
|
+
notify("⚠️ 远端变基冲突:请对比修改与上下文解决冲突,严禁直接使用 ours/theirs。", "warning");
|
|
186
|
+
} else {
|
|
187
|
+
notify(`⚠️ 推送失败: ${pushRes.output}`, "error");
|
|
188
|
+
}
|
|
189
|
+
pushText = `\n\n${pushRes.output}`;
|
|
177
190
|
}
|
|
178
191
|
}
|
|
179
192
|
|
|
@@ -79,7 +79,7 @@ export async function commitWithMsg(cwd: string, message: string): Promise<{ ok:
|
|
|
79
79
|
export async function pushCurrentBranch(
|
|
80
80
|
cwd: string,
|
|
81
81
|
onLog?: (msg: string) => void,
|
|
82
|
-
): Promise<{ ok: boolean; output: string; autoRebased?: boolean }> {
|
|
82
|
+
): Promise<{ ok: boolean; output: string; autoRebased?: boolean; hasConflict?: boolean; conflictFiles?: string[] }> {
|
|
83
83
|
let initialPush = await runGit(cwd, ["push"]);
|
|
84
84
|
if (initialPush.ok) {
|
|
85
85
|
return { ok: true, output: initialPush.stdout || "推送成功" };
|
|
@@ -111,9 +111,36 @@ export async function pushCurrentBranch(
|
|
|
111
111
|
const pullRebase = await runGit(cwd, ["pull", "--rebase"]);
|
|
112
112
|
if (!pullRebase.ok) {
|
|
113
113
|
const rebaseErr = `${pullRebase.stderr} ${pullRebase.stdout}`;
|
|
114
|
+
|
|
115
|
+
// 检索冲突文件清单
|
|
116
|
+
const conflictDiff = await runGit(cwd, ["diff", "--name-only", "--diff-filter=U"]);
|
|
117
|
+
let conflictFiles = conflictDiff.ok && conflictDiff.stdout.trim()
|
|
118
|
+
? conflictDiff.stdout.trim().split("\n").map((f) => f.trim()).filter(Boolean)
|
|
119
|
+
: [];
|
|
120
|
+
|
|
121
|
+
if (conflictFiles.length === 0) {
|
|
122
|
+
const statusRes = await runGit(cwd, ["status", "--porcelain"]);
|
|
123
|
+
if (statusRes.ok && statusRes.stdout.trim()) {
|
|
124
|
+
conflictFiles = statusRes.stdout
|
|
125
|
+
.split("\n")
|
|
126
|
+
.filter((l) => /^(UU|AA|UD|DU|DD|AU|UA)\s+/.test(l.trim()))
|
|
127
|
+
.map((l) => l.trim().slice(3).trim());
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const filesListText = conflictFiles.length > 0
|
|
132
|
+
? `\n${conflictFiles.map((f) => `- \`${f}\``).join("\n")}\n`
|
|
133
|
+
: "\n";
|
|
134
|
+
|
|
135
|
+
const conflictOutput = `⚠️ **远端变基拉取存在代码冲突**:${filesListText}
|
|
136
|
+
- **解决原则**:严禁直接使用 theirs 或 ours 覆盖,必须根据双方修改对比与代码上下文解决冲突。
|
|
137
|
+
- **后续步骤**:解决冲突 ➔ \`git add <文件>\` ➔ \`git rebase --continue\` ➔ 再次执行 \`/commit-push\`(放弃可 \`git rebase --abort\`)。\n\nGit 输出:\n${rebaseErr}`;
|
|
138
|
+
|
|
114
139
|
return {
|
|
115
140
|
ok: false,
|
|
116
|
-
output:
|
|
141
|
+
output: conflictOutput,
|
|
142
|
+
hasConflict: true,
|
|
143
|
+
conflictFiles,
|
|
117
144
|
};
|
|
118
145
|
}
|
|
119
146
|
|