本地仓库下的快捷提交
zoe.X Lv3

git-zhou: AI 驱动的一键提交

使用 AI 自动生成符合 Conventional Commits 规范的提交信息,并提供交互式确认/重试/手动编辑。脚本文件为 commit.py,适用于 macOS。

脚本文件commit.py

已内置一个gemini key,不保证何时实效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
#!/usr/bin/env python3
import subprocess
import json
import os
import requests # 需要安装: pip install requests
import sys
import codecs
from typing import Optional

# --- 配置 ---
# 你的 OpenAI 兼容 API 的 Base URL
# 例如: "http://localhost:8000/v1" 或 "https://api.openai.com/v1"
BASE_URL = os.environ.get("OPENAI_API_BASE", "https://api-proxy.me/gemini/v1beta/openai")
# 你的 API Key (如果你的服务需要)
# 建议通过环境变量 OPENAI_API_KEY 设置,或者直接在这里填写
API_KEY = os.environ.get("OPENAI_API_KEY", "AIzaSyBbbkbGOCylzw9Kgt9y8SqNvdQoO0wCb9Q")
# 使用的模型名称
MODEL_NAME = "gemini-2.0-flash" # 或者你部署的模型名
# 生成commit message的最大token数
MAX_TOKENS = 60
# 控制输出的随机性
TEMPERATURE = 0.3
# 是否在提交成功后自动推送到远程(需要已配置上游分支)
PUSH_TO_REMOTE = True
# 可选:通过环境变量覆盖,取值 true/false/1/0/yes/no/on/off
_env_push = os.environ.get("GIT_ZHOU_PUSH")
if _env_push is not None:
PUSH_TO_REMOTE = _env_push.strip().lower() in ("1", "true", "yes", "on")
# --- END 配置 ---

SYSTEM_PROMPT = """你是一个专业的Git提交信息生成器。
请根据提供的 'git diff --staged' 输出,生成一个简短、清晰且符合 Conventional Commits 规范的提交信息。
规范格式为: <type>(<scope>): <subject>
例如: feat: add new login button
fix(parser): handle malformed input
docs: update README with API instructions

- type: feat, fix, docs, style, refactor, perf, test, chore
- scope: 可选,指明影响范围
- subject: 动词开头,现在时态,简洁描述。

只输出最终的commit信息本身,不要包含任何解释、前缀如 "Commit message:" 或 markdown 代码块标记。
请使用中文回答
"""


def run_git_cmd(args, check=False, text=True, capture_output=True, env=None, cwd=None):
return subprocess.run([
"git",
*args,
], check=check, text=text, capture_output=capture_output, env=env, cwd=cwd)


def is_git_repo() -> bool:
try:
r = run_git_cmd(["rev-parse", "--is-inside-work-tree"], check=True)
return r.stdout.strip() == "true"
except subprocess.CalledProcessError:
return False


def stage_all_changes(include_untracked=True) -> None:
# 包括暂存与非暂存以及新文件
args = ["add", "-A"] if include_untracked else ["add", "-u"]
run_git_cmd(args, check=True)


def has_any_changes_staged() -> bool:
r = run_git_cmd(["diff", "--staged", "--name-only"])
return bool(r.stdout.strip())

def get_staged_diff():
"""获取 git staged 的 diff 内容"""
try:
# 首先获取原始字节输出,避免编码问题
result = subprocess.run(
["git", "diff", "--staged", "--patch", "--unified=0"],
capture_output=True,
check=True
)

# 尝试多种编码方式解码输出
raw_output = result.stdout

# 尝试的编码列表,按优先级排序
encodings = ['utf-8', 'gbk', 'gb2312', 'latin-1', 'cp1252']

for encoding in encodings:
try:
decoded_output = raw_output.decode(encoding)
# 如果成功解码,检查是否包含二进制文件标记
if "Binary files" in decoded_output:
# 过滤掉二进制文件的diff,只保留文本文件的diff
lines = decoded_output.split('\n')
filtered_lines = []
skip_binary = False

for line in lines:
if line.startswith("Binary files") and "differ" in line:
skip_binary = True
continue
elif line.startswith("diff --git"):
skip_binary = False

if not skip_binary:
filtered_lines.append(line)

decoded_output = '\n'.join(filtered_lines)

return decoded_output.strip()

except UnicodeDecodeError:
continue

# 如果所有编码都失败,使用 latin-1 强制解码(不会失败)
# 然后替换无法显示的字符
try:
decoded_output = raw_output.decode('latin-1')
# 替换可能的问题字符
decoded_output = decoded_output.encode('utf-8', errors='ignore').decode('utf-8')
print("⚠️ 警告: 检测到编码问题,已尝试修复,但可能影响diff内容的准确性")
return decoded_output.strip()
except Exception as e:
print(f"⚠️ 严重编码错误: {e}")
return None

except subprocess.CalledProcessError as e:
print(f"获取 git diff 失败: {e}")
if e.stderr:
try:
stderr_text = e.stderr.decode('utf-8', errors='replace')
print(f"Git Stderr: {stderr_text}")
except:
print(f"Git Stderr: {e.stderr}")
return None
except FileNotFoundError:
print("错误: git 命令未找到。请确保 git 已安装并在 PATH 中。")
return None

def generate_commit_message(diff_content):
"""调用 AI API 生成 commit message"""
if not diff_content:
return "chore: no changes to commit" # 或者返回空,让调用者处理

if BASE_URL == "YOUR_OPENAI_COMPATIBLE_BASE_URL/v1":
print("错误:请在脚本中或通过环境变量 OPENAI_API_BASE 设置 BASE_URL。")
return None

headers = {
"Content-Type": "application/json; charset=utf-8",
}
if API_KEY and API_KEY != "YOUR_API_KEY":
headers["Authorization"] = f"Bearer {API_KEY}"
elif "openai.com" in BASE_URL and (not API_KEY or API_KEY == "YOUR_API_KEY"):
print("错误:使用 OpenAI 官方 API 时必须提供 API_KEY。")
return None


user_prompt = f"请为以下 git diff 内容生成一个 commit message:\n\n```diff\n{diff_content}\n```"

payload = {
"model": MODEL_NAME,
"messages": [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_prompt}
],
"max_tokens": MAX_TOKENS,
"temperature": TEMPERATURE,
"stream": False
}

api_endpoint = f"{BASE_URL.rstrip('/')}/chat/completions"

try:
response = requests.post(api_endpoint, headers=headers, json=payload, timeout=30)
response.raise_for_status() # 如果 HTTP 错误 (4xx or 5xx) 则抛出异常

response_data = response.json()

if "choices" in response_data and len(response_data["choices"]) > 0:
message_content = response_data["choices"][0].get("message", {}).get("content", "")
# 清理AI可能添加的多余字符
message_content = message_content.strip()
message_content = message_content.removeprefix("```").removesuffix("```")
message_content = message_content.removeprefix("`").removesuffix("`")
message_content = message_content.strip('"').strip("'")
return message_content.strip()
else:
print("错误:API 响应中没有找到有效的 'choices'。")
print("API 原始响应:", response.text)
return None

except requests.exceptions.RequestException as e:
print(f"API 请求失败: {e}")
return None
except json.JSONDecodeError:
print("错误:解析API响应失败,不是有效的JSON。")
print("API 原始响应:", response.text)
return None


def commit_with_message(message: str) -> bool:
try:
r = run_git_cmd(["commit", "-m", message], check=True)
# 打印简短commit输出
sys.stdout.write(r.stdout)
sys.stderr.write(r.stderr)
return True
except subprocess.CalledProcessError as e:
print("提交失败。")
if e.stdout:
sys.stdout.write(e.stdout)
if e.stderr:
sys.stderr.write(e.stderr)
return False


def prompt_user(prompt: str, valid: Optional[list] = None, default: Optional[str] = None) -> str:
while True:
ans = input(prompt).strip().lower()
if ans == '' and default:
return default
if not valid or ans in valid:
return ans
if default:
print(f"请输入 {', '.join(valid)} 之一。直接回车默认为 {default}。")
else:
print(f"请输入 {', '.join(valid)} 之一。")


def has_any_remote() -> bool:
try:
r = run_git_cmd(["remote"], check=True)
return bool(r.stdout.strip())
except subprocess.CalledProcessError:
return False


def has_upstream_tracking() -> bool:
try:
# 仅用于检测是否设置了上游分支
r = run_git_cmd(["rev-parse", "--abbrev-ref", "@{u}"], check=True)
return bool(r.stdout.strip())
except subprocess.CalledProcessError:
return False


def push_upstream() -> bool:
try:
r = run_git_cmd(["push"], check=True)
sys.stdout.write(r.stdout)
sys.stderr.write(r.stderr)
return True
except subprocess.CalledProcessError as e:
if e.stdout:
sys.stdout.write(e.stdout)
if e.stderr:
sys.stderr.write(e.stderr)
return False


if __name__ == "__main__":
if sys.platform.startswith('win'):
import ctypes
kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleOutputCP(65001) # 设置控制台输出为 UTF-8
kernel32.SetConsoleCP(65001) # 设置控制台输入为 UTF-8

# 确保输出编码
if hasattr(sys.stdout, 'buffer'):
sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer)

my_env = os.environ.copy()
my_env["PYTHONIOENCODING"] = "utf-8"
my_env["LANG"] = "zh_CN.UTF-8"
my_env["LC_ALL"] = "zh_CN.UTF-8"

if not is_git_repo():
print("当前目录不是 Git 仓库。")
sys.exit(1)

# 先将所有改动(包含未暂存与未跟踪文件)加入暂存区
try:
stage_all_changes(include_untracked=True)
except subprocess.CalledProcessError as e:
print("git add 失败:")
if e.stderr:
sys.stderr.write(e.stderr)
sys.exit(1)

# 优先从 stdin 读取 diff 内容(允许从外部传入自定义diff)
if not sys.stdin.isatty():
diff = sys.stdin.read()
else:
diff = get_staged_diff()

if diff is None: # 错误已在 get_staged_diff 中打印
sys.exit(1)

if not diff.strip():
print("没有可提交的更改。")
sys.exit(0)

# 限制diff长度,避免请求体过大或token超限
max_diff_length = 800000 # 根据模型上下文调整
if len(diff) > max_diff_length:
print(f"警告: Diff内容过长 ({len(diff)} characters),将截断为 {max_diff_length} characters。")
diff = diff[:max_diff_length] + "\n... (diff truncated)"

# 交互式确认/重试/编辑
attempt = 0
commit_msg: Optional[str] = None
while True:
attempt += 1
if commit_msg is None:
print(f"正在生成提交信息(第 {attempt} 次)...")
commit_msg = generate_commit_message(diff)

if not commit_msg:
print("未能生成 commit message。选择:")
action = prompt_user("[r] 重试生成, [e] 手动输入, [q] 退出: ", ["r", "e", "q"], default="r")
if action == 'r':
commit_msg = None
continue
elif action == 'e':
commit_msg = input("请输入提交信息: ").strip()
if not commit_msg:
print("提交信息为空,已取消。")
sys.exit(1)
else:
print("已取消。")
sys.exit(1)

print("\n---- 生成的提交信息 ----")
print(commit_msg)
print("----------------------\n")

action = prompt_user("确认使用该提交信息? [y] 确认, [r] 重新生成, [e] 手动编辑, [q] 取消: ", ["y", "r", "e", "q"], default="y")
if action == 'y':
ok = commit_with_message(commit_msg)
if not ok:
sys.exit(1)
# 尝试推送到远程(若配置了上游分支),失败则跳过
if PUSH_TO_REMOTE:
if has_any_remote() and has_upstream_tracking():
print("检测到上游分支,尝试推送到远程...")
pushed = push_upstream()
if pushed:
print("已推送到远程。")
else:
print("推送失败,已跳过(本地提交已完成)。")
else:
print("未配置远程或上游分支,跳过推送。")
else:
print("已配置为不自动推送,跳过推送。")
sys.exit(0)
elif action == 'r':
commit_msg = None
continue
elif action == 'e':
manual = input("请编辑提交信息(留空取消):\n").strip()
if manual:
ok = commit_with_message(manual)
if not ok:
sys.exit(1)
if PUSH_TO_REMOTE:
if has_any_remote() and has_upstream_tracking():
print("检测到上游分支,尝试推送到远程...")
pushed = push_upstream()
if pushed:
print("已推送到远程。")
else:
print("推送失败,已跳过(本地提交已完成)。")
else:
print("未配置远程或上游分支,跳过推送。")
else:
print("已配置为不自动推送,跳过推送。")
sys.exit(0)
else:
print("为空,返回生成流程。")
continue
else:
print("已取消,不会提交。改动仍保留在暂存区。")
sys.exit(1)

依赖与环境

  • 需要已安装 git
  • 使用指定 Python 解释器:/opt/miniconda3/envs/zhouzhou/bin/python
  • 安装依赖:
    • /opt/miniconda3/envs/zhouzhou/bin/python -m pip install requests
  • 配置(按需):
    • OPENAI_API_BASE:OpenAI 兼容接口的基础地址,形如 https://your.domain/v1
    • OPENAI_API_KEY:若你的服务需要鉴权,请设置该值。
    • 文件内默认模型为 gemini-2.0-flash,可按需调整。
    • 说明:脚本会优先读取环境变量 OPENAI_API_BASE/OPENAI_API_KEY;若未设置,则使用 commit.py 文件中的默认值。你也可以直接编辑 commit.py 修改默认配置(不推荐硬编码敏感密钥)。优先级:环境变量 > 文件默认。

快速接入

以下三种方式任选其一。

方式 A:Git 子命令别名(推荐)

将脚本绑定为 git zhou

1
git config --global alias.zhou '!/opt/miniconda3/envs/zhouzhou/bin/python /Users/zhouzhou/Desktop/test/warp/commit.py'

用法:在任意 Git 仓库目录中执行:

1
git zhou

不想使用时如何移除(取消别名):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 全局配置移除(如果按上述命令设置过)
git config --global --unset alias.zhou

# 若仍存在,可能是仓库级或系统级设置:
# 在具体仓库中运行以移除仓库级别别名
git config --unset alias.zhou

# 系统级(较少使用,可能需要 sudo)
# sudo git config --system --unset alias.zhou

# 验证是否已移除
git config --global --get alias.zhou # 无输出表示已移除
# 或直接尝试
git zhou # 应提示 Unknown command 或未定义

方式 B:独立命令 git-zhou

在你的 ~/.zshrc 增加别名:

1
2
alias git-zhou='/opt/miniconda3/envs/zhouzhou/bin/python /Users/zhouzhou/Desktop/test/warp/commit.py'
source ~/.zshrc

用法:

1
git-zhou

不想使用时如何移除(取消别名):

1
2
3
4
5
6
7
8
9
10
11
12
13
# 仅在当前终端会话临时取消
unalias git-zhou 2>/dev/null || true

# 从 zsh 配置中删除别名行(手动或使用 sed)
# 手动:编辑 ~/.zshrc 删除包含 "alias git-zhou=" 的那行,然后保存
# 或自动:
sed -i '' '/alias git-zhou=/d' ~/.zshrc

# 重新加载配置
source ~/.zshrc

# 验证
type git-zhou # 应提示 not found

方式 C:加入 PATH(可执行方式)

1
2
3
4
chmod +x /Users/zhouzhou/Desktop/test/warp/commit.py
ln -sf /Users/zhouzhou/Desktop/test/warp/commit.py ~/bin/git-zhou
# 确保 PATH 包含 ~/bin
[[ ":$PATH:" != *":$HOME/bin:"* ]] && echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc

随后:

1
git-zhou

不想使用时如何移除(PATH 方式):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 删除放入 ~/bin 的脚本/链接
rm -f ~/bin/git-zhou

# 如此前向 ~/.zshrc 写入了 PATH 追加,可按需移除该行
# 手动:编辑 ~/.zshrc 删除包含 "export PATH=\"$HOME/bin:$PATH\"" 的行
# 或自动(谨慎使用):
sed -i '' '/export PATH="\$HOME\/bin:\$PATH"/d' ~/.zshrc

# 刷新 shell 环境
hash -r
source ~/.zshrc

# 验证
command -v git-zhou || echo 'git-zhou 已移除'

commit.py 使用 Python 运行,请在 shebang 或调用时仍显式使用:/opt/miniconda3/envs/zhouzhou/bin/python

提示:可以同时设置多个指令名(例如 git aigit cmgit zhou),详见下文“多指令名使用”。

使用说明

  • 执行后脚本会:
    • 自动 git add -A(包含暂存、未暂存与未跟踪文件)。
    • 基于 git diff --staged 生成 AI 提交信息。
    • 显示交互菜单:
      • y 确认提交
      • r 重新生成
      • e 手动编辑
      • q 取消
  • 若取消提交,你的改动仍留在暂存区(如需撤销可运行 git reset)。
    • 提交成功后:若当前分支已配置上游(tracking)分支,将自动 git push;若未配置或推送失败,则跳过推送但保留本地提交。

提示:未配置上游分支时可手动设置一次,例如:

1
git push -u origin $(git rev-parse --abbrev-ref HEAD)

可选环境变量

  • OPENAI_API_BASE:兼容 OpenAI 的 chat/completions 接口基础地址。
  • OPENAI_API_KEY:鉴权所需 Token。
  • MODEL_NAMEMAX_TOKENSTEMPERATURE 可在 commit.py 中调整。
    • 优先级:环境变量会覆盖 commit.py 中的默认值。

故障排查

  • AI 生成失败:选择 r 重试或 e 手输提交信息。
  • 网络/鉴权问题:确认 OPENAI_API_BASEOPENAI_API_KEY 设置正确。
  • GPG/Hook:脚本遵循你仓库现有配置,如需签名请保持 Git 全局/本地设置不变。

进阶:从标准输入提供 diff(可选)

1
git diff --staged | /opt/miniconda3/envs/zhouzhou/bin/python /Users/zhouzhou/Desktop/test/warp/commit.py

当从标准输入传入内容时,脚本会优先使用该 diff。


文件位置:/Users/zhouzhou/Desktop/test/warp/commit.py
建议将上述命令中路径替换为你本机的实际路径。

配置:是否自动推送到远程

脚本内提供开关控制提交后是否自动 git push

  • commit.py 顶部(配置区)修改:

    • PUSH_TO_REMOTE = True 开启自动推送(默认)
    • PUSH_TO_REMOTE = False 关闭自动推送
  • 也可以使用环境变量覆盖(不改代码):

    • 开启:export GIT_ZHOU_PUSH=true(接受 1/true/yes/on)
    • 关闭:export GIT_ZHOU_PUSH=false(接受 0/false/no/off)

当关闭自动推送时,脚本会在本地完成提交并打印“已配置为不自动推送,跳过推送。”

多指令名使用(给他人或自己多入口)

你可以同时配置多个不同名称来调用同一个脚本,适合团队或个人多习惯共存。

方式 1:多个 Git 别名

1
2
3
4
5
6
7
git config --global alias.ai '!/opt/miniconda3/envs/zhouzhou/bin/python /Users/zhouzhou/Desktop/test/warp/commit.py'
git config --global alias.cm '!/opt/miniconda3/envs/zhouzhou/bin/python /Users/zhouzhou/Desktop/test/warp/commit.py'

# 使用
git ai
git cm
git zhou

移除时分别执行对应的 unset:

1
2
git config --global --unset alias.ai
git config --global --unset alias.cm

方式 2:Git 外部子命令(git-

将脚本链接为多个 git-<name> 可执行文件(在 PATH 中):

1
2
3
4
5
6
7
ln -sf /Users/zhouzhou/Desktop/test/warp/commit.py ~/bin/git-ai
ln -sf /Users/zhouzhou/Desktop/test/warp/commit.py ~/bin/git-cm
# 确保 ~/bin 在 PATH;若未添加,请参考上文“方式 C:加入 PATH”。

# 使用
git ai # 等价于调用 ~/bin/git-ai
git cm

移除:

1
rm -f ~/bin/git-ai ~/bin/git-cm

方式 3:Shell 别名(非 git 前缀)

1
2
3
4
5
6
7
echo "alias ai='/opt/miniconda3/envs/zhouzhou/bin/python /Users/zhouzhou/Desktop/test/warp/commit.py'" >> ~/.zshrc
echo "alias cm='/opt/miniconda3/envs/zhouzhou/bin/python /Users/zhouzhou/Desktop/test/warp/commit.py'" >> ~/.zshrc
source ~/.zshrc

# 使用
ai
cm

移除(示例):

1
2
3
4
unalias ai cm 2>/dev/null || true
sed -i '' '/alias ai=/d' ~/.zshrc
sed -i '' '/alias cm=/d' ~/.zshrc
source ~/.zshrc

提示:当同名 Git 别名与外部子命令同时存在时,Git 优先使用别名定义。

Windows 使用说明

可在 Windows 上使用本脚本(支持 Git for Windows、PowerShell、CMD)。

依赖安装

  • 安装 Python(建议 3.9+)。
  • 安装依赖(任选其一):
    • PowerShell/CMD:py -m pip install requests

环境变量(可选)

如果不想改动 commit.py 内的配置,或需要在不同机器/会话中灵活注入配置,建议使用环境变量。脚本会优先读取这些变量;若未设置则落回到 commit.py 的默认值。否则可跳过本节。

  • 临时设置(当前会话):
    • PowerShell:
      • $env:OPENAI_API_BASE = 'https://your.domain/v1'
      • $env:OPENAI_API_KEY = 'your_key'
      • $env:GIT_ZHOU_PUSH = 'true' # 或 false
    • CMD:
      • set OPENAI_API_BASE=https://your.domain/v1
      • set OPENAI_API_KEY=your_key
      • set GIT_ZHOU_PUSH=true
  • 永久设置(用户级):
    • PowerShell/CMD:
      • [Environment]::SetEnvironmentVariable('OPENAI_API_BASE','https://your.domain/v1','User')
      • [Environment]::SetEnvironmentVariable('OPENAI_API_KEY','your_key','User')
      • [Environment]::SetEnvironmentVariable('GIT_ZHOU_PUSH','true','User')

快速接入方式(三选一)

  • Git 别名:

    • 在 Git Bash 或 PowerShell 中:
      • git config --global alias.zhou '!"C:/Path/To/python.exe" "C:/Path/To/commit.py"'
    • 使用:git zhou
  • 外部子命令(推荐,便于多名称):

    • 新建 %USERPROFILE%\bin 并加入 PATH。
    • 新建文件 %USERPROFILE%\bin\git-zhou.cmd,内容:
      • @echo off
      • "C:\\Path\\To\\python.exe" "C:\\Path\\To\\commit.py" %*
    • 之后可用:git zhou(Git 会调用 git-zhou.cmd)。
  • PowerShell 函数(当前会话):

    • function git-zhou { & 'C:\\Path\\To\\python.exe' 'C:\\Path\\To\\commit.py' @args }
    • 使用:git-zhou
    • 永久生效:将上述函数写入 $PROFILE

说明与排错

  • Git 外部子命令在 Windows 上支持 .exe/.cmd/.bat,建议用 .cmd 包装器。
  • 若中文显示异常,可在 PowerShell 里使用 UTF-8 终端;脚本已在 Windows 下切换至 UTF-8 控制台编码。
  • 若自动推送失败,先执行一次:git push -u origin <当前分支> 设置上游分支。

Windows 多指令名使用

可以像 macOS 一样同时配置多个名称来调用同一脚本。

  • 多个 Git 别名:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    git config --global alias.ai '!"C:/Path/To/python.exe" "C:/Path/To/commit.py"'
    git config --global alias.cm '!"C:/Path/To/python.exe" "C:/Path/To/commit.py"'

    # 使用
    git ai
    git cm
    git zhou

    # 移除
    git config --global --unset alias.ai
    git config --global --unset alias.cm
  • 多个外部子命令(推荐):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    mkdir %USERPROFILE%\bin 2>nul
    # git-ai.cmd
    echo @echo off> %USERPROFILE%\bin\git-ai.cmd
    echo "C:\\Path\\To\\python.exe" "C:\\Path\\To\\commit.py" %%*>> %USERPROFILE%\bin\git-ai.cmd

    # git-cm.cmd
    echo @echo off> %USERPROFILE%\bin\git-cm.cmd
    echo "C:\\Path\\To\\python.exe" "C:\\Path\\To\\commit.py" %%*>> %USERPROFILE%\bin\git-cm.cmd

    # 确保将 %USERPROFILE%\bin 加入 PATH 后,直接可用:
    git ai
    git cm

    # 移除
    del %USERPROFILE%\bin\git-ai.cmd 2>nul
    del %USERPROFILE%\bin\git-cm.cmd 2>nul
  • PowerShell 额外命令名(非 git 前缀):

    1
    2
    3
    function ai { & 'C:\\Path\\To\\python.exe' 'C:\\Path\\To\\commit.py' @args }
    function cm { & 'C:\\Path\\To\\python.exe' 'C:\\Path\\To\\commit.py' @args }
    # 写入 $PROFILE 可持久化
 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
访客数 访问量