Forgotten a .meta file? Stop the line!

Keep Calm and Stop the Line

Many of the practices we see in Agile development originated in the field of Lean Manufacturing as pioneered by companies like Toyota.

One of the important ideas in Lean Manufacturing is “Stop the Line”. This empowers any member of the team to halt the production line if they detect quality issues.

While halting production can be a costly exercise, it ensures that quality issues are fixed rapidly before they accumulate, incurring even greater costs further down the line.

If you or a member of your team mistakenly adds an Asset to version control without its meta file, or vice versa, you can incur a variety of costly knock-on effects.

If the mistake goes unaddressed, the rest of team will continue to work on top of bad a commit, potentially overwriting settings and breaking references between Assets.

In this article we show how these kinds of commit mistakes lead to accumulated problems across the team and we should “Stop the Line”, halting further commits until they are dealt with.

 Heads up: Prevention is better than cure

If you can catch problems at source with processes or tooling you’ll save yourself a lot of time and frustration unpicking mistakes. We give a couple of good approaches to this here.

So what’s all the fuss about with meta files?

We’ve seen elsewhere in this guide that Unity does an admirable job of managing meta files for us, doing exactly what we expect whenever we add, rename, move and delete Assets.

It even uses the GUIDs in meta files to let us move and rename assets in the Editor without having to worry about breaking references.

Most of the difficulties arise when we makes change to files in our project from outside the Unity Editor, and this happens more often than you might think, even if you aren’t doing it explicitly.

A Tale of Two Developers

The most common case we see is when a developer forgets to commit the meta file for an asset. Here’s what we’ll see when that happens.

Imagine that a developer, Andrew adds a new asset to our Unity project. He imports it as a new Asset from within Unity creating a pair of files under Assets/Textures/ as follows:

➜  unity-meta-file-test git:(master) git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	Assets/Textures/Sad.png
	Assets/Textures/Sad.png.meta

nothing added to commit but untracked files present (use “git add” to track)

But, he makes a mistake and commits only the image file, forgetting the associated .meta file.

When this happens, Andrew probably won’t see anything wrong on his own machine. After all, he has both of the files for the Asset. Unfortunately his team mates don’t…

An Unexpected Change

Andrew’s colleague, Beatrice, updates her local repository with Andrew’s changes using git pull before opening the project in Unity.

At first glance everything looks fine. Andrew’s new image shows up in the Project window as we would expect:

Unity Asset in Project Window

But when Beatrice next run git status, she sees a new file that she didn’t expect:

➜  coworker-unity-meta-file-test git:(master) ✗ git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	Assets/Textures/Sad.png.meta

Beatrice has only opened the project in Unity after pulling Andrew’s changes. She hasn’t made any changes herself.

So why is git showing her that a new file Assets/Textures/Sad.png.meta has been created?

So what happened?

The Unity Editor has noticed Sad.png in the Assets folder, without an accompanying Sad.png.meta (because Andrew forgot to commit it).

When Unity encounters this situation, its behavior is pretty unhelpful. It silently creates a new meta file for the file that doesn’t already have one.

Unity has taken a guess at the appropriate import type for the file and created a new meta file for it using the default settings.

But here’s the thing, the resulting Asset is a different Asset to the one that Andrew created. The image is the same, but the meta file is different. This has a couple of negative consequences:

Missing Asset settings

The meta file contains the import settings for the Asset that Andrew configured in the Inspector window. Settings like Filter Mode or Max Size.

Unity meta file Inspector Equivalence

The new meta file that Unity created for us only contains default import settings. This means that the Asset may not be imported into the game as Andrew intended.

  • Maybe the team gets lucky and the incorrect settings are obvious when we they hit Play (ie. things look wrong in-game).
  • But maybe the difference is something less obvious (like the Max Size setting) and the project looks fine at first glance, while quietly using extra memory and rendering inefficiently.

Different GUID

While the Asset has the same name as the one that Andrew created, it has a different GUID. And that means it is actually a completely different asset in Unity’s eyes.

This means that any references to the Asset from elsewhere in the project will be silently broken, leading to our project to defects that may not be immediately obvious.

Unity broken reference between assets

  • If we’re lucky an eagle-eyed developer notices a broken reference while working in Unity Editor and raises it the attention of the team.
  • Maybe the breakage is obvious and a developer notices it as soon as they hit Play.
  • But maybe it gets caught in test a month later when everyone is up against a deadline and last thing anyone wants is another defect to fix 😧.

Quick “fixes” that brush the problem under the carpet

If Beatrice goes ahead and checks in the unexpected change, we have the makings of a bigger problem that is going to cost some time untangle.

Any references to Andrew’s asset will remain broken, but now we have a meta file in the project (not the correct meta file mind you) and the issue becomes more difficult to recognize and fix.

Let’s say that sometime later, Andrew notices his mistake and and commits the missing meta file. He adds and commits it locally, but next time he does a git pull he sees this:

➜  unity-meta-file-test git:(master) git pull
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 5 (delta 2), reused 5 (delta 2), pack-reused 0
Unpacking objects: 100% (5/5), done.
From github.com:unity-at-scale/unity-meta-file-test
   e199d54..c9e5a56  master     -> origin/master
CONFLICT (add/add): Merge conflict in Assets/Textures/Sad.png.meta
Auto-merging Assets/Textures/Sad.png.meta
Automatic merge failed; fix conflicts and then commit the result.

Now we have a conflict, with two different versions of the file that need to be resolved.

git diff shows us which lines are in conflict:

diff --cc Assets/Textures/Sad.png.meta
index 70d503d,4cba05d..0000000
--- a/Assets/Textures/Sad.png.meta
+++ b/Assets/Textures/Sad.png.meta
@@@ -1,5 -1,5 +1,9 @@@
  fileFormatVersion: 2
++<<<<<<< HEAD
 +guid: be713b9fcb4ce446daf73bb3bf7842e1
++=======
+ guid: 6194fc950260a4f23bca1652ec227db7
++>>>>>>> c9e5a5634f0f3d02ca11d39fe7e3cb710c384e71
  TextureImporter:
    internalIDToNameTable: []
    externalObjects: {}
(END)

Gulp, its the GUID that is in conflict, which one is correct?

be713b9fcb4ce446daf73bb3bf7842e1? 6194fc950260a4f23bca1652ec227db7?

No matter which one we choose, we will break any references to other one that we throw away.

The impact widens to more people in the team

If Andrew isn’t familiar with meta files, he’s going to need help from someone else in the team to help him progress.

Even with help, and careful checking for broken references, there’s fair odds that some references in the project are going to remain broken.

No doubt we’ll find them all eventually, but by the time we do so, we will have wasted a bunch of time that could have been used to make our game better.

From the simple mistake of forgetting to commit a meta file, we have caused interruption and friction for:

  • The original author of the change (Andrew)
  • Anyone who pulled the broken commit (Beatrice + others)
  • Those who helped Andrew to diagnose and fix the issue, most likely a Senior Developer or Technical Lead

Stop the line to nip problems in the bud, before they grow

We can avoid these kinds of knock-on effects by establishing a few simple rules for our team to observe:

  • When you notice a missing meta file, tell your teammates working in the affected branch to STOP THE LINE until it has been resolved.
  • This means no pushes to the affected branch until the all-clear is given.

Time is of the essence

How you notify the team this is up to you, but bear in mind that when these mistakes happen, time is of the essence.

So an email that might not get read for another hour or so won’t cut it.

We recommend you use something more “interuptful” to notify the team that the line needs to stop. Here are a few suggestions:

  • Get up from your desk and talk to the affected people IRL.
  • A group message in Slack (or whatever messaging app your team uses).

Some teams also add a note to their Scrum/Kanban board to signal that the line is stopped.

Once you have stopped the line and protected the project from further breakage, you need to find out who authored the commit that was missing the meta file and get them to commit it ASAP.

Diagnosing the issue

We can track down the missing file by looking at the commit history for the asset file that is missing its associated meta file.

You are looking for the author of the commit where the asset was added.

Here’s how that history looks in GitHub:

Commit with missing Unity meta file in Github

When you find the author of that commit, ask them to add, commit and push the missing meta file.

Then, get someone else on the team to do a clean pull from the remote repository and open the project in Unity.

If opening the project in Unity after a clean pull doesn’t generate any new changes, then you can restart the line, telling the team they can start committing changes again. (Don’t forget to tell the team once the excitement is over!)

Forgetting an Asset file

What happens if we make the opposite mistake, checking in the meta file, but not the Asset?

This is a bit more obvious because Unity raises a warning in the Console window to tell us that something is awry:

Unity missing Asset file for meta

A meta data file (.meta) exists but its asset ‘Assets/Textures/Cry.jpg’ can’t be found.

When moving or deleting files outside of Unity, please ensure that the corresponding .meta file is moved or deleted along with it.

But Unity also silently deletes the meta file, resulting in another unexpected change. In this case a deletion:

➜  unity-meta-file-test git:(master) ✗ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	deleted:    Assets/Textures/Cry.jpg.meta

no changes added to commit (use "git add" and/or "git commit -a")

Any references to the asset will be silently broken as they were in the missing meta file case.

The steps for rectifying this particular problem are essentially the same as those given above for fixing a missing meta file:

  • Stop the line.
  • Find the author of the missing asset.
  • Get the author to add the missing asset.
  • Restart the line

Summary

In this article we have seen how forgetting to commit an Asset file or it’s accompanying meta can cause our project to break.

We have also seen how that breakage can affect more than one person on the team and how more people will affected the longer it goes unfixed.

Finally, we have shown how stopping the line to fix the breakage quickly can limit the impact on the team. The steps are:

  1. Use tools or processes to catch mistakes before committing.

  2. Stop the line as soon as a missing Asset file is noticed.

  3. Use version control history to find the author of the missing Asset.

  4. Get the original author to add, commit and push the missing Asset.

  5. Get someone other than the original author to pull the fix and verify it on their machine.

  6. Once the fix is verified, restart the line

Prevention is better than cure

While stopping the line is a good way to limit the negative effects of a forgotten Asset file, we can do better by making sure they aren’t forgotten in the first place.

Pre-commit checklists are a low-tech yet effective way to help everyone in your team to check their work before committing.

Tool based automation takes checking to the next level. Tools save your team from working through checklists manually.

Find out how our MetaBuddy plugin helped one team eliminate meta file problems and save valuable time here.