不能在即将提交的提交中包含钩子所做的更改

问题描述 投票:0回答:1

我有一个存储库,其版本(语义版本控制)硬编码在其文件之一中。每次开发人员添加更改(我们将其称为类型 1 更改)时,我都需要检查这些更改并增加次要版本组件。如果开发人员添加类型 2 更改,我会增加补丁版本组件。

我为开发人员制定了一个约定:如果他们要添加类型 1 更改,则必须创建一个分支并将其命名为

A/ID
。如果他们要添加类型 2 更改,则必须创建一个分支并将其命名为
bugfix/A/ID

此外,我还编写了一些 Git hook(

commit-msg
,因为它会在
git commit
git merge
中调用)脚本,根据合并到默认分支的分支,自动递增相关版本组件。下面是我写的Git hook脚本:

#!/usr/bin/env python3
import subprocess
import sys
import pathlib
import re


def main():
    default, base = "main", "package/__init__.py"

    head = pathlib.Path(".git/MERGE_HEAD")
    if not head.exists():
        exit(0)

    with head.open() as f:
        commit = f.read().strip()

    command = ["git", "name-rev", "--name-only", commit]
    process = subprocess.run(command, capture_output=True, encoding="UTF-8")
    if process.returncode != 0:
        print(
            f"Failing to perform `commit-msg` commit operations. The `{' '.join(command)}` command and its logs may be helpful.",
            " ".join(process.args),
            process.stderr,
            sep="\n",
            file=sys.stderr,
        )
        exit(process.returncode)

    merge = process.stdout.strip()

    command = ["git", "rev-parse", "--abbrev-ref", "HEAD"]
    process = subprocess.run(command, capture_output=True, encoding="UTF-8")
    if process.returncode != 0:
        print(
            f"Failing to perform `commit-msg` commit operations. The `{' '.join(command)}` command and its logs may be helpful.",
            " ".join(process.args),
            process.stderr,
            sep="\n",
            file=sys.stderr,
        )
        exit(process.returncode)

    current = process.stdout.strip()

    if current != default or (
        not merge.startswith("A/") and not merge.startswith("bugfix/A/")
    ):
        exit(0)

    semver = re.compile(
        r"(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?"
    )
    version = {"major": 0, "minor": 0, "patch": 0}

    with open(base, mode="r", encoding="UTF-8") as f:
        line, match = f.readline(), None
        while line:
            if line.startswith("__version__"):
                match = re.match(r'__version__.*"(?P<version>.*?)"', line)
                break

            line = f.readline()

    if match == None:
        print(
            "Failing to perform `commit-msg` commit operations. The Semantic Versioning regular expression cannot find the detection version in the Python module!",
            file=sys.stderr,
        )
        exit(1)

    match = semver.match(match.group("version"))
    if match == None:
        print(
            "Failing to perform `commit-msg` commit operations. The detection version format in this repository does not match the Semantic Versioning format.",
            file=sys.stderr,
        )
        exit(1)

    version["major"], version["minor"], version["patch"] = (
        int(match.group("major")),
        int(match.group("minor")),
        int(match.group("patch")),
    )

    if merge.startswith("A/"):
        version["minor"] += 1

    elif merge.startswith("bugfix/A/"):
        version["patch"] += 1

    with open(base, mode="r", encoding="UTF-8") as f:
        module = f.read()

    with open(base, mode="w", encoding="UTF-8") as f:
        module = re.sub(
            r'__version__ = "(?P<version>.*?)"',
            f'__version__ = "{version["major"]}.{version["minor"]}.{version["patch"]}-rc"',
            module,
        )
        f.write(module)

    command = ["git", "add", base]
    process = subprocess.run(command, capture_output=True, encoding="UTF-8")
    if process.returncode != 0:
        print(
            f'Failing to perform `commit-msg` commit operations. The `{" ".join(command)}` command and its logs may be helpful.',
            " ".join(process.args),
            process.stderr,
            sep="\n",
            file=sys.stderr,
        )
        exit(process.returncode)

    print("Upgraded.")


if __name__ == "__main__":
    main()

脚本按预期工作,但有一个例外:在脚本末尾,您可以看到我正在使用

git add <FILE>
来包含之前对 Python 模块中硬编码的版本所做的更改。

此命令按预期工作并将更改添加到 Git 索引。 但是,在挂钩完成并出现合并提交消息后,当我接受该消息时,更改不会包含在合并提交中,而是单独保留在索引中!

我做错了什么?我在线且活跃,回答出现的问题。

我描述的前一个问题的解决方案是第一位的,但欢迎对问题的各个方面提出建议,包括对总体方法、Python 代码、Git 挂钩名称和哲学的更改。

python git githooks
1个回答
0
投票

我会尝试使用普通的

pre-merge-commit
钩子,选择
commit-msg
钩子似乎很奇怪“因为它会在
git commit
git merge
中被调用”,但如果没有被调用,它就会立即退出用于合并;此外,预提交和预合并提交并没有明确用于设置消息文本,这使得它们看起来不太可能在所有事情之后运行,但消息文本已经准备好并锁定。

© www.soinside.com 2019 - 2024. All rights reserved.