在做git commit时发出警告

有时候从肌肉记忆中,我运行git commit -a当我有一些文件或文件的一部分仔细地上演并准备提交时,导致我失去了谨慎的分段操作。

有没有办法让git commit -a如果有任何东西(文件或补丁)目前上演警告?

(很明显,我应该使用-a减少来缓解我的问题,但是我的问题仍然存在。)


不幸的是,Git不允许别名覆盖现有的命令,否则您可以通过别名轻松添加此功能。

但是,你可以在那里获得一部分。 这将需要重新训练自己键入一些东西,而不是git commit git c

你可以这样做:

  • 将下面的shell代码放在某个脚本文件中(例如, /path/to/commit-wrapper

    #!/bin/sh
    
    # avoid echo because some implementations treat backslashes specially
    log() { printf '%sn' "$*"; }
    error() { log "ERROR: $*" >&2; }
    fatal() { error "$*"; exit 1; }
    
    check_for_staged() {
        git diff-index --cached --quiet HEAD || {
    
            # simply exit with an error if run non-interactively
            tty >/dev/null 
                || fatal "don't use '$1' when you have staged changes"
    
            # this script is being run interactively; prompt the user to
            # continue
            error "'$1' option used when there are staged changes"
            while true; do
                printf 'Continue anyway? [y/N] ' >&2
                read answer || { printf 'n'; answer=N; }
                [ -n "${answer}" ] || answer=N
                case ${answer} in
                    y|Y) break;;
                    n|N) echo "aborted" >&2; exit 1;;
                    *) error "Please answer 'y' or 'n'.";;
                esac
            done
        }
    }
    
    # TODO:  use 'git rev-parse --parseopt' to reliably detect '-a' (e.g.,
    # to properly handle invocations such as 'git commit -sa')
    for i in "$@"; do
        case ${i} in
            --) break;;
            -a|--all) check_for_staged "${i}"; break;;
        esac
    done
    
    git commit "$@"
    
  • 使文件可执行: chmod a+x /path/to/commit-wrapper
  • 设置别名: git config --global alias.c '!/path/to/commit-wrapper'
  • 使用git c而不是git commit
  • 如果Git被更改为允许现有命令的别名,请将最后一行更改为"$(git --exec-path)"/git-commit "$@"以避免无限循环。


    在回购库中添加一个pre-commit hooke,如下所示:

    #!/bin/sh
    echo "Make sure you haven't used the -a flag or verify git diff --cached returns nothing"
    echo "Run commit again with --no-verify if ok to proceed"
    exit 1
    

    这应该有助于你克服你的“肌肉记忆”。

    不幸的是,预先提交钩子不能够强大到足以做更多的检查(就像你为提交提供了-a参数一样)。另外,当你做-a ,预先提交钩子就会看起来好像所有的文件都是上演后,尽管在执行后,你会看到他们未分阶段。 所以你不能区分你之前上演的内容和因为-a而上演的文件。


    你可以使用你最喜欢的脚本语言来创建git2命令,它会检查你是否用参数commit -a来运行它。 如果是这样的话,运行/usr/bin/git status --porcelain并检查是否有一些对索引的更改(瓷格式的输出更容易解析,我的第一个猜测是通过grep '^[AMD]'并检查它是否找到了一些东西,现在,你可以打印一个警告然后退出,或者运行/usr/bin/git所有原始参数继续,就像没有git2一样(这也是你如果避难的话没有与提交运行-a)。

    下面是Perl中的一个例子(无论如何git都需要这样做):

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    my %aliases = map { split(/n/, $_, 2) }
       split //,
       `git config -z --get-regexp alias.`;
    
    my %commit_aliases = (( commit => 1 ),
       map { s/alias.//; $_ => 1 }
       grep $aliases{$_} =~ /^commitb/,
       keys %aliases);
    
    my ($command, @args) = @ARGV;
    
    if ($commit_aliases{$command} && $args[0] =~ /^-a|^--all/) {
       my @staged = grep /^M/, split //, `git status -z`;
       if (@staged) {
          print "There are staged changes, are you sure you want to commit all? (y/N) ";
          chomp(my $answer = <STDIN>);
          if ($answer =~ /^y/i) {
             run_command()
          }
       } else {
          run_command()
       }
    } else {
       run_command()
    }
    
    sub run_command {
       system 'git', $command, @args;
       exit $? >> 8;
    }
    

    然后,创建一个bash别名alias git2 git ,你就全部设置好了。

    链接地址: http://www.djcxy.com/p/50881.html

    上一篇: Warn when doing git commit

    下一篇: How to push my changes back to the source code in git