在最近的提交中检测文件或目录是否已更改的可靠方法是什么?

时间:2017-07-04 19:12:45

标签: git githooks

我有一个Web项目,只需通过推送新提交即可部署到ec2实例。我远程使用post-recieve git钩子来执行一个shell脚本,通过将项目检入生产目录来“部署”该项目。步骤是:快速应用上的npm install,前端npm install应用create-react-app上的npm run build,然后运行web-pack(基本上使用srcs/components/来从我的节点源代码构建一个优化的分发文件夹)。

这些步骤很昂贵,在许多情况下并不需要。例如。如果我所做的只是更新npm run build中的节点组件,那么npm install应该运行,但服务器上的#!/usr/bin/env bash GIT_WORK_TREE=/home/ec2-user/absiteProd git checkout -f ### TODO: conditional NPM work pm2 restart index 和前端不应该。如果我所做的只是在我的快递应用程序中添加了注释,则不应运行任何脚本。

我目前的服务器端部署脚本如下所示:

/home/ec2-user/absiteProd/frontend/package.json

我的问题是如何使用git(或grep,sed,awk等)来可靠地告诉我何时/home/ec2-user/absiteProd/server/package.json, {home> / home / ec2-user / absiteProd / frontend / sources`中的if `git log --stat -n 1` | grep --quite frontend/src/* ; then cd home/ec2-user/frontend npm run build fi 或其他内容已更改?

目前我在以下方面取得了一些成功:

group by

但是,由于这似乎是应用程序部署中的一个常见要求,我觉得必须有一个更简单的方法?

2 个答案:

答案 0 :(得分:1)

您可以在this thread中找到类似的需求:

  

如何在存储库中找到给定目录的最后一次提交?

     

如果自上次构建以来没有任何更改,我想避免重建项目的特定部分,所以我需要找到上次更改目录的sha。

您可以使用git rev-list

比较修改元素的最后一次提交
git rev-list -1 HEAD -- frontend/package.json
git rev-list -1 HEAD -- absiteProd/server/package.json
git rev-list -1 HEAD -- frontend/src

使用当前的HEAD SHA1(git rev-parse--verify是可选的):

git rev-parse --verify HEAD

那是:

h=$(git rev-parse --verify HEAD)
b=false
if [[ "$(git rev-list -1 HEAD -- frontend/package.json)" == "${h}" ]]; then b=true; fi
if [[ "$(git rev-list -1 HEAD -- frontend/package.json)" == "${h}" ]]; then b=true; fi
if [[ "$(git rev-list -1 HEAD -- frontend/package.json)" == "${h}" ]]; then b=true; fi
if !b; then exit 0; fi
cd home/ec2-user/frontend
npm run build

答案 1 :(得分:1)

Git没有以任何有用的方式存储目录,因此您必须自己定义“任何内容”的含义(这有其优点,因为您可以定义 >意味着而不是陷入别人对你无用的定义,但意味着你必须做更多的工作。)

也就是说,Git将每个文件存储为每次提交中的路径名。您的部署脚本需要一些工作树 - 在这种情况下,/home/ec2-user/absiteProd - 从一个州到另一个州。由于它使用git checkout来执行此操作,并且git checkout对时间戳没有任何特殊处理,因此您现在有许多选项,其中包含许多不同的低级详细信息和后续后果。以下是两个显而易见且相当简单的起点:

  • /home/ec2-user/absiteProd与先前的提交完全相同吗?如果是这样,哪个提交? (提交具有唯一的哈希ID,这些通常是在脚本中使用的东西。)然后,您可以使用Git将先前的提交与新提交进行比较,例如使用git diff --name-status。这与你现在正在做的类似,但更好。

    如果您的部署脚本是接收后脚本,则您已经拥有了从标准输入读取的引用的旧哈希ID和新哈希ID。因此,在这两个提交之间改变的文件集及其状态是:

    git diff-tree -r --name-status $oldhash $newhash
    
  • 如果git checkout在任何文件上写入,那么这些文件将具有“now”作为其修改时间时间戳,因为git checkout只是让系统的时间适用于更新文件。你能用这个吗?只要您从未在一秒钟内部署超过两次,您可以将其与make构建系统相结合,后者根据时间戳构建文件。

如果此处make合适,它可能是最佳选择,除了它最多每秒一次部署(或者您的底层操作系统对文件的时间戳解析有什么用)。您可以声明无论输出文件是什么,它们都依赖于相应的输入文件,并给出配方以从输入构建输出并运行{{1} }。