Inspired by the question Ignoring folder meta files on version control I wrote a small bash script for git to be used as client side pre-commit hook (available on GitHub under MIT license). As it was my first git hook I wrote a short description.
Overview
The problem is to prevent users from adding a local test directory under Assets to file .gitignore but forget to add the according meta file to add as well. An example:
- MyProject/Assets/Test/LocalFolder
New folder that should not be under version control. - LocalTest.meta is created by Unity automatically
- The user adds the directory to .gitignore so there is one new line:
MyProject/Assets/Imports/LocalTest - But forgot to add LocalTest.meta to .gitignore which is created by Unity automatically
Download git-pre-commit-hook-unity-assets from GitHub and put the file pre-commit in the project’s .git/hooks directory. Ensure that it is executable (chmod a+x git-pre-commit). Works on Mac, Linux, but Windows users need to have Cygwin installed.
How It Works
First of all Unity docs say: „When creating new assets, make sure both the asset itself and the associated .meta file is added to version control“. I always try to conform to that kind of things although there are other people setting these files to be ignored in their version control system and of course looking into a .meta file seems to reveal no mogic at all. Anyway, I don’t see the great advantage in ignoring them and on other hand I never had problems with corrupted project files.
As said above client side hooks reside in .git/hooks sub-directory of the project root dir. According to 7.3 Customizing Git – Git Hooks they are fired on certain actions when there is an executable script matching the appropriate naming convention. The pre-commit hook is executed immediately after git commit has been called. If it returns anything other than 0 git commit aborts.
- Check if .gitignore is staged for commit using git diff –name-only –cached, which lists all file names of staged files.
- Read all changes from .gitignore into variable raw_diff_output to avoid unnecessary calls to diff. git diff –cached –word-diff=plain .gitignore retrieves all changes, new lines look like:
{+MyProject/Assets/Test/LocalFolder+} - Separate raw_diff_output into 2 string lists and check if every directory has a corresponding .meta entry
For my test I created 2 new folder under Assets/Test and added following new entries in .gitignore:
rrrunner/Assets/Test/LocalFolder
rrrunner/Assets/Test/ForgottenFolder
LocalFolder.meta
So ForgottenFolder.meta is missing. Now I try to commit with SourceTree, et voilá:
If you need to force a commit for whatever reason, you can check „Bypass commit hooks“ in the commit dialog.
It should work fine on a Mac but Windows users have to either install Cygwin or must port the bash script to another scripting language like Python or Ruby.
Feel free to leave your comments in the section below and clone the repository on GitHub.
Comments are closed.