4

我正在使用 RVM。我为一个项目写了一个 Gitpre-commit钩子:

#!/usr/bin/env ruby

puts RUBY_VERSION
puts `echo $PATH`
exit(1)

由 Git 运行时输出:

$ git ci -m 'foo'
1.8.7
/usr/libexec/git-core:/usr/bin:/usr/local/heroku/bin:/Users/mgoerlich/.rvm/gems/ruby-2.0.0-p195@global/bin:/Users/mgoerlich/.rvm/rubies/ruby-2.0.0-p195/bin:/Users/mgoerlich/.rvm/bin:/Users/mgoerlich/adt-bundle-mac-x86_64-20130219/sdk/platform-tools:/Users/mgoerlich/adt-bundle-mac-x86_64-20130219/sdk/tools:/usr/local/bin:/usr/local/sbin:/Users/mgoerlich/.dotfiles/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/bin/core_perl:/Users/mgoerlich/bin:/usr/local/share/npm/bin:/usr/local/share/npm/bin

它似乎使用错误版本的 Ruby 运行,因为$PATH与 bash 或 zsh 或 sh 中的不同。似乎 git 正在操纵$PATH. 手动运行时,我得到这个:

$ .git/hooks/pre-commit
2.0.0
/usr/local/heroku/bin:/Users/mgoerlich/.rvm/gems/ruby-2.0.0-p195@global/bin:/Users/mgoerlich/.rvm/rubies/ruby-2.0.0-p195/bin:/Users/mgoerlich/.rvm/bin:/Users/mgoerlich/adt-bundle-mac-x86_64-20130219/sdk/platform-tools:/Users/mgoerlich/adt-bundle-mac-x86_64-20130219/sdk/tools:/usr/local/bin:/usr/local/sbin:/Users/mgoerlich/.dotfiles/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/bin/core_perl:/Users/mgoerlich/bin:/usr/local/share/npm/bin:/usr/local/share/npm/bin

在提交钩子的输出中,前面有两个路径,其中一个/usr/bin是放置系统 Ruby 可执行文件的位置。

这是一种已知的行为吗?我可以以某种方式操纵它吗?我知道我可以在 shebang 中指定正确 Ruby 版本的完整路径,但这不是我想要的。

4

3 回答 3

4

我不想使用env固定路径而不是使用 ruby​​ 或 rvm 包装器的原因是这是针对团队项目的,并不是团队中的每个人都在使用 RVM。

我的最终解决方案是编写自己的包装脚本并将其添加到该项目中。

所有客户端 git 钩子$PROJECT/bin/hooks都存在于 ruby​​ 脚本中。现在,我刚刚将提到的包装器放在那里,并$PROJECT/.git/hooks为所有钩子创建了指向该包装器的符号链接。

脚本检查是否使用了 RVM,如果是,则修复var,如果项目根目录中$PATH.ruby-version和/或文件,它会加载相应的版本/gemset。.ruby-gemset

然后它将运行相应的 ruby​​ 脚本,如果您有兴趣,这是包装器:

#!/bin/bash
if [ -d "$HOME/.rvm/bin" ]; then
  PATH="$HOME/.rvm/bin:$PATH"
  [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"

  if [ -f ".ruby-version" ]; then
    rvm use "$(cat .ruby-version)"
  fi

  if [ -f ".ruby-gemset" ]; then
    rvm gemset use "$(cat .ruby-gemset)"
  fi
fi
ruby "bin/hooks/$(basename "$0").rb"

所以,我会得到我的 rvm 版本/gemset 和其他人他们在 PATH 中拥有的 ruby​​ 版本,每个人都很开心。

于 2013-07-09T09:37:37.020 回答
0

您需要将 ruby​​ 设置为包装器:

#!$rvm_path/wrappers/ruby-2.0.0-p195/ruby

您可以使用别名简化它:

rvm alias create git_hooks 2.0.0-p195

然后 ne shebang 将如下所示:

#!$rvm_path/wrappers/git_hooks/ruby

在文件中,只需确保替换$rvm_path/Users/mgoerlich/.rvm,最后它看起来像:

#!/Users/mgoerlich/.rvm/wrappers/git_hooks/ruby
于 2013-07-08T03:27:17.203 回答
0

我最终做的是:.git文件结构:

  • .git/hooks/pre-commit
  • .git/hooks/pre-commit-main.rb

.git/hooks/pre-commit:

#!/usr/bin/env bash
export PATH="$THE_GOOD_PATH"
ruby "$GIT_DIR/hooks/pre-commit-main.rb"

.git/hooks/pre-commit-main.rb:

#!/usr/bin/env ruby
puts RUBY_VERSION

然后,当您调用 时git commit,请确保THE_GOOD_PATH已定义 ,:

export THE_GOOD_PATH="$PATH"
git commit

THE_GOOD_PATH="$PATH"您还可以从您的应用程序或应用程序的顶层导出.profile并将所有挂钩符号链接到单个文件。

此方法具有与 rbenv 无关的优点:它也适用于 RVM 或 Python virtualenv。

我写信给 Git 开发人员:http ://permalink.gmane.org/gmane.comp.version-control.git/258454要求他们不要理会我们PATH,但最初的回复是 WONTFIX。

于 2014-10-18T17:38:03.267 回答