跳到主要内容

Version Control with Git / 用 Git 做版本管理

源文档地址

手上的东西一旦不只是随手一画的草稿,就该考虑用 Git 管你的 .vl 文档了。版本管理系统还有别的,但 Git 用得最广。上手要花点时间,可一旦用惯,你就再也回不去了。

别再把进度存成 foo_1.vl、foo_2.vl、foo_3.vl 了 —— 版本堆成山,回头也认不出哪个是哪个。改用版本管理,你可以:

  • 把工作的某个状态(哪怕横跨多个 .vl 文档)存进一个「提交」
  • 给每个提交加一句人能读懂的说明
  • 查看你的提交说明历史
  • 回到你此前提交过的任意一步

而且这一切都不必忍受同一个文件夹里躺着同一份文件的多个版本。此外你还可以把工作推送到云服务,额外得到这些好处:

  • 备份
  • 从另一台 PC 访问你的工作
  • 与同事共享

如果还需要点说服力,你可以看看这些入门视频(英文)

前置条件

软件

本质上你需要的是:

  • Git 本身
  • 一个 Git 图形客户端

Git 也可以只用命令行,不装图形客户端 —— 有些人就喜欢这样,那只要下载 Git 就够了。要是决定用图形客户端,多数会顺手替你把 Git 装上,不必另外下载。

选哪个图形客户端?多半得挨个试,看自己顺手哪个。vvvv 开发团队用 GitExtensions 用了很多年,一直挺舒服。差异/合并工具里我们觉得最好的是 P4Merge,可以在 GitExtensions 里把它设成默认的差异/合并工具,别的客户端多半也能这么设。

云服务

如果你想把 git 仓库备份到云上(这同时也方便与人共享),去这些 git 云服务商里注册一个。

vvvv 的节点库仓库大多在 GitHub 上,所以如果你以后想给它们做贡献,就需要一个 GitHub 账号。

术语

  • 每个项目存放在一个仓库(repository)里
  • 要把本地仓库镜像到云服务,你得给它一个远端(remote),也就是远程仓库的 URL
  • 每当你觉得工作到了一个不错的状态,就把它存进仓库的一个提交(commit)
  • 仓库存放着你的提交历史
  • 仓库里最后一个提交被称为 HEAD
  • 要把你的提交上传到远程仓库,运行 push 命令
  • 克隆(clone)是指为远程仓库做一份最初的本地副本
  • 要从远程仓库下载提交,运行 pull 命令
  • 要回到工作的某个特定状态,就 checkout 相应的那个提交

上手

创建一个新仓库

(上游此处待写)

fork 和/或克隆一个已有仓库

(上游此处待写)

提交

关于提交的一些通盘想法:

  • 尽量提交那些你能用一句提交说明讲清楚的改动
  • 避免把牵涉多个「任务」的改动提交在一起
  • 建议一个任务/一次修复/一处改动对应一个提交
  • 绝不要提交你并非有意改动的文件(文件可能在你忙别的事时被意外改到,或者你在某处试过什么但并不打算提交,自己却忘了)
  • 提交前一定检查一遍即将提交的改动,确认它们与你想改的东西相符

一个人干活

只要项目是你一个人在做,一切基本上都直截了当。典型的工作流大概是这样:

  • 为新项目建一个新仓库
  • 提交最初的工作状态
  • 做改动,做一次新提交
  • 做改动,做一次新提交
  • 做改动,做一次新提交
  • 一天结束时把提交推到远端,好有个备份
  • 万一你得换到另一台 PC,在那台上克隆这个仓库就行
  • 做改动,做一次新提交
  • 做改动,做一次新提交
  • 把提交推到远端
  • 回到第一台 PC,拉取你从第二台推上去的那些远端提交,接着干

有了 git,你可以切到工作的任何一个状态,不用担心弄丢最新的。做法是对历史里的任意一个提交执行 checkout。看完旧状态,再 checkout 回最新的就行,很容易。

git 的名堂远不止这些,但上面这些够你看清最简单的工作流了。先在自己的项目上练熟,再去和团队协作 —— 那边事情会更有意思。

和团队一起干活

和团队协作时,视各人的 git 熟练程度而定,大家约好用同一个 Git 客户端可能会有帮助。这样一旦出问题,彼此更容易搭把手。

团队里可能出现的那个显而易见的问题是:不同的人各干各的,却同时在改同一份 .vl 文档。

比如说,你把本地改动做成了一个提交,正想推上去,git 却让你先拉取远端的改动。如果你改的那份文件没被这些远端提交碰过,那没事。否则 git 就要把远端的改动合并进你的本地文件 —— 岔子正是在这一步出的。

你会看到三种情形:

  • 最好的情形:合并顺利完成
  • 最坏的情形:git 声称合并没问题,实际上却出了问题
  • 还行的情形:git 告诉你它没法自动合并,请你帮忙

问题在于 git 是为文本编程语言做的。vvvv 把 .vl 文档存成 XML,好在也是文本。可惜 git 不懂 XML 的结构,只当普通文本处理 —— 所以某些情况下,合并会把你的 .vl 文件弄坏。

所以关键真的在于:尽你所能避免合并冲突。记住,只要大家同时干活但改的是不同文件,就不会有冲突,因此:

把项目拆成多个 .vl 文档

整个项目做在一个 .vl 文档里,vvvv 当然也支持。但按下面这些原则拆成多个文档是个好习惯:

  • 留一个主 .vl 文档,它不含任何定义,只有应用
  • 另做多个按主题划分的 .vl 文档,它们装着所有定义,而应用部分是空的
    • 比如:InputHandling.vl、Scene1Logic.vl、Scene2Logic.vl、LightControls.vl、Audio.vl、Rendering.vl……
  • 为各个文件指定归属人,也就是只有归属人才能提交对该文件的改动
  • 在主文档里把这些定义文档作为依赖引用进来,并在那里搭出主应用

主 .vl 文档显然是个典型的冲突点 —— 每个人都得动它,才能看到自己的改动跑起来。可以试试这样:如果你负责的那部分足够独立,就自己复制一份主文档,在副本里搭。那份副本你想怎么折腾都行,只给自己测试用,不提交。等你那部分整合妥当了,先拉到最新的主文档,跟大家打声招呼说要推了,然后一次性把你那部分复制粘贴过去 —— 一次合并都不用冒。当然,这招不是每种场合都管用。

沟通

总有些改动一次要动很多文档。这种时候先让所有人都知道,让大家把最新状态提交并推上去,再由一个人来做这次跨文档的改动。拿不准就共享屏幕一起做,让大家都看清发生了什么。

分支

分支不是你该一上来就碰的东西。

合并

VL 文档的合并工具