views:

720

answers:

3

This is primarily a question about effective Git usage. I should first say I'm not an expert in Rails (at least in a production sense) and definitely a Git newbie, however, I have had some experience using SVN.

My problem is that I am trying to create a rails application but do not know the best way to keep development local on my computer but be able to deploy to my shared hosting account on Dreamhost.

I figured that Git would allow me to do this, but I am not completely sure how. I was thinking of creating a Git repo on the server and having my local stuff pushed onto it after each commit. I have read a few tutorials on Git, but am still confused on what to do. The alternative to this would be to just use FTP and copy over the files but that doesn't seem right.

Does anybody have a few first steps and/or commands that I can use? Is this deployment method fishy or is there a better way to do this?

+3  A: 

What I do is have a shared, bare Git repository (created with git init --shared --bare) which is the "master" repository and is where I push my work. A bare repository does not have a working directory. For my web directory, I clone the master repository so it has a working directory and all the files are there. From there, I git pull any new work that I've committed.

I always do development work on a separate machine with a clone of the repository and a test development environment. When I've finished a feature, I push it up to the master and then log in to the production server and pull it to the working directory there.

This is just me for not-terribly-important projects. One could extend this with many more steps and checks and balances for Important Work.

Greg Hewgill
I thought about doing this with GitHub since this is, too, a personal project. However, I did not know about the --shared and --bare options, which seem to help a lot in this case.
trinth
Right, a Github repository is equivalent to --shared --bare. For projects that I push up to Github, I set up two remote repositories in my usual working directory, one called "origin" for my own master repository, and one called "github" that pushes to github. I can then push to either, or both, at any time with just one command (`git push` (which defaults to origin) or `git push github`).
Greg Hewgill
A: 

I'd recommend using GitHub and keep your Dreamhost resources as free as you can to run your Rails app (in fact, depending on your project, I'll need as much as it can have to coup with it, being a shared hosting).

My usual workflow involves having a development environment and a GitHub account. We use Capistrano (which is fairly simple to learn and understand) to manage the push to GitHub, and then the respective deployment to the hosting, in your case Dreamhost, through SSH/SCP.

That way, you won't have to worry about what it's actually on your production repository, neither having to do maintenance tasks on it. Works pretty fast too and can easily be adapted for when you decide to change hostings o servers.

Yaraher
+1  A: 

I run a Rails website for a brass band in Wisconsin in a very similar setup to what you're describing, though it currently operates out of hostingrails.com. I host my code on github, though there's no reason you couldn't host it privately. My flow has evolved over the last year and a half, so take from this only what you need in the short term.

At the center of my flow, I have set up a semi-elaborate Capistrano script to handle the deployment, including a separate staging environment that makes a whole copy of the production database for testing. This took a while (hours, not days) to build, but it has been so worth it.

My workflow keeps at least 2 branches:

  • current_release: Live production code. Emergency bugfixes are made here.
  • master: Finished features ready for release. These features wait here to be tested live. Emergency bugfixes are merged in from current_release.
  • <feature_name>: Features under development. I try not to have more than 3 of these outstanding at any given time. Emergency bugfixes are merged in, and master is frequently merged in to keep the feature current.

Having this setup allows me to work on several things concurrently. Week-to-week (as this is nowhere near a full-time occupation), I do the following:

  1. I edit in feature branches. I switch back and forth, get bored, get excited, whatever. Sometimes I merge two features that grow together.

    [edit]
    $ git commit
    $ git push github [feature]

  2. Finished features ready for iminent deployment are merged one-at-a-time to the master branch.

    $ git checkout master
    $ git merge [feature]
    [fix immediate problems or inconsistencies]
    $ git commit
    $ git push github master
    $ git branch -d [feature]

  3. I stage the website to a private URL (happens to be stage.madisonbrass.com). The staging environment always pulls from the master branch.

    $ cap staging deploy # master is now live at stage.madisonbrass.com

  4. Bam, while I'm testing, I find an emergency bug on the public website. Fortunately, I have current_release working separately, and thus can separately fix and deploy it.

    $ git checkout current_release
    [fix bug]
    $ git commit
    $ git push github current_release
    $ cap production deploy

  5. I return to the master branch, and start by merging the emergency fix.

    $ git checkout master
    $ git merge current_release

  6. I continue testing master. Hopefully no new issues appear, but if they do I fix them in master, I merge these changes into current_release and do another production deployment.

    $ git checkout current_release
    $ git merge master
    $ git push github current_release
    $ cap production deploy

  7. I tear down my staging environment, lest it somehow get indexed by a search engine.

    $ git staging teardown

Andres Jaan Tack