防止意外直接编辑或在 git 主分支上提交

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

我正在做一个Python项目;我是 git 新手,仍在学习如何分支。由于我仍在学习,有时我只是忘记并直接编辑/提交文件到 main。

我不喜欢必须回滚更改并在非主 git 分支上重新提交。我不想过早地将我的主分支变基或合并到开发中。

我可以在 git 客户端中配置一些东西,以便它在我进行直接编辑或提交到 main 之前阻止我吗?这对我的开发来说是一个大问题,因为处理 git 提交会大大减慢我的 python 开发速度。

python git vim workflow
2个回答
0
投票

我可以在 git 客户端中配置一些东西,以便在我直接提交到 main 之前它会阻止我吗?

我不确定如何配置 git 客户端来做到这一点;作为一种替代方案,您可以使用脚本包装 vim,以便它在编辑之前检查 git 分支。

我用 python 编写了一个

vim
包装器来为你进行检查。

用于检查编辑 git main 的 python 包装器

保存并使其可执行;

/usr/bin/env
是 Linux 和 WSL 的本机...我不确定是否可以在 Windows 文件系统中运行它。

#!/usr/bin/env python
from subprocess import run
import locale
import shutil
import shlex
import sys
import os


class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKCYAN = '\033[96m'
    OKGREEN = '\033[92m'
    RED = '\033[91m'
    RED_FLASH = '\033[5;37;91m'
    RED_REVERSE = '\033[0;37;41m'
    RED_FLASH_REVERSE = '\033[5;37;41m'
    WARNING = '\033[93m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'


class _GetchUnix:

    def __call__(self):
        import termios
        import tty
        import sys
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch


class _GetchWindows:
    def __init__(self):
        pass

    def __call__(self):
        import msvcrt
        return msvcrt.getch()


class Getchar:
    """Gets a single character from standard input.  Does not echo to the screen."""
    def __init__(self):
        try:
            import msvcrt
            msvcrt.LK_LOCK
            self.impl = _GetchWindows()
        except ImportError:
            self.impl = _GetchUnix()

    def __call__(self):
        return self.impl()


class cd:
    """Context manager for changing the current working directory"""
    def __init__(self, newPath):
        self.newPath = os.path.expanduser(newPath)

    def __enter__(self):
        self.savedPath = os.getcwd()
        os.chdir(self.newPath)

    def __exit__(self, etype, value, traceback):
        os.chdir(self.savedPath)


getchar = Getchar()


def find_git_branch(directory):
    """cd into a directory and return the git branch that it's on"""
    with cd(directory):
        enc_str = locale.getpreferredencoding()
        proc = run(shlex.split("git status"), capture_output=True)
        try:
            git_branch_list = proc.stdout.decode(enc_str).splitlines()[0].split()[2:]
            git_branch = ' '.join(git_branch_list).strip()
        except IndexError:
            git_branch = ""
        return git_branch


def check_git_edit(directory, vi_command):
    """if a file is on a git master branch, ask before editing it"""
    # check the git branch of the directory...
    git_branch = find_git_branch(directory)
    if git_branch == "main" or git_branch == "master":
        print(f"{bcolors.RED_FLASH_REVERSE}You are editing on git {git_branch}, are you sure? (Y/N){bcolors.ENDC}")
        user_input = getchar()
        if user_input.upper() == "Y":
            # Run vim.basic which allows ~/.vimrc... vim.tiny does not!
            run(shlex.split(vi_command))
    else:
        run(shlex.split(vi_command))


if __name__ == "__main__":
    if shutil.which("vim") and not shutil.which("vim.basic"):
        vim = "vim"
    elif shutil.which("vim.basic"):
        vim = "vim.basic"
    else:
        raise OSError("vim is not installed")
    vi_command = f"{vim} {' '.join(sys.argv[1:])}"
    filepath = os.path.expanduser(' '.join(sys.argv[1:]))
    dir_part = os.path.split(filepath)[0]
    if dir_part != "":
        dirname = os.path.dirname(filepath)
        check_git_edit(dirname, vi_command)
    else:
        check_git_edit(os.getcwd(), vi_command)

0
投票

@Guy 评论了一个内容丰富的链接。

我还建议您养成在不同分支工作的习惯,在这些分支中添加新功能或修复错误。如果您正在处理一个非常小的项目,也许没有必要使用除主分支之外的其他分支,在这种情况下您可以直接进行所有更改

根据您的问题:

我可以在 git 客户端中配置一些东西,以便在我直接提交到 main 之前它会阻止我吗?

是的,您可以配置 Git 在允许直接提交到主分支之前添加额外的保护层。一种常见的方法是使用 Git 挂钩,特别是预提交挂钩,在允许提交之前强制执行某些检查。

这是一个使用预提交挂钩的简单示例:

  1. 在命令行中导航到您的 Git 存储库。
  2. 转到 .git/hooks 目录。如果您找不到预提交文件,请创建一个。
  3. 打开或创建预提交文件并添加以下脚本:
#!/bin/bash

# Prevent direct commits to the main branch
if [ "$(git rev-parse --abbrev-ref HEAD)" = "main" ]; then
    echo "Direct commits to main are not allowed. Please use feature branches." >&2
    exit 1
fi

保存文件并使其可执行:

chmod +x pre-commit

然后,每当您尝试直接提交到主分支时,脚本都会阻止它并显示错误消息。

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