bash 在 post-receive hook 中重用 GIT_WORK_TREE 来 rm 几个文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6635018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 00:20:21  来源:igfitidea点击:

Reuse GIT_WORK_TREE in post-receive hook to rm a few files

gitgit-checkoutbash

提问by Rudie

I've used this 'tutorial' to set up a DSP environment: http://toroid.org/ams/git-website-howto(Yes, I don't have a T).

我已经使用这个“教程”来设置 DSP 环境:http: //toroid.org/ams/git-website-howto(是的,我没有 T)。

My workflow is very easy:

我的工作流程非常简单:

  1. Develop locally (D)
  2. Commit a few things
  3. Commit more things
  4. Push to Staging (and Github) (S)
  5. Test new code on Staging
  6. Push to Production (P)
  1. 本地开发 ( D)
  2. 承诺一些事情
  3. 提交更多的东西
  4. 推送到登台(和 Github)(S
  5. 在 Staging 上测试新代码
  6. 推送到生产 ( P)

My code contains CSS files that are minified by my code and then saved to 1 file: all.css. Locally, I've turned that option off, so I don't have to manually remove all.cssall the time every time I change my CSS. On both Staging and Production, they should cache as soon as possible (so create all.cssfrom the separate CSS files).

我的代码包含由我的代码缩小的 CSS 文件,然后保存到 1 个文件:all.css. 在本地,我已关闭该选项,因此all.css每次更改 CSS 时都不必手动删除。在 Staging 和 Production 上,它们应该尽快缓存(所以all.css从单独的 CSS 文件创建)。

The problem is every time I push, I have to remove all.css(and all.js-- same exact story) to see the changes (and properly test).

问题是每次我推送时,我都必须删除all.css(和all.js- 完全相同的故事)以查看更改(并正确测试)。

From the tutorial I made a post-receivehook that checks out the changes into a certain folder (where Apache reads the code).

在教程中,我制作了一个post-receive钩子,将更改检查到某个文件夹(Apache 读取代码的位置)。

My current post-receivehook:

我目前的post-receive钩子:

#!/bin/sh
GIT_WORK_TREE=/var/www/www.example.org git checkout -f

I want to reuse $GIT_WORK_TREEto remove two files within $GIT_WORK_TREE(being www/all.cssand www/all.js), but I can't... There's no var $GIT_WORK_TREE on the next line.

我想重用$GIT_WORK_TREE以删除$GIT_WORK_TREE(beingwww/all.csswww/all.js)中的两个文件,但我不能......下一行没有 var $GIT_WORK_TREE。

So I changed it to this, but I don't like that, especially if I want to do more with it in the future:

所以我把它改成了这个,但我不喜欢那个,特别是如果我以后想用它做更多的事情:

#!/bin/sh
GIT_WORK_TREE=/var/www/www.example.org git checkout -f
rm /var/www/www.example.org/www/all.css
rm /var/www/www.example.org/www/all.js

$GIT_WORK_TREEis NOT reused like this.

$GIT_WORK_TREE不会像这样重复使用。

Things I've tried that don't work:

我尝试过但不起作用的事情:

GIT_WORK_TREE=/var/www/www.example.org git checkout -f
rm $GIT_WORK_TREE/www/all.css
rm $GIT_WORK_TREE/www/all.js

rm: file doesn't exist etc (/www/all.css) ($GIT_WORK_TREEis empty)

rm: 文件不存在等 (/www/all.css) ($GIT_WORK_TREE为空)

GIT_WORK_TREE=/var/www/www.example.org
git checkout -f

fatal: this operation must be run in a work tree

致命:此操作必须在工作树中运行

GIT_WORK_TREE=/var/www/www.example.org
cd $GIT_WORK_TREE
git checkout -f

fatal: Not in a git repository (or any .....)

致命的:不在 git 存储库中(或任何......)

I guess my problem is as much with how Bash works as it is with how GIT works =)

我想我的问题与 Bash 的工作方式和 GIT 的工作方式一样多 =)

回答by Mark Longair

There are a few problems with that you're trying at the moment. Perhaps it's best to explain what's wrong with each example you've tried in turn:

您目前正在尝试存在一些问题。也许最好依次解释您尝试过的每个示例的问题:

GIT_WORK_TREE=/var/www/www.example.org git checkout -f
rm $GIT_WORK_TREE/www/all.css
rm $GIT_WORK_TREE/www/all.js

The problem here is that if you define a variable directly before the command, the environment variable is only set in the environment of the command you're running - it's not set in the current shell. You can easily test this:

这里的问题是,如果您直接在命令之前定义一个变量,则环境变量只会在您正在运行的命令的环境中设置 - 它不会在当前 shell 中设置。您可以轻松测试:

$ FOO=bar sh -c 'echo $FOO'            
bar
$ echo $FOO

$ 

Your next attempt was:

您的下一次尝试是:

GIT_WORK_TREE=/var/www/www.example.org
git checkout -f

In this case, in order for the variable to be set in the environment of other commands you invoke in the script, you need to export it, for example with export GIT_WORK_TREE=/var/www/www.example.orginstead of your first line.

在这种情况下,为了在脚本中调用的其他命令的环境中设置变量,您需要导出它,例如用export GIT_WORK_TREE=/var/www/www.example.org而不是第一行。

Your last attempt was:

您的最后一次尝试是:

GIT_WORK_TREE=/var/www/www.example.org
cd $GIT_WORK_TREE
git checkout -f

This has the same problem as your previous attempt (i.e. that you need to export GIT_WORK_TREE) but it also has a more subtle problem. As I describe in this blog post, GIT_DIRis set to .(i.e. the current directory) in the post-receivescript's environment. So, if you change directory to the top of the working tree, GIT_DIRwill point to that directory, and not the .gitdirectory! A couple of good rules of thumb are (a) that you should only set GIT_DIRand GIT_WORK_TREEtogether, and (b) if you do set them, you should set them both to absolute paths. So, I think the following hook will work in your case:

这与您之前的尝试存在相同的问题(即您需要 export GIT_WORK_TREE),但它还有一个更微妙的问题。正如我在介绍这个博客帖子GIT_DIR被设定为.在(即当前目录)post-receive脚本环境。因此,如果将目录更改到工作树的顶部,GIT_DIR将指向该目录,而不是.git目录!一些好的经验法则是 (a) 应该只设置GIT_DIRGIT_WORK_TREE,以及 (b) 如果确实设置了它们,则应该将它们都设置为绝对路径。因此,我认为以下挂钩适用于您的情况:

#!/bin/sh
export GIT_WORK_TREE=/var/www/www.example.org
export GIT_DIR=/var/www/www.example.org/.git
cd $GIT_WORK_TREE
git checkout -f
rm www/all.css
rm www/all.js

回答by a1catraz

why not use a variable for the path?

为什么不为路径使用变量?

#!/bin/sh
work_tree=/var/www/www.example.org
GIT_WORK_TREE=$work_tree git checkout -f
rm $work_tree/www/all.css
rm $work_tree/www/all.js

then you don't need to export. This works perfect for me.

那么你不需要导出。这对我来说很完美。

回答by cdegroot

GIT_WORK_TREE=....
export GIT_WORK_TREE
git ...
rm $GIT_WORK_TREE/...

should work and is safest (you don't always need to export your environment variables, but usually it doesn't harm :))

应该可以工作并且最安全(您并不总是需要导出您的环境变量,但通常它不会造成伤害:))