How should I approach getting serialized items into source control? I have Unicorn sync down to my ~/App_Data/serialization/ so auto-publish does the deed, but how do you get changes if you're developing outside the web root? I am currently using a gulp script to look out for changes to YML files and pull them back, but I wanted to make sure I wasn't missing something.

2 Answers 2


This is an alternative method to @Kasaku's answer - it effectively gives the same result but can be a little more flexible, especially if you are following Helix guidelines.

Instead of patching the physicalRootPath in the targetDataStore for the defaults, you can also do this in each configuration file.

So that you only have one place to put the full path, create a zDeveloper.config file. In that add a new variable called sourceFolder:

<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sc.variable name="sourceFolder" value="C:\projects\myproject\src" />

Now you can use that in your serialization configs. For example, here is a config for the Habitat Accounts feature:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
        <configuration name="Feature.Accounts" description="Feature Accounts" dependencies="Foundation.Serialization,Foundation.Assets" patch:after="configuration[@name='Foundation.Serialization']">
          <targetDataStore physicalRootPath="$(sourceFolder)\feature\accounts\serialization" type="Rainbow.Storage.SerializationFileSystemDataStore, Rainbow" useDataCache="false" singleInstance="true" />
          <predicate type="Unicorn.Predicates.SerializationPresetPredicate, Unicorn" singleInstance="true">
            <include name="Feature.Accounts.Templates" database="master" path="/sitecore/templates/Feature/Accounts" />
            <include name="Feature.Accounts.Renderings" database="master" path="/sitecore/layout/renderings/Feature/Accounts" />
            <include name="Feature.Accounts.Core.Templates" database="core" path="/sitecore/templates/Feature/Accounts" />
            <include name="Feature.Accounts.Media" database="master" path="/sitecore/media library/Feature/Accounts" />
          <roleDataStore type="Unicorn.Roles.Data.FilesystemRoleDataStore, Unicorn.Roles" physicalRootPath="$(sourceFolder)\feature\accounts\serialization\Feature.Accounts.Roles" singleInstance="true"/>
          <rolePredicate type="Unicorn.Roles.RolePredicates.ConfigurationRolePredicate, Unicorn.Roles" singleInstance="true">
            <include domain="modules" pattern="^Feature Accounts .*$" />

Notice that the targetDataStore is overwritten:

<targetDataStore physicalRootPath="$(sourceFolder)\feature\accounts\serialization" ... />

Using this method, each of your Foundation, Feature and Project layers can have their Unicorn files in their own folder - keeping the Helix pattern. It's still all under the source folder in your repo, so you have no issues with source control.

  • So the implied Step 1 is to ensure that you have your own personal instance of Sitecore running on your own developer machine that you also do your coding from. Each additional developer working on the Sitecore solution must also have their own instance of Sitecore running on their local machine.
    – TxRegex
    Commented Feb 12, 2018 at 23:18
  • this seems like it would be a problem with branching in source... e.g. I create a branch in TFS that lives in C:/codebase/devroot-newfeature/ ... so now I have to change the sc.variable name="sourceFolder" for my branch to get serialization to work, and then undo that when I eventually merge back into the root Dev branch C:/codebase/devroot/ Commented Dec 16, 2019 at 19:24
  • I you use TFVC - everything is a problem with branching ;)
    – Richard Seal
    Commented Dec 17, 2019 at 18:32

The files can be serialized to anywhere on disk, and you're not limited to the folder of the Sitecore installation.

With this in mind, it's easy to add another configuration file on development machines that overrides the root folder with a folder directly in your source. I find this a much easier method than relying on another task that has to keep two folders in-sync. Additionally, pulling and syncing changes to Sitecore becomes very easy.

Unicorn in fact comes with an example configuration file included for achieving just this, you just need to remove the .example extension:


    This is an example of how to configure Unicorn to override the location on disk to store the serialized items.

    If used, this should be present on all environments where Unicorn is active (usually all but CD).
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
                    Sitecore config patch files load in alphabetical order, followed by folders.
                    So either place this in App_Config/Include/Unicorn, or a folder that loads after that like 'zSite'

                    The target data store is where we write serialized items to, use this patch to alter where items are serialized to and from.

                    Note the target data store's rootPath can be any of:
                    Absolute filesystem path, e.g. c:\foo\bar
                    Web-root-relative path, e.g. ~/data/serialization or ~/../out-of-root-serialization
                    Data-folder-relative path, e.g. $(dataFolder)\serializedItems

                    DO NOT SHARE A ROOT PATH BETWEEN CONFIGURATIONS (at least if you're using SFS).
                    They can clobber each other's folders. You may inject the name of the current
                    configuration as a variable with $(configurationName).

                    The data cache uses a memory cache to store serialized items read from disk. It
                    is recommended if using transparent syncing for performance. It's not really
                    needed otherwise.
                <targetDataStore type="Rainbow.Storage.SerializationFileSystemDataStore, Rainbow">
                    <patch:attribute name="physicalRootPath">c:\path-to-source\Unicorn\$(configurationName)</patch:attribute>

If you have a setup where all developers have their source folder in the same location, you can keep this file in source and just make sure it isn't included in deployments.

If you each use different working folders for your source, you can omit the file from source control completely and make sure that the developers add it to their deployed sites locally. If you are using git for source control, you can even have it in source control but ask git to not track any further changes to the file, so devs don't accidentally commit the file back in with changes.

  • As long as the relative path from the website to the source folder is the same, you can also provide a relative path. For instance, we patch the path as ~/../Source/Serialization/$(configurationName).
    – Thomas D
    Commented Nov 18, 2016 at 14:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.