git pull检查文件是否改变了bash

时间:2014-02-11 13:47:18

标签: git bash

我在cronjob中运行以下bash脚本来更新我的网站

#!/bin/bash

cd /home/username/public_html
git pull origin master

这个cronjob每5分钟运行一次,所以如果我提交更改为git repo,它会被拉到实时网站。

我想要做的是,每次运行此脚本时,检查特定文件是否已更改,如果文件已更改,请运行curl / wget命令。

我需要跟踪更改的文件是style.css和script.js

我正在做的是,如果更改了这些文件,请在我的网站模板中更新脚本的修订版号,以便清除缓存并加载最新更改的css和js文件。

<link href="/css/style.css?REVISION_NUMBER_HERE" rel="stylesheet" type="text/css">

我可以使用curl请求轻松增加JS / CSS修订号,因为它存储在mysql DB中。

这是一个git pull结果示例,所以我们可以在结果中找到那个style.css / script.js

 * branch            master     -> FETCH_HEAD
Updating cbd0d46..36aeed6
Fast-forward
 admin/cf.php         |   16 ++++++++++++++++
 css/style.css        |   47 +++++++++++++++++++++++++++--------------------
 include/common.php   |    1 +
 templates/header.tpl |    4 ++--
 templates/index.tpl  |   13 ++++++-------
 5 files changed, 52 insertions(+), 29 deletions(-)

修改

感谢@torek的回复。

我需要一些BASH脚本的帮助,现在这是我的测试git命令。

[root@server70 public_html]# git diff --name-only 8613bd3ed718b27ca680bdf33e0a4b32b0f58b8c HEAD | egrep '.css|.js|.tpl'
css/style.css
templates/header.tpl
templates/index.tpl
templates/user/delete.tpl
[root@server70 public_html]#

我把硬编码的git rev号用于测试。我的bash脚本

[root@server70 public_html]# sh 1.sh
File changed css/style.css
File changed templates/header.tpl
File changed templates/index.tpl
File changed templates/user/delete.tpl
[root@server70 public_html]# cat 1.sh
#!/bin/bash


CSS_JS_CHANGED=0

git diff --name-only 8613bd3ed718b27ca680bdf33e0a4b32b0f58b8c HEAD | egrep '.css|.js|.tpl' |
while read name; do
   CSS_JS_CHANGED=1
   echo "File changed $name"
done

if [ "$CSS_JS_CHANGED" = "1" ]; then
    echo expression evaluated as true
fi

[root@server70 public_html]#

如果我在里面运行我的脚本,如果多个文件发生更改,它会多次执行。我只需要在每次更改时运行一次脚本。

所以我需要设置变量CSS_JS_CHANGED,将其值设置为0.然后,如果检测到文件更改,则将其值设置为1.如果CSS_JS_CHANGED的值为1,则运行我的脚本。

但由于某种原因,我无法在while循环中将CSS_JS_CHANGED的值设置为1。与变量范围有什么关系?

**编辑2 **

我发现为什么我无法在循环here

中从内部设置变量

作为一个bash noob,有人可以让我的脚本工作,请:)

编辑3

使用了CSS_JS_CHANGED变量。

[root@server70 public_html]# cat update
#!/bin/bash
# */5 * * * * /home/USERNAME/public_html/update >/dev/null 2>&1


cd /home/USERNAME/public_html
OLD_HEAD=$(git rev-parse HEAD)
git pull origin master
NEW_HEAD=$(git rev-parse HEAD)

[ $OLD_HEAD = $NEW_HEAD ] && exit 0

git diff --name-only $OLD_HEAD $NEW_HEAD | egrep '.css|.js' |
while read name; do
   touch /tmp/css_js_update
done

if [ -f "/tmp/css_js_update" ]
then
    /usr/bin/curl 'http://mywebsite.com/admin/cf.php?js_version_update=mywebsite'
    rm -f /tmp/css_js_update
fi
[root@server70 public_html]#

现在正在等待.css / .js文件提交:)

再次感谢@torek

1 个答案:

答案 0 :(得分:3)

任何时候你做这种事情你应该问:“改变了什么?”

如果您要将内容部署到Web服务器,可能您的意思是“从服务器读取的版本更改”。在这种情况下,首先保存关于服务器读取的版本的内容,例如“内容”,或者在git的情况下,这很容易 - 服务器读取的版本的唯一标识符。

好像你正在服务器上直接做git pull(这有一些缺点,但让我们一起运行)。而不是试图解释git merge输出,捕获一些SHA-1值似乎更简单。例如,你可以抓住你感兴趣的两个文件blob:

OLD_STYLE_ID=$(git rev-parse HEAD:css/style.css)
OLD_SCRIPT_ID=$(git rev-parse HEAD:script.js) # fix path here if/as needed

之后你可以进行fetch-and-merge / pull操作,然后获取新的SHA-1:

git pull origin master
NEW_STYLE_ID=$(git rev-parse HEAD:css/style.css)
NEW_SCRIPT_ID=$(git rev-parse HEAD:script.js) # again, fix path if needed

现在,如果新ID与旧ID匹配,那么这些文件将保持不变;任何不匹配的ID都代表这些文件的变化。

或者,保存新旧HEAD值的ID,如果这些值发生变化,请使用有趣的路径执行某些操作,例如:

OLD_HEAD=$(git rev-parse HEAD)
git pull origin master
NEW_HEAD=$(git rev-parse HEAD)
[ $OLD_HEAD = $NEW_HEAD ] && exit 0 # no change to repo = no change to any files

此时有很多选项,例如:

git diff --name-only ${OLD_HEAD} ${NEW_HEAD} -- css/style.css script.js |
while read name; do
    ...
done

或只是检查git diff --name-only是否限制在那些路径上(如上所述),是否打印任何内容。