[英]git stash in pre-commit hook fails on first commit
我正在研究一個使用YUI Compressor的預提交鈎子,以最小化已准備提交的任何CSS和JavaScript文件。 縮小文件后,縮小的版本會自動上載以供提交。 我已經讀到,自動將機器生成的文件添加到提交中通常不是一個好主意,但是我認為在這種情況下可以。 看起來是這樣的:
git status
輸出:
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: _site-wide.css
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: _subpage.css
#
git commit -m "Updated site-wide styling"
:
1 CSS file was minified and added to the Git repository
0 JavaScript files were minified and added to the Git repository
[master 41f1815] Updated site-wide styling
2 files changed, 2 insertions(+), 2 deletions(-)
此處發生的是使用YUI Compressor最小化_site-wide.css
的預提交鈎子,將結果輸出到site-wide.css
(無下划線)。 然后,它上演site-wide.css
進行提交。 pre-commit鈎子跳過了_subpage.css
因為盡管已對其進行了修改,但尚未上載它。
由於磁盤上的CSS和JavaScript文件可能與為提交而暫存的CSS和JavaScript文件不同,因此我在縮小文件之前先運行git stash -q --keep-index
,然后再運行git stash pop -q
。 這個預先提交的鈎子在已經具有提交的存儲庫上可以正常工作,但是如果我在進行第一次提交之前將預先提交的鈎子放在適當的位置,我會得到:
git status
輸出:
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: _site-wide.css
# new file: _subpage.css
#
git commit -m "Initial commit"
:
fatal: bad revision 'HEAD'
fatal: bad revision 'HEAD'
fatal: Needed a single revision
You do not have the initial commit yet
2 CSS files were minified and added to the Git repository
0 JavaScript files were minified and added to the Git repository
No stash found.
git status
輸出:
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: _site-wide.css
# new file: _subpage.css
# new file: site-wide.css
# new file: subpage.css
#
現在,我將粘貼預提交的鈎子代碼。 請記住,為了靈活起見,我編寫了此腳本,以便可以在任何CakePHP項目中運行它,而不僅僅是具有Git存儲庫的項目。 我還編寫了它,以便您可以強制它縮小所有CSS和JavaScript文件,而不僅僅是縮小提交階段。 這是通過運行.git/hooks/pre-commit force
。 這是代碼:
#!/bin/bash
css_files_to_ignore=(
#"_do_not_minify.css"
)
js_files_to_ignore=(
#"_do_not_minify.js"
)
if git rev-parse --git-dir > /dev/null 2>&1; then
git_repository=true
base_folder="$(git rev-parse --show-toplevel)/app/webroot"
if [ "$1" == "force" ]; then
process_unstaged_files=true
else
process_unstaged_files=false
fi
else
git_repository=false
base_folder="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/webroot"
fi
if [ -f /Applications/yuicompressor.jar ]; then
# Mac
yuicompressor_path=/Applications/yuicompressor.jar
else
# Linux
yuicompressor_path=$(command -v yui-compressor)
fi
function process_assets()
{
extension=$1
files_minified=0
for infile in $(echo "$base_folder/$extension/*.$extension")
do
# Only process files.
[[ -f $infile ]] || continue
filename=${infile##*/}
# If the filename starts with an underscore, that means that the file is
# eligible for minification.
[[ ${filename:0:1} == "_" ]] || continue
ignore_this_file=false
files_to_ignore=$extension"_files_to_ignore"
for i in $(eval echo \${$files_to_ignore[@]})
do
if [[ $i == $filename ]]; then
ignore_this_file=true
break
fi
done
if [ $git_repository == true ] && [ $process_unstaged_files == false ] && git diff --quiet --cached $infile; then
# This file is NOT staged for commit.
ignore_this_file=true
fi
if [ $ignore_this_file == false ]; then
minified_file="$base_folder/$extension/${filename:1}"
if [ ! -f "$minified_file" ] || test $infile -nt $minified_file; then
$yuicompressor_command "$infile" -o "$minified_file"
if [ $git_repository == true ] && [ $process_unstaged_files == false ]; then
git add "$minified_file"
fi
((files_minified++))
fi
fi
done
# Output a summary of what was done.
if [ $extension == "css" ]; then
file_type="CSS"
else
file_type="JavaScript"
fi
echo -n "$files_minified $file_type file"
if [ $files_minified -eq 1 ]; then
echo -n " was"
else
echo -n "s were"
fi
echo -n " minified"
if [ $git_repository == true ] && [ $process_unstaged_files == false ]; then
echo " and added to the Git repository"
else
echo
fi
}
if [ -f "$yuicompressor_path" ]; then
if [ ${yuicompressor_path: -4} == ".jar" ]; then
yuicompressor_command="java -jar $yuicompressor_path"
else
yuicompressor_command=$yuicompressor_path
fi
if [ $git_repository == true ] && [ $process_unstaged_files == false ] && ! git diff --quiet --cached; then
# The staging area is what should be processed rather than what is currently
# on disk.
git stash -q --keep-index
stashed=true
else
stashed=false
fi
process_assets css
process_assets js
if [ $stashed == true ]; then
git stash pop -q
fi
else
echo "YUI Compressor was not found. Aborting."
exit 1
fi
我該如何進行這項工作? 任何幫助,將不勝感激。
我得出的結論是,對此沒有解決方案,因為在沒有HEAD的情況下,某些Git命令根本無法工作。 另外,經過更多考慮之后,我認為無論如何,至少對於我而言,這是一種邊緣情況,因為我的第一次提交通常是一些基本的東西,例如我使用的框架文件。 因此,我可以在第一次提交后實施鈎子。
我感謝Hassek的時間以及其他閱讀此書的人的時間。 謝謝!
在Git 2.22(2019年第二季度,7年后)中,有一個, git stash
用C重寫 。
參見Paul-Sebastian Ungureanu( weekly-digest[bot]
) 提交1ac528c (2019年2月25日) 。
stash
:使push -q
安靜
此提交的行為有所變化。
如果沒有初始提交,則stash的shell版本仍會顯示一條消息。
如果指定了--quiet
或-q
則此提交使push
不顯示任何消息。
因此,您應該不會從git stash -q <command>
看到“ You do not have the initial commit yet
”,從Git 2.22的新的C語言stash
命令開始。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.