الوحدة + البوابة = الصداقة: الجزء الأول من مجموعة النبلاء

صورة
أصبح نظام التحكم في إصدار git منذ فترة طويلة المعيار الفعلي في عالم التطوير ، ولكن بالنسبة لمعظم مطوري Unity ، ليس سراً أن هناك عددًا من الصعوبات المرتبطة بميزات Unity التي تمنع استخدامه بشكل فعال مع git.

فيما يلي قائمة بالمشكلات الشائعة:

  1. الملفات غير الضرورية تدخل إلى المستودع أو العكس لا تحصل على الملفات الصحيحة
  2. تضخم العديد من الملفات الكبيرة حجم المستودع
  3. مشكلة في دمج ملفات yaml Unity
  4. تتم إضافة الملف نفسه فقط أو التعريف فقط إلى المستودع
  5. هناك مجلدات فارغة في المشروع
  6. تعقيد الترقيم التلقائي للإصدارات والبنيات
  7. إزعاج استخدام التعليمات البرمجية بين مشاريع متعددة

يمكنك أن تقرأ عن حل هذه المشاكل المتعلقة بالاستخدام المشترك لـ git و Unity في سلسلة مقالاتي.

تصف هذه المقالة حل المشاكل الثلاث الأولى.

دعنا نحاول أن

نوضح في الخطوات طرق حل كل مشكلة. أول شيء يتعين علينا القيام به بعد إنشاء المستودع لمشروعك هو تكوين الاستثناءات ، لن أتطرق إلى هذا الأمر بتفصيل كبير ، هنا مثال جيد .

الملاحظة الوحيدة هي أنه ربما يجب عليك إضافة بعض الاستثناءات إلى النهاية
! * Dll - لأنه إذا كنت تستخدم المكونات الإضافية أو أصول الطرف الثالث ، فسيتعين عليك تخزين dll في المستودع وعلى Windows git يتجاهل dll بشكل افتراضي ؛
! *. obj - إذا كنت تستخدم نماذج بهذا التنسيق ، يمكن تجاهل ملفات obj windows افتراضيًا

الإصدار الخاص بي هو .gitignore
# This .gitignore file should be placed at the root of your Unity project directory
#
# Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore
#
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/[Ll]ogs/
/[Uu]ser[Ss]ettings/

# MemoryCaptures can get excessive in size.
# They also could contain extremely sensitive data
/[Mm]emoryCaptures/

# Asset meta data should only be ignored when the corresponding asset is also ignored
!/[Aa]ssets/**/*.meta

# Uncomment this line if you wish to ignore the asset store tools plugin
# /[Aa]ssets/AssetStoreTools*

# Autogenerated Jetbrains Rider plugin
/[Aa]ssets/Plugins/Editor/JetBrains*

# Visual Studio cache directory
.vs/

# Gradle cache directory
.gradle/

# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
*.opendb
*.VC.db

# Unity3D generated meta files
*.pidb.meta
*.pdb.meta
*.mdb.meta

# Unity3D generated file on crash reports
sysinfo.txt

# Builds
*.apk
*.unitypackage

# Crashlytics generated file
crashlytics-build.properties

# Packed Addressables
/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*

# Temporary auto-generated Android Assets
/[Aa]ssets/[Ss]treamingAssets/aa.meta
/[Aa]ssets/[Ss]treamingAssets/aa/*

# Exceptions
!*.dll
!*.obj


الخطوة الثانية سنحاول حل مشكلة نمو المستودعات من الملفات الكبيرة. هذا الحل هو LFS

المزيد عن LFS
LFS — git, git , key-value .

, git LFS checkout .

:
www.atlassian.com/git/tutorials/git-lfs

لتهيئة أنواع ملفات lfs لمستودعنا ، أضف .gitattributesبضعة أسطر إلى الملف في جذر المشروع (قد تضطر إلى إنشائه ، وقد لا يسمح لك Windows بإنشاء ملف باستخدام هذا في Explorer)

## git-lfs ##

#Image
*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.gif filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text
*.ai filter=lfs diff=lfs merge=lfs -text
*.tif filter=lfs diff=lfs merge=lfs -text
*.tga filter=lfs diff=lfs merge=lfs -text
*.cubemap filter=lfs diff=lfs merge=lfs -text
*.svg filter=lfs diff=lfs merge=lfs -text

#Audio
*.mp3 filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text
*.ogg filter=lfs diff=lfs merge=lfs -text

#Video
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.mov filter=lfs diff=lfs merge=lfs -text
*.webm filter=lfs diff=lfs merge=lfs -text

#3D Object
*.FBX filter=lfs diff=lfs merge=lfs -text
*.fbx filter=lfs diff=lfs merge=lfs -text
*.blend filter=lfs diff=lfs merge=lfs -text
*.obj filter=lfs diff=lfs merge=lfs -text

#ETC
*.a filter=lfs diff=lfs merge=lfs -text
*.exr filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text
*.unitypackage filter=lfs diff=lfs merge=lfs -text
*.aif filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.rns filter=lfs diff=lfs merge=lfs -text
*.reason filter=lfs diff=lfs merge=lfs -text
*.lxo filter=lfs diff=lfs merge=lfs -text

معظم الملفات الثنائية التي يمكن أن تكون كبيرة جدًا مدرجة هنا. سأشرح قليلاً:

السطور التي تبدأ بـ # هي تعليقات ،
filter=lfs diff=lfs merge=lfs- هذه كلمات سحرية تجعل استخدام git lfs لهذه الأنواع من الملفات ؛ يعني النص أن الملف ثنائي ولا تحتاج إلى دمجه.

إذا كان مشروعك يستخدم أي ملفات ثنائية كبيرة أخرى ، فقم بإضافتها هنا لاحقًا لتغيير نوع تخزين الملفات (النقل إلى lfs أو إزالته من هناك) سيكون صعبًا للغاية.

الخطوة التالية هي محاولة تحسين الوضع قليلاً مع عمليات الدمج المعقدة.
تتضمن الوحدة أداة UnityYAMLMerge ، والتي تتيح لك دمج ملفات yaml بشكل فعال. أضف .gitattributesبضعة أسطر إلى الملف :

*.cs diff=csharp text
*.cginc text
*.shader text

*.mat merge=unityyamlmerge
*.anim merge=unityyamlmerge
*.unity merge=unityyamlmerge
*.prefab merge=unityyamlmerge
*.physicsMaterial2D merge=unityyamlmerge
*.physicsMaterial merge=unityyamlmerge
*.asset merge=unityyamlmerge
*.meta merge=unityyamlmerge
*.controller merge=unityyamlmerge

اسمحوا لي أن أشرح ما قمنا به:
بالنسبة لملفات cs. اقترحوا أنه سيكون هناك نص هو رمز C # ؛
بالنسبة لملفات cginc و shader ، اختاروا أيضًا تمثيلًا نصيًا
لمعظم ملفات Unity yaml ، واختاروا برنامجًا مخصصًا لدمج برنامج unityamlmerge

تحتاج أيضًا إلى تهيئته: أضف التعليمات البرمجية التالية إلى أي. جذر المستودع:

[merge "unityyamlmerge"]
	name = Unity SmartMerge (UnityYamlMerge)
	driver = \"{    Unity}/Editor/Data/Tools/UnityYAMLMerge.exe\" merge -h -p --force --fallback none %O %B %A %A
	recursive = binary

يفرض العلم -p UnityYamlMerge على تغيير محتويات الملفات حتى إذا لم يتم حل التعارض تمامًا ، ويبسط إلى حد كبير حلها الإضافي يدويًا. على سبيل المثال ، عند دمج فرعين حيث تم تغيير المشهد نفسه ، باستخدام آلية دمج git القياسية ، سنرى العديد من التغييرات. عند استخدام برنامج تشغيل مخصص ، حتى إذا تم تغيير نفس الحقل لنفس المكون ، فسيكون هناك سطر واحد بالضبط في التعارض.

من أجل الراحة ، أنشأت نصًا صغيرًا يسمح بتثبيت وحدة التحكم بشكل تلقائي في المرة الأولى التي يتم فيها فتح المشروع بواسطة Unity. يمكن وضعه في أي مكان في مجلد الأصول (يتطلب تثبيت git على النظام وتسجيله في متغير PATH ، أي يمكن الوصول إليه بواسطة الأمر git) ؛

هذه الفئة
#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}";

        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();
        }

        [MenuItem("Tools/Git/SmartMerge registration")]
        static void SmartMergeRegister()
        {
            try
            {
                var UnityYAMLMergePath = EditorApplication.applicationContentsPath + "/Tools" + "/UnityYAMLMerge.exe";
                ExecuteGitWithParams("config merge.unityyamlmerge.name \"Unity SmartMerge (UnityYamlMerge)\"");
                ExecuteGitWithParams($"config merge.unityyamlmerge.driver \"\\\"{UnityYAMLMergePath}\\\" merge -h -p --force --fallback none %O %B %A %A\"");
                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

: , Unity , EditorPrefs «» , ( , Unity, ) git gitconfig .

النسخة النهائية من .gitattributes
## Unity ##

*.cs diff=csharp text
*.cginc text
*.shader text

*.mat merge=unityyamlmerge
*.anim merge=unityyamlmerge
*.unity merge=unityyamlmerge
*.prefab merge=unityyamlmerge
*.physicsMaterial2D merge=unityyamlmerge
*.physicsMaterial merge=unityyamlmerge
*.asset merge=unityyamlmerge
*.meta merge=unityyamlmerge
*.controller merge=unityyamlmerge


## git-lfs ##

#Image
*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.gif filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text
*.ai filter=lfs diff=lfs merge=lfs -text
*.tif filter=lfs diff=lfs merge=lfs -text
*.tga filter=lfs diff=lfs merge=lfs -text
*.cubemap filter=lfs diff=lfs merge=lfs -text
*.svg filter=lfs diff=lfs merge=lfs -text

#Audio
*.mp3 filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text
*.ogg filter=lfs diff=lfs merge=lfs -text

#Video
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.mov filter=lfs diff=lfs merge=lfs -text
*.webm filter=lfs diff=lfs merge=lfs -text

#3D Object
*.FBX filter=lfs diff=lfs merge=lfs -text
*.fbx filter=lfs diff=lfs merge=lfs -text
*.blend filter=lfs diff=lfs merge=lfs -text
*.obj filter=lfs diff=lfs merge=lfs -text

#ETC
*.a filter=lfs diff=lfs merge=lfs -text
*.exr filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text
*.unitypackage filter=lfs diff=lfs merge=lfs -text
*.aif filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.rns filter=lfs diff=lfs merge=lfs -text
*.reason filter=lfs diff=lfs merge=lfs -text
*.lxo filter=lfs diff=lfs merge=lfs -text


بعد الانتهاء من هذه الخطوات ، أوصي بشدة بتنفيذ الحالة الحالية للمستودع.

مشروع جاهز https://github.com/newnon/UnityGitHabr1
أذكرك مرة أخرى للعمل بشكل صحيح ، يجب تثبيت git في النظام ويمكن الوصول إليه عن طريق الأمر git.

إذا كنت ترغب في التجربة
github test1 test2 test3
merge test1 test2 test3
test2 test1 test3 m_LocalPosition
E Unity Tools/Git/

All Articles