Open-source project
ProjectBorealis/UEGitPlugin avatar
ProjectBorealis/UEGitPlugin

UEGitPlugin: putting Git LFS under Unreal Engine's revision control UI

Unreal Engine Git Source Control Plugin (refactored)

829 stars170 forksC++MIT

At a glance

What is it?
ProjectBorealis/UEGitPlugin is a C++ source control plugin that brings Git and Git LFS into the Unreal Engine editor, with multi-threaded locking, rebase-based pull and status branches. The gain is editor-level lock awareness, the cost is a plugin you must compile yourself and a configuration model that expects explicit file attributes.
Who is it for?
UEGitPlugin fits studios that keep Unreal content in Git LFS, work on Windows with Visual Studio available, and want lock status visible in the editor. It is a poor match for teams that need a downloadable plugin build, for Linux or macOS contributors, or for anyone unwilling to write explicit .gitattributes entries for every .uasset and .umap.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 77 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A refactor of the SRombauts Git LFS plugin, aimed at production

UEGitPlugin is described in its README as a refactor of the Git LFS 2 plugin by SRombauts, carrying what its authors call lessons learned from production. The repository is C++, MIT licensed, and lives under the ProjectBorealis organisation. Its default branch is dev, and the repository root carries a plain Unreal plugin descriptor, GitSourceControl.uplugin, alongside a Source directory.

The interesting part is what the refactor changes rather than what it exposes. Upstream plugins of this kind tend to sit alongside the engine's own Perforce and Subversion providers as a second-class option. This one is presented as a first-class provider with its own status display in the editor, its own handling of lockable and non-lockable files, and a rewritten pull path. The README lists background remote refresh, automatic handling of pushing from an outdated local copy, and general improvements to memory usage among the headline items. That is a meaningful change in kind, since the plugin now competes with a hosted service's own client rather than merely offering a command line behind the scenes.

Multi-threaded locking and a local lock cache

The feature list leads with the operational detail rather than the user-visible outcome: multi-threaded lock handling, which the README says greatly improves performance when many files are locked or released. Underneath that sits a decision about how often the plugin bothers the server. Remote lock status is only checked when it is actually needed, and a local lock cache was added to speed up local operations.

This is the shape of a plugin written for teams with large shared content libraries, where a single scene may pull in thousands of lockable assets. A lock query that round-trips to a remote for every file is the kind of thing that makes people stop using the editor's source control panel at all. Caching locally and checking remotely only when necessary trades a small risk of stale lock state for responsiveness.

Lockable and non-lockable files are both managed in the editor. The README names assets and maps as lockable and configs and the project file as non-lockable, which matters for the checkout settings described later. The plugin also keeps a periodic background remote refresh running so remote file statuses do not drift far from reality. Whether that background refresh is frequent enough for a team with heavy contention is not documented, and the README does not describe any way to tune its interval.

Pull inside the editor refreshes only what changed

The pull path is the part most likely to change a team's day. The README calls out a greatly improved pull within editor, and explains two consequences of how it works. Only changed files are refreshed, which the project attributes to preventing crashes in large projects. And the pull uses a rebase workflow to manage local work rather than merging.

Selective refresh is the fix for a familiar Unreal problem. A blanket reimport or a full status refresh on a project with tens of thousands of assets can stall the editor or take it down, and the plugin's answer is to narrow the operation to the set of files that actually differ. Rebase-based pull is a stricter choice. Merge commits accumulate in a long-running branch and hide real conflicts; rebase keeps a linear history and surfaces divergence at the moment you pull, which is a better time to deal with it. The cost is that a team used to Perforce's change lists and to merge commits as a record of intent will have to change habits.

Automatic handling of pushing from an outdated local copy is also listed, so a push that would overwrite newer remote work is addressed by the plugin rather than left as a raw Git error. Optimized status updates for successful operations are mentioned as well, which suggests the editor status column is meant to settle rather than flicker while a batch of locks completes.

Status Branches require an engine subclass, not a setting

Status Branches are the feature with the largest setup cost, and the README is unusually clear about that. Epic Games added Status Branches in Unreal Engine 4.20, and this plugin implements support for them. The concept is that a user on any branch is protected from locking and modifying files that are out of date relative to the registered branch list.

Enabling it is not a config toggle. You must make a UUnrealEdEngine subclass, preferably in an editor-only module or guarded by WITH_EDITOR, and register the branch list at engine init time:

cpp
#include "ISourceControlModule.h"
#include "ISourceControlProvider.h"

void UMyEdEngine::Init(IEngineLoop* InEngineLoop)
{
	Super::Init(InEngineLoop);

	// Register state branches
	const ISourceControlModule& SourceControlModule = ISourceControlModule::Get();
	{
		ISourceControlProvider& SourceControlProvider = SourceControlModule.GetProvider();
		// Order matters. Lower values are lower in the hierarchy, i.e., changes from higher branches get automatically merged down.
		// (Automatic merging requires an appropriately configured CI pipeline)
		// With this paradigm, the higher the branch is, the stabler it is, and has changes manually promoted up.
		const TArray<FString> Branches {"origin/develop", "origin/promoted"};
		SourceControlProvider.RegisterStateBranches(Branches, TEXT("Content"));
	}
}

The engine class then has to be wired up in the project config, and the class name has to match the class exactly:

ini
[/Script/Engine.Engine]
UnrealEdEngine=/Script/MyModule.MyEdEngine

Two cautions come with it. The second argument to RegisterStateBranches is Perforce specific and is ignored by this plugin, so it only serves as a pointer to the relative content path. And if the subclass lives in an editor-only module, that module's loading phase has to be Default in the .uproject, otherwise the editor has trouble locating the class:

json
		{
			"Name": "MyTestProjectEditor",
			"Type": "Editor",
			"LoadingPhase": "Default"
		}

The ordering of the branch array encodes policy: the higher the branch, the more stable it is, and changes are manually promoted upward after a merge review. Automatic merging back down assumes you have a CI pipeline configured to do it, so the feature is half plugin and half pipeline.

Explicit .gitattributes for .umap and .uasset, and a hard-coded assumption about adding files

The plugin does not tolerate loose configuration. It requires explicit file attributes for *.umap and *.uasset, and the README is direct that this is instead of wildcarding the content folder with a wildcard over the whole Content folder. The project points at its own .gitattributes in the PBCore repository as the example, and at a companion .gitignore.

This is a reasonable demand. Wildcard rules apply to any file that later lands in the folder, including intermediate files the engine writes, and LFS patterns that over-match tend to turn text diffs into binary blobs. Requiring per-extension attributes keeps the tracking explicit. The cost is that teams arriving with a broad wildcard rule over Content have to rewrite it, and any new asset type added later needs its own attribute entry.

There is a second assumption baked into the editor config, and it changes how a team works. The plugin assumes files are always explicitly added, which the README says is a decision made for performance and workflow reasons. That is enforced in Config/DefaultEditorPerProjectUserSettings.ini:

ini
[/Script/UnrealEd.EditorLoadingSavingSettings]
bSCCAutoAddNewFiles=False

On top of that sit two optional checkout behaviours, auto-checkout on modification or a prompt on modification, with the README preferring the auto-checkout route for OFPA style workflows while warning that it needs user attention to avoid excessive locking of content:

ini
[/Script/UnrealEd.EditorLoadingSavingSettings]
bAutomaticallyCheckoutOnAssetModification=True
bPromptForCheckoutOnAssetModification=False

Two performance-related settings complete the picture. Checked out packages can be loaded at editor startup, and the engine's own source control check for editable packages can be switched off with r.Editor.SkipSourceControlCheckForEditablePackages=1 in Config/DefaultEngine.ini, which the README recommends as unnecessary work for Git.

No prebuilt binaries: the plugin compiles from source on Windows

Installation is deliberately small. The plugin can be dropped into a project's Plugins folder, or installed to the engine by renaming the engine's own provider out of the way and copying the plugin into Engine/Plugins. The descriptor to rename is Engine/Plugins/Developer/GitSourceControl.uplugin, and it becomes Engine/Plugins/Developer/GitSourceControl.uplugin.disabled.

The README states plainly that no precompiled binaries are provided, so Visual Studio is needed to compile the plugin. That is the single largest practical constraint and it is worth being blunt about: a studio with mixed tooling cannot hand this to an artist and expect a double-click install. Anyone on macOS or Linux is excluded from the documented path entirely, even though the repository root does contain git-lfs-mac-amd64 and git-lfs-mac-arm64 binaries alongside git-lfs.exe and a git-lfs directory, which suggests macOS support for the LFS side exists at some level. The README does not describe a macOS build of the plugin itself.

Authentication guidance points the same way. HTTPS authentication is strongly recommended for the repository, since a single credential path pairs with the HTTPS support in LFS, and Git Credential Manager is named as the convenient option with a GUI for authenticating against any Git provider. The plugin does not appear to ship a separate credential flow of its own, so whatever your provider uses is what you will use.

Where this plugin is the wrong tool

Three cases stand out. First, teams that need a downloadable or one-click plugin. The build step is a hard requirement, not a convenience, so a team without a Windows build culture inherits a setup cost before the plugin does anything useful.

Second, teams that do not want to revisit their attribute rules. The explicit .umap and .uasset requirement is not optional, and it interacts with LFS tracking in ways that are cheap to get right and annoying to get wrong, particularly when the same repository also stores code and non-asset content.

Third, teams with no CI pipeline at all who plan to use Status Branches. The README is explicit that automatic merging from higher branches down requires an appropriately configured CI pipeline. Without one, the branch hierarchy is decorative: it will tell you a file is out of date, but nothing will push a promoted change back to develop.

A fourth case is simply working without a shared remote. The plugin's value is concentrated in lock awareness and remote status, so a solo developer or a team with no Git server will not see most of the benefit. The comparison with the engine's built-in providers is worth stating plainly: this is a Git-native implementation with LFS and rebase semantics, not a Perforce replacement, and a studio that standardised on Perforce for good reasons is not the audience. On a comparison with the SRombauts plugin it is meant to replace, the difference is entirely in the mechanics: multi-threaded locking, a local lock cache, selective refresh on pull, rebase semantics and status branch support.

Editorial conclusion

UEGitPlugin fits studios that keep Unreal content in Git LFS, work on Windows with Visual Studio available, and want lock status visible in the editor. It is a poor match for teams that need a downloadable plugin build, for Linux or macOS contributors, or for anyone unwilling to write explicit .gitattributes entries for every .uasset and .umap. Before adopting it, verify that your existing .gitattributes already lists those patterns explicitly, that your CI can promote changes between the branches you register with RegisterStateBranches, and that the LFS binaries shipped in the repository work with your Git provider and credential setup.

Frequently asked questions

How do I install UEGitPlugin in an Unreal Engine project?

Copy the plugin into your project's Plugins folder, or rename the engine's built-in provider out of the way and install into the Engine/Plugins folder. The README states that no precompiled binaries are provided, so you need Visual Studio to compile the plugin.

Does UEGitPlugin support Git LFS for .uasset and .umap files?

The plugin requires explicit file attributes for *.umap and *.uasset, and the README points to the ProjectBorealis PBCore repository for an example .gitattributes. The project points at it as an alternative to using wildcards for the content folder such as a wildcard over the content folder.

What are Status Branches in UEGitPlugin and how do I enable them?

Status Branches protect you from locking and modifying files that are out of date relative to a registered branch list, and support is built on the feature Epic Games added in Unreal Engine 4.20. Enabling it requires a UUnrealEdEngine subclass that calls RegisterStateBranches, and the class must then be set as UnrealEdEngine in Config/DefaultEngine.ini.

Which Unreal Engine source control settings should I change for UEGitPlugin?

The plugin assumes files are always explicitly added, so Config/DefaultEditorPerProjectUserSettings.ini should set bSCCAutoAddNewFiles=False. You can also choose auto-checkout or prompt-on-modification, and set r.Editor.SkipSourceControlCheckForEditablePackages=1 in Config/DefaultEngine.ini to skip a check the README calls unnecessary for Git.

Official sources

  1. Issues
  2. License: MIT
  3. ProjectBorealis/UEGitPlugin on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/projectborealis-uegitplugin.svg)](https://hysenlabs.com/projects/projectborealis-uegitplugin)

Was this useful?