感谢原作者https://www.cnblogs.com/murongxiaopifu/p/6086849.html

0x00 前言


目前所在的团队实行敏捷开发已经有了一段时间了。敏捷开发中重要的一个话题便是如何对项目进行恰当的版本管理。项目从最初使用svn到之后的Git One Track策略再到现在的GitFlow策略,中间有经验也有教训,所以记录在本文,既是和各位朋友交流也供自己日后查阅。

0x01 基础:Unity项目如何做版本管理?

为什么更喜欢git?

初来项目组到时候,项目还在使用SVN作为版本管理的工具。作为一个不喜欢SVN的人,自然而然想到了换用git来做版本管理。这里当然并不是说svn不如git好,只是它们的思路的确是不一样的。
与SVN相比,git是一个分布式的版本管理工具。这一点可能是我喜欢git胜过svn的一个决定性原因。
当我们使用git从远端版本库/服务器上chect out代码后,git会在自己的机器上克隆一个自己的本地版本库。这样我们在本地就实现了版本的管理,而不必像svn那样必须和服务器连接。举一个例子,当我们在本地开发自己的功能时一旦不小心有了错误的操作,我们只需要在本地进行版本回退即可。如果使用svn的话,这种问题的修改似乎就变得不那么方便了。
喜欢git的另一个原因就是使用git的分支了。我们可以在本地的同一个工作目录下快速的切换不同的分支,每个分支之间都是隔离的。当我们不想影响主分支的时候,可以十分轻松的利用git创建一个新的分支进行开发。
总之,使用git替换svn作为团队的新的版本管理工具之后,团队的开发效率提高了很多。

git和Unity

既然项目组决定采用git作为新的版本管理工具,那么首先的一点就是我们要先确认哪些文件是需要纳入版本管理的。同时,在确认需要管理的文件时,顺便重新规整一下整个项目的目录结构,不仅仅是为了更加便于git进行版本管理,同时也可以更好的维护项目。

上图便是一个典型的Unity项目的默认目录。我们可以看到默认的Unity项目的目录下就已经有很多文件和文件夹了。
但是,作为版本管理,我们通常只需要关注两个文件夹即可。即:Assets文件夹和ProjectSettings文件夹。
其中,Assets文件夹主要用来存放项目的资源,例如脚本文件、贴图、材质、声音资源等等。
而ProjectSettings文件夹则用来存放一些项目的设置,例如输入设置、物理系统的设置、Player设置、Layer、Tags等等。我们可以在Unity的编辑器中的Edit->Project Settings菜单来调整这些设置信息。
默认目录下的其余文件或文件夹都可以由这两个文件夹的内容生成出来。
例如,如果Assets文件夹中包括C#脚本文件,则Unity会在目录生成C#工程文件Assembly-CSharp.csproj。

除此之外, Unity的一些特殊的文件夹也会生成一些工程文件。例如Editor文件夹内如果有C#脚本,则会生成一个Assembly-CSharp-Editor工程文件。
除了这些工程文件之外,Unity还会生成一些文件夹。例如Library、Temp、obj这三个文件夹。它们同样是Unity自动生成的。

Library文件夹的内容主要是在项目中导入资源时产生的一些本地的缓存。
Temp和obj这两个文件夹则是在项目构建时产生的临时文件。
因此,我们可以通过git的.gitignore文件来将不需要被git管理的文件/文件夹添加到忽略列表。下面是github提供的一份适用于Unity项目的.gitignore文件列表。

/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/Assets/AssetStoreTools*# Autogenerated VS/MD/Consulo solution and project files
ExportedObj/
.consulo/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd# Unity3D generated meta files
*.pidb.meta# Unity3D Generated File On Crash Reports
sysinfo.txt# Builds
*.apk
*.unitypackage

除此之外,我们还需要将Unity为导入资源生成的.meta文件也纳入版本管理,和相应的资源一同维护。meta文件的重要性在于Unity会利用它来处理对应资源之间的引用关系。

为了处理资源之间的引用关系,Unity在序列化时会通过两个数据来保证正确的引用关系。即文件GUID和以及本地ID,其中文件GUID便保存在meta文件中。

fileFormatVersion: 2
guid: 437eb1afce72bb44ca24c6ac3fe90c1d
timeCreated: 1453720237
licenseType: Store
NativeFormatImporter:userData: assetBundleName: assetBundleVariant:

只要使用文本工具打开meta文件即可以看到其内容。

另外还需要注意到的事情便是git版本管理时的文件冲突问题。通常当我们合并两个相同的地方都有修改的分支时,都会产生冲突。

一旦git不知道如何自动合并,就需要我们来手动解决冲突了。如果文件是文本文件,git便会在有冲突的地方做上标记(如 <<<<<<< HEAD ==== >>>>>>> HASH_ID等),参考这些标记我们可以很方便的解决冲突问题。

但是,如果文件是二进制的文件,一旦发生冲突则很难查看git插入的冲突标识,解决起来是比较棘手的。因此Unity项目的资产序列化最好生成文本文件,而不是二进制文件。我们可以在设置中选择序列化的策略。

这样场景文件和prefab等文件就会被序列化为yaml文本文件:

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
SceneSettings:m_ObjectHideFlags: 0m_PVSData: m_PVSObjectsArray: []m_PVSPortalsArray: []m_OcclusionBakeSettings:smallestOccluder: 5smallestHole: 0.25backfaceThreshold: 100
--- !u!104 &2
RenderSettings:

智能合并场景和prefab文件

将场景文件和Prefab文件序列化为yaml文本文件之后,仍然有可能会在合并时遇到产生冲突的情况。不过好在Unity在5.X版本之后已经提供了一个便于处理合并的工具,并且已经集成在Editor中。你可以在你的Unity安装目录下的Unity/Editor/Data/Tools文件夹中找到这个名为YAML Merge的工具。

它的使用方法也十分简单,以使用git作为版本管理工具为例。我们需要在.gitconfig文件中加上下面这几行配置:

[merge]
tool = unityyamlmerge[mergetool "unityyamlmerge"]
trustExitCode = false
cmd = '<path to UnityYAMLMerge>' merge -p "$BASE" "$REMOTE" "$LOCAL" "$MERGED"

这样当两个人同时修改同一个场景,并且进行合并时,之前的git会报告这个冲突,让我们来手动解决该冲突。但是配置了YAML Merge工具之后的git会调用YAML Merge工具,并自动解决冲突。
更多相关的内容,各位可以去参考Unity官方的手册(https://docs.unity3d.com/Manual/SmartMerge.html)。

0x02 问题:大文件如何处理?

游戏开发,特别是3D游戏开发时会使用到很多美术资源、音频视频资源等等。如何把这些大型的二进制文件集成到git工作流中就成为了一个需要思考的问题。

由于git在处理二进制文件时默认会压缩并存储二进制文件的所有完整版本,如果二进制文件很多,这种做法显然不是最优,换句话说git在存储二进制文件时的效率不高。

针对这个问题,github开源了一个git的拓展,即Git Large File Storage(简称LFS),git大文件存储。规避了git传统的处理方法,Git LFS处理大型二进制文件的方式是用“文本指针”替换它们。

这些文本指针实际上是包含二进制文件信息的文本文件。文本指针存储在Git中,而大文件本身通过HTTPS托管在Git LFS服务器上。Git LFS 使用引用小文本文件指针指向存储在服务器的大型文件。

从git lfs的官网下载并安装好之后,我们就可以在项目中使用lfs来管理我们的大型二进制文件了。相关操作也很简单:

git lfs track "*.<file_extensions>"

例如我们要管理png文件,只需要输入git lfs track "*.png"就好了。

当然,我们也可以直接修改项目目录下的.gitattributes文件。

*.png filter=lfs diff=lfs merge=lfs -text

需要说明的是,很多公司使用的gitlab也已经宣布支持Git LFS了。所以项目的管理没有必要美术用svn、程序用git了。

0x03 策略:Git One Track 和 GitFlow

使用版本工具,除了要能正确合理的使用它之外,作为项目的管理者,还需要清楚一些和版本管理相关的策略。

因此,在本文的最后我们再聊聊使用git作为版本管理工具的管理策略吧。

简单的说,git的管理策略目前有两大流派。平时和同事聊天或和别的公司的朋友交流时也能够感觉的到,即Git One Track和Git-flow。

One Track

One Track简单的说,就是整个团队在开发项目时都在同一个分支上进行。这也就意味着开发阶段的所有工作都集中在同一个分支,例如新功能开发、bug的修复。当然,One Track策略并不意味着只有一个分支,而是只有一个开发分支。当达到团队设定的里程碑时,可以开一个新的分支用来维护这个基本稳定的版本,这个维护分支只进行维护的工作,而不进行开发的工作。同时,开发分支继续进行最新的开发工作。

使用这种策略的最大特点就是大家都在同一个分支上工作,因此每次提交代码都有可能会有冲突。为了减少冲突,团队也常常会提高提交的频率,同时每次提交的颗粒度都比较小。同时,管理成本比较低,整个团队的学习成本也比较低。

在我之前的项目中,参与过一个刚从svn切换到git的团队,我们使用过一段时间One Track的工作方式,可以看到这种策略对整个团队接触和适应git还是很有好处的。

但是我相信更多的人还是更推崇另外一种策略,即Git-Flow策略。

GitFlow

首先我相信很多人一定在哪里会见过下面这张图:

这张图已经能很好的说明了gitflow了。即任何变更都是一个分支。

可以看到,这张图中的分支虽然很多,但是大体上可以分为两类。即主要分支和辅助分支。

主要分支

主要分支即git默认的mater分支以及一个主开发分支develop。

master分支是git默认的主分支,平时团队不在该分支上进行开发。而主开发分支develop则管理着开发人员提交的代码,当代码稳定时或固定一个周期,将develop分支上的代码合并到主分支。

辅助分支

辅助分支是团队每个开发人员都能接触到的,常见的辅助分支包括:

  • 功能分支
  • 发布分支
  • 修复分支

这三类分支都有其对应的使用场景。

开发新的功能时,需要从主开发分支上创建一个新的功能分支,待该分支上的功能开发完毕之后,再合并会主功能分支。

发布分支则是在版本发布时创建的分支, 按照产品里程碑的需求包括应该完成的功能。

修复分支则是当出现bug时,为了不影响开发分支,因此创建出一个新的分支来修改bug,之后再合并回开发分支。

因此我们可以看到,GitFlow的策略无论是开发功能还是修复bug都是以分支的方式来进行。这样做的好处当然是管理上十分干净。但是由于功能开发时间相对要长、代码提交的粒度相对较大,因此在分支合并的时候有可能会出现冲突的问题,另外一个问题是对整个团队的要求要比One Track策略大。

不过,并没有最完美的方案,有的也仅仅是更适合团队的方案。例如很多团队包括我现在都更喜欢将两种方式混合使用,例如针对One Track都在同一个分支上开发,可能不够干净,我们就可以适当的开一个新的分支也用来开发。针对GitFlow提交合并时代码粒度大、冲突多,我们就每天都同步一次代码而不必等整个功能都完成再合并到主开发分支。

最后也希望大家也一起来聊聊项目管理,特别时游戏项目管理的一些经验吧。

聊聊Unity项目管理的那些事:Git-flow和Unity相关推荐

  1. 如何正确使用Git Flow 流程

    我们已经从SVN 切换到Git很多年了,现在几乎所有的项目都在使用Github管理, 本篇文章讲一下为什么使用Git, 以及如何在团队中正确使用. Git的优点 Git的优点很多,但是这里只列出我认为 ...

  2. 聊聊网络游戏同步那点事

    0x00 前言 16年年底的时候我从当时的公司离职,来到了目前任职的一家更专注于游戏开发的公司.接手的是一个platform游戏项目,基本情况是之前的团队完成了第一个版本,即单人模式的基础玩法,但是之 ...

  3. Git Flow分支策略与Azure DevOps相关功能简介

    想了很久,还是写这么一篇文章来总结一下有关分支策略和DevOps的一些内容吧.其实,DevOps相关的内容并不是我的工作范围,不过对于敏捷开发.DevOps.项目管理等等这一系列的与开发过程相关的内容 ...

  4. Git 在团队中的最佳实践--如何正确使用Git Flow

    我们已经从SVN 切换到Git很多年了,现在几乎所有的项目都在使用Github管理, 本篇文章讲一下为什么使用Git, 以及如何在团队中正确使用. Git的优点 Git的优点很多,但是这里只列出我认为 ...

  5. mac中使用Sourcetree的git flow

    mac中使用Sourcetree的git flow 前言 1.git flow工作流 1.1 什么是git flow 1.2 git flow上的分支 1.2.1 长期分支 1.2.2 短期分支 1. ...

  6. babun 如何安装git flow 以及使用

    推荐使用: windows环境: https://github.com/babun/babun linux 随意了 Git 在团队中的最佳实践--如何正确使用Git Flow 2018-10-14 0 ...

  7. Git Flow—Git团队协作最佳实践

    一.规范的Git使用 Git是一个很好的版本管理工具,不过相比于传统的版本管理工具,学习成本比较高. 实际开发中,如果团队成员比较多,开发迭代频繁,对Git的应用比较混乱,会产生很多不必要的冲突或者代 ...

  8. 从一个前端项目实践 Git flow 的流程与参考

    Git flow 出自 A successful Git branching model,这里使用了一个前端项目配合本文稿实施了 git flow 并记录流程作出示例和参考,对 hotfix 与持续部 ...

  9. 经验分享:聊聊多人游戏同步那点事

    16年年底的时候我从当时的公司离职,来到了目前任职的一家更专注于游戏开发的公司.接手的是一个platform游戏项目,基本情况是之前的团队完成了第一个版本,即单人模式的基础玩法,但是之后对该项目的定位 ...

最新文章

  1. 打造新华社「AI合成主播」的“分身术”为何物?
  2. CAN总线简明易懂教程(三)
  3. 如何设置MathType下标的正斜体
  4. android AsyncTask 的分析与运用
  5. chrome 插件 vimium 介绍
  6. python循环输出00-59
  7. linux5支持32,Red Hat发布RHEL5.3 可支持32颗虚拟CPU
  8. rust笔记13 闭包
  9. MYSQL的索引类型:PRIMARY, INDEX,UNIQUE,FULLTEXT,SPAIAL 区别与使用场合
  10. docker教程,dockerfile教程
  11. 怎样提高团队管理能力7
  12. 未解决:configure: error: XCode tool ‘metal‘ neither found in path nor with xcrunchecking for metal...
  13. 项目管理的五个过程和九大知识领域
  14. Excel:列的顺序颠倒(d-a列变成a-d列)
  15. linux gpfs,IBM GPFS并行文件系统解决方案
  16. 一些关于医学科研的好用网站(转载)
  17. 基于unity3D的趣味桌球游戏开发
  18. 在c语言中1和0的意思,!1在c语言中是什么意思?
  19. 统计学习(三):分类
  20. rabbitmq消息发布mandatory参数

热门文章

  1. python逐行读取字符串_python3.4.3下逐行读入txt文本并去重的方法
  2. ethercat主站给从站分配多个地址_Profinet 与 EtherCAT 网关使用方法
  3. android注册的模板下载地址,Android --LoginActivity模板登录
  4. java 删除压缩zip文件_从ZIP存档中删除文件,而无需在Java或Python中解压缩 - java...
  5. Treasure Island CodeForces - 1214D(dfs)
  6. 你真的懂点击率(CTR)建模吗?
  7. android accessibilityservice 被报病毒,无障碍功能AccessibilityService,卡顿,一直报warning...
  8. 深度学习之卷积神经网络(7)池化层
  9. linux 关机时卸载sd,Linux下U盘SD卡的自动挂载和卸载
  10. 图论--最短路--SPFA