<p>Matt has a point, this is similar to <a href="https://craftcms.stackexchange.com/questions/10/whats-the-best-practice-for-handling-data-migration-and-organization-across-dev">What's the best practice for handling data migration and organization across development environments?</a>, but that question focuses mainly on how to handle the database (definitely see those answers).</p>

<p>More generally speaking...</p>

<p><strong>Multi-Environment Config</strong></p>

<p>Set yourself up with <a href="http://buildwithcraft.com/docs/multi-environment-configs" rel="noreferrer">Multi-Environment Configs</a> in both <code>craft/config/general.php</code> and <code>craft/config/db.php</code> so that you don't have to be updating path settings every time you migrate data between environments.</p>

<p>Be sure to set some <a href="http://buildwithcraft.com/docs/multi-environment-configs#environment-specific-variables" rel="noreferrer">Environment-Specific Variables</a> for the site URL and server path for each environment. That way you can use those variables in the control panel settings (the Site URL setting in the <em>Setting → System → General</em> and Assets paths in <em>Settings → Assets → Your asset settings</em>).</p>

<p>Here is a sample <code>general.php</code> file</p>

<pre><code>return array(

    '*' =&gt; array(
        'omitScriptNameInUrls' =&gt; true,
        'usePathInfo'=&gt; true,
        'cpTrigger' =&gt; 'example-admin',
        'allowAutoUpdates' =&gt; false,
    ),

    'example.dev' =&gt; array(
        'devMode' =&gt; true,
        'useCompressedJs' =&gt; false,
        'allowAutoUpdates' =&gt; true,
        'environmentVariables' =&gt; array(
            'siteUrl' =&gt; 'http://example.dev/',
            'sitePath' =&gt; '/Applications/MAMP/htdocs/example/html/',
        ),
    ),

    'staging.example.com' =&gt; array(
        'environmentVariables' =&gt; array(
            'siteUrl' =&gt; 'http://staging.example.com/',
            'sitePath' =&gt; '/var/www/vhosts/staging.example.com/html/',
        ),
    ),

);
</code></pre>

<p>And an example <code>db.php</code> file</p>

<pre><code>return array(

    '*' =&gt; array(
        'tablePrefix'   =&gt; 'craft',
    ),

    'example.dev' =&gt; array(
        'server'        =&gt; 'localhost',
        'user'          =&gt; 'root',
        'password'      =&gt; 'root',
        'database'      =&gt; 'example_dev',
    ),

    'staging.example.com' =&gt; array(
        'server'        =&gt; 'localhost',
        'user'          =&gt; 'example_staging',
        'password'      =&gt; '********************',
        'database'      =&gt; 'example_staging',
    ),

);
</code></pre>

<p>For more on Multi-Environment Configs see <a href="http://straightupcraft.com/learn-craft-cms/multi-environment-workflows" rel="noreferrer">Multi-Environment Workflows</a> on Straight Up Craft</p>

<p><strong>Version control with Git</strong></p>

<p>You can definitely use Git. I version everything except for user file uploads and <code>/craft/storage</code> and it works great.</p>

<p>My master <code>.gitignore</code> file in the root of my project looks like (specific to my setup, YMMV)</p>

<pre><code>.DS_Store

# Node/Sass
node_modules
html/css/public/main.css.map

# Config
dandelion.yml
sftp-config.json
craft/config/db.php
</code></pre>

<p>Then in each directory I want to ignore the contents of (craft storage and user uploads) I put a <code>.gitignore</code> file with...</p>

<pre><code># Ignore everything
*

# But not this file
!.gitignore
</code></pre>

<p>And as Matt pointed out in his other comment on your question, do see the answers on the related question <a href="https://craftcms.stackexchange.com/questions/13/whats-the-best-practice-for-upgrading-a-versioned-craft-site">What's the best practice for upgrading a versioned Craft site?</a></p>

CC BY-SA 3.0
2014-06-12T14:24:42.537Z
You might as well add your .gitignore for posterity, since you've already added lovely multi-environment examples for the general and db configs. :)
Matt Stein
CC BY-SA 3.0
2015-05-02T18:01:25.403Z
How would I create templates for each of environments? `templates/staging/`?
Dominik Krulak
CC BY-SA 3.0
2015-05-02T18:45:48.077Z
You could have different branches in your git repo, one for each environment. Then deploy the staging branch to staging, the production branch to production, etc.
Alex Kendrick
CC BY-SA 3.0
2015-05-04T16:41:08.110Z
I probably misunderstood your question, Dominik. If Craft had a "path to templates" config setting then you could set that per environment, but I don't think it does.
Alex Kendrick
CC BY-SA 3.0
2014-06-12T14:19:49.547Z
2014-06-12T21:22:53.327Z
2017-04-13T12:51:00.303Z
Alex Kendrick
<p>I'd like to be able to use git version control with Craft. Is this possible and if it is what is the best approach to ensure that all files/assets and the database are properly synced across local, staging and production servers?</p>

CC BY-SA 3.0
2014-06-12T13:56:53.943Z
Possible duplicate of http://craftcms.stackexchange.com/questions/10/whats-the-best-practice-for-handling-data-migration-and-organization-across-dev? Or is there something different about this question?
Matt Stauffer
CC BY-SA 3.0
2014-06-12T14:16:53.020Z
Somewhat related to http://craftcms.stackexchange.com/questions/13/whats-the-best-practice-for-upgrading-a-versioned-craft-site?rq=1 as well.
Matt Stein
<git><multi-environment>
Git Workflow and Multi Environment - how to approach
# Git Workflow and Multi Environment - how to approach

(Asked by: username_0 on 2014-06-12)

I'd like to be able to use git version control with Craft. Is this possible and if it is what is the best approach to ensure that all files/assets and the database are properly synced across local, staging and production servers?

**Tags:** git, multi-environment
> **Comments:**
> **username_1**: Possible duplicate of http://craftcms.stackexchange.com/questions/10/whats-the-best-practice-for-handling-data-migration-and-organization-across-dev? Or is there something different about this question?  
> **username_2**: Somewhat related to http://craftcms.stackexchange.com/questions/13/whats-the-best-practice-for-upgrading-a-versioned-craft-site?rq=1 as well.  

---

## 1 answers

### Answer by username_3 on 2014-06-12. Score: 25 | Accepted answer

Matt has a point, this is similar to What's the best practice for handling data migration and organization across development environments?, but that question focuses mainly on how to handle the database (definitely see those answers).
More generally speaking...
Multi-Environment Config
Set yourself up with Multi-Environment Configs in both craft/config/general.php and craft/config/db.php so that you don't have to be updating path settings every time you migrate data between environments.
Be sure to set some Environment-Specific Variables for the site URL and server path for each environment. That way you can use those variables in the control panel settings (the Site URL setting in the Setting → System → General and Assets paths in Settings → Assets → Your asset settings).
Here is a sample general.php file
return array(

    '*' => array(
        'omitScriptNameInUrls' => true,
        'usePathInfo'=> true,
        'cpTrigger' => 'example-admin',
        'allowAutoUpdates' => false,
    ),

    'example.dev' => array(
        'devMode' => true,
        'useCompressedJs' => false,
        'allowAutoUpdates' => true,
        'environmentVariables' => array(
            'siteUrl' => 'http://example.dev/',
            'sitePath' => '/Applications/MAMP/htdocs/example/html/',
        ),
    ),

    'staging.example.com' => array(
        'environmentVariables' => array(
            'siteUrl' => 'http://staging.example.com/',
            'sitePath' => '/var/www/vhosts/staging.example.com/html/',
        ),
    ),

);

And an example db.php file
return array(

    '*' => array(
        'tablePrefix'   => 'craft',
    ),

    'example.dev' => array(
        'server'        => 'localhost',
        'user'          => 'root',
        'password'      => 'root',
        'database'      => 'example_dev',
    ),

    'staging.example.com' => array(
        'server'        => 'localhost',
        'user'          => 'example_staging',
        'password'      => '********************',
        'database'      => 'example_staging',
    ),

);

For more on Multi-Environment Configs see Multi-Environment Workflows on Straight Up Craft
Version control with Git
You can definitely use Git. I version everything except for user file uploads and /craft/storage and it works great.
My master .gitignore file in the root of my project looks like (specific to my setup, YMMV)
.DS_Store

# Node/Sass
node_modules
html/css/public/main.css.map

# Config
dandelion.yml
sftp-config.json
craft/config/db.php

Then in each directory I want to ignore the contents of (craft storage and user uploads) I put a .gitignore file with...
# Ignore everything
*

# But not this file
!.gitignore

And as Matt pointed out in his other comment on your question, do see the answers on the related question What's the best practice for upgrading a versioned Craft site?

> **Comments:**
> **username_2**: You might as well add your .gitignore for posterity, since you've already added lovely multi-environment examples for the general and db configs. :)  
> **username_4**: How would I create templates for each of environments? `templates/staging/`?  
> **username_3**: You could have different branches in your git repo, one for each environment. Then deploy the staging branch to staging, the production branch to production, etc.  
> **username_3**: I probably misunderstood your question, Dominik. If Craft had a "path to templates" config setting then you could set that per environment, but I don't think it does.  

---

