如果我之前手动添加文件,我可以让 git 拒绝所有提交吗?

Posted

技术标签:

【中文标题】如果我之前手动添加文件,我可以让 git 拒绝所有提交吗?【英文标题】:Can I make git reject an all-commit if I have before manually added files? 【发布时间】:2015-11-25 13:38:39 【问题描述】:

大多数时候,我使用git commit -am 提交,因为我对项目所做的一切都属于我正在处理的提交。

只有在某些时候,我不想提交一些更改,所以我使用git add -p 来仅暂存我真正想要的内容。麻烦的是,我已经习惯了输入git commit -am,以至于我通常最终还是会这样做。然后我得到了一个我不想要的东西的提交,并且不得不费力地回到HEAD^,并重新做add -p

显然,当手动添加了一些更改时,commit -am 不再有意义。有没有办法阻止 git 在这种情况下接受该选项(或-am 的其他替代方案,同样方便)?

【问题讨论】:

【参考方案1】:

更简单、更快、更诱人。 尽管git commit -am 可能很诱人,但你应该训练自己远离它。它确实适用于非常简单的(例如单文件)提交。充分利用暂存区:在拍摄快照之前花时间到compose the shot。

如果这个警告还不够,并且您需要一些帮助来避免git commit -am... 那么,不幸的是,Git API 本身并没有提供“禁止”其命令子集的简单方法。一种不是很健壮的方法,但这主要是解决问题的方法,是为git 编写一个简单的shell 包装函数,它密切关注命令行参数commit-am,并在这些参数出现时采取措施使用(与this other answer中相同的策略。):

# Git wrapper forbidding 'git commit -am'
git() 
    if [ "$1" = "commit" -a "$2" = "-am" ]; then
        printf "'git commit -am' is currently disabled by your Git wrapper.\n";
    else
        command git "$@";
    fi;

根据您的习惯,您当然可以改进此包装器以使其更加健壮。

【讨论】:

另一种方法是添加一个要求确认的预提交挂钩,但我认为没有办法告诉该挂钩使用了 -am 标志。 如果不是-am,恐怕我的手会习惯于输入git add . && git commit -m,我又会遇到同样的问题。 @leftaroundabout “坏习惯”很难改掉。除非您准备好编辑 Git 源代码并为自己构建一个自定义版本,否则除了我的答案中概述的之外,我想不出任何其他方式。【参考方案2】:

您可以创建一个脚本文件 git-cm,并将其放入您的 PATH 中

#!/bin/sh

DIRTY=$(git status -s| grep -e "^[A-Z]")
if [ ! "$DIRTY" ]; then
    git commit "$@";
    exit 0;
else 
    echo "Rejected, files already manually added";
    exit 1;
fi

当你想提交时运行它

git-cm -am "some message"

如果您已经手动添加了文件,脚本将拒绝提交并中止操作。

这是因为在这种情况下,git status -s 会生成以 e.g. 开头的行

M  file/Ive/just.added`

不用手动添加的地方

 M file/Ive/just.added

改为(注意前导空格)。

您可能需要根据自己的环境进行调整。

【讨论】:

egrep '^[A-Z]' 似乎是一个糟糕的 hack,但是哦,好吧......它成功了。谢谢! 一个人必须记住使用git-cm 而不是git... 当一个人已经在努力记住不要使用某个命令时,这有什么帮助?无论如何,您可能希望将--porcelain 标志添加到您的git status 命令中,以提高稳健性。

以上是关于如果我之前手动添加文件,我可以让 git 拒绝所有提交吗?的主要内容,如果未能解决你的问题,请参考以下文章

即使我在提交之前 git 添加了所有文件,我可以恢复到只有一个文件的先前版本吗?

加入.gitignore的文件有啥办法恢复出来不

致命:添加 git remote 后拒绝合并不相关的历史记录

在已跟踪大量文件的现有存储库上应用gitignore

Git复习之使用

Git复习之使用