使用RVM在不同的git分支中管理不同的Rails版本

时间:2011-09-13 08:58:03

标签: git rvm bundler

我正在开发一个项目,该项目在~> 3.0分支上的Rails master和另一个分支上的~> 3.1上运行。

显然这两个分支需要不同的宝石。

您是否知道使用RVM处理情况的便捷方法?

我想过几个选项,其中没有一个是最优的:

  • 使用gemset s 我必须记得在每个gemset

    之后手动切换git checkout
  • 使用bundle package 我必须跟踪vendor/bundle目录

  • 由于未跟踪.bundle/config,因此甚至无法混合使用这两种方法

  • 我可以写一个git post-checkout钩子,但听起来有点hacky(硬编码的分支名称和所有这些)

有没有更好的方法让我没有想到?

5 个答案:

答案 0 :(得分:1)

您可以在项目目录中创建一个.rvmrc文件,并将其添加到git repo中。对于一个分支,.rvmrc文件将包含类似

的行
rvm 1.9.3-head@rails30 --create

对于其他分支,它将包含

rvm 1.9.3-head@rails31 --create

这样你就会得到两个宝石套装(rails30和rails31)。另外,不要忘记在{home} /. rvmrc中激活.rvmrc文件的自动执行(对于最新版本的rvm是必需的,请参阅rvm文档)。

答案 1 :(得分:1)

当您更改为项目目录时,您将不再需要这样做。默认情况下,RVM 1.8.1已重新启用此功能。 (我已经向网站和rvm笔记添加了有关该文档的文档)

但是,由于这是一个目录内的rvmrc更改,并且未获取.rvmrc中的更改,您可以通过执行'rvm reload'来强制它。 应该被选中,但如果没有,那么就重新加载。

请在执行此操作后将您遇到的任何问题发布到https://github.com/wayneeseguin/rvm/issues

谢谢,

Deryl R. Doucette

注意:在与Wayne交谈后,他通过IRC传递给我,他建议您在.bash_profile中按照这一点做一些事情来帮助你想要的东西:

  git() { command git "$@" ; [[ -s .rvmrc ]] && . .rvmrc ; }

此外,您了解,RVM不会以任何形式或形式作为守护程序运行。所以你希望RVM最明确地做什么被添加到RVM。正如Wayne所说,这将是一个有趣的方式来捣乱别人的头! :)

这样想。虽然承认做作,但行动仍然是一样的。如果有人在你处于某事的中间时改变你下面的rvmrc(另一个开发dir并且不知道你的人),或者某个流氓beastie攻击你的系统并改变你的rvmrc,你认为他可能会怎么样通过这种方式以某种方式获得一些额外的权限。 (这可以在一个组控制的项目目录中,他通过另一个用户的帐户获取访问权限,发现你在同一个组中,将你下面的rvmrc更改为他设法通过组权限设置的不同ruby + gemset多用户安装中的RVM组,并导致执行一些任意命令。想象一下,你中,比如说轮组,你刚刚完成了root用户的一些命令暂停还没有完成授权减少。由于rvmrc实际上只不过是一个bash脚本,这不是想象中的一大部分。所以最终,这会造成一个非常危险的环境,更不用说一个非常困难的情况监督和控制。

答案 2 :(得分:1)

我最终使用了以下git post-checkout脚本。 在master分支中,我使用的是$GEM_HOME中安装的gem。在其他分支中,宝石本地安装到vendor/cache

#!/usr/bin/env bash

#set -x

git_rev() {
  ref=$(git symbolic-ref HEAD 2>/dev/null) || return
  echo ${ref#refs/heads/}
}

ref=$(git_rev)

case $ref in
  master)
    echo "removing .bundle/config"
    mv .bundle/config .bundle/config.no
    ;;
  *)
    if [ -f .bundle/config.no ] ; then
      echo "using vendor/cache"
      mv .bundle/config.no .bundle/config
    fi
    ;;
esac

答案 3 :(得分:0)

要继续morgler的回答,如果你的.itvrc被检入你的git项目,你可以使用git completion将git分支名称添加到.rvmrc gemset名称中,以自动为每个分支创建gemset,比如:

PROJECT_NAME="my_app"
RUBY_VERSION="ruby-1.9.2-p290"
GEMSET_NAME="${PROJECT_NAME}"
# if you have bash completion setup the way I do, you get a gemset for each git branch
if [ -f /usr/local/etc/bash_completion.d/git-completion.bash ]; then
  . /usr/local/etc/bash_completion.d/git-completion.bash;
  GEMSET_NAME="${PROJECT_NAME}-$(__git_ps1 '%s')";
fi
rvm --create "${RUBY_VERSION}@${GEMSET_NAME}"

(注意:您可能需要修改它。它在OS X中适用于我,但我已经在使用git completion for my terminal prompt。)

然后进入目录,如果你做rvm gemset列表,你应该看到为该git分支创建了一个gemset。唯一的打嗝是在你创建一个新的git分支之后,你需要cd并在目录中让它识别.rvmrc中创建的不同gemset(尽管.rvmrc是同一个文件,它会表现得很好)不同)。

这不是一个完美的解决方案,项目中的每个人都必须参与其中。如果你把.rvmrc用于一个项目,你应该考虑将它用于所有项目,否则只需通过cd进入一个目录,ruby版本和gemset可能会改变,然后如果你回到另一个没有的项目有一个.rvmrc,你可能没有注意到它发生了变化并且遇到了麻烦。

编辑:Michal Papis mentioned

  

可能的解决方案是使用.versions.conf引入   在这里:https://gist.github.com/1912050#gistcomment-86575 - 它应该是   容易放一面旗帜 - >将附加的ruby-gemset-git-branch   如果不同,则分支到gemset名称

答案 4 :(得分:-2)

使用rbenv代替RVM。然后你将完全使用Bundler来管理你的宝石。

修改你的Gemfile,使一个分支用于Rails 3,另一个分支用于Rails 3.1。

然后在启动WEBrick时运行bundle exec rails server,bundler将使用您所在分支所需的Rails版本。保持干燥;)

请阅读我的简介getting started with rbenv