2012-07-11 86 views
1

我正在使用YUI Compressor来缩小已提交的所有CSS和JavaScript文件的提交前钩子。文件缩小后,缩小的版本会自动获得提交阶段。我读过,自动将机器生成的文件添加到提交通常不是一个好主意,但我认为在这种情况下它是可以的。这是什么样子:第一次提交时git隐藏在提交前挂钩失败

输出 git status

输出 git commit -m "Updated site-wide styling"
# 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 
# 

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(-) 

这里发生了什么事是预先提交使用锐压缩机来缩小_site-wide.css挂钩,输出结果为site-wide.css(没有领先的下划线)。然后它提交site-wide.css进行提交。预提交钩子跳过_subpage.css,因为虽然它已被修改,但未提交进行提交。

由于CSS和JavaScript的磁盘文件可能不一样的CSS和JavaScript文件上演承诺,我涅槃的文件,然后运行后git stash pop -q之前运行git stash -q --keep-index。这pre-commit钩子工作在已经有一个承诺库罚款,但如果我把pre-commit钩子代替第一提交作出前,我得到这个:

输出的

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"

输出 git status
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. 

# 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 
# 

我现在将粘贴pre-commit钩子的代码。请记住,为了灵活起见,我编写了此脚本,以便它可以在任何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 

我该如何使这项工作?任何帮助,将不胜感激。

+1

你可以发布钩子码吗?它似乎试图检查还没有存在的HEAD版本,这就是为什么你会得到错误。你可以尝试添加一个try/catch。 – Hassek 2012-07-11 20:31:28

+0

@Hassek我添加了代码。 – Nick 2012-07-11 21:07:10

回答

1

我得出的结论是,没有解决方案,因为有些Git命令根本无法工作,当没有头。另外,在考虑了更多之后,我认为这是一种边缘情况,至少对我而言,因为我的第一次提交通常是基本的,比如我使用的框架的文件。所以我可以在第一次提交之后实现钩子。

我很欣赏Hassek的时间以及阅读本文的其他人的时间。谢谢!