GIT & Ruby:如何从 ruby​​ 脚本中取消设置 GIT_DIR 变量?

Posted

技术标签:

【中文标题】GIT & Ruby:如何从 ruby​​ 脚本中取消设置 GIT_DIR 变量?【英文标题】:GIT & Ruby: How can I unset the GIT_DIR variable from inside a ruby script? 【发布时间】:2011-07-28 10:42:01 【问题描述】:

我编写了一个非常简单的“部署”脚本,作为我的 post-update 钩子在我的裸 git 存储库中运行。

变量如下

live domain         = ~/mydomain.com
staging domain      = ~/stage.mydomain.com
git repo location   = ~/git.mydomain.com/thisrepo.git (bare)

core                = ~/git.mydomain.com/thisrepo.git
core                == added remote into each live & stage gits

livestage 都已初始化 git repos(非裸),我已将我的裸 repo 添加为它们每个的远程(命名为 core),以便 git pull core stagegit pull core livecore repo 的相应branch 中提取更新的文件。

脚本如下:

#!/usr/bin/env ruby

# Loop over each passed in argument
ARGV.each do |branch|

  # If it matches the stage then 'update' the staging files
  if branch == "refs/heads/stage"

    puts ""
    puts "Looks like the staging branch was updated."
    puts "Running a tree checkout now…"
    puts ""
    `cd ~/stage.mydomain.com`
    `unset GIT_DIR` # <= breaks!
    `git pull core stage`
    puts ""
    puts "Tree pull completed on staging branch."
    puts ""

  # If it's a live site update, update those files
  elsif branch == "refs/heads/live"

    puts ""
    puts "Looks like the live branch was updated."
    puts "Running a tree checkout now…"
    puts ""
    `cd ~/mydomain.com`
    `unset GIT_DIR` # <= breaks!
    `git pull core live`
    puts ""
    puts "Tree checkout completed on live branch."
    puts ""

  end

end

我已经尝试从 this bash script here 调整文件的“更新”,它使用 unset GIT_DIR 运行下一个 git 命令 git pull core stage 例如。 core 是我的bare 存储库在服务器上不同文件夹中添加的remote

但是在执行上面的脚本时,我遇到了以下错误:

remote: hooks/post-update:35: command not found: unset GIT_DIR        
remote: fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.        

有没有办法在我的 ruby​​ 脚本中的 bash 脚本中执行与 unset GIT_DIR 相同的操作?

非常感谢,

詹尼斯

【问题讨论】:

【参考方案1】:

这看起来像

`cd ~/stage.mydomain.com && unset GIT_DIR && git pull core stage`

可以完成这项工作。

推测原因(推测因为我不熟悉 ruby​​):您在与运行 git pull 的 shell 不同的 shell 中运行 unset 命令(以及 samold 点在他的回答中,当前工作目录也会出现同样的问题)。

这表明可能有一些 ruby​​ API 可以操纵环境 ruby​​ 传递给它使用反引号运算符启动的 shell,并更改当前工作目录。

【讨论】:

这就像魔术一样!非常感谢。现在一切就绪并开始运行!通过在提交注​​释中传递一个特殊格式的注释来了解如何做同样的事情 :) 我想知道是否可以使用类似 [update:live][update:stage] 的东西来触发这个 pull 动作…… 刚刚让我省了很多挫折 - 谢谢!没想到这些变量有这么大的意义!【参考方案2】:

尝试用这个替换你的行:

ENV['GIT_DIR']=nil

我不确定你的:

`cd ~/stage.mydomain.com`
`unset GIT_DIR` # <= breaks!
`git pull core stage`

即使 GIT_DIR 已正确取消设置,部分也将起作用;每个反引号都会启动一个新的 shell,与旧的 shell 无关,子 shell 不能更改其父进程的当前工作目录。

试试这个:

ENV["GIT_DIR"]=nil
`cd ~/stage.mydomain.com ; git pull core stage`

【讨论】:

感谢您的提示!这与 ndim 的答案一样好,但因为我的最终脚本在反引号格式中使用他的单个字符串,所以我选择接受他的答案而不是这个答案。无论如何,再次感谢! @Jannis,取决于您的目标:如果您只想为那个 one 调用取消设置GIT_DIR,@ndim 的答案会更好。如果您想为整个脚本取消设置GIT_DIR,我的会更好。他们做不同的事情:)所以选择更适合任务的那个。 哦,.. 既然你提到了它,那确实是完全有道理的!感谢您让我知道这一点,在这种情况下,我会将其保留为 unset ..,但对于未来的脚本冒险,这肯定会非常方便。再次感谢。 IMO 这是大多数情况下的最佳解决方案;例如对于整个构建,构建环境应该是干净的。我认识到某些构建可能会执行逐步的 ENV 更改,但我认为这不是最佳实践。我已经在我们的构建环境中实现了@sarnold 的解决方案。

以上是关于GIT & Ruby:如何从 ruby​​ 脚本中取消设置 GIT_DIR 变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ruby​​ / chef 中打印 git latest_tag 命令的值

从 git 引用 ruby​​ gem 会破坏 aws beanstalk 部署

如何从 Ruby 中的数组返回属性值?

如何使用 ruby​​ Faraday gem 执行以下 curl 请求?

如何使用 Ruby 和 Gitlab 优化占用的内存

使用正则表达式从 Ruby 中的字符串中提取子字符串