将Git分支直接推送到实时服务器目录中,以便文件可以实时查看。

10
我如何在Git中设置远程目录,在那里我可以将本地的stage分支推送到远程,并在staging服务器上查看实时更改,比如stage.example.com?
我的想法(部分原因是我正在远离SVN)是我可以维护(本地)3个不同的“主要”分支,如下所示:
- master - 用于本地开发,工作目录 - stage - 应该与演示服务器目录(远程)同步 - live - 这应该是公开的可访问网站(远程)
我有的想法(以及其他人声称的可能性)是,我可以从我的本地计算机维护这些远程“站点”,而无需不断登录到我的远程服务器shell并运行svn update(在我的当前svn工作流中,我需要一直这样做...),或者当然,在我的Git工作流程中在远程上运行git pull。
我该如何设置远程目录,以便我可以将我的stage分支推送到staging远程服务器,并立即在(例如)stage.example.com上查看更改?
然后,一旦stage全部正确并经过测试,我就只需本地能够将更改推送到live远程以使我已在stage上测试的更改应用到现场网站上。
这可行吗?还是我在这里产生了疯狂的想法,根本不应该用Git做?
如果这很重要,这里有一些关于我的本地和远程服务器的统计数据:
remote server: Dreamhost (shared account) remote GIT version: 1.7.1.1 remote GIT client: shell local computer: Mac Pro (Snow Leopard 10.6.6) local GIT version: 1.7.2.3 local GIT client: Tower.app // git-tower.com

此外,到目前为止,我尝试了以下工作流程,但都 未成功

  1. 在远程创建一个 --bare 的 Git 存储库(这样我就可以从任何地方访问它)
  2. 将此远程存储库克隆到本地目录,并使用 Git Tower 应用程序进行管理
  3. 在本地的 master (HEAD) 中进行工作
  4. scp -r--bare git 存储库从远程服务器复制到我的远程实时域名 stage.example.com
  5. 向本地工作副本添加远程分支,然后尝试推送到 origin/stage

显然,这种方法不起作用,但我不知道原因或如何更好地进行操作。

由于我来自 SVN 背景,所以对 Git 比较陌生,尽管看了很多教程(Peepcode 和 ThinkVitamin),但仍无法理解如何设置好这个工作流程。

1个回答

4
一种理解分布式版本控制系统(如Git或Mercurial)的方法是,它在分支的概念上增加了发布的概念(推送/拉取)。
而集中式版本控制系统(如SVN)只有分支(和一个中央服务器仓库用于推送)。
在您的情况下,暂存或生产环境是发布步骤,即不同的Git仓库已准备好接收您想要在暂存或生产环境中看到的修改。
这意味着:
  • 有2个分支用于跟踪属于staging(“staging”分支)或live(“live”分支)的内容。
  • 1个远程bare仓库(为了能够推送到它, 可以推送到staginglive分支中的任意一个)。
  • 1个post-update hook用于bare仓库,以便检出和更新工作树(表示实际的“staging”或“live”文件)。
  • 1个本地仓库,在其中将bare仓库添加为远程仓库,并且可以将其推送到staging或live。
    您还可以将bare仓库克隆到任何其他需要进行工作的本地计算机上。
一个 `post-receive` 和一个 `post-update` 钩子的区别在于,对于每个修改的分支,`post-update` 只会执行一次:
请参见 "Git hook to update various web folders based on branch pushed to remote server" SO 问题。
在初始推送时,执行 "git push --all origin" 命令,所有分支都将在远程裸仓库上创建。
这个想法是服务器端不应该涉及到拉取:只需要根据 post-update 钩子的参数执行 `git --work-tree=/path/to/your/live/files/ checkout live` 或者 `git --work-tree=/path/to/your/staging/files/ checkout staging` 命令,你只需要将裸仓库中的文件检出到服务器上的这些 '文件夹' 中。
如果你为你的钩子编写了 Ruby 脚本,请确保:
  • 使用正确的shebang: #!/usr/bin/env ruby,
  • 用反引号括起来就足够了:`git ...`就像这个脚本中那样,
  • 在脚本中使用ENV['HOME']来指定当前用户的主目录,如果你想让类似于`cd ~/stagedomain.com``--work-tree=~/stagedomain.com`这样的命令工作(其中`~`被设置为正确的路径),
  • 如果你选择git pull,则在与其他命令相同的行上取消设置GIT_DIR就像你之前的问题中那样`cd ~/stage.mydomain.com && unset GIT_DIR && git pull core stage`

再次感谢!我相信对于任何其他阅读此内容的人来说,这一切都已经非常清晰了,但我仍然担心如何设置“post-update”脚本。我如何为每个推送的分支关联一个不同的更新服务器路径?例如,推送“live”会触发“cd〜/livedomain.com/; unset GIT_DIR; git pull;”,但当推送“stage”分支时,“〜/livedomain.com”显然需要更改为类似“〜/stagedomain.com/”的东西,但我不知道如何根据当前运行“post-update”的ref名称动态获取此数据。如果您有链接,我很乐意阅读相关文档。 - Jannis
@Jannis:不应涉及任何拉取操作。只需使用git --git-tree=/path/to/your/live/files/ checkout livegit --git-tree=/path/to/your/staging/files/ checkout staging,具体取决于post-update钩子的参数。我链接的答案(http://stackoverflow.com/questions/5365476/git-hook-to-update-various-web-folders-based-on-branch-pushed-to-remote-server/5370467#5370467)明确提到,在推送期间更新的分支(或分支)名称是“post-update”钩子的参数。 - VonC
@Jannis:抱歉打错字了:是的,--work-tree 是我想要用作选项以在“正常”(--git-dir)目录之外检出工作树(即包含.git的目录)。 - VonC
@Jannis:请参考http://rubypond.com/blog/slaying-dragons-git-bash-ruby#helping_your_workflow,这里有一个具体的例子:用反引号包围git命令就足够了:`\`git ...`` - VonC
@Jannis:这应该意味着在exec(\...`)上没有正确设置$HOME:尝试echo它并查看它是否指向任何内容。同时也echo用户名。也许你需要在ruby脚本中引用 ENV['HOME']`,如 http://ruby.about.com/od/rubyfeatures/a/envvar.htm 所述。 - VonC
显示剩余12条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接