title: Git: application configuration and different environments
body: <p>We use <a href="http://git-scm.com/" rel="nofollow noreferrer">git</a> for most of the web applications we build in our shop, and though the applications themselves use a variety of technologies (PHP, Rails, etc), we generally have a staging and production server for each site.  Typically, these servers have different sets of database credentials as well as different environment-based configuration settings (e.g. caching).  Our workflow generally involves maintaining two git branches per project: master, which reflects the production server, and staging, which reflects staging. New features are developed on staging (or a sub-branch) and are merged back to master upon completion and deployment.</p>
  
  <p>My question is with respect to the best way to maintain the configuration files that are branch- and environment-specific.  I've seen the answers from similar questions <a href="https://stackoverflow.com/questions/2964120/how-to-use-git-to-manage-one-codebase-but-have-different-environments">here</a> and <a href="https://stackoverflow.com/questions/922411/maintaining-configuration-differences-between-dev-and-live-environments-during-de">here</a>, and neither really satisfies.  The main two approaches seem to be a) using .gitignore exclusion to leave config files outside of git's purview, or b) writing reflective, environment-aware code that determines e.g. what database credentials to use based on hostname.  My problem with a) is that it only allows one set of config files to exist in the codebase (irrespective of the current branch), so the other environment's config files get lost.  b), on the other hand, just seems to require unnecessary modification of the codebase in a way that doesn't feel related to the application's functionality.</p>
  
  <p>Ideally, I'd like a way to "lock" configuration files within a certain branch, so that whenever I checkout master, I get the master config files, and whenever I checkout staging, I get the staging config files.  Additionally, merging staging into master shouldn't affect the master config files in any way.  To date, we've dealt with this by having folders containing environment-specific configuration files outside of the git root and manually moving the appropriate files into codebase when deploying, but this is of course needlessly hackish (and potentially dangerous).</p>
  
  <p>Is there any way to accomplish this using git?  </p>
  
  <p>Thanks for your consideration!</p>