GitVer

命令行版本管理工具,从 Git 仓库读取 tag 自动生成并回写版本号。


用法总览

gitver
gitver rewrite [PEType] [-f]
gitver setver=<pid> [repodir=<path>] [-test] [-setup=0|1]
gitver nuitkabuild=<pid> [repodir=<path>] [-test] [params="<mainPy> <nuitka参数>"]
gitver nuitkapydbuild=<pid> [repodir=<path>] [-test] [params="<modulePy> <nuitka参数>"]
gitver pyinstaller=<pid> [repodir=<path>] [-test] [params="<mainPy|specFile> <pyinstaller参数>"]
gitver setup=n [pid=m] [repodir=<path>] [-test]

通用参数说明:

参数 说明
pid 产品 ID整数范围 0-65535内嵌在命令名中setver=5
repodir=<path> Git 仓库目录,缺省使用当前运行目录
-test 将产品版本号的 major/minor 置为 0测试版本构建
params="..." 传递给 Nuitka 或 PyInstaller 的参数(含入口文件名),用双引号括起来

BID 规则: main/master 分支固定 bid=0;其他分支格式须为 <描述>.<数字>,自动读取末尾数字作为 bid


命令详解

gitver(无参数交互模式)

自动读取当前分支最近三次符合 <分支>.major.minor 格式的 tag提示用户选择 major+1 或 minor+1二次确认后创建新 tag。

当前分支无有效 tag 时进入首发引导:提示输入默认 major/minor回车使用默认 1/0再创建首个 tag。

交互示例(已有 tag

当前分支: main最近三个 tag
  main.1920.9
  main.1920.10
  main.1920.11
输入 1 → 创建 main.1921.0
输入 2 → 创建 main.1920.12

交互示例(无 tag 首发):

未找到符合规则的历史标签
输入默认 major回车=1: 2
输入默认 minor回车=0: 5
→ 创建 <分支>.2.5

gitver rewrite

自动识别当前目录源码类型C++、C#、Python执行默认版本回写。

gitver rewrite [PEType] [-f]
参数 说明
PEType 可选,1=EXE默认2=DLL最多出现一次
-f 强制模式:未找到目标文件或回写失败仅提示,不返回错误码 35

回写行为:

  • C++:递归查找首个 .rc 文件,回写 FILEVERSIONPRODUCTVERSIONVALUE "FileVersion"VALUE "ProductVersion"(限定在 VS_VERSION_INFO 版本块内)
  • C#:递归查找首个 AssemblyInfo.cs,回写 AssemblyVersionAssemblyFileVersion
  • Python:不执行回写,提示改用 nuitkabuild=nuitkapydbuild=

示例:

gitver rewrite
gitver rewrite 2
gitver rewrite -f

gitver setver=<pid>

从 Git 仓库读取 tag生成产品版本号与文件版本号并按源码类型自动回写。

gitver setver=<pid> [repodir=<path>] [-test]

版本号生成规则:

  • ProductVersion = pid.bid.major.minor(取当前分支前缀的最新 tag
  • FileVersion = pid.yy.mmdd.idid = 当天当前分支提交次数)

示例:

gitver setver=5
gitver setver=5 repodir=E:\Code\OTH\gitver
gitver setver=5 -test

输出示例:

ProductVersion=5.0.1920.11
FileVersion=5.26.0519.3

回写说明:

  • C++:回写 .rc 文件中的 FILEVERSION、PRODUCTVERSION 及对应字符串字段
  • C#:回写 AssemblyInfo.cs 中的 AssemblyVersion、AssemblyFileVersion
  • Python:仅输出版本号,不执行文件回写,提示改用 Nuitka 命令
  • 编码:支持 ANSI/UTF-8保留 UTF-8 BOMUTF-16 文件会报错停止
  • 当前分支无匹配 tag 时自动使用默认版本 1.0

gitver nuitkabuild=<pid>

生成版本号并调用 Nuitka 打包 Python 程序EXE 模式)。

gitver nuitkabuild=<pid> [repodir=<path>] [-test] [params="<mainPy> <nuitka参数>"]

自动调用:

python -m nuitka --windows-product-version=<版本> --windows-file-version=<版本> <params>

示例:

gitver nuitkabuild=5 params="main.py"
gitver nuitkabuild=5 -test params="main.py"
gitver nuitkabuild=5 repodir=E:\Code\MyPyProj params="src\\app.py --standalone --output-dir=dist"

输出示例:

Nuitka 打包开始..
ProductVersion=5.0.1920.11
FileVersion=5.26.0519.3

需要当前环境已安装 Nuitka可通过 python -m nuitka --version 验证)。


gitver nuitkapydbuild=<pid>

生成版本号并调用 Nuitka 打包 Python 模块pyd/DLL 模式)。

gitver nuitkapydbuild=<pid> [repodir=<path>] [-test] [params="<modulePy> <nuitka参数>"]

自动调用:

python -m nuitka --module --windows-product-version=<版本> --windows-file-version=<版本> <params>

示例:

gitver nuitkapydbuild=5 params="module.py"
gitver nuitkapydbuild=5 -test params="module.py"
gitver nuitkapydbuild=5 repodir=E:\Code\MyPyProj params="src\\core.py --output-dir=dist"

需要当前环境已安装 Nuitka可通过 python -m nuitka --version 验证)。


gitver pyinstaller=<pid>

生成版本号并调用 PyInstaller 打包 Python 程序,支持直接传入 .py 入口脚本或 .spec 构建配置文件。

gitver pyinstaller=<pid> [repodir=<path>] [-test] [params="<mainPy|specFile> <pyinstaller参数>"]

自动调用:

python -m PyInstaller <params>

版本号照常从 Git tag 计算并输出。在 spec 模式gitver 会在调用 PyInstaller 前自动将版本号写入版本信息,具体行为取决于 spec 文件中 version= 字段的值:

spec 中 version= 的值 行为
'version_info.txt'(引号路径,文件存在) 就地更新外部版本信息文件
'1.2.3.4'(引号字符串,非有效文件路径) 替换 spec 内该引号字符串为新版本号
version_info无引号标识符spec 内定义的 VSVersionInfo 对象) 就地更新 spec 文件内的版本字段
version= / version=None 在 spec 目录生成 version_info.txt 并自动注入 version='version_info.txt'

脚本模式.py 入口PyInstaller 不接受命令行版本参数,版本号仅输出到控制台,不嵌入 EXE。

两种打包模式:

模式 参数示例 说明
脚本模式 params="main.py" 由 PyInstaller 自动生成 spec 并打包
spec 模式 params="myapp.spec" 使用已有 spec 文件,打包配置完全由 spec 控制gitver 在调用 PyInstaller 前自动将版本号写入版本信息(见下表)

示例:

gitver pyinstaller=5 params="main.py"
gitver pyinstaller=5 -test params="main.py"
gitver pyinstaller=5 repodir=E:\Code\MyPyProj params="src\\app.py --onefile --name=MyApp"
gitver pyinstaller=5 params="myapp.spec"
gitver pyinstaller=5 -test params="myapp.spec"
gitver pyinstaller=5 repodir=E:\Code\MyPyProj params="myapp.spec"

输出示例:

PyInstaller 打包开始.. (main.py)
ProductVersion=5.0.1920.11
FileVersion=5.26.0519.3

需要当前环境已安装 PyInstaller可通过 python -m PyInstaller --version 验证)。


gitver setup=n(独立打包命令)

独立调用安装脚本打包,不依赖其他命令。

gitver setup=n [pid=m] [repodir=<path>] [-test]
参数 说明
n 安装脚本类型,0=Inno Setupsetup.iss1=NSISsetup.nsi
pid=m 可选,产品 ID整数 0-65535不指定时自动从项目的 .rcAssemblyInfo.cs.spec 文件中读取版本信息

示例:

gitver setup=0
gitver setup=1
gitver setup=0 pid=5
gitver setup=1 pid=5 repodir=E:\Code\MyProj

Nuitka 与 PyInstaller 常用参数速查

Nuitka 常用参数

通过 params="..." 传递给 gitver nuitkabuild= / nuitkapydbuild=

参数 说明
--standalone 独立模式:将所有依赖打包进输出目录,可单独分发
--onefile 单文件模式:将独立包压缩为单个 EXE需配合 --standalone
--output-dir=<dir> 指定输出目录,如 --output-dir=dist
--windows-icon-from-ico=<ico> 设置 EXE 图标
--windows-company-name=<name> 设置公司名(写入文件属性)
--windows-product-name=<name> 设置产品名
--enable-plugin=<plugin> 启用插件,如 pyside6tk-internumpy
--follow-imports 跟踪所有隐式导入(打包更完整,体积也更大)
--nofollow-import-to=<mod> 排除指定模块不展开,如 --nofollow-import-to=tests
--include-package=<pkg> 强制包含指定包
--include-data-files=<src>=<dst> 打包额外数据文件
--remove-output 打包前先清理上次输出
--lto=yes 启用链接时优化Release 构建推荐)
--jobs=<n> 并行编译线程数,如 --jobs=4

典型用法示例:

# 最小单文件 EXE
gitver nuitkabuild=5 params="main.py --standalone --onefile --output-dir=dist"

# 带图标、公司名的独立包
gitver nuitkabuild=5 params="main.py --standalone --windows-icon-from-ico=app.ico --windows-company-name=MyCompany --output-dir=dist"

# PySide6 GUI 应用
gitver nuitkabuild=5 params="main.py --standalone --enable-plugin=pyside6 --output-dir=dist"

# 打包 pyd 模块
gitver nuitkapydbuild=5 params="core.py --output-dir=dist"

# 异地仓库
gitver nuitkabuild=5 repodir=E:\Code\MyProj params="main.py --standalone --onefile --output-dir=dist"

PyInstaller 常用参数

通过 params="..." 传递给 gitver pyinstaller=

参数 说明
--onefile / -F 单文件模式:打包成单个 EXE
--onedir / -D 单目录模式(默认)
--name=<name> / -n 指定输出文件名(不含后缀)
--icon=<ico> / -i 设置 EXE 图标
--distpath=<dir> 指定输出目录,默认 dist
--workpath=<dir> 中间文件目录,默认 build
--specpath=<dir> spec 文件生成位置,默认当前目录
--noconsole / -w 不显示控制台窗口GUI 应用)
--hidden-import=<mod> 手动指定隐式导入的模块
--add-data=<src>;<dst> 打包额外数据文件Windows 分隔符为 ;Linux/macOS 为 :
--version-file=<file> 从文件读入 Windows 版本信息嵌入 EXE
--uac-admin 请求管理员权限运行
--clean 构建前清理缓存
--log-level=WARN 减少构建输出噪音,可选 DEBUGINFOWARNERROR

典型用法示例:

# 最小单文件 EXE
gitver pyinstaller=5 params="main.py --onefile --name=MyApp"

# GUI 应用(关指控制台)
gitver pyinstaller=5 params="main.py --onefile --noconsole --icon=app.ico --name=MyApp"

# 包含资源文件
gitver pyinstaller=5 params="main.py --onefile --add-data=assets;assets --name=MyApp"

# 指定输出目录
gitver pyinstaller=5 params="main.py --onefile --distpath=dist --workpath=build --name=MyApp"

# 使用 spec 文件(配置均在 spec 中,不需要其他 params
gitver pyinstaller=5 params="myapp.spec"

# 使用 spec 并覆盖输出路径
gitver pyinstaller=5 params="myapp.spec --distpath=release"

# 异地仓库
gitver pyinstaller=5 repodir=E:\Code\MyProj params="main.py --onefile --name=MyApp"

spec 文件嵌入版本信息(推荐方式):

PyInstaller 不支持命令行版本参数。需将版本号嵌入 EXE 时,建议先用 gitver setver=<pid> 生成版本号,再在 spec 文件中设置 version_file 字段:

# myapp.spec 片段
exe = EXE(
    pyz,
    ...,
    version='version_info.txt',   # Windows 版本信息文件
    name='MyApp',
)

完整 spec 文件示例(myapp.spec

# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(
    ['src\\main.py'],           # 入口脚本
    pathex=[],
    binaries=[],
    datas=[
        ('assets', 'assets'),   # 额外资源目录:源路径, 目标路径
    ],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='MyApp',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,              # True=控制台程序False=GUI程序
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon='assets\\app.ico',     # 图标文件路径
    version='version_info.txt', # Windows 版本信息文件
)

配套的 version_info.txt 示例:

# UTF-8
# Windows EXE 版本信息文件
# 版本号格式major, minor, patch, build均为整数

VSVersionInfo(
    ffi=FixedFileInfo(
        filevers=(5, 0, 1920, 11),      # FileVersion对应 FileVersion=5.0.1920.11
        prodvers=(5, 0, 1920, 11),      # ProductVersion
        mask=0x3f,
        flags=0x0,
        OS=0x40004,
        fileType=0x1,                   # 0x1=EXE, 0x2=DLL
        subtype=0x0,
        date=(0, 0),
    ),
    kids=[
        StringFileInfo([
            StringTable(
                '040904B0',             # 语言 0409=英语, 04B0=Unicode
                [
                    StringStruct('CompanyName', 'MyCompany'),
                    StringStruct('FileDescription', 'MyApp Application'),
                    StringStruct('FileVersion', '5.0.1920.11'),
                    StringStruct('InternalName', 'MyApp'),
                    StringStruct('LegalCopyright', 'Copyright (C) 2026 MyCompany'),
                    StringStruct('OriginalFilename', 'MyApp.exe'),
                    StringStruct('ProductName', 'MyApp'),
                    StringStruct('ProductVersion', '5.0.1920.11'),
                ]
            )
        ]),
        VarFileInfo([VarStruct('Translation', [0x0409, 0x04B0])])
    ]
)

在 spec 模式下gitver 会在调用 PyInstaller 前自动将计算出的版本号写入版本信息,无需手动维护 version_info.txt


错误码

含义
2 默认回写流程下未获取到 git 提交号
3 参数非法或未知参数
4 setver= 的 pid 非法
5 setver= 无法根据分支名计算 bid
9 setver= 获取当天分支提交次数失败
15 回写流程未识别源码类型
16 回写流程识别到 Python请改用 nuitka 命令
17 nuitkabuild= 参数不足(缺少 mainPy
18 nuitkabuild= 的 pid 非法
19 nuitkabuild= 无法根据分支名计算 bid
21 nuitkabuild= 获取当天分支提交次数失败
22 rewrite 参数非法PEType 非法或重复)
23 repodir= 不是有效目录
24 nuitkapydbuild= 参数不足(缺少 modulePy
25 nuitkapydbuild= 的 pid 非法
26 nuitkapydbuild= 无法根据分支名计算 bid
28 nuitkapydbuild= 获取当天分支提交次数失败
29 无参数模式下无法获取当前分支
30 无参数模式下读取标签列表失败
31 无参数模式下未读取到用户输入
32 无参数模式下用户选择非法,或 major/minor 已达上限
33 无参数模式下创建 tag 失败
34 无参数模式下创建 tag 后校验失败
35 未找到可回写目标文件,或回写失败
36 setup= 值不支持(仅支持 0 和 1
37 未找到安装脚本setup.iss / setup.nsi
38 修改安装脚本失败
39 未找到安装编译器ISCC.exe / makensis.exe
40 pyinstaller= 参数不足(缺少 mainPy 或 specFile
41 pyinstaller= 的 pid 非法
42 pyinstaller= 无法根据分支名计算 bid
43 pyinstaller= 读取 tag 失败
44 pyinstaller= 获取当天分支提交次数失败
45 pyinstaller= 版本信息文件无法生成或更新
46 pyinstaller= spec 文件无法注入或修改版本信息

最小自测

基础验证:setver=

# 初始化测试仓库
mkdir test_repo && cd test_repo
git init
echo test > README.txt
git add . && git commit -m "init"
git tag main.1920.10
git tag main.1920.11

# 验证版本生成
gitver setver=5
# 预期:
#   ProductVersion=5.0.1920.11
#   FileVersion=5.yy.mmdd.<id>
# 返回码: 0

验证无 tag 时自动使用默认版本

git checkout -b newbranch
gitver setver=5
# 预期: ProductVersion=5.<bid>.1.0(无 tag 自动回落默认 1.0
# 返回码: 0

验证分支 tag 隔离

git checkout -b feature.12
git tag feature.12.1930.7
git tag feature.12.1930.8
gitver setver=5
# 预期: ProductVersion=5.12.1930.8(忽略 main.* tag
# 返回码: 0

验证 -test

gitver setver=5 -test
# 预期: ProductVersion=5.0.0.0major/minor 置零)
# 返回码: 0

验证 nuitkabuild=

gitver nuitkabuild=5 params="main.py"
# 预期: 调用 python -m nuitka注入版本号参数

gitver nuitkabuild=5 params="src\\app.py --standalone --output-dir=dist"
# 预期: 额外参数传递给 Nuitka

验证 pyinstaller=

gitver pyinstaller=5 params="main.py"
# 预期: 调用 python -m PyInstaller main.py
#        输出 ProductVersion / FileVersion

gitver pyinstaller=5 params="myapp.spec"
# 预期: 调用 python -m PyInstaller myapp.specspec 模式)

gitver pyinstaller=5 params="main.py --onefile --name=MyApp"
# 预期: 额外参数传递给 PyInstaller

验证 setup=

# 确保 exe 目录或上级目录有 setup.iss
gitver setup=0
# 预期: 从 .rc 或 AssemblyInfo.cs 读取版本号,修改 setup.iss 并调用 ISCC.exe 编译

gitver setup=0 pid=5
# 预期: 使用 pid=5 生成版本号,修改 setup.iss 并调用 ISCC.exe 编译

回归清单

rewrite 组

命令 预期返回码
gitver rewrite 0 / 15 / 16 / 35
gitver rewrite -f 0 / 15 / 16
gitver rewrite 2 0 / 15 / 35
gitver rewrite 1 2 22

setver= 组

命令 预期返回码
gitver setver=5 0
gitver setver=5 -test 0
gitver setver=5 repodir=E:\NotExists 23
gitver setver=abc 4

nuitkabuild= 组

命令 预期返回码
gitver nuitkabuild=5 params="main.py" 0 / 19 / 21
gitver nuitkabuild=5 -test params="main.py" 0
gitver nuitkabuild=5 params="main.py --standalone" 0
gitver nuitkabuild=5 repodir=E:\NotExists params="main.py" 23
gitver nuitkabuild=5 0

nuitkapydbuild= 组

命令 预期返回码
gitver nuitkapydbuild=5 params="module.py" 0 / 26 / 28
gitver nuitkapydbuild=5 -test params="module.py" 0
gitver nuitkapydbuild=5 params="module.py --output-dir=dist" 0
gitver nuitkapydbuild=5 repodir=E:\NotExists params="module.py" 23
gitver nuitkapydbuild=5 0

pyinstaller= 组

命令 预期返回码
gitver pyinstaller=5 params="main.py" 0 / 42 / 44
gitver pyinstaller=5 -test params="main.py" 0
gitver pyinstaller=5 params="main.py --onefile" 0
gitver pyinstaller=5 params="myapp.spec" 0
gitver pyinstaller=5 -test params="myapp.spec" 0
gitver pyinstaller=5 repodir=E:\NotExists params="main.py" 23
gitver pyinstaller=5 0
gitver pyinstaller=abc params="main.py" 41

setup= 组

命令 预期返回码
gitver setup=0 0 / 37 / 38 / 39
gitver setup=1 0 / 37 / 38 / 39
gitver setup=0 pid=5 0 / 37 / 38 / 39
gitver setup=0 pid=5 repodir=E:\NotExists 23
gitver setup=9 36
gitver setup=0 pid=abc 4

注意如果打包时提示“未找到安装编译器ISCC.exe / makensis.exe请手动下载安装对应工具并将其可执行文件路径ISCC.exemakensis.exe 所在目录)添加到系统环境变量 PATH。常见下载地址:

添加方法:

  1. 复制编译器安装目录路径(如 C:\Program Files (x86)\Inno Setup 6)。
  2. 打开“系统属性”→“高级”→“环境变量”,在“系统变量”中找到 PATH,点击“编辑”,添加上述路径。
  3. 重新打开命令行窗口后再运行打包命令。
Description
命令行工具,主要用来生成版本信息:文件版本信息、产品版本信息、创建Tag标签等;避免手动输入版本号导致的错误值输出,同时自动版本号也可以更容易追溯出问题的代码记录。
Readme 303 KiB
Languages
C++ 96.6%
C 3.4%