Git for UE Projects: Using .gitignore, LFS, and Locking Together

Created: 2026-07-20Last updated: 2026-09-05

How to separate UE assets from generated files, configure Git LFS, and make a first commit. Explains how storage works, verifying what gets tracked, locking for collaboration, and what One File Per Actor does.

The door gimmick works, so you want to keep this state. You also want to receive the stage your friend built. Add a UE project to Git, though, and not just assets but piles of logs and temporary files line up as candidates.

The first thing to decide is what to record and what not to . On top of that, use Git LFS for large assets and locking to avoid simultaneous edits of the same asset. Understanding each role makes the configuration files easier to follow.

This article goes as far as recording a small UE project for the first time. At the end we verify not by size numbers but by whether the needed files are present, generated files are excluded, and assets are recorded through LFS .

Three roles: gitignore excluding generated files, LFS separating asset storage, and locking serializing edits to the same asset

What You'll Learn

  • What commit and push do, and what the two configuration files are for
  • Which files UE projects keep and which generated files to exclude
  • A first commit using LFS, and how to verify it
  • Organizing simultaneous edits with locking and One File Per Actor

Sponsored

The flow up to recording in Git

Git is a tool that keeps file changes as history. Recording at points like "added the door" and "enemy attack works" lets you review changes and return to an earlier state. The place managing that history is a repository .

OperationWhat it does
git addChooses the changes to include in the next record, also called staging
git commitRecords what you chose into local history with a message
git pushSends your local record to another destination such as GitHub
git cloneFetches a repository from a shared destination into a new working folder

Committing alone keeps the record on the same PC. To guard against a PC failure, you need the record somewhere else too. That shared destination is called a remote. We first record correctly locally and cover sharing checks later.

Add and commit stay on the same PC, and only push sends it to another destination

Saving in UE comes first too. Changes made in the editor but not saved are invisible to Git. Save the game, then commit at a natural break in the work.

Files to keep and generated files to exclude

A project mixes assets and settings with temporary data the engine generates. The criterion is whether, without that file, you or someone else could not open the same project .

What to recordContents
.uprojectProject information
Content/Blueprints, maps, materials, and other assets
Config/Project settings
Source/C++ code. May not exist in a Blueprint-only project
Needed Plugins/ and Build/Custom plugins and build settings or resources

Folder structure thinking is also covered in the asset management article. Meanwhile, these are typical exclusions from normal development history.

What to excludeWhy
Saved/Logs, autosaves, runtime saves. They change with every session
Intermediate/Files created during builds. Regenerable
DerivedDataCache/A cache reusing shader and other processing results
Binaries/ at the project rootBuilt files. Exclude if you regenerate them from your source and environment
Recording needed data such as Content and excluding generated files at the project root, while keeping plugins that cannot be regenerated

Excluding does not mean deleting from disk. It only keeps them out of Git's record. To rescue an autosave that exists only in Saved, handle that outside version control.

The file where you write those exclusion rules is .gitignore . It keeps files out of the candidates for new additions; it does not automatically untrack files already recorded.

Do not exclude Binaries everywhere unconditionally

Some binaries, such as plugins shipped without source, cannot be regenerated. Check the plugin's distribution form and restoration method and keep them. For the same reason, do not decide that Build or imported source images and audio are wholesale unnecessary.

LFS separates where assets are stored

UE's .uasset and .umap are binary files the engine reads. Blueprint nodes are not saved as human-readable source lines in Git.

Updating large assets repeatedly makes storing and fetching that history heavy. Git has its own compression, but for large-asset workflows you use Git LFS (Large File Storage) to separate where the real data lives.

With LFS, Git history holds a small marker called a pointer and the asset itself is stored on the LFS side. The pointer carries information identifying which real data it is, used to retrieve the file when fetching. Your working folder holds the original asset UE can open.

So LFS is not a mechanism shrinking assets from gigabytes to megabytes. It is a mechanism separating Git history from large real data . The LFS side needs storage too, so check your sharing service's storage and bandwidth terms.

A pointer in Git history pointing to each version's real data on the LFS side, fetching the needed version of BP_Door into the working folder

Which files LFS handles is recorded in .gitattributes . Where .gitignore holds "rules for excluding from the record", this holds "how to handle files being recorded".

*.uasset filter=lfs diff=lfs merge=lfs -text
*.umap filter=lfs diff=lfs merge=lfs -text

Those two lines specify "read and write files with the uasset and umap extensions through LFS". The hands-on creates them from commands, so there is no need to memorize each field. If you keep large FBX or audio in the same repository, add those extensions.

Sponsored

Hands-On: configure LFS and make a first commit

Use a small practice UE project not yet added to Git . Something like the Third Person template, with assets in Content. If you use a project already committed in the initial settings article, read "Switching to LFS partway" at the end first.

Initializing Git, configuring LFS, placing exclusion and LFS rules, then verifying the contents and recording the assets

1. Confirm where you are running commands

Install Git and Git LFS and run these in a terminal. Version output for both means you can invoke them. They come from Git official and Git LFS official.

git --version
git lfs version

"Save All" in UE and close the editor. Open a terminal in the folder containing .uproject and run these. On Windows you can use "Open in Terminal" from Explorer.

git init
git lfs install --local

git init starts history management in that folder. --local puts LFS configuration into this repository and is separate from installing LFS itself.

2. Prepare the exclusion and LFS rules

Create .gitignore with a text editor at the same level as .uproject . As a practice project with no extra plugins, start with this.

/Saved/
/Intermediate/
/DerivedDataCache/
/Binaries/
/.vs/
/*.sln

The leading / specifies the project root. This example does not blanket-exclude everything under Plugins. Once you add C++ or plugins, look at the generated files and the required distribution files and add rules.

GitHub's UnrealEngine.gitignore is another starting point. It also includes rules excluding plugin Binaries and Build and SourceArt images, so read it before using it. On Windows, check the file is not named .gitignore.txt .

Next, register the LFS targets. Running these with the quotes writes the extension rules into .gitattributes .

git lfs track "*.uasset"
git lfs track "*.umap"

Everything up to here is preparation for recording. Placing the rules before you git add assets records them as LFS pointers from the start.

3. Review what will be added before committing

First list the candidates.

git status --short --untracked-files=all

Confirm Config, Content, .uproject , and the two configuration files are candidates and that Saved and Intermediate are not. Once the needed items are present, add them.

git add .gitignore .gitattributes
git add .
git diff --cached --name-only
git lfs ls-files

--cached shows "what you chose for the next commit". Confirm the first listing has no generated files mixed in and that the LFS listing shows .uasset and .umap files. If something is wrong, revisit the settings before committing.

git commit -m "Add UE project with Git LFS"

If it asks for a name and email on the first commit, follow Git's guidance to set user.name and user.email and redo the commit. That information is recorded as the author in history.

You can split the configuration files into a separate commit, but what matters is that the rules are in effect when the assets are added , not that they were committed first.

4. Do not conclude "empty listing means success"

An empty git status --short after committing means there are no unrecorded changes. But it is also empty if you accidentally committed generated files. Check these listings too.

git ls-files -- Saved Intermediate DerivedDataCache Binaries
git lfs ls-files
git log -1 --oneline
  • The first command empty: the specified generated folders are not recorded.
  • Assets listed by the second: those files are recorded through LFS.
  • The last showing your commit message: this record was created.

To inspect the exclusion rules themselves, run something like git check-ignore -v Saved/Logs/check.log . It reports the rule matching that path even if the file does not exist.

5. Record one change

Open UE, add one Cube to the practice level, and save. Close the editor again and look at git status --short and git lfs status . The saved map and similar show up as changes.

Confirm the targets, then git add . and git commit -m "Add practice cube" . Two entries in git log -2 --oneline mean daily work records too, not just the setup.

In levels using World Partition, a mechanism handling large levels in pieces, separate Actor files change rather than the map itself. That is OFPA, explained later. Unfamiliar file names are not a reason to exclude changes without checking them.

Confirm it reopens from the shared destination

When using a remote, register a Git LFS-capable destination and push. Confirm both the Git history and the LFS real data uploaded successfully.

The receiving side installs Git LFS too and completes that user's setup with git lfs install . Clone into another folder, prepare the same UE version and required plugins, and being able to open .uproject confirms it is shareable. C++ projects also need a rebuild.

If the asset data did not arrive, check authentication and quota limits and then use git lfs pull inside the cloned repository.

Sponsored

Use locking when collaborating

Suppose two people edit the same door Blueprint. One changes the opening speed and the other adds a sound effect. Combining those two changes into one is a merge .

Source code can be compared line by line, but ordinary Git cannot read the nodes inside a .uasset and combine them as intended. On a conflict, one side is not silently discarded; a person has to decide which to adopt and how to reflect the other change .

So before editing, you reserve a file with a lock , saying "I am using this now". It is the mechanism for editing the same asset in turn.

Preparing to use locks

LFS supporting file transfer does not mean lock support; check that separately. It requires every team member's LFS configuration and lock support on the shared destination.

To switch to a locking workflow, add the lockable attribute to the targets below and commit and share the modified .gitattributes .

git lfs track --lockable "*.uasset"
git lfs track --lockable "*.umap"

lockable makes unlocked files read-only in the working folder. It does not mean "you will always get a warning". When you cannot save, it lets you check the lock status first.

Acquire the lock, edit and save, commit and push, then release. Confirm the push succeeded before releasing

From editing to releasing

Say you edit Content/Blueprints/BP_Door.uasset . With no local changes, fetch the shared destination's latest state and proceed in this order.

  1. Check usage with git lfs locks .
  2. Once git lfs lock Content/Blueprints/BP_Door.uasset succeeds, edit and save in UE.
  3. Review your changes and related files and commit.
  4. Confirm the push succeeded.
  5. Release with git lfs unlock Content/Blueprints/BP_Door.uasset .

Standard Git LFS does not release a lock on push alone. Release it so the next person can work. If you also added a new sound asset, record and send that too.

Locking is a mechanism used with aligned team tooling and procedures. It differs from permission management forbidding changes on someone else's PC by any means. Share who is responsible for what to avoid conflicts.

Split work with One File Per Actor

Consider someone fixing the lighting and someone else fixing enemy placement, both with the same level open. With everything in one map file, touching different Actors still means editing the same file.

One File Per Actor (OFPA) saves each level Actor's data into its own file. An Actor is a light or enemy you place in a level. With lighting and enemy placement in separate files, work overlaps less.

Comparing saving lighting and enemy placement into one map with OFPA saving each into its own Actor file

It is enabled by default in World Partition levels. Regular levels can enable it via "World Settings → Use External Actors". It changes an existing level's save structure, though, so test the conversion and sharing on a practice copy before adopting it.

What gets split is the placed Actors' data. If two people edit the same enemy Blueprint asset or move the same Actor, OFPA still conflicts. It does not eliminate map-level setting changes either.

Files under Content/__ExternalActors__/ and similar are necessary data despite unreadable names. Sending or reverting only the map can be insufficient. When adding or removing Actors, record the related files together.

Bonus: when you get the setup wrong

You already committed generated files

Writing .gitignore afterwards has no effect on tracked files. Check what is recorded with git ls-files first. For paths you confirmed are unnecessary generated files, git rm --cached untracks them while keeping the local file. Folders also need -r .

That excludes them from the next commit; it does not shrink past history. Do not run it across the whole project while unsure whether files are needed.

Switching to LFS partway

Adding LFS rules to files previously recorded with ordinary Git leaves past commits unchanged. To switch from now on, you need a step re-adding the targets after preparing the rules.

To convert past history there is a tool called git lfs migrate , but rewriting history changes commit identifiers. Back up your working files and history first and check whether it is already shared and how much you intend to convert. Do not assume repeating the initial setup commands solved it.

The LFS listing is empty

There may be no assets yet, the target extensions may differ, you may not have added them, or they may already be recorded with ordinary Git. Check the rules with git lfs track and inspect LFS-handled changes with git lfs status . Also check .gitattributes is in the right place.

The size keeps growing

Deleting an old large file from the current folder still keeps history if it exists in past commits. Old versions of the real data remain on the LFS side too, so manage the history you need against your storage. Not recording caches and generated files from the start helps here as well.

Summary

.gitignore excludes generated files and .gitattributes routes assets to LFS. Place the rules, then add, then verify with the listing of what is recorded. Keeping that order lets you explain your own first commit.

In collaboration, include acquiring and releasing locks in the work, and send the related OFPA files together. Finally, confirm it reopens in another working folder and move on to building the next gimmick.

Further Reading

Unreal Engine Notes in this section98