I'm using RVM. I wrote a Git pre-commit
hook for a project:
#!/usr/bin/env ruby
puts RUBY_VERSION
puts `echo $PATH`
exit(1)
which outputs this when run by 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
It seems to run with the wrong version of Ruby because $PATH
is not the same as in bash or zsh or sh. It seems like git is manipulating $PATH
. When run manually, I get this:
$ .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
In the output of the commit hook, there are two paths prepended, one of them /usr/bin
where the system Ruby's executable is placed.
Is this a known behavior? Can I manipulate that somehow? I know I could specify the full path to the correct Ruby version in the shebang, but this is not what I want.
What I ended up doing is: the
.git
file structure:.git/hooks/pre-commit
.git/hooks/pre-commit-main.rb
.git/hooks/pre-commit:
.git/hooks/pre-commit-main.rb:
Then, when you call
git commit
, make sure thatTHE_GOOD_PATH
, is defined:You could also export
THE_GOOD_PATH="$PATH"
from your.profile
or the toplevel of your application and symlink all hooks to a single file.This method has the advantage of being rbenv agnostic: it also works with RVM or Python virtualenv.
I wrote to the Git developers at: http://permalink.gmane.org/gmane.comp.version-control.git/258454 asking them to leave our
PATH
alone, but the initial reply was WONTFIX.you need to set ruby to a wrapper:
You can simplify it with an alias:
And then the ne shebang will look like this:
In the file just make sure to replace
$rvm_path
with/Users/mgoerlich/.rvm
so finally it looks like:The reason i didn't wanted to use
env
instead of a fixed path to ruby or a rvm wrapper was that this is for a Team Project and not everyone in the Team is using RVM.My final solution was to write my own wrapper script an add it to that project.
All client-side git hooks 're living in
$PROJECT/bin/hooks
, all of them ruby scripts. Now, i've just put that mentioned wrapper in there, and created a symlink to that wrapper in$PROJECT/.git/hooks
for all the hooks.The script check's if RVM is used and if so fixes the
$PATH
var and if there are.ruby-version
and/or.ruby-gemset
files in the project root it loads the according version/gemset.Then it'll run the according ruby script Here's the wrapper in case you're interested:
So, i'll get my rvm version/gemset and everybody else the ruby version they have in their PATH, and everyone is Happy.