Unreal Engine has a built-in source control interface. It supports multiple backends — Perforce, Subversion, Git, and third-party providers through a plugin system. You can check out assets, see modification history, and submit changelists without leaving the editor.
In theory, setting up source control for an Unreal project is a few clicks in the editor preferences panel. In practice, there are enough rough edges and non-obvious decisions that most teams figure this out the hard way. Here is what actually matters.
The .uasset Problem
Everything in Unreal is a .uasset. Blueprints, materials, meshes, textures after import, audio after import, level files (.umap) — all stored as binary .uasset files. This is not unique to Unreal but it concentrates the binary problem: virtually all the content in your project is in a format that cannot be meaningfully diff-ed or merged by standard tools.
This means your source control setup for an Unreal project needs to treat almost everything as binary. The only text files are C++ source code, config files (.ini), and your .uproject descriptor. Everything else in the Content folder is binary and needs either locking or a binary-aware version control backend.
Configuring Git for Unreal
Git is not Unreal's native source control, but many studios use it, especially for smaller projects. The baseline configuration:
Your .gitattributes should mark all Unreal asset types as binary:
*.uasset binary
*.umap binary
*.ubulk binary
*.uexp binary
Set up Git LFS for all of these file types. Without LFS, your repo will bloat rapidly as .uasset files accumulate.
For the Unreal Editor's source control panel to work with Git, install the Git LFS 2 plugin from the marketplace. The built-in Git support in Unreal is limited; the plugin provides a more complete integration including checkout status indicators in the Content Browser.
What Unreal's Content Browser shows
When source control is configured, Unreal's Content Browser displays icons on assets indicating their source control status: checked out (modified), up to date, marked for add, in conflict. This visibility is important for artists working in the editor — they can see at a glance which assets are modified and which are clean.
The checkout status is only as reliable as the underlying source control integration. With Git LFS, the status is sometimes stale and requires a manual refresh. With Perforce, the status is more reliable because the checkout model is enforced by the server.
Perforce with Unreal
Perforce is Unreal's preferred source control backend. Epic's own development uses Perforce, and the integration in the editor reflects that. The checkout-before-edit model maps naturally to Unreal's .uasset system: when you double-click an asset to edit it, Unreal automatically checks it out in Perforce.
Configuring Perforce for Unreal:
- Set your Perforce workspace root to the project directory containing the .uproject file
- In Unreal Editor, go to Edit → Editor Preferences → Source Control and select Perforce
- Enter your Perforce server address, username, and workspace name
- Set the
P4IGNOREenvironment variable or create a.p4ignorefile to exclude Intermediate, Saved, and DerivedDataCache directories
The key directories to exclude from source control entirely:
Intermediate/— compiled shaders and build artifacts, regenerated on buildSaved/— autosaves, crash dumps, logsDerivedDataCache/— local cache, extremely large, should not be shared via source controlBinaries/— compiled binaries, unless you are distributing them for teams without a compile environment
The Derived Data Cache
The Derived Data Cache (DDC) deserves special attention. Unreal processes imported assets into a platform-specific format optimized for runtime loading. This processed data can be large — often comparable in size to the raw assets. It lives in the DerivedDataCache directory by default.
New team members, fresh checkouts, and CI machines regenerate the DDC on first launch. For a 20GB project, this regeneration can take 2-4 hours. This is a major onboarding bottleneck and CI slowdown.
The solution is a shared DDC — a network share or blob storage location where the processed data is stored and shared across the team. Configure it in Engine.ini:
[DerivedDataBackendGraph]
Hierarchy=(Type=KeyLength, Length=120, Inner=Pak)
Pak=(Type=ReadPak, Filename="%GAMEDIR%DDC/DDC.ddp")
...
Shared=(Type=FileSystem, ReadOnly=false, Clean=false, Flush=false, PurgeTransient=true, DeleteUnused=true, UnusedFileAge=34, FoldersToClean=-1, Path=\\your-network-share\DDC)
With a shared DDC, new machines warm up in minutes rather than hours, pulling the cached data from the share instead of regenerating from source.
Practical Decisions for Your Setup
For teams under 10 people: Git with LFS and careful .gitattributes configuration is workable. Invest in the Git LFS 2 Unreal plugin. Accept that you will need to manage some manual locking for shared assets.
For teams of 10-50: The manual locking friction in Git becomes a real productivity problem. Either commit to a proper locking workflow with enforcement, or evaluate whether the operational cost of Perforce is worth the improved asset management.
For teams above 50: Perforce is the standard for a reason. The alternative is a purpose-built system that handles Unreal's binary asset model natively, with engine-integrated locking and asset status — which is what we are building at Diversion.
The Unreal source control setup decisions you make in the first month of a project are hard to change later. The migration cost from one system to another is real. Get the foundations right early, and the rest of the project runs more smoothly.