6.1 Git


文档摘要

6.1 Git 6.1 Git:Unity3D 项目的版本控制利器 在 Unity3D 项目开发中,版本控制是至关重要的环节。它不仅能帮助我们追踪项目历史变更、回溯错误,更能实现团队协作开发,提升效率和代码质量。而在众多版本控制系统中,Git 以其强大的功能、灵活的分支管理和分布式特性,成为了现代软件开发,包括 Unity3D 项目开发的事实标准。 本章节将深入探讨 Git 在 Unity3D 项目中的应用,从基础概念到实践操作,再到高级技巧,助您掌握 Git,为您的 Unity 项目保驾护航。 6.1.1 为什么 Unity3D 项目需要 Git? 在深入 Git 的具体操作之前,我们首先需要理解为什么 Unity3D 项目如此需要版本控制,以及 Git 如何满足这些需求。

6.1 Git

6.1 Git:Unity3D 项目的版本控制利器

在 Unity3D 项目开发中,版本控制是至关重要的环节。它不仅能帮助我们追踪项目历史变更、回溯错误,更能实现团队协作开发,提升效率和代码质量。而在众多版本控制系统中,Git 以其强大的功能、灵活的分支管理和分布式特性,成为了现代软件开发,包括 Unity3D 项目开发的事实标准

本章节将深入探讨 Git 在 Unity3D 项目中的应用,从基础概念到实践操作,再到高级技巧,助您掌握 Git,为您的 Unity 项目保驾护航。

6.1.1 为什么 Unity3D 项目需要 Git?

在深入 Git 的具体操作之前,我们首先需要理解为什么 Unity3D 项目如此需要版本控制,以及 Git 如何满足这些需求。

  • 版本历史追踪与回溯: Unity 项目随着开发深入,会经历无数次的修改和迭代。如果没有版本控制,一旦项目出现问题(例如,引入 Bug、误删资源),将难以定位问题根源,更无法轻松回退到之前的稳定版本。Git 能够记录每一次代码和资源文件的变更,形成清晰的版本历史,让您可以随时回溯到任何一个历史状态,快速定位和修复问题。

  • 团队协作开发: 现代 Unity3D 项目往往由多人团队协作完成。Git 的分支管理和合并功能,允许多个开发者并行工作,互不干扰。每个人可以在自己的分支上进行开发,完成后再将代码合并到主分支,有效解决代码冲突,提升团队协作效率。

  • 资源文件管理: Unity 项目不仅包含代码脚本,还包含大量的资源文件,如场景、模型、贴图、音频等。Git 能够有效地管理这些资源文件,追踪其变更,确保项目资源的完整性和一致性。虽然 Git 对于大型二进制文件(如高清纹理、大型场景文件)的管理并非完美,但结合 Git LFS(Large File Storage)等工具,可以很好地解决这个问题(我们将在后续章节讨论 Git LFS)。

  • 实验性功能与特性开发: 在 Unity 项目开发过程中,我们经常需要尝试新的功能或特性,但这些尝试可能并不成功,甚至会破坏项目的稳定性。使用 Git 分支,我们可以安全地在独立的分支上进行实验性开发,一旦实验失败,可以轻松丢弃该分支,而不会影响主项目的稳定性。如果实验成功,则可以将特性分支合并回主分支。

  • 项目备份与恢复: Git 仓库本身就是项目的一个完整备份。即使本地项目文件丢失或损坏,也可以从远程 Git 仓库中恢复项目到任何一个提交点。这为项目安全提供了可靠的保障。

  • 代码审查与质量控制: Git 的分支和 Pull Request/Merge Request 工作流,可以方便地进行代码审查。团队成员在合并代码之前,可以先提交 Pull Request/Merge Request,让其他成员进行代码审查,确保代码质量,减少 Bug 的引入。

  • 持续集成与持续部署 (CI/CD): Git 是 CI/CD 流程的基础。通过 Git 仓库的变更触发 CI/CD 流程,可以实现自动化构建、测试和部署 Unity 项目,提高开发效率和交付速度。

6.1.2 Git 基础概念详解

在开始 Git 代码实践之前,我们需要先了解一些 Git 的核心概念。

  • 仓库 (Repository): 仓库是 Git 用来存储项目所有版本历史信息的地方。可以分为两种类型:

    • 本地仓库 (Local Repository): 位于开发者本地计算机上的仓库,存储了项目的完整版本历史。

    • 远程仓库 (Remote Repository): 托管在服务器上的仓库,用于团队成员之间共享代码和协作。常见的远程仓库平台包括 GitHub、GitLab、Bitbucket 等。

  • 工作区 (Working Directory): 工作区是开发者在本地计算机上实际编辑项目文件的地方。当我们从 Git 仓库检出 (checkout) 某个版本或分支后,工作区就会包含该版本或分支的文件。

  • 暂存区 (Staging Area 或 Index): 暂存区是位于本地仓库和工作区之间的一个中间区域。当我们修改了工作区的文件后,需要先将这些修改添加到暂存区,然后才能将暂存区的文件提交 (commit) 到本地仓库。暂存区允许我们选择性地提交工作区的修改,而不是一次性提交所有修改。

  • 提交 (Commit): 提交是 Git 中最基本的操作单元。一次提交代表项目在某个时间点的一个快照 (snapshot)。每次提交都会包含以下信息:

    • 提交 ID (Commit Hash): 一个唯一的哈希值,用于标识本次提交。

    • 作者 (Author): 提交者的姓名和邮箱。

    • 提交日期 (Commit Date): 提交的时间。

    • 提交消息 (Commit Message): 对本次提交所做修改的简要描述。

    • 父提交 (Parent Commit): 本次提交的父提交 (通常是上一次提交)。

  • 分支 (Branch): 分支是 Git 中实现并行开发和版本管理的重要机制。一个分支可以看作是项目版本历史的一条独立线路。默认情况下,Git 仓库会有一个主分支 (通常命名为 mainmaster)。开发者可以基于主分支创建新的分支,在分支上进行开发,完成后再将分支合并回主分支。

  • 合并 (Merge): 合并是将一个分支的修改集成到另一个分支的操作。通常,我们会将特性分支的修改合并回主分支,或者将主分支的更新合并到特性分支。合并可能会产生冲突 (conflict),需要手动解决。

  • 标签 (Tag): 标签是 Git 中用于标记版本库中特定提交点的静态引用。通常用于标记重要的版本发布 (例如 v1.0.0, v1.1.0)。标签类似于分支,但标签是不可变的,一旦创建就不能移动或修改。

  • 远程仓库操作:

    • 克隆 (Clone): 从远程仓库复制一个完整的本地仓库。

    • 拉取 (Pull): 从远程仓库获取最新的提交并合并到本地仓库。

    • 推送 (Push): 将本地仓库的提交上传到远程仓库。

    • 抓取 (Fetch): 从远程仓库下载最新的提交,但不合并到本地仓库。

为了更形象地理解这些概念,我们可以用 Mermaid graph TD 图来表示 Git 的基本工作流程:

图 6.1.1:Git 基本工作流程

6.1.3 Unity3D 项目的 Git 初始化与配置

现在我们已经了解了 Git 的基本概念,接下来我们将学习如何在 Unity3D 项目中初始化 Git 仓库,并进行一些必要的配置。

步骤 1:安装 Git

首先,确保您的计算机上已经安装了 Git。您可以访问 Git 官网 https://git-scm.com/ 下载并安装适合您操作系统的 Git 版本。

安装完成后,您可以在终端 (macOS/Linux) 或命令提示符 (Windows) 中输入 git --version 命令,检查 Git 是否安装成功以及版本信息。

步骤 2:创建本地 Git 仓库

在您的 Unity3D 项目根目录下 (与 Assets, ProjectSettings 等文件夹同级),打开终端或命令提示符,输入以下命令:

git init

这个命令会在当前目录下创建一个 .git 隐藏文件夹,这就是 Git 的本地仓库。.git 文件夹包含了 Git 的所有版本历史和配置信息,请勿手动修改或删除该文件夹

步骤 3:配置 .gitignore 文件

.gitignore 文件用于指定 Git 在版本控制时需要忽略的文件或文件夹。在 Unity3D 项目中,有很多临时文件、缓存文件和用户本地配置文件是不需要纳入版本控制的,例如:

  • Library/:Unity 项目的 Library 文件夹,包含导入资源的缓存、索引等,体积庞大,且每个开发者的本地环境可能不同。

  • Temp/:Unity 项目的 Temp 文件夹,包含临时文件。

  • Obj/:Unity 项目的 Obj 文件夹,包含编译产生的中间文件。

  • UserSettings/:Unity 项目的用户设置文件夹,包含用户本地的编辑器设置。

  • *.csproj, *.sln:Visual Studio 项目文件和解决方案文件 (通常由 Unity 自动生成,且每个开发者的 IDE 配置可能不同)。

  • *.userprefs:Unity 编辑器的用户偏好设置文件。

  • *.unity.meta, *.prefab.meta, *.asset.meta.meta 文件 (虽然 .meta 文件很重要,但通常不需要手动修改,Git 会自动处理,但为了避免误操作,也可以添加到 .gitignore 中,并确保在首次提交时包含所有必要的 .meta 文件,或者使用 Git LFS 来管理 .meta 文件,详见后续 LFS 章节讨论)。

  • 构建输出文件夹 (例如 Build/, Release/ 等)。

在项目根目录下创建一个名为 .gitignore 的文本文件 (注意文件名以点号开头,没有后缀),并将以上忽略规则添加到文件中,每行一条规则。一个典型的 Unity3D 项目 .gitignore 文件内容可能如下所示:

# This file should contain all the directories and files created by Unity. # Local environment dependent files Library/ Temp/ Obj/ UserSettings/ # Visual Studio generated files *.csproj *.sln *.suo *.user *.userprefs *.pidb *.booproj *.svd *.VC.db *.VC.VC.opendb *.vspscc *.vssscc *.vspolicy *.opendb *.sdf *.cache ipch/ [Mm]icroBuildCache/ *.log *.VC.db* *.opensdf *.uncompressed.zip *.vspolicy* *.dbmdl *.metastore *.vs *.jot # Build results Build/ Builds/ Release/ # Package Manager Cache /Packages/packages-lock.json /Packages/package-cache/ # Autogenerated files *.gen.cs # Rider generated files .idea/ # Mac OS X metadata files .DS_Store ._* # Editor log files Editor.log Editor-prev.log # Crash reports CrashReport* # Shader compiler cache ShaderCache/ # Asset Store download cache AssetStoreDownloads/ # Lightmap cache Lightmap*Data/

重要提示: .gitignore 文件需要在 仓库初始化之前 创建并配置好,或者在仓库初始化之后,立即创建并添加到 Git 版本控制中。如果先创建了仓库,再添加 .gitignore,那么之前已经被 Git 追踪的文件可能仍然会被追踪,需要手动取消追踪 (使用 git rm --cached <file> 命令)。

步骤 4:首次提交 (Initial Commit)

配置好 .gitignore 文件后,我们可以进行首次提交,将项目文件添加到 Git 仓库中。

首先,使用 git status 命令查看当前 Git 仓库的状态。您会看到工作区中有很多未被追踪的文件 (Untracked files),这些都是 Unity 项目的文件。

然后,使用 git add . 命令将所有未被忽略的文件添加到暂存区 (注意 . 代表当前目录)。

git add .

再次使用 git status 命令,您会看到这些文件已经变为 "Changes to be committed",表示它们已经进入暂存区,等待提交。

最后,使用 git commit -m "Initial commit" 命令提交暂存区的文件到本地仓库,并添加提交消息 "Initial commit"。

git commit -m "Initial commit"

至此,您的 Unity3D 项目已经成功初始化了 Git 仓库,并完成了首次提交。

6.1.4 Git 常用操作与实践

掌握了 Git 的初始化和基本配置后,我们来学习 Git 的常用操作,并结合 Unity3D 项目的开发场景进行实践。

1. 查看仓库状态 (git status)

git status 命令用于查看当前 Git 仓库的状态,包括:

  • 工作区是否有修改。

  • 暂存区是否有文件等待提交。

  • 当前所在分支。

  • 是否有未推送或未拉取的提交。

在 Unity3D 项目开发中,我们经常使用 git status 命令来了解项目的当前状态,例如,在修改代码后,查看哪些文件被修改了,或者在切换分支前,确认工作区是否干净 (没有未提交的修改)。

2. 添加文件到暂存区 (git add)

git add 命令用于将工作区的文件添加到暂存区。常见的用法有:

  • git add <file>:添加指定文件到暂存区。

  • git add .:添加当前目录及其子目录下所有未被忽略的文件到暂存区。

  • git add -u:添加所有已被追踪的修改过的文件到暂存区 (不包括新增的文件)。

  • git add -Agit add --all:添加所有文件 (包括新增、修改、删除的文件) 到暂存区。

在 Unity3D 项目开发中,当我们修改了代码脚本、场景文件、Prefab 等资源后,需要使用 git add 命令将这些修改添加到暂存区,才能进行提交。

3. 提交更改 (git commit)

git commit 命令用于将暂存区的文件提交到本地仓库,创建一个新的提交记录。每次提交都应该包含一个清晰的提交消息,描述本次提交所做的修改。

  • git commit -m "<commit message>":提交暂存区的文件,并添加提交消息。

  • git commit -am "<commit message>":跳过暂存区,直接提交所有已被追踪的修改过的文件,并添加提交消息 (不包括新增的文件,新增文件仍然需要先 git add)。

  • git commit --amend:修改上一次提交的提交消息或内容 (慎用,特别是已经推送的提交)。

在 Unity3D 项目开发中,我们应该养成频繁提交的习惯,每次完成一个小的功能、修复一个 Bug 或完成一个阶段性任务时,都应该进行一次提交。良好的提交习惯有助于追踪项目历史,方便回溯和协作。

提交消息的最佳实践:

  • 简洁明了: 提交消息应该简洁明了,概括本次提交所做的修改。

  • 使用祈使语气: 例如 "Fix bug...", "Add feature...", "Refactor code..."。

  • 第一行简述 (Subject Line): 不超过 50 个字符,概括提交的主要内容。

  • 空一行

  • 详细描述 (Body): 详细描述提交的背景、目的和具体修改内容 (可选)。

示例提交消息:

Fix: NullReferenceException in PlayerController 修复了 PlayerController 脚本中可能出现的 NullReferenceException 错误。 问题出现在当 PlayerController 组件被添加到场景中,但尚未初始化时, 直接访问了未赋值的 `_animator` 变量,导致空引用异常。 本次提交修改了 PlayerController 的初始化逻辑,在 `Start()` 方法中 添加了对 `_animator` 变量的判空检查,避免了空引用异常的发生。

4. 查看提交历史 (git log)

git log 命令用于查看 Git 仓库的提交历史。

  • git log:查看所有提交历史,按时间倒序排列。

  • git log --oneline:以简洁的单行格式显示提交历史。

  • git log --graph:以图形化的方式显示分支和合并历史。

  • git log --author="<author name>":查看指定作者的提交历史。

  • git log <file>:查看指定文件的提交历史。

在 Unity3D 项目开发中,我们可以使用 git log 命令查看项目的版本历史,了解项目的演进过程,或者查找某个 Bug 的引入时间点。

5. 分支管理 (Branching)

分支是 Git 的核心功能之一,在 Unity3D 项目开发中,分支管理尤为重要。常见的分支操作包括:

  • 创建分支 (git branch <branch_name>): 创建一个新的分支,但当前仍然停留在原来的分支。

  • 切换分支 (git checkout <branch_name>): 切换到指定分支。

  • 创建并切换分支 (git checkout -b <branch_name>): 一步完成创建并切换分支。

  • 查看分支列表 (git branch): 列出所有本地分支,当前分支会用 * 标记。

  • 删除分支 (git branch -d <branch_name>): 删除指定分支 (分支必须已经合并到其他分支)。

  • 强制删除分支 (git branch -D <branch_name>): 强制删除指定分支 (即使分支尚未合并)。

分支策略:

在 Unity3D 项目开发中,常用的分支策略包括:

  • 主分支 (Main Branch 或 Master Branch): 用于存放稳定、可发布的代码。所有开发分支最终都会合并回主分支。

  • 开发分支 (Develop Branch): 用于集成各个特性分支的代码。开发分支的代码可能不稳定,但应该是相对较新的版本。

  • 特性分支 (Feature Branch): 用于开发新的功能或特性。每个特性分支应该只关注一个特定的功能,开发完成后再合并回开发分支或主分支。

  • 修复分支 (Hotfix Branch): 用于修复线上版本的 Bug。修复分支通常基于主分支创建,修复完成后合并回主分支和开发分支。

  • 发布分支 (Release Branch): 用于准备发布版本。发布分支通常基于开发分支创建,在发布分支上进行最后的测试和 Bug 修复,发布完成后合并回主分支和开发分支。

分支工作流示例 (Feature Branch Workflow):

图 6.1.2:Feature Branch Workflow 示例

在 Unity3D 项目开发中,推荐使用 Feature Branch Workflow,为每个新功能或特性创建一个独立的分支进行开发,完成后再合并回开发分支或主分支。这样可以保持主分支的稳定,并方便团队成员并行开发。

6. 合并分支 (git merge)

git merge 命令用于将一个分支的修改合并到当前分支。

  • git merge <branch_name>:将指定分支合并到当前分支。

合并分支时,可能会出现冲突 (conflict)。当两个分支修改了同一个文件的同一部分内容时,Git 无法自动合并,需要手动解决冲突。

解决冲突:

当 Git 提示合并冲突时,需要打开冲突文件,手动编辑文件,解决冲突。冲突文件中会用特殊标记 (例如 <<<<<<<, =======, >>>>>>>) 标识出冲突的部分,我们需要根据实际情况,选择保留哪些代码,删除哪些代码,然后移除冲突标记,保存文件。

解决冲突后,需要将冲突文件添加到暂存区 (git add <冲突文件>),然后完成合并 (git commit)。

7. 远程仓库操作 (Remote Operations)

  • 克隆远程仓库 (git clone <remote_url>): 从远程仓库复制一个完整的本地仓库。

  • 添加远程仓库 (git remote add <remote_name> <remote_url>): 添加一个远程仓库,并为其指定一个名称 (例如 origin)。

  • 查看远程仓库列表 (git remote -v): 列出所有已配置的远程仓库及其 URL。

  • 拉取远程仓库更新 (git pull <remote_name> <branch_name>): 从远程仓库的指定分支获取最新的提交,并合并到本地仓库的当前分支。

  • 推送本地提交到远程仓库 (git push <remote_name> <branch_name>): 将本地仓库的当前分支的提交上传到远程仓库的指定分支。

  • 抓取远程仓库更新 (git fetch <remote_name>): 从远程仓库下载最新的提交,但不合并到本地仓库。抓取后可以使用 git merge origin/<branch_name> 手动合并。

在 Unity3D 项目团队协作开发中,远程仓库操作至关重要。团队成员通过克隆远程仓库获取项目代码,通过拉取远程仓库更新同步代码,通过推送本地提交共享代码。

常用的远程仓库平台:

  • GitHub (https://github.com/): 全球最大的代码托管平台,提供免费的公共仓库和付费的私有仓库。

  • GitLab (https://gitlab.com/): 功能强大的代码托管平台,提供免费的私有仓库和 CI/CD 功能。

  • Bitbucket (https://bitbucket.org/): Atlassian 旗下的代码托管平台,提供免费的私有仓库 (团队人数限制)。

6.1.5 Git 高级技巧与 Unity3D 项目优化

除了基本的 Git 操作,还有一些高级技巧可以帮助我们更好地管理 Unity3D 项目,提升开发效率和项目质量。

1. Git LFS (Large File Storage)

Unity3D 项目中通常包含大量的二进制资源文件 (例如纹理、模型、音频、场景文件等)。Git 擅长管理文本文件,但对于大型二进制文件,Git 的效率较低,且仓库体积会快速膨胀。

Git LFS (Large File Storage) 是 Git 的一个扩展,专门用于管理大型文件。Git LFS 将大型文件的实际内容存储在单独的 LFS 服务器上,而在 Git 仓库中只保存文件的指针 (text pointer)。这样可以显著减小 Git 仓库的体积,并提升大型文件的版本控制效率。

使用 Git LFS 的步骤:

  • 安装 Git LFS: 访问 https://git-lfs.github.com/ 下载并安装 Git LFS。

  • 初始化 Git LFS: 在 Git 仓库根目录下运行 git lfs install 命令,初始化 Git LFS。

  • 追踪大型文件类型: 使用 git lfs track "<file_pattern>" 命令指定需要使用 LFS 管理的文件类型。例如,git lfs track "*.psd" 将追踪所有 .psd 文件。

  • 正常使用 Git: 配置好 Git LFS 后,可以像往常一样使用 git add, git commit, git push, git pull 等命令。Git LFS 会自动处理大型文件的上传和下载。

Unity3D 项目中建议使用 Git LFS 管理的文件类型:

  • *.psd, *.png, *.jpg, *.jpeg, *.tga, *.exr (纹理文件)

  • *.fbx, *.obj, *.blend, *.ma, *.mb (模型文件)

  • *.wav, *.mp3, *.ogg (音频文件)

  • *.unity (场景文件)

  • *.prefab (Prefab 文件)

  • *.asset (Asset 文件,特别是大型 Asset)

2. .gitattributes 文件

.gitattributes 文件用于为 Git 仓库中的文件指定属性,例如行尾符处理、二进制文件处理、LFS 管理等。

常用的 .gitattributes 配置:

  • 行尾符处理: 不同操作系统 (Windows, macOS, Linux) 使用不同的行尾符 (CRLF, LF)。为了避免跨平台协作时出现行尾符问题,可以在 .gitattributes 文件中配置行尾符处理规则。

    * text=auto eol=lf

    这条规则表示所有文件默认使用自动行尾符转换,并将行尾符统一为 LF。

  • 二进制文件处理: 对于二进制文件,应该禁用行尾符转换和文本diff。

    *.png binary *.jpg binary *.fbx binary
  • LFS 管理: .gitattributes 文件会记录哪些文件类型使用 Git LFS 管理。git lfs track 命令会自动更新 .gitattributes 文件。

3. Stash (储藏)

git stash 命令用于将当前工作区的修改 (包括暂存区和工作区的修改) 临时保存起来,以便切换到其他分支或进行其他操作。之后可以使用 git stash applygit stash pop 命令恢复之前储藏的修改。

在 Unity3D 项目开发中,当我们正在开发某个功能,但需要紧急切换到其他分支修复 Bug 时,可以使用 git stash 命令保存当前工作进度,切换到 Bug 修复分支,修复完成后再切换回原来的分支,并使用 git stash apply 恢复工作进度。

4. Reset 和 Revert (回退)

git resetgit revert 命令都用于回退代码,但它们的实现方式和适用场景有所不同。

  • git reset 将当前分支的 HEAD 指针移动到指定的提交,并可以选择性地修改暂存区和工作区。git reset修改版本历史,慎用,特别是已经推送的提交。

    • git reset --soft <commit>:只移动 HEAD 指针,暂存区和工作区保持不变。

    • git reset --mixed <commit> (默认):移动 HEAD 指针和暂存区,工作区保持不变。

    • git reset --hard <commit>:移动 HEAD 指针、暂存区和工作区,丢弃指定提交之后的所有修改 (慎用,数据丢失风险)。

  • git revert 创建一个新的提交,用于撤销指定提交的修改。git revert 不会修改版本历史,而是 通过创建一个新的提交来抵消之前的提交

在 Unity3D 项目开发中,如果需要回退到之前的某个版本,但又不想修改版本历史,可以使用 git revert 命令。如果只是想撤销本地的未推送的修改,可以使用 git reset 命令。

5. Commit Message 规范化

统一的 Commit Message 规范有助于提高代码可读性和维护性,方便团队协作和版本追踪。

常见的 Commit Message 规范:

  • Angular Commit Message Conventions (https://gist.github.com/stephenparish/9941e89d80e2aa1f533e): 一种流行的 Commit Message 规范,包括以下结构:

    <type>(<scope>): <subject> <body> <footer>
    • type (类型): 提交类型,例如 feat (新功能), fix (Bug 修复), docs (文档), style (代码风格), refactor (重构), perf (性能优化), test (测试), build (构建), ci (持续集成), chore (杂项)。

    • scope (范围): 受影响的模块或组件 (可选)。


发布者: 作者: 转发
评论区 (0)
U