如何创建每次Git推送时自动更新的version.py文件?
问题修复与优化方案
现有脚本的核心问题
你的脚本无法生效主要有以下几个原因:
- 钩子类型不匹配:
pre-push钩子的参数不是提交消息文件,直接使用会导致读取文件失败;prepare-commit-msg钩子的时机是提交消息生成后、提交创建前,此时git rev-parse HEAD获取的是上一次提交的哈希,并非本次提交的哈希。 - Shebang错误:原脚本的
#!/usr/bin/env /usr/bin/python写法错误,env后应跟命令名而非绝对路径,兼容性差。 - 异常处理缺失:未处理文件读取失败、版本号解析失败、Git命令执行失败等情况,容易崩溃。
- 冗余操作:重复执行
git add命令,无意义。
修复后的prepare-commit-msg钩子脚本
该脚本会在提交消息生成后修改version.py,并将其加入当前提交的暂存区(注意:此时无法获取本次提交的哈希,改用暂存区的树哈希替代):
#!/usr/bin/env python3 import os import subprocess import re import sys # 检查参数是否存在 if len(sys.argv) < 1: print("错误:未提供提交消息文件", file=sys.stderr) sys.exit(1) commit_msg_file = sys.argv[1] # 读取提交消息 try: with open(commit_msg_file, 'r') as file: commit_msg = file.read().strip() except Exception as e: print(f"读取提交消息文件失败:{e}", file=sys.stderr) sys.exit(1) version_file = os.path.abspath('version.py') # 获取暂存区的树哈希(提交未创建,无法获取提交哈希) try: hashed_code = subprocess.check_output(['git', 'write-tree']).strip().decode('utf-8') except subprocess.CalledProcessError as e: print(f"获取Git哈希失败:{e}", file=sys.stderr) sys.exit(1) # 解析或初始化版本号 major, minor, patch = 0, 0, 1 if os.path.exists(version_file): print(f'读取已有版本文件:{version_file}') try: with open(version_file, 'r') as f: content = f.read() match = re.search(r'version = "(\d+)\.(\d+)\.(\d+)"', content) if match: major, minor, patch = map(int, match.groups()) patch += 1 else: print("警告:版本号格式错误,重置为0.0.1", file=sys.stderr) except Exception as e: print(f"读取版本文件失败:{e}", file=sys.stderr) print("重置版本号为0.0.1", file=sys.stderr) else: print(f'创建新的版本文件:{version_file}') # 写入version.py内容 print(f'写入版本文件,提交消息:"{commit_msg}"') try: with open(version_file, 'w') as f: f.write(f'''# This file is created by the prepare-commit-msg script class Version: comment = "{commit_msg}" hash = "{hashed_code}" version = "{major}.{minor}.{patch}" if __name__ == "__main__": print(Version.version) ''') except Exception as e: print(f"写入版本文件失败:{e}", file=sys.stderr) sys.exit(1) # 将版本文件加入暂存区 print(f'将{version_file}加入暂存区') try: subprocess.check_call(['git', 'add', version_file]) except subprocess.CalledProcessError as e: print(f'Git添加文件失败:{e}', file=sys.stderr) sys.exit(1)
使用方法
- 将脚本保存到项目的
.git/hooks/prepare-commit-msg文件中 - 赋予执行权限:
chmod +x .git/hooks/prepare-commit-msg
更好的实现(获取真实提交哈希)
如果需要version.py中包含本次提交的真实哈希,可以使用post-commit钩子,提交完成后自动更新版本文件并创建新提交(通过提交消息判断避免循环):
#!/usr/bin/env python3 import os import subprocess import re import sys version_file = os.path.abspath('version.py') # 获取当前提交的哈希和消息 try: hashed_code = subprocess.check_output(['git', 'rev-parse', 'HEAD']).strip().decode('utf-8') commit_msg = subprocess.check_output(['git', 'log', '-1', '--pretty=%B']).strip().decode('utf-8') except subprocess.CalledProcessError as e: print(f"获取Git信息失败:{e}", file=sys.stderr) sys.exit(1) # 避免循环提交:如果当前提交是自动更新版本的提交,则跳过 if commit_msg.strip() == "Update version.py": print("跳过自动生成的版本更新提交", file=sys.stdout) sys.exit(0) # 解析或初始化版本号 major, minor, patch = 0, 0, 1 if os.path.exists(version_file): print(f'读取已有版本文件:{version_file}') try: with open(version_file, 'r') as f: content = f.read() match = re.search(r'version = "(\d+)\.(\d+)\.(\d+)"', content) if match: major, minor, patch = map(int, match.groups()) patch += 1 else: print("警告:版本号格式错误,重置为0.0.1", file=sys.stderr) except Exception as e: print(f"读取版本文件失败:{e}", file=sys.stderr) print("重置版本号为0.0.1", file=sys.stderr) else: print(f'创建新的版本文件:{version_file}') # 写入version.py内容 print(f'写入版本文件,提交消息:"{commit_msg}"') try: with open(version_file, 'w') as f: f.write(f'''# This file is created by the post-commit script class Version: comment = "{commit_msg}" hash = "{hashed_code}" version = "{major}.{minor}.{patch}" if __name__ == "__main__": print(Version.version) ''') except Exception as e: print(f"写入版本文件失败:{e}", file=sys.stderr) sys.exit(1) # 提交版本文件修改 try: subprocess.check_call(['git', 'add', version_file]) subprocess.check_call(['git', 'commit', '-m', 'Update version.py']) except subprocess.CalledProcessError as e: print(f'提交版本文件失败:{e}', file=sys.stderr) sys.exit(1)
使用方法
- 将脚本保存到项目的
.git/hooks/post-commit文件中 - 赋予执行权限:
chmod +x .git/hooks/post-commit
内容的提问来源于stack exchange,提问作者jordanthompson
相关产品推荐
相关产品推荐

