代码之家  ›  专栏  ›  技术社区  ›  perpetual

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

  •  0
  • perpetual  · 技术社区  · 1 年前

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

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

    有什么可以在我的 git 客户端,所以它会在我直接编辑或提交到main之前阻止我?这对我的开发来说是一个大问题,因为处理git提交会大大减慢我的python开发速度。

    高代表用户须知

    请不要在没有发表评论的情况下武断地决定你知道我的问题是关于什么的。这个问题的一半编辑来自那些做出错误假设的人,然后我不得不回滚/重新编辑。

    这个问题是关于:

    2 回复  |  直到 1 年前
        1
  •  0
  •   Mike Pennington ThiefMaster    1 年前

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

    我不确定是否要配置git客户端来做到这一点;作为一种选择,您可以用脚本包装vim,使其在编辑之前检查git分支。

    warn on git main

    我写了一个 vim 包装在python中为您做检查。

    用于检查编辑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)
    
        2
  •  0
  •   Tomás Iglesias    1 年前

    @盖伊评论了一个很好的信息链接。

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

    根据您的问题:

    我是否可以在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

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