Every Shopify developer has a version of this story. You make a small change to a theme file. Something breaks. You cannot remember exactly what you changed or where. You try to undo it manually but cannot isolate the problem. Meanwhile the store is live, customers are visiting, and every minute of a broken experience costs real money.

This scenario is entirely preventable. The solution is version control with Git, combined with a structured theme testing workflow that keeps your development, staging, and production environments cleanly separated.

This guide covers the complete setup: how Git works with Shopify themes, how to structure your development workflow, how to use Shopify CLI for local development, how to manage theme environments correctly, and the best practices that professional Shopify development teams use to ship changes confidently without ever breaking a live store.

Why Version Control Matters for Shopify Theme Development

Shopify’s built-in theme editor has a duplicate and publish workflow that provides a basic form of version control. You can duplicate your live theme before making changes and roll back to the duplicate if something goes wrong. This approach works for simple one-off edits but breaks down quickly in any serious development context.

The problems with the duplicate-only approach become apparent the moment more than one developer is working on a theme, or when you are managing multiple rounds of changes across different features. Which duplicate is the current version? Which contains the feature that was half-finished last week? What exactly changed between the version that worked and the version that does not?

Git solves all of these problems by maintaining a complete history of every change made to every file in your theme. Every commit records exactly what changed, who changed it, and when. You can compare any two versions of any file at any point in the project’s history. You can create branches for separate features, merge them when they are ready, and revert any change instantly if it causes a problem.

For Shopify theme development specifically, Git provides three things that are otherwise impossible to replicate: a complete audit trail of every code change, the ability to work on multiple features in parallel without them interfering with each other, and a reliable rollback mechanism that works at the individual file level rather than requiring you to restore an entire duplicate theme.

These capabilities are not just quality-of-life improvements. They are fundamental requirements for any professional development workflow. Our Shopify Custom Development team uses Git-based workflows on every project for exactly this reason.

Understanding Shopify Theme Environments

Before setting up Git, you need to understand how Shopify handles multiple theme environments within a single store, because this is the foundation your version control workflow builds on.

Every Shopify store can have multiple themes installed simultaneously, but only one theme is live to customers at any given time. All other installed themes are in an unpublished state. Unpublished themes are fully functional, can be previewed with a theme preview URL, and can be edited without affecting the live store in any way.

This means you can maintain three separate theme environments within a single store:

Your development theme is where active development happens. It is never shown to real customers. Developers make changes here freely, test features, and iterate without any risk to the live store.

Your staging theme is a near-production copy used for final review and testing before any changes go live. Quality assurance happens here. Stakeholders review designs here. This theme should always represent what the next production release will look like.

Your production theme is the live theme that customers see. Changes only reach this theme after they have been reviewed and approved in staging. It should never be edited directly.

This three-environment structure is the industry standard for professional Shopify development. It prevents the single most common cause of live store breakage: editing the production theme directly.

Setting Up Your Local Development Environment

Installing Shopify CLI

Shopify CLI is the command-line tool that connects your local development environment to your Shopify store. It enables you to sync files between your local machine and a Shopify theme in real time, pull theme files down from your store, push changes up, and run a local development server that reflects changes instantly as you save files.

Install Shopify CLI through npm:

npm install -g @shopify/cli @shopify/theme

Verify the installation:

shopify version

You also need Node.js version 18 or higher and Ruby installed on your machine. On macOS, install these through Homebrew. On Windows, use the official installers from nodejs.org and ruby-lang.org.

Authenticating with Your Store

Authenticate Shopify CLI with your store by running:

shopify auth login --store your-store-name.myshopify.com

This opens a browser window where you log in with your Shopify Partner or store credentials. Once authenticated, CLI stores your session locally so you do not need to re-authenticate for subsequent commands against the same store.

Initializing Git in Your Theme Project

Pulling Your Theme Down Locally

The first step is getting your theme files onto your local machine. Navigate to the directory where you want to store your project and pull down your theme:

shopify theme pull --store your-store-name.myshopify.com --theme THEME_ID

Replace THEME_ID with the numeric ID of your theme. You can find this in your Shopify admin under Online Store and then Themes. The theme ID appears in the URL when you click Customize on any theme.

This creates a local directory with your complete theme file structure:

your-theme/
├── assets/
├── config/
├── layout/
├── locales/
├── sections/
├── snippets/
└── templates/

Initializing Git

Navigate into your theme directory and initialize a Git repository:

cd your-theme
git init

Creating a .gitignore File

Before making your first commit, create a .gitignore file to exclude files that should not be tracked. For Shopify themes, this primarily means the config/settings_data.json file, which stores your theme customizer settings and changes frequently with every save in the theme editor:

# Shopify CLI
.shopify/

# Theme settings data (customizer settings - managed per environment)
config/settings_data.json

# Node modules if using build tools
node_modules/

# OS files
.DS_Store
Thumbs.db

# Editor directories
.vscode/
.idea/

# Build output
dist/

The decision about whether to track settings_data.json deserves explanation. This file changes every time anyone saves settings in the theme customizer. If you track it in Git, you will have constant conflicts between environments where settings differ. Most professional workflows exclude it from Git and manage it per-environment. However, if you need settings to be consistent across environments, you can include it but must manage merges carefully.

Making Your First Commit

Add all files and make your initial commit:

git add .
git commit -m "Initial theme commit: baseline from production"

This establishes your baseline. Every subsequent change has this commit as its reference point, meaning you can always see exactly what changed from the original state.

Connecting to a Remote Repository

A local Git repository protects you against local mistakes but not against hardware failure or the need to collaborate with other developers. Connect your repository to a remote host.

GitHub is the most widely used option. Create a new private repository on GitHub, then connect your local repository:

git remote add origin https://github.com/your-org/your-store-theme.git
git branch -M main
git push -u origin main

GitLab and Bitbucket are equally capable alternatives. The choice depends on your team’s existing tooling preferences. All three support the Git workflows described in this guide without any differences in capability for Shopify theme development.

Make your repository private. Your theme code contains your store’s design, custom functionality, and potentially configuration details that should not be publicly accessible.

Branching Strategy for Shopify Theme Development

A branching strategy defines how you use Git branches to organize different types of work and control what gets deployed where. The right branching strategy eliminates the confusion of multiple developers working on the same codebase and ensures that only reviewed, tested code reaches your live store.

The Three-Branch Foundation

Structure your permanent branches to mirror your three theme environments:

main is your production branch. It mirrors exactly what is live on your store. Only merge into main when you are ready to deploy to production. Every commit on main should represent a deployable state.

staging is your pre-production branch. It mirrors your staging theme environment. Features merge here first for integration testing and final review before going to main.

develop is your active development branch. Daily development work happens here and on feature branches that merge into develop.

Feature Branches

For any change beyond a trivial single-file fix, create a dedicated feature branch:

git checkout develop
git pull origin develop
git checkout -b feature/homepage-banner-redesign

Work on this branch until the feature is complete. Feature branches keep your work isolated so that an incomplete feature never blocks other work from moving forward.

Name branches descriptively using a consistent convention. Common patterns are feature/description for new functionality, fix/description for bug fixes, and hotfix/description for urgent production fixes that need to bypass the normal staging process.

Merging Flow

The normal flow for any change is: feature branch to develop, develop to staging for testing, staging to main for production deployment.

# Merge feature into develop
git checkout develop
git merge feature/homepage-banner-redesign
git push origin develop

# When develop is ready for staging review
git checkout staging
git merge develop
git push origin staging

# When staging is approved for production
git checkout main
git merge staging
git push origin main

This linear flow ensures that every change passes through testing before reaching production. Nothing goes to main that has not first been reviewed in staging.

Syncing Git Branches with Shopify Theme Environments

The connection between your Git branches and your Shopify theme environments is the operational core of this workflow. Each branch should correspond to a specific theme in your Shopify store.

Setting Up Theme Environments with Shopify CLI

Shopify CLI uses an environments configuration to manage connections between your local repository and specific themes in your store. Create a shopify.theme.toml file in your project root:

[environments.development]
store = "your-store-name.myshopify.com"
theme = "DEVELOPMENT_THEME_ID"

[environments.staging]
store = "your-store-name.myshopify.com"
theme = "STAGING_THEME_ID"

[environments.production]
store = "your-store-name.myshopify.com"
theme = "PRODUCTION_THEME_ID"

Replace each THEME_ID with the actual numeric ID of the corresponding theme in your Shopify admin.

Add shopify.theme.toml to your .gitignore if it contains sensitive store information, or keep it tracked if you want all team members to share the same environment configuration. Most teams track it, since theme IDs are not sensitive credentials.

Pushing to Specific Environments

With environments configured, you can push to any theme environment directly:

# Push to development theme
shopify theme push --environment development

# Push to staging theme
shopify theme push --environment staging

# Push to production theme (use carefully)
shopify theme push --environment production

Pushing to production should be a deliberate, reviewed action. Some teams add a confirmation step or require two-person sign-off before any production push.

Running Local Development Against Your Development Theme

For active development, use the Shopify CLI dev server to get real-time sync between your local files and your development theme:

shopify theme dev --environment development

This command starts a local development server that watches your files for changes. Every time you save a file locally, the change syncs to your development theme in Shopify and the browser previewing that theme refreshes automatically. This eliminates the manual upload cycle of traditional Shopify theme development and dramatically speeds up iteration.

A Professional Git Workflow in Practice

Here is how a complete feature cycle looks from start to finish using this workflow:

Step 1: Start from a clean develop branch

git checkout develop
git pull origin develop

Always pull the latest before starting new work to ensure you are not building on a stale base.

Step 2: Create your feature branch

git checkout -b feature/product-page-sticky-atc

Step 3: Start the local dev server

shopify theme dev --environment development

Step 4: Make your changes

Edit your theme files locally. Changes sync to the development theme in real time. Test in the browser preview. Iterate until the feature works correctly.

Step 5: Commit your work in logical chunks

git add sections/product-template.liquid
git commit -m "Add sticky ATC bar for mobile product pages"

git add assets/product-sticky-atc.css
git commit -m "Add CSS for sticky ATC bar positioning and animation"

Write commit messages that describe what the change does, not what files were touched. A message like “Add sticky ATC bar for mobile product pages” is useful. “Updated liquid file” is not.

Step 6: Push your feature branch

git push origin feature/product-page-sticky-atc

Step 7: Create a pull request to develop

On GitHub, open a pull request from your feature branch into develop. Assign a reviewer. The reviewer checks the code, leaves comments if needed, and approves when satisfied.

Step 8: Merge and deploy to staging

After approval, merge into develop, then merge develop into staging and push to your staging theme:

git checkout staging
git merge develop
git push origin staging
shopify theme push --environment staging

Step 9: Review on staging

Open the staging theme preview URL and review the feature in the actual Shopify environment. Check on mobile and desktop. Test edge cases. Have a stakeholder sign off if required.

Step 10: Deploy to production

When staging review is complete:

git checkout main
git merge staging
git push origin main
shopify theme push --environment production

Handling Hotfixes

Sometimes a critical bug in production requires an immediate fix that cannot wait for the full develop-to-staging-to-production cycle. Hotfixes have their own flow:

# Branch directly from main
git checkout main
git pull origin main
git checkout -b hotfix/checkout-button-broken

# Make the fix, commit it
git add .
git commit -m "Fix checkout button visibility on mobile Safari"

# Push to production immediately after testing
git push origin hotfix/checkout-button-broken
shopify theme push --environment production

# Then merge the hotfix back into main and develop
git checkout main
git merge hotfix/checkout-button-broken
git push origin main

git checkout develop
git merge hotfix/checkout-button-broken
git push origin develop

The critical step that many teams miss is merging the hotfix back into develop. If you only merge into main, the next time develop merges to main it will overwrite your hotfix and the bug will reappear.

Handling Merge Conflicts in Shopify Themes

Merge conflicts occur when two branches have both modified the same lines of the same file. In Shopify theme development, the files most likely to generate conflicts are heavily edited Liquid files like sections/header.liquid, layout/theme.liquid, and busy product or collection templates.

When a conflict occurs, Git marks the conflicting sections in the file:

<<<<<<< HEAD
<div class="header-nav">
=======
<nav class="site-navigation" aria-label="Main">
>>>>>>> feature/navigation-redesign

The section between <<<<<<< HEAD and ======= is what exists in your current branch. The section between ======= and >>>>>>> is what the incoming branch wants to replace it with.

Resolve conflicts by editing the file to contain the correct final state, removing all conflict markers, then committing the resolved file:

git add layout/theme.liquid
git commit -m "Resolve merge conflict in theme.liquid header markup"

The best way to minimize conflicts is to keep branches short-lived and merge frequently. A feature branch that diverges significantly from develop over two weeks of parallel work will have more conflicts than one that gets merged after two days. Small, frequent merges are less painful than large, infrequent ones.

Theme Backup and Safety Practices

Git provides code-level version control but it does not replace a proper Shopify theme backup strategy. Your Git repository tracks code changes but not content changes made through the Shopify admin: product descriptions, page content, metafield values, and theme customizer settings are all outside Git’s scope.

A complete backup strategy combines Git for code with a Shopify backup app for store data. Our blog on backup apps for Shopify stores covers the best options for protecting your full store data, including content that Git cannot track.

Before any significant theme deployment, manually duplicate your live theme in the Shopify admin. This gives you a one-click rollback option within Shopify itself, independent of Git. Keep the last two or three production theme duplicates at all times.

Comparing This Workflow to Common Alternatives

Approach Version History Multi-Developer Support Environment Separation Rollback Speed Recommended For
Direct theme editor edits None None None Manual re-edit Solo stores, minor text changes only
Duplicate before editing Single snapshot None None One click (limited) Solo developers, simple stores
Git without Shopify CLI Full history Yes Manual Git revert Small teams, limited automation
Git with Shopify CLI environments Full history Yes Structured Git revert + push Professional teams, all stores
Git with CI/CD pipeline Full history Yes Automated Automated rollback Enterprise, high-frequency deployments

For most professional Shopify development work, the Git with Shopify CLI environments approach strikes the right balance of structure and simplicity. It does not require DevOps infrastructure but provides all the version control and environment management a serious team needs.

Integrating with CI/CD for Automated Deployments

For teams shipping changes frequently, a CI/CD pipeline automates the process of pushing theme changes to Shopify when code is merged to specific branches. This removes the manual step of running shopify theme push after every merge.

GitHub Actions is the most straightforward option for Shopify theme CI/CD. Create a workflow file at .github/workflows/deploy.yml:

name: Deploy Shopify Theme

on:
  push:
    branches:
      - staging
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Install Shopify CLI
        run: npm install -g @shopify/cli @shopify/theme

      - name: Deploy to Staging
        if: github.ref == 'refs/heads/staging'
        run: shopify theme push --environment staging
        env:
          SHOPIFY_FLAG_STORE: ${{ secrets.SHOPIFY_STORE_URL }}
          SHOPIFY_CLI_THEME_TOKEN: ${{ secrets.SHOPIFY_STAGING_TOKEN }}

      - name: Deploy to Production
        if: github.ref == 'refs/heads/main'
        run: shopify theme push --environment production
        env:
          SHOPIFY_FLAG_STORE: ${{ secrets.SHOPIFY_STORE_URL }}
          SHOPIFY_CLI_THEME_TOKEN: ${{ secrets.SHOPIFY_PRODUCTION_TOKEN }}

Store your Shopify API tokens as GitHub secrets rather than in the workflow file. This prevents credential exposure in your repository.

With this pipeline in place, merging to staging automatically deploys to your staging theme and merging to main automatically deploys to production. The deployment happens within seconds of the merge, without any manual intervention.

Liquid Code Quality in a Git Workflow

Version control pairs naturally with code quality practices. When reviewing pull requests for Shopify theme changes, there are specific things worth checking in Liquid code beyond general correctness.

Check for forloop performance issues, particularly deeply nested loops and loops inside loops that query the store’s product catalog. These are among the most common causes of slow theme rendering. Our detailed guide on Shopify Liquid optimization covers the specific patterns to watch for when reviewing Liquid code in pull requests.

Check that new sections follow your theme’s existing schema conventions for settings and blocks. Inconsistent section schemas create confusion in the theme customizer and make future maintenance harder.

Check that any new JavaScript added to assets is appropriately deferred or loaded asynchronously so it does not block page rendering. New scripts are one of the most common causes of performance regression after a theme update.

Our Shopify Speed Optimization Checklist is a useful reference during code review to verify that new theme changes do not introduce performance regressions before they reach production.

Common Mistakes and How to Avoid Them

Committing settings_data.json conflicts. If you track settings_data.json in Git, conflicts between environments are frequent and often confusing. Either exclude it entirely or establish a clear policy about which environment’s settings take precedence during merges.

Working directly on main. Every change, no matter how small, should go through a branch. Direct commits to main bypass the review process and make your history harder to understand.

Vague commit messages. A history full of “fixed stuff” and “updated template” messages provides no audit trail value. Write messages that describe the actual change clearly enough that someone reading the history six months later understands what happened.

Forgetting to pull before branching. Starting a feature branch from a stale version of develop creates unnecessary conflicts when you eventually merge. Always pull the latest before creating a new branch.

Not syncing hotfixes back to develop. This is the most common source of “the bug came back” situations. Any change that goes to production must also merge back into develop, or it will be overwritten by the next deployment.

Pushing directly to production without staging review. The staging environment exists specifically to catch problems before they reach real customers. Skipping it saves five minutes and risks breaking a live store.

These are among the patterns we specifically watch for when conducting a Shopify Site Audit on stores that have had development quality issues.

How KolachiTech Manages Theme Development

At KolachiTech, every theme project uses the Git workflow described in this guide as standard practice. All of our Custom Shopify Theme Development work uses structured branching, environment separation, and pull request reviews before any code reaches a live store.

For clients who want ongoing theme development with professional version control practices built in, our Shopify Maintenance Services team maintains the Git workflow and handles all deployments through a structured, reviewed process. No surprises, no direct production edits, and a complete history of every change ever made to your theme.

If you are dealing with Shopify technical mistakes that have accumulated from years of uncontrolled theme edits, or if you want to set your development workflow up correctly from the beginning, book a free consultation with our development team.

For teams looking at headless approaches where theme version control intersects with framework-level development, our Shopify Hydrogen guide and our blog on serverless functions in Shopify Hydrogen cover how version control practices evolve in a headless context. And our Shopify Webhooks guide covers how event-driven architecture integrates with the kind of custom development work that version control makes safe to build and deploy.

Conclusion

Version control with Git is not an advanced practice reserved for large development teams. It is the baseline standard for any professional Shopify theme development work, whether you are a solo developer or part of a team of ten.

The workflow covered in this guide gives you a complete system: local development with Shopify CLI, three-environment separation between development, staging, and production, a branching strategy that keeps features isolated and deployments controlled, and a pull request review process that catches problems before they reach your live store.

The upfront investment in setting this up correctly is measured in hours. The time it saves, and the store-breaking incidents it prevents, are measured over the entire lifetime of your store.

Set it up once. Use it on every project. Your future self will be grateful every time something breaks in staging instead of in production.

Frequently Asked Questions (FAQs)

1. Do I need Git for Shopify theme development if I work alone? Yes. Version control is valuable even for solo developers because it provides a complete history of every change you have made, the ability to revert any change instantly, and protection against accidental overwrites. The effort of setting up Git is small compared to the time lost investigating and manually reversing an untracked change that broke something in production.

2. What is the difference between Shopify CLI and the Shopify Theme Kit? Shopify Theme Kit was the previous command-line tool for Shopify theme development. Shopify CLI replaced it as the official tool and offers significantly more capability including local development servers with hot reload, environment configuration management, and deeper integration with the Shopify platform. Theme Kit is no longer actively developed and new projects should use Shopify CLI.

3. Can I use this Git workflow with a purchased premium theme? Yes. Most premium themes are purchased as a one-time download, which you can initialize as a Git repository just like a custom-built theme. The key difference is that you will need to manage theme updates from the theme developer carefully, merging their updates into your codebase without overwriting your customizations. A clean Git history makes this significantly easier since you can see exactly what you changed from the original.

4. Should I track config/settings_data.json in Git? Most professional workflows exclude it. This file changes every time anyone saves in the Shopify theme customizer, which generates frequent low-value commits and conflicts between environments that have different customizer settings. Exclude it from Git and manage settings per-environment through the Shopify admin instead.

5. How do I handle a situation where the production theme has been edited directly in the Shopify admin without going through Git? This is a common situation when inheriting a store that did not have version control in place. The solution is to pull the current production theme down as your new baseline commit, establish the Git workflow from that point forward, and accept that pre-Git history is not recoverable. Going forward, all changes go through the workflow. Our Shopify Site Audit service helps identify and reconcile the state of themes that have had uncontrolled edits before establishing a clean development workflow.

6. What is the best way to test theme changes before deploying to staging? Use the Shopify CLI dev server pointed at a dedicated development theme. The dev server provides real-time sync between your local files and the theme, allowing you to test in an actual Shopify storefront environment before committing anything. Test across multiple devices and browsers in development before promoting to staging, so staging review can focus on final approval rather than catching basic functionality issues.

7. How does this workflow change for Shopify Plus stores? The core Git workflow remains identical for Shopify Plus stores. The main additions at the Plus level are that checkout customizations built with Checkout UI Extensions have their own deployment process through the Shopify CLI extensions command rather than through theme push, and that Scripts or Functions used for custom discount and shipping logic also deploy separately. The theme version control workflow described in this guide handles the storefront theme itself, while Plus-specific customizations sit alongside it as separate deployable units within the same repository.

Your Trusted Shopify Partner.

Get in touch with our expert Shopify consultants today and let’s discuss your ideas and business requirements.