Skip to content

feat: Unreal Engine support - One File Per Actor filename decoding#2068

Open
Jus2Cat wants to merge 1 commit intosourcegit-scm:developfrom
Jus2Cat:feature/ofpa-naming
Open

feat: Unreal Engine support - One File Per Actor filename decoding#2068
Jus2Cat wants to merge 1 commit intosourcegit-scm:developfrom
Jus2Cat:feature/ofpa-naming

Conversation

@Jus2Cat
Copy link

@Jus2Cat Jus2Cat commented Jan 25, 2026

This PR adds support for Unreal Engine's One File Per Actor system. It decodes hashe filenames
(e.g. KCBX0GWLTFQT9RJ8M1LY8.uasset) into human-readable view.

One-file-per-actor-git-support

This solves a major pain point for UE developers where file names are meaningless hash strings.

This makes it impossible to identify which actors have been modified without opening the Unreal Editor, causing significant workflow delays.
Currently, only one paid Git client offers a similar feature, and there are no free alternatives.

🛡️ Safety & Performance (Key Highlights)

  • Zero Overhead by Default: The feature is completely opt-in. All heavy logic is guarded by
    EnableUnrealEngineSupport. If disabled, this code path is never executed.
  • Memory Safe: Binary decoding is capped at 256KB per file. This prevents
    System.OutOfMemoryException and UI freezes, even if users modify huge binary assets (1GB+).
  • Batched Processing: Instead of spawning a process for every file, it uses git cat-file --batch
    to read Git objects. This makes it performant even with thousands of changes.
  • Caching: Decoded names are cached based on file size/timestamp to avoid redundant I/O on
    refresh.

🛠️ Changes

  1. Core: Added OFPAParser (custom binary reader for .uasset headers).
  2. ViewModel: Integrated async decoding into WorkingCopy.cs using Task.Run to keep UI responsive.
  3. UI: Added toggle in Repository Settings and Working Copy toolbar. Added specific icons for
    decoded files.
  4. Tests: Added comprehensive unit tests covering Parser edge cases and UI Converters.
  5. Locales: Added translations for English, Russian, and Chinese (Simplified).

One-file-per-actor-git-support-modes

  • Full View Support: Works across all three display modes: Tree, List, and Grid.
  • The feature is active only within Unreal Engine projects containing __ExternalActors__ or __ExternalObjects__ folders and a .uproject file.
  • Zero Clutter: For non-Unreal repositories, the OFPA toggle and icons are not displayed,
    ensuring no impact on the standard Git workflow.

@Jus2Cat Jus2Cat changed the base branch from master to develop January 25, 2026 19:04
@redsigma
Copy link

redsigma commented Jan 26, 2026

does the decoding also allow to show if the file is locked by someone ? It would be nice if it name shows
<actor name> - <locked by PersonX>

I think it would be useful to have that if possible

@Jus2Cat
Copy link
Author

Jus2Cat commented Jan 28, 2026

does the decoding also allow to show if the file is locked by someone ? It would be nice if it name shows <actor name> - <locked by PersonX>

I think it would be useful to have that if possible

Updated.

One-file-per-actor-git-lock-support

@redsigma
Copy link

redsigma commented Jan 30, 2026

@Jus2Cat Awesome work with this PR . I see you added a button to view the locked files in a separate window. I think this approach might be difficult to use if you have 50 locked files and you have to figure out which person locked it.

Would it be possible maybe to achieve one of the following:

  1. Locked files show with a different icon. Currently there is green (added), red(removed) , orange(modified). Maybe some icon like blue can be added ?

  2. Have the locked files be hidden from the commit list. And have a separate button to show them as well.

  3. Have separate button which checks every file in the staging, and lists the locked files and who has locked them.

@love-linger love-linger force-pushed the develop branch 2 times, most recently from 5142a5f to 62d2908 Compare February 3, 2026 10:59
@pabermod
Copy link

If File lock is independent from this functionality (And usable for other file type) I think is better to not mix it and do it in another PR?

Regards

@Jus2Cat
Copy link
Author

Jus2Cat commented Mar 9, 2026

Hi! I've rebased and significantly cleaned up this PR:

What changed:

  • Rebased onto latest develop
  • Removed unrelated changes (LFS locks, QueryFileContent, extra locales) — as suggested by @pabermod
  • Extracted OFPADecodingContext to eliminate ~250 lines of duplication across ViewModels
  • Added fallback to index/HEAD when working tree decode fails
  • Follows project code style conventions
  • Single checkbox in Repository Configuration instead of a separate section

Why this is safe to merge:

  • Zero overhead when disabled — all decode logic is behind an opt-in per-repo toggle, no code paths are hit for non-UE repos
  • No UI clutter — just one checkbox in settings, no extra UI when disabled
  • Safety — binary reads capped at 256KB, batched via git cat-file --batch, async with stale-guard
  • Tested — unit tests for parser across UE 5.3 / 5.6 / 5.7 formats

This solves a real pain point for Unreal Engine developers: OFPA generates opaque hash-based filenames that make it impossible to identify which actors changed without opening the editor. Currently no free Git client offers this.

Happy to split, simplify, or adjust anything. Would appreciate feedback on what would make this easier to review.

…r names

Unreal Engine's One File Per Actor (OFPA) system stores actors as files
with opaque hash-based names (e.g. `KCBX0GWLTFQT9RJ8M1LY8.uasset`),
making it impossible to identify modified actors without opening the editor.

This adds opt-in OFPA decoding that resolves these hashes to actor names
by reading the binary `.uasset` header. The feature is controlled by a
per-repository toggle in Repository Configuration.

Core:
- OFPAParser: binary reader for UE4/UE5 `.uasset` NameMap headers
- OFPAFilePrefixReader: reads only the first 256KB to avoid OOM on large assets
- OFPAGitBatchReader: uses `git cat-file --batch` for efficient bulk reads
- OFPANameLookup: async lookup with working-tree-first, index/HEAD fallback
- OFPADecodingContext: shared refresh/stale-guard logic used by all ViewModels

Integration:
- WorkingCopy, CommitDetail, StashesPage: async OFPA refresh via OFPADecodingContext
- ChangeCollectionView: display decoded names via OFPAConverters.PathToDisplayName
- RepositoryConfigure: `EnableOFPADecoding` toggle with explanatory tooltip

Tests:
- OFPAParserTests: decoding across UE 5.3, 5.6, 5.7 formats
- OFPAFilePrefixReaderTests: prefix reading and boundary conditions
- OFPANameLookupTests: working tree, index fallback, and revision object lookup
- OFPAConvertersTests: display name converter edge cases
@Jus2Cat Jus2Cat force-pushed the feature/ofpa-naming branch from 808da75 to 784975c Compare March 9, 2026 18:40
@Jus2Cat
Copy link
Author

Jus2Cat commented Mar 9, 2026

[Repository] to manually test the feature (no Unreal Engine needed):

The repo has 4 commits with ~210 OFPA files, including additions and deletions — enough to test all views (Local Changes, History, Stashes).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants