How to use git to maintain a slightly different copy of production source code?
I have a Ruby on Rails application, which sends out emails.
In production, I want to use some X SMTP server, but in development I want to use some开发者_JAVA百科 other SMTP server (thus my configuration file for the SMTP settings is different in the development and production environments)
So I need to maintain 2 configuration files (one file each for the development/production environments' SMTP settings).
As of now, I keep settings for Y STMP in a file on my development machine. I clone the production code from the github repo, modify the working copy with settings for Y SMTP and proceed. Then when I have to push changes to github, I reverse the process. It works, but I'm thinking there should be a better way?
What is the "git way" to handle this sort of "small differences" between development and production code bases?
UPDATE
Per @Mike Axiak, is this the flow that you mean: (presume for simplicity that I'm not using ln
, but using the copy
method)
Set up source code so that there are 2 settings files on local machine:
- smtp.settings.prod
- smtp.settings.dev
Both are added to .gitignore
To work on local copy:
- Pull code from github
- Copy smtp.settings.dev to smtp.settings
- Use.
To push changes to server:
- Just before push, copy file smtp.settings.prod to smtp.settings
- Push
If this is what you meant, is there some way to automate the copying process via git?
Rails already support this kind of thing using the files the configuration/environments directory. Just add your settings in the appropriate file.
In most places I've dealt with this by having a small override configuration file, usually with a .prod or .dev suffix. Then in the actual checked out environment you use ln to symlink (or in windows copy) the current file to the real settings file name. Then you tell git to ignore the settings file (using .gitignore)
If the config files aren't changing all the time, I usually keep a generic settings file versioned in the repository, say settings.conf.dist
, and then add settings.conf
to my .gitignore
. Now when I clone a fresh repository, I would just cp settings.conf.dist settings.conf
to make a copy (ignored by git) of the app settings, and then modify as needed.
The advantage is you never have to worry about it when committing/pushing/pulling. The disadvantage is when you make changes like adding a new setting, you want to remember to put it into the .dist
version of it, as well as add it separately to each local settings.conf
file. Like I said, works best when you're not adding new settings all the time.
Edit: I only have settings that would change across machines in these local settings files. If you had other settings that would be the same for all sites, I'd have another config file for that, which would then include the "local" settings file.
Do what Gitorious does, it uses the configuration/environments
support and you provide an RAILS_ENV
environment variable to the script when running it so it knows which configuration to use.
One directory, multiple configurations. Delete the unused configs when promoting a release to production.
I have also done something similar but more automatic by basing configuration off the hostname of the server that it is deployed it. dev.mycompany.com vs test.mycompany.com vs mycompany.com there are lots of more automated ways of doing this than juggling multiple files, that is just a recipe for human error and suffering.
I solved it like this. With a little help from .bash_aliases.
git clone
git checkout -b production.conf
Modify config.file as needed.
git commit -a
git checkout master
Do something with working copy.
git checkout production.conf -- config.file
git commit -a
git push
精彩评论