git reset——hard-q产生关于空格的错误
我正在编写一个预提交钩子来运行我的Python测试,一切都运行得非常好。。。直到我遇到合并冲突。在此合并冲突中,引入了一些带有尾随空格的文档文件,每次我尝试提交时,都会收到以下消息:git reset——hard-q产生关于空格的错误,git,sh,githooks,Git,Sh,Githooks,我正在编写一个预提交钩子来运行我的Python测试,一切都运行得非常好。。。直到我遇到合并冲突。在此合并冲突中,引入了一些带有尾随空格的文档文件,每次我尝试提交时,都会收到以下消息: <stdin>:28: trailing whitespace. Ticket Link: <stdin>:54: trailing whitespace. Then visit `http://app.dev` <stdin>:13528: trailing whitesp
<stdin>:28: trailing whitespace.
Ticket Link:
<stdin>:54: trailing whitespace.
Then visit `http://app.dev`
<stdin>:13528: trailing whitespace.
//most be provided for ALL resource updates, and
<stdin>:13531: trailing whitespace.
"deleted": false, //indicates if this action resulted in a resource delete;
warning: squelched 415 whitespace errors
warning: 420 lines add whitespace errors.
fatal: could not open '.git/MERGE_HEAD' for reading: No such file or directory
通过这一点,我了解到,proper\u pop
中的行:git reset--hard-q
是唯一的罪魁祸首(删除它会删除错误)。没有安装其他钩子,git版本是:1.8.1.2
,但是我也在版本2.5.0
上运行了这个钩子,同样的问题也发生了。有人知道发生了什么事吗
我试着用管道将stdout和stderr连接到/dev/null
,只是为了看看它是否有效,错误仍然被打印出来
这完全是一个我可以解决的问题,它确实不会引起任何问题,但我不想让一个技术程度较低的同事看到这个错误并将其丢弃(我不确定这是否会在每次合并带有尾随空格的内容时打印出来),所以我很想知道发生了什么以及如何解决这个问题(或告诉git reset
忽略尾随空格错误)
编辑:
下面是一个完整的工作repo,它演示了这个问题:,只需按照README.md
中的步骤操作,不管您是否处于合并状态,都会得到错误
我的git配置(适用于1.8.x版本的工作站和2.5.x版本的笔记本电脑)可以找到。敏感信息已被剥离,但没有任何相关信息。正如中的第二个脚注所指出的,git stash apply
仅调用git diff…| git apply--index
。警告来自这些命令
如果您有尾随空格,将包含尾随空格的文件隐藏起来,然后应用隐藏,就会发生这种情况。
更准确地说,它发生在任何时候,只要您尝试git将尾随换行符应用于代码体
如果创建带有尾随空格的git修补程序,并尝试通过cat a.patch | git diff--index
应用它,则会出现相同的错误
至于解决这个问题,在本地、全局或系统gitconfig
中设置core.whitespace=nowarn
将使其静音是有道理的,但这对我来说似乎不是真的,而是YMMV。(这些设置似乎没有被读取).运行git config core.whitespace-如注释中所指出,eol处为空。
。
除了上面提到的以外,我看到的唯一解决方案是在git stash bash脚本中找到有问题的行,并将--whitespace=nowarn
参数添加到git apply
。我应该提到的是一个相当非标准、不可移植的解决方案。您必须让每个人都这样做,很可能每次git更新时都要这样做。但如果他们无休无止地打扰你,那就是你能做的
从好的方面来说,正如你所提到的,这是可以解决的,但是在git上打开一个bug可能是值得的,如果我没有把事情搞得一团糟,而且它甚至忽略了系统gitconfig
。我希望它至少应该尊重这一点。感谢你让它这么容易复制
问题似乎是钩子中的git命令将空格错误写入当前的tty
,而不是stdout
或stderr
。然后,钩子运行程序接收错误,然后错误地声称它是stdout
修复来自于我之前的一个问题
#!/bin/sh
git stash > /dev/null
unbuffer sh -c 'git stash apply -q --index && git stash drop -q ' >/dev/null 2>&1
编辑:如果您想在OSX上使用解除缓冲程序,可以使用说明获取该程序
运行重置-硬存储似乎是一个灾难的一个预先提交的配方。当你在Git的中间尝试放松和改变头部的时候,如果你在合并过程中做了一个Git重置,你基本上中止了合并。也许不使用预提交,而是一个分阶段分支。这是一个CI系统的工作流,它为您测试暂存并合并到master。我正在尝试查看stdin通过管道传输到diff的位置,因为这就是投诉的来源(:28
),但语法似乎不存在。您确认过预提交钩子在新安装git的干净机器上会导致相同的问题吗?运行您的脚本不会产生任何错误,但这些错误看起来确实让人想起git rebase--whitespace=warn
之类的警告。我很想看看y我们的repo、global和system.gitconfigs也是(gitconfig-l
,gitconfig--global-l
,gitconfig--system-l
)。@Bujiraso我用我的git配置(笔记本电脑上的2.5.x和工作站上的1.8.x)编辑了我的原始问题,以及一个示例repo,它使用一个剥离的钩子和一个文本文件演示了这个确切的问题。无论您是否处于合并状态,错误都会发生,钩子只是隐藏了一个索引,而没有索引就正确地取消了绑定。我没有任何简单的机器可以重新安装,但是repo中的那些指令应该会触发一个错误如果你想玩的话,100%的时候都会出错。我不知道这是从哪里传送到git diff的。谢谢!@Sukima-在预提交钩子中隐藏更改并不是世界上最疯狂的事情。我看到的大量示例脚本都是这样做的,这样你就只需要对即将提交的内容进行筛选和测试,而不需要测试什么您还必须重置--hard
才能正确撤消隐藏所做的操作,否则git stash pop
将给您带来合并冲突。不过,我明白您对合并的看法,我可能会禁用此功能
#!/bin/sh
RED='\033[0;31m'
NC='\033[0m'
proper_pop() {
git reset --hard -q
git stash apply -q --index && git stash drop -q
}
exit_and_pop() {
proper_pop
if [ "$1" -ne 0 ]; then
echo "${RED}Your code failed the pre-commit hook! Please examine the output and fix your issues!${NC}"
fi
exit $1
}
run_and_bail() {
bash -c "$1";
ret=$?;
if [ "${ret}" -ne 0 ]; then
exit_and_pop "${ret}"
fi
}
if git rev-parse --verify HEAD >/dev/null 2>&1
then
against=HEAD
else
# Initial commit: diff against an empty tree object
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
old_stash=$(git rev-parse -q --verify refs/stash)
git stash -q --keep-index
new_stash=$(git rev-parse -q --verify refs/stash)
if [ "$old_stash" = "$new_stash" ]; then
echo "pre-commit script: No changes to test. Not running."
sleep 1 # HACK: Editor may erase message if done too quickly, make the programmer read
exit 0
fi
proper_pop
#!/bin/sh
git stash > /dev/null
unbuffer sh -c 'git stash apply -q --index && git stash drop -q ' >/dev/null 2>&1
brew tap homebrew/dupes/expect
brew install homebrew/dupes/expect