@unifan/pi-commit-zh 1.0.10 → 1.0.11

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.
Files changed (3) hide show
  1. package/index.ts +24 -2
  2. package/package.json +1 -1
  3. package/src/git.ts +33 -2
package/index.ts CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  commitWithMsg,
4
4
  getChangedFiles,
5
5
  getStagedDiff,
6
+ getUnpushedCommits,
6
7
  getUnstagedDiff,
7
8
  isGitRepo,
8
9
  pushCurrentBranch,
@@ -114,7 +115,28 @@ export default function (pi: ExtensionAPI) {
114
115
  const changedFiles = await getChangedFiles(ctx.cwd);
115
116
 
116
117
  if (!stagedDiff && !unstagedDiff) {
117
- notify("当前工作区没有任何修改,无需提交。", "info");
118
+ if (andPush) {
119
+ const unpushed = await getUnpushedCommits(ctx.cwd);
120
+ if (unpushed.length > 0) {
121
+ notify(`当前工作区干净,但检测到有 ${unpushed.length} 个未推送提交,正在推送到远端...`, "info");
122
+ const pushRes = await pushCurrentBranch(ctx.cwd, (msg) => notify(msg, "info"));
123
+ if (pushRes.ok) {
124
+ const successMsg = pushRes.autoRebased
125
+ ? `🚀 已自动完成变基 (pull --rebase),并成功将 ${unpushed.length} 个本地提交推送至远端!`
126
+ : `🚀 成功将本地未推送的 ${unpushed.length} 个提交推送至远端!`;
127
+ notify(successMsg, "info");
128
+ pi.sendMessage({
129
+ customType: "pi-commit-result",
130
+ content: `### 🚀 远端推送完成\n\n当前工作区无未提交的修改,已成功将本地 **${unpushed.length} 个历史提交** 推送至远端分支:\n\n\`\`\`text\n${unpushed.join("\n")}\n\`\`\`\n\n${successMsg}`,
131
+ display: true,
132
+ });
133
+ } else {
134
+ notify(`⚠️ 推送失败: ${pushRes.output}`, "error");
135
+ }
136
+ return;
137
+ }
138
+ }
139
+ notify("当前工作区干净,且所有本地提交均已同步至远端,无需提交和推送。", "info");
118
140
  return;
119
141
  }
120
142
 
@@ -178,7 +200,7 @@ export default function (pi: ExtensionAPI) {
178
200
  });
179
201
 
180
202
  pi.registerCommand("commit-push", {
181
- description: "智能 Git 提交并推流:生成标准中文 Commit 后自动提交并执行 git push (支持自动变基重试)",
203
+ description: "智能 Git 提交并推流:生成标准中文 Commit 后自动提交并执行 git push (支持自动变基与未推送提交自动推流)",
182
204
  handler: async (args, ctx) => {
183
205
  await handleCommitCommand(args, ctx, true);
184
206
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unifan/pi-commit-zh",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "Pi 智能 Git 提交助手(规范化 Conventional Commits 纯中文版,支持一键提审与推流)",
5
5
  "type": "module",
6
6
  "main": "index.ts",
package/src/git.ts CHANGED
@@ -45,6 +45,27 @@ export async function getChangedFiles(cwd: string): Promise<string[]> {
45
45
  .filter(Boolean);
46
46
  }
47
47
 
48
+ export async function getUnpushedCommits(cwd: string): Promise<string[]> {
49
+ const res = await runGit(cwd, ["log", "@{u}..HEAD", "--oneline"]);
50
+ if (res.ok && res.stdout.trim()) {
51
+ return res.stdout.trim().split("\n").filter(Boolean);
52
+ }
53
+ const statusRes = await runGit(cwd, ["status", "--porcelain=v1", "-b"]);
54
+ if (statusRes.ok) {
55
+ const match = statusRes.stdout.match(/\[ahead\s+(\d+)\]/);
56
+ if (match && match[1]) {
57
+ const count = parseInt(match[1], 10);
58
+ if (count > 0) {
59
+ const logRes = await runGit(cwd, ["log", "-n", String(count), "--oneline"]);
60
+ if (logRes.ok && logRes.stdout.trim()) {
61
+ return logRes.stdout.trim().split("\n").filter(Boolean);
62
+ }
63
+ }
64
+ }
65
+ }
66
+ return [];
67
+ }
68
+
48
69
  export async function stageAll(cwd: string): Promise<boolean> {
49
70
  const res = await runGit(cwd, ["add", "-A"]);
50
71
  return res.ok;
@@ -59,12 +80,22 @@ export async function pushCurrentBranch(
59
80
  cwd: string,
60
81
  onLog?: (msg: string) => void,
61
82
  ): Promise<{ ok: boolean; output: string; autoRebased?: boolean }> {
62
- const initialPush = await runGit(cwd, ["push"]);
83
+ let initialPush = await runGit(cwd, ["push"]);
63
84
  if (initialPush.ok) {
64
85
  return { ok: true, output: initialPush.stdout || "推送成功" };
65
86
  }
66
87
 
67
- const pushError = `${initialPush.stderr} ${initialPush.stdout}`.toLowerCase();
88
+ let pushError = `${initialPush.stderr} ${initialPush.stdout}`.toLowerCase();
89
+
90
+ if (pushError.includes("no upstream branch") || pushError.includes("set-upstream")) {
91
+ if (onLog) onLog("未关联远端分支,正在自动关联并推送 (git push -u origin HEAD)...");
92
+ const setUpstream = await runGit(cwd, ["push", "-u", "origin", "HEAD"]);
93
+ if (setUpstream.ok) {
94
+ return { ok: true, output: setUpstream.stdout || "推送成功" };
95
+ }
96
+ pushError = `${setUpstream.stderr} ${setUpstream.stdout}`.toLowerCase();
97
+ }
98
+
68
99
  const needsPull =
69
100
  pushError.includes("fetch first") ||
70
101
  pushError.includes("non-fast-forward") ||