diff --git a/Assets/GitIntegration/GitHooks.meta b/Assets/GitIntegration/GitHooks.meta
new file mode 100644
index 0000000..d52d6e1
--- /dev/null
+++ b/Assets/GitIntegration/GitHooks.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 3be40ca8e152a494c8bbd3fb4e67a9f4
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/GitIntegration/GitHooks/Editor.meta b/Assets/GitIntegration/GitHooks/Editor.meta
new file mode 100644
index 0000000..e11cd40
--- /dev/null
+++ b/Assets/GitIntegration/GitHooks/Editor.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: bfbfef011bf613c4bb717b66949c6b89
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/GitIntegration/GitHooks/Editor/EmptyFolderCleaner.cs b/Assets/GitIntegration/GitHooks/Editor/EmptyFolderCleaner.cs
new file mode 100644
index 0000000..be7a0d0
--- /dev/null
+++ b/Assets/GitIntegration/GitHooks/Editor/EmptyFolderCleaner.cs
@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using UnityEditor;
+using UnityEngine;
+
+namespace GitIntegration
+{
+ ///
+ /// Cleans all the empty folders
+ ///
+ public class EmptyFolderCleaner
+ {
+ ///
+ /// Cleans empty folders and corresponding .meta files in the Assets folder
+ ///
+ [MenuItem("Tools/Git/Clean Empty Folders")]
+ public static void CleanEmptyFolders()
+ {
+ var directoryInfo = new DirectoryInfo(Application.dataPath).Parent;
+ if (directoryInfo == null)
+ {
+ return;
+ }
+
+ var assetsPath = Path.Combine(directoryInfo.ToString(), "assets");
+ Debug.Log($"Start cleaning: {assetsPath}");
+
+ var found = true; // TRUE means that at least one directory was deleted during the DeleteIteration(...)
+ while (found)
+ {
+ found = CleanIteration(assetsPath);
+ }
+
+ Debug.Log($"Finish cleaning: {assetsPath}");
+ }
+
+ ///
+ /// Deletes all the tail empty folders and corresponding metas
+ ///
+ /// Root folder
+ /// Returns true, if atl least one folder was deleted in the iteration
+ private static bool CleanIteration(string rootFolderPath)
+ {
+ var pending = new Queue();
+ pending.Enqueue(rootFolderPath);
+
+ var result = false;
+
+ while (pending.Count > 0)
+ {
+ rootFolderPath = pending.Dequeue();
+ string[] files;
+
+ try
+ {
+ files = Directory.GetFiles(rootFolderPath);
+ }
+ catch (UnauthorizedAccessException)
+ {
+ continue;
+ }
+
+ var foundCandidateDirectory =
+ files.Length == 0 || files.Length == 1 && files[0].ToLower().Contains(".meta");
+
+
+ var subDirectories = Directory.GetDirectories(rootFolderPath);
+
+ if (foundCandidateDirectory && subDirectories.Length == 0)
+ {
+ result = true;
+ var directoryInfo = new DirectoryInfo(rootFolderPath);
+ var parentFolder = directoryInfo.Parent.FullName;
+
+ var siblings = Directory.GetFiles(parentFolder);
+ foreach (var sibling in siblings)
+ {
+ // Ignore all the files except the directory .meta
+ if (!sibling.Contains(new DirectoryInfo(rootFolderPath).Name + ".meta"))
+ {
+ continue;
+ }
+
+
+ File.Delete(sibling);
+ Debug.LogWarning($"File {sibling} was deleted");
+ }
+
+ Debug.LogWarning($"Folder {rootFolderPath} was deleted");
+
+ Directory.Delete(rootFolderPath, true);
+ }
+ else // If the directory is not the tail one, add all the subirectories to the iteration
+ {
+ foreach (var t in subDirectories)
+ {
+ pending.Enqueue(t);
+ }
+ }
+ }
+
+ return result;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/GitIntegration/GitHooks/Editor/EmptyFolderCleaner.cs.meta b/Assets/GitIntegration/GitHooks/Editor/EmptyFolderCleaner.cs.meta
new file mode 100644
index 0000000..27d0336
--- /dev/null
+++ b/Assets/GitIntegration/GitHooks/Editor/EmptyFolderCleaner.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e614f70b98bd0fa4ba2e1c7ffe2e713a
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/GitIntegration/GitHooks/Editor/GitHooksInstaller.cs b/Assets/GitIntegration/GitHooks/Editor/GitHooksInstaller.cs
new file mode 100644
index 0000000..7926332
--- /dev/null
+++ b/Assets/GitIntegration/GitHooks/Editor/GitHooksInstaller.cs
@@ -0,0 +1,97 @@
+using UnityEngine;
+using UnityEditor;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Collections.Generic;
+using System;
+
+namespace GitIntegration
+{
+ [InitializeOnLoad]
+ public class GitHooksInstaller
+ {
+ const string HooksFolder = "hooks~";
+ const int Version = 2;
+
+ private static string GetThisFilePath([CallerFilePath] string path = null) => path;
+
+ private static string ResourcesPath = MakeResourcesPath();
+
+ static bool IsParentOrSame(string dir1, string dir2)
+ {
+ DirectoryInfo di1 = new DirectoryInfo(dir1);
+ DirectoryInfo di2 = new DirectoryInfo(dir2);
+ bool isParent = false;
+ while (di2 != null)
+ {
+ if (di2.FullName.Equals(di1.FullName))
+ {
+ isParent = true;
+ break;
+ }
+ else di2 = di2.Parent;
+ }
+ return isParent;
+ }
+
+ [MenuItem("Tools/Git/Install Hooks")]
+ public static void InstallHooks()
+ {
+ var filePath = GetThisFilePath();
+ var hooksPath = Path.Combine(Path.GetDirectoryName(filePath), HooksFolder);
+
+ var hooksDirectory = new DirectoryInfo(hooksPath);
+ var hookFiles = hooksDirectory.GetFiles();
+ var projectPath = new DirectoryInfo(Application.dataPath).Parent;
+
+ var assetsPath = Path.Combine(projectPath.FullName, "Assets");
+
+ var gitPath = Utils.FindGitFolder();
+ List submodules = new List();
+
+ try
+ {
+ var modulesStrings = File.ReadAllLines(Path.Combine(new DirectoryInfo(gitPath).Parent.FullName, ".gitmodules"));
+ for (int i = 0; i < modulesStrings.Length; i += 3)
+ {
+ var internalPath = modulesStrings[i].Substring(10, modulesStrings[i].Length - 11).Trim();
+ internalPath = internalPath.Substring(1, internalPath.Length - 2);
+ var externalPath = modulesStrings[i + 1].Split('=')[1].Trim();
+ if (IsParentOrSame(assetsPath, externalPath))
+ submodules.Add(internalPath);
+ }
+ }
+ catch (System.Exception)
+ {
+ }
+
+ foreach (var file in hookFiles)
+ {
+ if (!Path.GetExtension(file.FullName).Equals(".meta"))
+ {
+ File.Copy(file.FullName, Path.Combine(gitPath, "hooks", file.Name), true);
+ foreach (var submodule in submodules)
+ {
+ File.Copy(file.FullName, Path.Combine(gitPath, "modules", submodule, "hooks", file.Name), true);
+ }
+ }
+ }
+ Utils.WriteInstalledVersion(ResourcesPath, Version);
+ Debug.Log("Git hooks installed");
+ }
+
+ //Unity calls the static constructor when the engine opens
+ static GitHooksInstaller()
+ {
+ if (Utils.GetInstalledVersion(ResourcesPath) != Version)
+ InstallHooks();
+ }
+
+ private static string MakeResourcesPath()
+ {
+ var ret = Path.Combine(Directory.GetParent(GetThisFilePath()).FullName, "Resources", "GitHooks.asset");
+ var result = (new Uri(Application.dataPath)).MakeRelativeUri(new Uri(ret));
+ return result.ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/GitIntegration/GitHooks/Editor/GitHooksInstaller.cs.meta b/Assets/GitIntegration/GitHooks/Editor/GitHooksInstaller.cs.meta
new file mode 100644
index 0000000..996719e
--- /dev/null
+++ b/Assets/GitIntegration/GitHooks/Editor/GitHooksInstaller.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 37d25d0715bf3b1409f342a4ea7ecfcd
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/GitIntegration/GitHooks/Editor/Resources.meta b/Assets/GitIntegration/GitHooks/Editor/Resources.meta
new file mode 100644
index 0000000..5e1d5e8
--- /dev/null
+++ b/Assets/GitIntegration/GitHooks/Editor/Resources.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 4d4363b2396ebd542a6cb3de5aeb1bb0
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/GitIntegration/GitHooks/Editor/Resources/.gitignore b/Assets/GitIntegration/GitHooks/Editor/Resources/.gitignore
new file mode 100644
index 0000000..1e8ab26
--- /dev/null
+++ b/Assets/GitIntegration/GitHooks/Editor/Resources/.gitignore
@@ -0,0 +1,2 @@
+GitHooks.asset
+GitHooks.asset.meta
\ No newline at end of file
diff --git a/Assets/GitIntegration/GitHooks/Editor/hooks~/post-checkout b/Assets/GitIntegration/GitHooks/Editor/hooks~/post-checkout
new file mode 100644
index 0000000..51e214e
--- /dev/null
+++ b/Assets/GitIntegration/GitHooks/Editor/hooks~/post-checkout
@@ -0,0 +1,30 @@
+#!/bin/sh
+command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-checkout.\n"; exit 2; }
+git lfs post-checkout "$@"
+
+PREV_COMMIT=$1
+POST_COMMIT=$2
+
+# Grab a list of deleted files:
+changedFiles="$(git diff-tree -r --name-only --diff-filter=D --no-commit-id "$PREV_COMMIT" "$POST_COMMIT")"
+
+# Early exit if there are no removed files at all:
+if [ -z "$changedFiles" ]; then
+ exit 0
+fi
+
+# Get the list of dir paths and then sort and remove dupes:
+dirsToCheck="$(echo "$changedFiles" | xargs -d '\n' dirname | sort -u)"
+
+# For each dir check if its empty and if so, remove it:
+for dir in $dirsToCheck; do
+ if [ ! -d "$dir" ]; then
+ continue
+ fi
+
+ dirsRemovedCounter=$((dirsRemovedCounter+1))
+
+ find "$dir" -type d -empty -delete
+done
+
+echo "Removed" $dirsRemovedCounter "directories."
\ No newline at end of file
diff --git a/Assets/GitIntegration/GitHooks/Editor/hooks~/post-merge b/Assets/GitIntegration/GitHooks/Editor/hooks~/post-merge
new file mode 100644
index 0000000..ecb630a
--- /dev/null
+++ b/Assets/GitIntegration/GitHooks/Editor/hooks~/post-merge
@@ -0,0 +1,34 @@
+#!/bin/sh
+command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-merge.\n"; exit 2; }
+git lfs post-merge "$@"
+
+# Command line options:
+isSquashMerge="$1"
+
+dirsRemovedCounter=0
+
+echo "Removing empty directories..."
+
+# Grab a list of deleted files:
+changedFiles="$(git diff-tree -r --name-only --diff-filter=D --no-commit-id ORIG_HEAD HEAD)"
+
+# Early exit if there are no removed files at all:
+if [ -z "$changedFiles" ]; then
+ exit 0
+fi
+
+# Get the list of dir paths and then sort and remove dupes:
+dirsToCheck="$(echo "$changedFiles" | xargs -d '\n' dirname | sort -u)"
+
+# For each dir check if its empty and if so, remove it:
+for dir in $dirsToCheck; do
+ if [ ! -d "$dir" ]; then
+ continue
+ fi
+
+ dirsRemovedCounter=$((dirsRemovedCounter+1))
+
+ find "$dir" -type d -empty -delete
+done
+
+echo "Removed" $dirsRemovedCounter "directories."
\ No newline at end of file
diff --git a/Assets/GitIntegration/GitHooks/Editor/hooks~/pre-commit b/Assets/GitIntegration/GitHooks/Editor/hooks~/pre-commit
new file mode 100644
index 0000000..f5f50ed
--- /dev/null
+++ b/Assets/GitIntegration/GitHooks/Editor/hooks~/pre-commit
@@ -0,0 +1,115 @@
+#!/bin/bash
+#
+# An example hook script to verify what is about to be committed.
+# Called by "git commit" with no arguments. The hook should
+# exit with non-zero status after issuing an appropriate message if
+# it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-commit".
+
+skip_by_unity () {
+ path=$1
+ while [ $path != "/" -a $path != "." ]
+ do
+ filename="$(basename $path)"
+ path="$(dirname $path)"
+ if [ ${filename: 0: 1} == "." ] || [ ${filename: -1} == "~" ]; then
+ return 0
+ fi
+ done
+ return 1
+}
+
+ASSETS_DIR="$(git config --get unity3d.assets-dir || echo "Assets")"
+
+if [ ! -d "$ASSETS_DIR" ]; then
+ ASSETS_DIR="."
+fi
+
+if git rev-parse --verify HEAD >/dev/null 2>&1
+then
+ against=HEAD
+else
+ # Initial commit: diff against an empty tree object
+ against=04a52ddc5edd3d750b5ef328597afe4d2ac7e587
+fi
+
+# Redirect output to stderr.
+exec 1>&2
+
+git diff --cached --name-only --diff-filter=A -z $against -- "$ASSETS_DIR" | while read -d $'\0' f; do
+ ext="${f##*.}"
+ base="${f%.*}"
+
+ if [ "$ext" = "meta" ]; then
+ if [ $(git ls-files --cached -- "$base" | wc -l) = 0 ] && [ -d $base ] && [ ! -z "$(ls -A $base)" ]; then
+ cat < path;
+
+ private static string ResourcesPath = MakeResourcesPath();
+
+ [MenuItem("Tools/Git/SmartMerge registration")]
+ static void SmartMergeRegister()
+ {
+ try
+ {
+ var UnityYAMLMergePath = EditorApplication.applicationContentsPath + "/Tools" + UnityyamlmergeFileName;
+ Utils.ExecuteGitWithParams("config merge.unityyamlmerge.name \"Unity SmartMerge (UnityYamlMerge)\"");
+ Utils.ExecuteGitWithParams($"config merge.unityyamlmerge.driver \"\\\"{UnityYAMLMergePath}\\\" merge -h -p --force --fallback none %O %B %A %A\"");
+ Utils.ExecuteGitWithParams("config merge.unityyamlmerge.recursive binary");
+ Utils.WriteInstalledVersion(ResourcesPath, Version);
+ Debug.Log($"Successfully registered UnityYAMLMerge with path {UnityYAMLMergePath}");
+ }
+ catch (Exception e)
+ {
+ Debug.LogError($"Fail to register UnityYAMLMerge with error: {e}");
+ }
+ }
+
+ //Unity calls the static constructor when the engine opens
+ static SmartMergeRegistrator()
+ {;
+ if (Utils.GetInstalledVersion(ResourcesPath) != Version)
+ SmartMergeRegister();
+ }
+
+ private static string MakeResourcesPath()
+ {
+ var ret = Path.Combine(Directory.GetParent(GetThisFilePath()).FullName, "Resources", "SmartMergeRegistrator.asset");
+ var result = (new Uri(Application.dataPath)).MakeRelativeUri(new Uri(ret));
+ return result.ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/GitIntegration/SmartMerge/SmartMergeRegistrator.cs.meta b/Assets/GitIntegration/SmartMerge/Editor/SmartMergeRegistrator.cs.meta
similarity index 100%
rename from Assets/GitIntegration/SmartMerge/SmartMergeRegistrator.cs.meta
rename to Assets/GitIntegration/SmartMerge/Editor/SmartMergeRegistrator.cs.meta
diff --git a/Assets/GitIntegration/SmartMerge/SmartMergeRegistrator.cs b/Assets/GitIntegration/SmartMerge/SmartMergeRegistrator.cs
deleted file mode 100644
index e906e2f..0000000
--- a/Assets/GitIntegration/SmartMerge/SmartMergeRegistrator.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-#if UNITY_EDITOR
-using UnityEngine;
-using UnityEditor;
-using System;
-
-namespace GitIntegration
-{
- [InitializeOnLoad]
- public class SmartMergeRegistrator
- {
- const string SmartMergeRegistratorEditorPrefsKey = "smart_merge_installed";
- const int Version = 1;
- static string VersionKey = $"{Version}_{Application.unityVersion}";
-
- [MenuItem("Tools/Git/SmartMerge registration")]
- static void SmartMergeRegister()
- {
- try
- {
- var UnityYAMLMergePath = EditorApplication.applicationContentsPath + "/Tools" + "/UnityYAMLMerge.exe";
- Utils.ExecuteGitWithParams("config merge.unityyamlmerge.name \"Unity SmartMerge (UnityYamlMerge)\"");
- Utils.ExecuteGitWithParams($"config merge.unityyamlmerge.driver \"\\\"{UnityYAMLMergePath}\\\" merge -h -p --force --fallback none %O %B %A %A\"");
- Utils.ExecuteGitWithParams("config merge.unityyamlmerge.recursive binary");
- EditorPrefs.SetString(SmartMergeRegistratorEditorPrefsKey, VersionKey);
- Debug.Log($"Succesfuly registered UnityYAMLMerge with path {UnityYAMLMergePath}");
- }
- catch (Exception e)
- {
- Debug.Log($"Fail to register UnityYAMLMerge with error: {e}");
- }
- }
-
- //Unity calls the static constructor when the engine opens
- static SmartMergeRegistrator()
- {
- var instaledVersionKey = EditorPrefs.GetString(SmartMergeRegistratorEditorPrefsKey);
- if (instaledVersionKey != VersionKey)
- SmartMergeRegister();
- }
- }
-}
-#endif
\ No newline at end of file
diff --git a/Assets/GitIntegration/Utils.cs b/Assets/GitIntegration/Utils.cs
deleted file mode 100644
index 95012a9..0000000
--- a/Assets/GitIntegration/Utils.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-
-namespace GitIntegration
-{
- public class Utils
- {
- public static string ExecuteGitWithParams(string param)
- {
- var processInfo = new System.Diagnostics.ProcessStartInfo("git");
-
- processInfo.UseShellExecute = false;
- processInfo.WorkingDirectory = Environment.CurrentDirectory;
- processInfo.RedirectStandardOutput = true;
- processInfo.RedirectStandardError = true;
- processInfo.CreateNoWindow = true;
-
- var process = new System.Diagnostics.Process();
- process.StartInfo = processInfo;
- process.StartInfo.FileName = "git";
- process.StartInfo.Arguments = param;
- process.Start();
- process.WaitForExit();
-
- if (process.ExitCode != 0)
- throw new Exception(process.StandardError.ReadLine());
-
- return process.StandardOutput.ReadLine();
- }
- }
-}
\ No newline at end of file
diff --git a/Assets/GitIntegration/Utils.meta b/Assets/GitIntegration/Utils.meta
new file mode 100644
index 0000000..0f61a6a
--- /dev/null
+++ b/Assets/GitIntegration/Utils.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 5541d769b7995464eb5f1241283b30a3
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/GitIntegration/Utils/Editor.meta b/Assets/GitIntegration/Utils/Editor.meta
new file mode 100644
index 0000000..02d0bfb
--- /dev/null
+++ b/Assets/GitIntegration/Utils/Editor.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 31beed2acb2659541b553ac0bb30ee11
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/GitIntegration/Utils/Editor/InstalledVersionManifest.cs b/Assets/GitIntegration/Utils/Editor/InstalledVersionManifest.cs
new file mode 100644
index 0000000..1298473
--- /dev/null
+++ b/Assets/GitIntegration/Utils/Editor/InstalledVersionManifest.cs
@@ -0,0 +1,12 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEditor;
+using UnityEngine;
+
+namespace GitIntegration
+{
+ public class InstalledVersionManifest : ScriptableObject
+ {
+ public int Version;
+ }
+}
diff --git a/Assets/GitIntegration/Utils/Editor/InstalledVersionManifest.cs.meta b/Assets/GitIntegration/Utils/Editor/InstalledVersionManifest.cs.meta
new file mode 100644
index 0000000..77a182f
--- /dev/null
+++ b/Assets/GitIntegration/Utils/Editor/InstalledVersionManifest.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 21b2c0b4e96602e4b87e8d6a9718ecfc
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/GitIntegration/Utils/Editor/Utils.cs b/Assets/GitIntegration/Utils/Editor/Utils.cs
new file mode 100644
index 0000000..00b3153
--- /dev/null
+++ b/Assets/GitIntegration/Utils/Editor/Utils.cs
@@ -0,0 +1,68 @@
+using System;
+using System.IO;
+using UnityEditor;
+using UnityEngine;
+
+namespace GitIntegration
+{
+ public class Utils
+ {
+ public static int GetInstalledVersion(string path)
+ {
+ var oldManifest = AssetDatabase.LoadAssetAtPath(path);
+ if (oldManifest)
+ return oldManifest.Version;
+ else
+ return 0;
+ }
+
+ public static void WriteInstalledVersion(string path, int version)
+ {
+ var manifest = ScriptableObject.CreateInstance();
+ manifest.Version = version;
+ AssetDatabase.CreateAsset(manifest, path);
+ }
+
+ public class ExitCodeException : Exception
+ {
+ public ExitCodeException(string message) : base(message) {}
+ }
+
+ public static string ExecuteGitWithParams(string param)
+ {
+ var processInfo = new System.Diagnostics.ProcessStartInfo("git");
+
+ processInfo.UseShellExecute = false;
+ processInfo.WorkingDirectory = Environment.CurrentDirectory;
+ processInfo.RedirectStandardOutput = true;
+ processInfo.RedirectStandardError = true;
+ processInfo.CreateNoWindow = true;
+
+ var process = new System.Diagnostics.Process();
+ process.StartInfo = processInfo;
+ process.StartInfo.FileName = "git";
+ process.StartInfo.Arguments = param;
+ process.Start();
+ process.WaitForExit();
+
+ if (process.ExitCode != 0)
+ throw new ExitCodeException("gir error: " + process.StandardError.ReadLine());
+
+ return process.StandardOutput.ReadLine();
+ }
+ public static string FindGitFolder()
+ {
+ var dirInfo = new DirectoryInfo(Application.dataPath);
+ while (dirInfo.Parent != null)
+ {
+ dirInfo = dirInfo.Parent;
+ var gitDir = dirInfo.GetDirectories(".git", SearchOption.TopDirectoryOnly);
+ if (gitDir.Length > 0)
+ {
+ return gitDir[0].FullName;
+ }
+ }
+ throw new Exception(".git folder cannot be found");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/GitIntegration/Utils.cs.meta b/Assets/GitIntegration/Utils/Editor/Utils.cs.meta
similarity index 100%
rename from Assets/GitIntegration/Utils.cs.meta
rename to Assets/GitIntegration/Utils/Editor/Utils.cs.meta
diff --git a/Assets/GitIntegration/Version.meta b/Assets/GitIntegration/Version.meta
new file mode 100644
index 0000000..2d9c79d
--- /dev/null
+++ b/Assets/GitIntegration/Version.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 7629f594033470f48a61eb36421c25c3
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/GitIntegration/Version/Editor.meta b/Assets/GitIntegration/Version/Editor.meta
new file mode 100644
index 0000000..a3efb43
--- /dev/null
+++ b/Assets/GitIntegration/Version/Editor.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b94faebdde9bad846aedee7c7cfa9a8f
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/GitIntegration/Version/Editor/VersionGenerator.cs b/Assets/GitIntegration/Version/Editor/VersionGenerator.cs
new file mode 100644
index 0000000..c1bd5dd
--- /dev/null
+++ b/Assets/GitIntegration/Version/Editor/VersionGenerator.cs
@@ -0,0 +1,112 @@
+using System;
+using System.IO;
+using System.Runtime.CompilerServices;
+using UnityEditor;
+using UnityEngine;
+
+namespace GitIntegration
+{
+ static public class VersionGenerator
+ {
+ public static string VersionString { get; private set; } = VersionHelper.UNDEFINED_VERSION;
+ public static string ShortVersion { get; private set; } = VersionHelper.UNDEFINED_SHORT_VERSION;
+ public static string BranchName { get; private set; } = VersionHelper.UNKNOWN_BRANCH;
+ public static string BuildType { get; private set; } = VersionHelper.UNKNOWN_BUILD_TYPE;
+
+ private static string GetThisFilePath([CallerFilePath] string path = null) => path;
+
+ private static string ManifestPath = MakeManifestPath();
+
+ private static string MakeManifestPath()
+ {
+ var ret = Path.Combine(Directory.GetParent(GetThisFilePath()).Parent.FullName, "Resources", "VersionManifest.asset");
+ var result = (new Uri(Application.dataPath)).MakeRelativeUri(new Uri(ret));
+ return result.ToString();
+ }
+
+ static void SetVersions()
+ {
+ try
+ {
+ BranchName = Utils.ExecuteGitWithParams("rev-parse --abbrev-ref HEAD");
+ }
+ catch (Exception e)
+ {
+ Debug.LogError($"Can't read branch name with error: {e}");
+ return;
+ }
+ string latestTag;
+ try
+ {
+ latestTag = Utils.ExecuteGitWithParams("describe --tags --match v* --abbrev=0");
+ }
+ catch (Exception e)
+ {
+ Debug.LogError($"Can't find tag with error: {e}");
+ return;
+ }
+
+ string commitCount = Utils.ExecuteGitWithParams(string.Format("rev-list --no-merges --count --invert-grep --grep=@skip_version --all-match {0}", latestTag.Length == 0 ? "HEAD" : String.Format("{0}..", latestTag)));
+
+ string versionTag = latestTag.Remove(0, 1);
+
+ if (BranchName.StartsWith("release/"))
+ {
+ var temp = BranchName.Remove(0, "release/".Length);
+ var version = Version.Parse(temp);
+ ShortVersion = VersionString = string.Format("{0}.{1}.{2}", version.Major, version.Minor, commitCount);
+ BuildType = "release";
+ }
+ else if (BranchName.StartsWith("feature/"))
+ {
+ var temp = BranchName.Remove(0, "feature/".Length);
+ VersionString = string.Format("{1}-{0}.{2}", versionTag, temp, commitCount);
+ ShortVersion = string.Format("{0}.{1}", versionTag, commitCount);
+ BuildType = "feature";
+ }
+ else if (BranchName.StartsWith("hotfix/"))
+ {
+ var temp = BranchName.Remove(0, "hotfix/".Length);
+ VersionString = string.Format("{1}-{0}.{2}", versionTag, temp, commitCount);
+ ShortVersion = string.Format("{0}.{1}", versionTag, commitCount);
+ BuildType = "hotfix";
+ }
+ else
+ {
+ VersionString = string.Format("{1}-{0}.{2}", versionTag, BranchName, commitCount);
+ ShortVersion = string.Format("{0}.{1}", versionTag, commitCount);
+ BuildType = "dev";
+ }
+ }
+
+ [MenuItem("Tools/Git/Print version")]
+ static void PrintBuildNumber()
+ {
+ Debug.Log($"VersionString: {VersionString}");
+ Debug.Log($"BranchName: {BranchName}");
+ Debug.Log($"ShortVersion: {ShortVersion}");
+ }
+
+ static void WriteVersionManifest()
+ {
+ var oldManifest = AssetDatabase.LoadAssetAtPath(ManifestPath);
+ if (oldManifest && oldManifest.VersionString == VersionString)
+ return;
+
+ var manifest = ScriptableObject.CreateInstance();
+ manifest.VersionString = VersionString;
+ manifest.ShortVersion = ShortVersion;
+ manifest.BranchName = BranchName;
+ manifest.BuildType = BuildType;
+ AssetDatabase.CreateAsset(manifest, ManifestPath);
+ }
+
+ [InitializeOnLoadMethod]
+ static void OnProjectLoadedInEditor()
+ {
+ SetVersions();
+ WriteVersionManifest();
+ PrintBuildNumber();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/GitIntegration/Version/Editor/VersionGenerator.cs.meta b/Assets/GitIntegration/Version/Editor/VersionGenerator.cs.meta
new file mode 100644
index 0000000..27a2d81
--- /dev/null
+++ b/Assets/GitIntegration/Version/Editor/VersionGenerator.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 2fb67bd52f20627438d74c5ea50fd006
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/GitIntegration/Version/Resources.meta b/Assets/GitIntegration/Version/Resources.meta
new file mode 100644
index 0000000..8d73f48
--- /dev/null
+++ b/Assets/GitIntegration/Version/Resources.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b382fda04a2c85044940a5ddf69d9d18
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/GitIntegration/Version/Resources/.gitignore b/Assets/GitIntegration/Version/Resources/.gitignore
new file mode 100644
index 0000000..d5e24c6
--- /dev/null
+++ b/Assets/GitIntegration/Version/Resources/.gitignore
@@ -0,0 +1,2 @@
+VersionManifest.asset
+VersionManifest.asset.meta
\ No newline at end of file
diff --git a/Assets/GitIntegration/Version/VersionHelper.cs b/Assets/GitIntegration/Version/VersionHelper.cs
new file mode 100644
index 0000000..4cb11db
--- /dev/null
+++ b/Assets/GitIntegration/Version/VersionHelper.cs
@@ -0,0 +1,37 @@
+using UnityEngine;
+
+namespace GitIntegration
+{
+ public static class VersionHelper
+ {
+ public const string UNDEFINED_VERSION = "undefined";
+ public const string UNKNOWN_BRANCH = "unknown";
+ public const string UNDEFINED_SHORT_VERSION = "0.0";
+ public const string UNKNOWN_BUILD_TYPE = "unknown";
+
+ public static string VersionString { get; }
+ public static string ShortVersion { get; }
+ public static string BranchName { get; }
+ public static string BuildType { get; }
+
+ static VersionHelper()
+ {
+ var versionManifest = Resources.Load("VersionManifest");
+ if (versionManifest != null)
+ {
+ VersionString = versionManifest.VersionString;
+ ShortVersion = versionManifest.ShortVersion;
+ BranchName = versionManifest.BranchName;
+ BuildType = versionManifest.BuildType;
+ }
+ else
+ {
+ VersionString = UNDEFINED_VERSION;
+ ShortVersion = UNDEFINED_SHORT_VERSION;
+ BranchName = UNKNOWN_BRANCH;
+ BuildType = UNKNOWN_BUILD_TYPE;
+ }
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/GitIntegration/Version/VersionHelper.cs.meta b/Assets/GitIntegration/Version/VersionHelper.cs.meta
new file mode 100644
index 0000000..ac0eb6c
--- /dev/null
+++ b/Assets/GitIntegration/Version/VersionHelper.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 1ee19d709f2978748902553974303bb4
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/GitIntegration/Version/VersionManifest.cs b/Assets/GitIntegration/Version/VersionManifest.cs
new file mode 100644
index 0000000..9de6d48
--- /dev/null
+++ b/Assets/GitIntegration/Version/VersionManifest.cs
@@ -0,0 +1,9 @@
+using UnityEngine;
+
+public class VersionManifest : ScriptableObject
+{
+ public string VersionString;
+ public string ShortVersion;
+ public string BranchName;
+ public string BuildType;
+}
diff --git a/Assets/GitIntegration/Version/VersionManifest.cs.meta b/Assets/GitIntegration/Version/VersionManifest.cs.meta
new file mode 100644
index 0000000..d139f78
--- /dev/null
+++ b/Assets/GitIntegration/Version/VersionManifest.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 651f9cc86d27ea246a172332ac7a98e3
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/manifest.json b/Packages/manifest.json
index 46d26f4..be7b6e1 100644
--- a/Packages/manifest.json
+++ b/Packages/manifest.json
@@ -4,8 +4,8 @@
"com.unity.2d.tilemap": "1.0.0",
"com.unity.collab-proxy": "1.2.16",
"com.unity.ide.rider": "1.1.4",
- "com.unity.ide.vscode": "1.1.4",
- "com.unity.test-framework": "1.1.11",
+ "com.unity.ide.vscode": "1.2.3",
+ "com.unity.test-framework": "1.1.20",
"com.unity.textmeshpro": "2.0.1",
"com.unity.timeline": "1.2.12",
"com.unity.ugui": "1.0.0",
diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json
new file mode 100644
index 0000000..557a092
--- /dev/null
+++ b/Packages/packages-lock.json
@@ -0,0 +1,324 @@
+{
+ "dependencies": {
+ "com.unity.2d.sprite": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.2d.tilemap": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.collab-proxy": {
+ "version": "1.2.16",
+ "depth": 0,
+ "source": "registry",
+ "dependencies": {},
+ "url": "https://packages.unity.com"
+ },
+ "com.unity.ext.nunit": {
+ "version": "1.0.6",
+ "depth": 1,
+ "source": "registry",
+ "dependencies": {},
+ "url": "https://packages.unity.com"
+ },
+ "com.unity.ide.rider": {
+ "version": "1.1.4",
+ "depth": 0,
+ "source": "registry",
+ "dependencies": {
+ "com.unity.test-framework": "1.1.1"
+ },
+ "url": "https://packages.unity.com"
+ },
+ "com.unity.ide.vscode": {
+ "version": "1.2.3",
+ "depth": 0,
+ "source": "registry",
+ "dependencies": {},
+ "url": "https://packages.unity.com"
+ },
+ "com.unity.test-framework": {
+ "version": "1.1.20",
+ "depth": 0,
+ "source": "registry",
+ "dependencies": {
+ "com.unity.ext.nunit": "1.0.6",
+ "com.unity.modules.imgui": "1.0.0",
+ "com.unity.modules.jsonserialize": "1.0.0"
+ },
+ "url": "https://packages.unity.com"
+ },
+ "com.unity.textmeshpro": {
+ "version": "2.0.1",
+ "depth": 0,
+ "source": "registry",
+ "dependencies": {
+ "com.unity.ugui": "1.0.0"
+ },
+ "url": "https://packages.unity.com"
+ },
+ "com.unity.timeline": {
+ "version": "1.2.12",
+ "depth": 0,
+ "source": "registry",
+ "dependencies": {},
+ "url": "https://packages.unity.com"
+ },
+ "com.unity.ugui": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.ui": "1.0.0",
+ "com.unity.modules.imgui": "1.0.0"
+ }
+ },
+ "com.unity.modules.ai": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.androidjni": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.animation": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.assetbundle": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.audio": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.cloth": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.physics": "1.0.0"
+ }
+ },
+ "com.unity.modules.director": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.audio": "1.0.0",
+ "com.unity.modules.animation": "1.0.0"
+ }
+ },
+ "com.unity.modules.imageconversion": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.imgui": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.jsonserialize": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.particlesystem": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.physics": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.physics2d": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.screencapture": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.imageconversion": "1.0.0"
+ }
+ },
+ "com.unity.modules.subsystems": {
+ "version": "1.0.0",
+ "depth": 1,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.jsonserialize": "1.0.0"
+ }
+ },
+ "com.unity.modules.terrain": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.terrainphysics": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.physics": "1.0.0",
+ "com.unity.modules.terrain": "1.0.0"
+ }
+ },
+ "com.unity.modules.tilemap": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.physics2d": "1.0.0"
+ }
+ },
+ "com.unity.modules.ui": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.uielements": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.imgui": "1.0.0",
+ "com.unity.modules.jsonserialize": "1.0.0"
+ }
+ },
+ "com.unity.modules.umbra": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.unityanalytics": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.unitywebrequest": "1.0.0",
+ "com.unity.modules.jsonserialize": "1.0.0"
+ }
+ },
+ "com.unity.modules.unitywebrequest": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.unitywebrequestassetbundle": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.assetbundle": "1.0.0",
+ "com.unity.modules.unitywebrequest": "1.0.0"
+ }
+ },
+ "com.unity.modules.unitywebrequestaudio": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.unitywebrequest": "1.0.0",
+ "com.unity.modules.audio": "1.0.0"
+ }
+ },
+ "com.unity.modules.unitywebrequesttexture": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.unitywebrequest": "1.0.0",
+ "com.unity.modules.imageconversion": "1.0.0"
+ }
+ },
+ "com.unity.modules.unitywebrequestwww": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.unitywebrequest": "1.0.0",
+ "com.unity.modules.unitywebrequestassetbundle": "1.0.0",
+ "com.unity.modules.unitywebrequestaudio": "1.0.0",
+ "com.unity.modules.audio": "1.0.0",
+ "com.unity.modules.assetbundle": "1.0.0",
+ "com.unity.modules.imageconversion": "1.0.0"
+ }
+ },
+ "com.unity.modules.vehicles": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.physics": "1.0.0"
+ }
+ },
+ "com.unity.modules.video": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.audio": "1.0.0",
+ "com.unity.modules.ui": "1.0.0",
+ "com.unity.modules.unitywebrequest": "1.0.0"
+ }
+ },
+ "com.unity.modules.vr": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.jsonserialize": "1.0.0",
+ "com.unity.modules.physics": "1.0.0",
+ "com.unity.modules.xr": "1.0.0"
+ }
+ },
+ "com.unity.modules.wind": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {}
+ },
+ "com.unity.modules.xr": {
+ "version": "1.0.0",
+ "depth": 0,
+ "source": "builtin",
+ "dependencies": {
+ "com.unity.modules.physics": "1.0.0",
+ "com.unity.modules.jsonserialize": "1.0.0",
+ "com.unity.modules.subsystems": "1.0.0"
+ }
+ }
+ }
+}
diff --git a/ProjectSettings/PackageManagerSettings.asset b/ProjectSettings/PackageManagerSettings.asset
new file mode 100644
index 0000000..6920e3a
--- /dev/null
+++ b/ProjectSettings/PackageManagerSettings.asset
@@ -0,0 +1,38 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!114 &1
+MonoBehaviour:
+ m_ObjectHideFlags: 61
+ m_CorrespondingSourceObject: {fileID: 0}
+ m_PrefabInstance: {fileID: 0}
+ m_PrefabAsset: {fileID: 0}
+ m_GameObject: {fileID: 0}
+ m_Enabled: 1
+ m_EditorHideFlags: 0
+ m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0}
+ m_Name:
+ m_EditorClassIdentifier:
+ m_ScopedRegistriesSettingsExpanded: 1
+ oneTimeWarningShown: 0
+ m_Registries:
+ - m_Id: main
+ m_Name:
+ m_Url: https://packages.unity.com
+ m_Scopes: []
+ m_IsDefault: 1
+ m_UserSelectedRegistryName:
+ m_UserAddingNewScopedRegistry: 0
+ m_RegistryInfoDraft:
+ m_ErrorMessage:
+ m_Original:
+ m_Id:
+ m_Name:
+ m_Url:
+ m_Scopes: []
+ m_IsDefault: 0
+ m_Modified: 0
+ m_Name:
+ m_Url:
+ m_Scopes:
+ -
+ m_SelectedScopeIndex: 0
diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt
index e51db95..acbe3fd 100644
--- a/ProjectSettings/ProjectVersion.txt
+++ b/ProjectSettings/ProjectVersion.txt
@@ -1,2 +1,2 @@
-m_EditorVersion: 2019.3.5f1
-m_EditorVersionWithRevision: 2019.3.5f1 (d691e07d38ef)
+m_EditorVersion: 2019.4.19f1
+m_EditorVersionWithRevision: 2019.4.19f1 (ca5b14067cec)