Git 与 GitHub 快速上手教程

Git 与 GitHub 快速上手教程

1 什么是 GitHub?

GitHub 名声在外,已经不是一两年了;但是,许多人并不清楚这是怎样的一个「网站」。那么,GitHub 是做什么的呢?

说到 GitHub,就不能不介绍 Git。Git 是一个版本控制软件,这类软件能够精确的记录制定目录下代码的增删变动,在必要时允许还原到原来的状态。当然,对 Git 而言,其还有许多特有的功能,在此暂不详述1。Git 并不仅仅只是一个在本地运行的软件,它能够实现分布式的版本控制——也就是说,通过一个远程的代码托管平台,Git 可以帮助程序员实现多个分立终端上的共同开发、信息交互与同步,从而可以实现多人协作。

一个需要记住的事实:Git 的最初作者是 Linux 之父 Linus Torvalds,因此这个程序有一些特性与 UNIX/Linux 系统相关(不过一般影响不大),需要 Windows 用户逐渐熟悉。

GitHub 则正是一个基于 Git 而建立的在线代码托管平台,用户可以在其上建立属于自己或与他人共享的代码仓库,并在此基础上实现版本控制、团队协作,甚至开源软件发布、网站建设、文档维护等诸多超出 Git 固有功能以外的事情。至2019年四月,GitHub 上已托管超过一亿个开源代码仓库,有超过3600万名用户活跃其中2

GitHub 的出现3,使我们不再担心备份与远程协作:一切提交,均有记录。

2 Git 是怎么运作的

GitHub 是基于 Git 的代码托管平台,所以我们仍然需要了解 Git 的运作机制。以下内容并不涉及复杂的工作原理,仅是对 Git 运行机制的大致描摹。

如果你对枯燥无味的概念感到厌烦,可以先跳到第 3 节「GitHub 指南」进行一些尝试,再在需要时到本节补充相关知识。

Git 是一个版本控制系统,即可以记录一个目录(文件夹)下各个文件的增删改动情况,并允许用户回溯历史、修改或撤销之前的操作。为此,需要了解 Git 实现这些功能的机制。

2.1 文件储存区域

在使用 Git 管理代码仓库/文件夹时,存在着三个区域:工作区、暂存区、版本库。

  • 工作区就是当前的各种文件所在的区域,就是实实在在地存在你的文件夹里、能从系统的窗口里看到的内容。
  • 暂存区是一个由 Git 通过所谓「索引文件」创设出来的虚构区域,其所存放的是一些被你要求「记录在案」但尚未确定去留的文件。
  • 版本库则是 Git 根据当前目录的各个历史版本而创建的虚构区域,以压缩文件的形式存储在当前文件夹下(存放在名为.git的隐藏文件夹中)。与暂存区不同的是,版本库中所记录的文件版本、改动记录已经被固结,只能删除而不能修改。特别地,在远程平台——如 GitHub 上——所留存的文件,都是以版本库的形式存在的。

读者可能会问:为什么做版本控制需要三个区域来记录呢?为了方便理解,有这样一个例子可供参考:

你是一个美食博主。今天你心情不错,打算精心准备一桌菜,然后再拍照发布。在准备的过程中:

  • 你所烹饪出来的、摆在饭桌上的菜,真实存在,这张饭桌便是所谓的工作区
  • 你是一个心思细腻的人,不光期待着结果,还随时用手机记录做饭过程中各个阶段的状况。这些由你在不同时间拍下来的照片,「记录」了你所烹饪的菜品之「改动」;而存储着这些照片的手机空间,就是所谓的暂存区
  • 烹饪渐近尾声,桌上的菜品玲琅满目,你的手机里也储存了许多或好或坏的照片。这时,你可以对你的照片仔细筛选,最终挑选出一组完美的「九图大法阵」;配上一段文字说明,你轻按微博界面上的「发布」按钮,一条新的微博就经由你手机上的一个本地数据库传递到微博平台的服务器上,进而可以在整个互联网上看到。你所最终发布的这条微博,便是代码管理过程中所谓的「版本」;储存着这些微博的本地数据库和远程服务器,就是所谓的版本库

很显然,在以上三个储存区中,只有工作区储存着真正的美食,而暂存区和版本库记录的不过是照片——在代码管理过程中,相应的事物则叫做「快照」。至于为什么要在工作区与版本库之间多加上暂存区这一环节,打一个比方便是:如果你用手机拍的每一张照片都会自动发布在微博上,你还敢轻易的拍照片吗?还能「仔细筛选」吗?

当然,以上的这个例子,与 Git 的实际运作方式仍有很大不同。最大的不同在于:在现实世界中,你不能通过手机或微博上的照片把真实的菜品还原出来;而在 Git 中,代码版本管理的最大意义,恰在于你总是可以由版本库(有时也可以是暂存区)还原、覆盖你的工作区

为了理清这三者的关系,读者不妨先从下面这几条原则开始:

  1. 工作区就是电脑窗口上看到的东西,存在硬盘里。
  2. 暂存区和版本库都是「看不见」的,它们以特殊文件的形式存在于工作区中一个名为 .git 的神秘文件夹之下。
  3. 工作区中的文件必须先记录到暂存区中,才能再由暂存区发布到版本库内;工作区的文件无法直接进入版本库。
  4. 暂存区和版本库都可将工作区内的文件直接覆盖。
  5. GitHub 上发布的文件以版本库存在;或者说,GitHub 就是一个在线储存版本库的平台,而并不像工作区那样直接储存文件。
  6. 版本库中确实记录了很多版本,工作区和暂存区则并不负责此事。

以下的示意图,有助于加深读者对这三个区域之关系的理解。其中,所谓的远程仓库与(本地)版本库是使用相同的方式存储的,只不过前者储存在网络上,而后者储存在用户自己的电脑上。

三区示意图

(图片来源:Git 学习笔记 - git reset 详解,作者:howzy)

2.2 版本管理命令

观察上面所给出的示意图,读者可以发现其中用若干箭头标明了文件流转的方向,并注有英文描述。例如,文件从工作区记录到暂存区的操作,被称作 add ;而将暂存区中的记录正式提交到版本库内,则被称作 commit 。这些英文词汇,就是在 Git 客户端中需要调用的命令名称。对于初级用户而言,以下几个操作是需要牢记在心的:

命令 字面意思 行为
clone 「复制」、「克隆」 将一个发布在远程仓库4(如 GitHub)上的版本库复制到本地。这通常是参与代码协作的第一步。
init 「初始化」 在本地的一个空目录下新建版本库。与 clone 的实际效果是相近的,只不过来源不同而已。此命令很少用到。
add 「添加」 将工作区的文件改动记录到暂存区。这是将一个文件发布到正式版本之前不可跳过的一步。
commit 「记录」、「交付」 将所有记录在暂存区的文件改动发布于版本库中;与 add 不同的是,在 commit 时必须对这次发布的内容进行必要的说明(称为 commit message),且 commit一旦提交就只能删除,而不能再修改这次的发布记录。commit 也常被作为一个名词来使用。
push 「推」、「推送」 将本地版本库的内容发布到远程版本库(如 GitHub)上。能够正确 push 的前提是:本地版本库的版本超前于远程版本库。
pull 「拉」、「拉取」 将远程版本库的更新同步到本地的版本库与工作区。一般而言,执行 pull 的原因是:本地版本库的版本落后于远程版本库。

以上几个操作中,initaddcommit 都是不需要网络而在本地执行的操作,剩余的则需要与远程平台交互。

2.3 版本控制流程

看过 Git 的三大区域与若干操作命令后,Git 做的事情就可以只需要几句话来说清楚了。当然,Git 本身只是一个工具,有很多的「玩法」;但在一般的软件、代码、文档开发流程中,Git 的使用一般遵循着下面的几个步骤:

  1. 在 GitHub 上找到一个他人已经有所开发的代码仓库,并在本地的 Git 客户端用 clone 命令复制到自己的电脑上。(注意,对于已经公开的仓库,clone 之前并不需要登录或取得权限,就像「免费下载」一样。)经过此操作,你便在本地获得了一个版本库和与之同步的工作区。
  2. 你可以在工作区中按需要做任意的改动,参与协作。(记得随时保存文件, Git 并不会负责这件事情。)
  3. 完成(或部分完成)你所要做的工作后,执行 add 操作以将你所做的改动记录进暂存区。
  4. 所有你所需要的改动都暂存之后,就可以由 commit 操作正式发布到版本库中——记得认真填写 commit message。
  5. 在你修改文件的同时,你的同伴也许已经在千里之外的一台电脑上修改了其他的文件,甚至已经先于你一步将这些改动发布到 GitHub 上了。为了保持与远程仓库的同步,你需要在将你的改动发布前再耐心地执行一次 pull 操作,以确认自己的改动与其他人的改动并无冲突,并将他人的改动纳入到你的版本库中。如果你的改动不幸的与他人的改动发生了冲突,你就还需要额外做一些工作了——这一步骤将在之后进一步讨论。
  6. 与目前的远程仓库同步成功后,你就可以通过 push 操作将自己的改动全数发布到 GitHub 上,一次版本更新至此告一段落。

以上步骤之中,第一步显然只需要执行一次;在以后的写作过程中,你只需要及时用 pull 命令与远程仓库保持同步即可。

上面所给出的这些步骤,并不是一个必须遵守的范式。例如,如果你在独自开发一个仓库(并未与他人协作),并且只从一个客户端使用 Git 工具,则上面所说的第五步(pull)便是多余的。又如,为了使自己的改动清晰明了,你可以将对一份文件的多处更改或多份文件的更改手动拆解到若干个不同的 commit 之中,就像发微博的时候将一系列照片分好几条微博发送一样。

2.4 Git 特色:分支管理

与 Git 相仿的版本控制软件,不在少数。不过,Git 却具有一个特殊的机制:分支管理;这项功能,可以说是对过去许多年来软件开发流程之经验的总结,对程序的开发是非常有帮助的。

如果读者想初步了解一下分支管理的价值,可读阮一峰的一篇博客:Git 分支管理策略

所谓分支(branch),就是一系列前后相贯的版本所构成的整体,它本是版本管理过程中一个常常出现的现象、范畴。例如,两位作者经由同一份原始的代码发展、开发出两个不同的程序,则这两个程序的源代码就属于两个分支;它们有着相同的起点、有若干公用的版本,但在某一个版本结点时便「分道扬镳」了。分支的创建不一定总是「分道扬镳」;对同一个开发小组而言,他们可能会将代码开发主动分散到不同的分支上,同时又经常地将分支进行合并(merge),以此满足不同的需要。

作为 Git 的一项特色机制,其将代码开发过程中的分支给实体化了(也就是说,在 Git 中,分支是真实存在的对象,而不再是一个抽象的范畴),并鼓励使用者利用分支机制下提升开发体验。在 Git 中,通常有一个主分支,其名称为 master ;如无特殊情况,所有代码改动都只需要在 master 上提交即可。如果需要进行多分支开发,则可以新创建一些分支,在这些新的分支上进行开发;再在合适的时候,将这些分支上的改动汇入 master 分支。这样做的好处是:master的改动不会太过频繁,所有的改动都是在经开发人员测试无误之后在才发布在用户所用的 master 分支上,保证了软件的稳定性。

3 GitHub 指南

对于新手来说,Git 似乎是一个「高深莫测」的工具,牵涉许多新的机制;对于将来没有「改行」意向的计算机小白而言,更是无法挤出时间、下定决心钻研这样一个看似距离他们很遥远的技术工具。事实上,如果仅仅是希望用 GitHub 实现基本的文档或代码协作,则不必大费周折,只需在 GitHub 的网页或客户端上操作就已足够。下面,针对这一部分内容作简单的讲解。

开始之前,需要先完成下面的两项工作:

  • 注册 GitHub
  • 如果你希望以小白的身份获得 GitHub 的最佳体验,可以尝试下载 GitHub 客户端(正式名称为 GitHub Desktop)。当然,这一步可以略去不做,这样的后果是:你只能在网页上创建或上传文件,而不能建立起远程仓库与本地仓库的联系。

由于一些原因,GitHub 在国内访问时速度并不很快,常常掉线或中断连接。针对这种情况,你有两种选择:

  1. 访问 GitHub 网页、上传文件时,学会更加耐心或者充分利用加载的时间完成泡茶、点外卖、洗衣服、写作业等闲杂事项
  2. 自备梯子。(梯子是什么? 怎样做梯子? 有哪些好的梯子?

3.1 创建新的仓库

在注册 GitHub 之后,网站通常会建议你阅读一份名为 Hello World 的指南(以下简称「指南」),帮助你建立一个名为 hello-world 的仓库。这是一个很好的练习,此处将给予一些额外的说明。

创建仓库时,指南要求你按以下的配置创建仓库:

init settings

(图片来源:Hello World · GitHub Guides)

这里的几个选项值得说明:

  • Owner 即仓库所有者的名字——一般情况下,所有者是你自己,但也可以是你管理的组织(如 qyxf)。
  • Repository name 是仓库的名字。按照目前惯例,一般采用连接线命名方法(如 hello-world),但也可以使用驼峰命名法或 Pascal 命名法(如 BookHub)。风格统一即可。
  • 以上的 Owner 及 Repository name,决定了代码仓库的地址。例如,qyxfBookHub 仓库,网页地址便是 https://github.com/qyxf/BookHub
  • Description 是 GitHub 页面上显示的仓库描述,与代码无关。尽管是 optional 的,还是建议用户认真填写。
  • Public (公开)与 private (私有)决定了仓库的可见性。公开仓库可以为所有人看到,无论他们是否登录了 GitHub;而私有仓库只能为仓库所有者和其所许可的其他 GitHub 用户访问、克隆、修改。过去,GitHub 的私有仓库是收费项;在微软收购 GitHub 之后不久,三人以下协作的私有仓库可以免费使用。此外,仓库的可见性可以在创建之后修改,所以不用担心最开始的选择。
  • 指南中要求你「Initialize with a README」,即在你新建的仓库中自动生成一份名为 README 的 Markdown 文档。README 相当于这个仓库的说明,会由 GitHub 自动展示在仓库的首页,当然有必要创建;不过,这里创建这份文件还有另一个作用——由此创建的仓库,不是空的,便于你通过 clone 命令直接复制到本地,也便于 GitHub 配置相关的属性。

如果你不打算使用 Git 或 GitHub 客户端,只想在网页上操作,请务必在创建仓库时初始化 README。(跳过这一步的人都后悔了。

之后,指南按照 GitHub 所推荐的分支管理模式来,指导你如何在独立于 master 分支的侧分支上修改文件,并通过名为 Pull request 的操作(这并不是 Git 中的固有机制)将其合并到 master 内。在一般的代码协作中,仓库内的分支管理机制不常被使用,读者可以在自己的仓库中稍作尝试;而 Pull request 则尤为重要,是代码协作的关键,在 3.4 节中将详细介绍。

3.2 玩转自己的仓库

创建新的仓库之后,你就可以在 GitHub 网页端开始编辑。开始之前,有件事值得注意:

与 Git 客户端不同,GitHub 的网页端与客户端都没有暂存区的概念。其中,网页端上只能同时编辑一个文件,且每次改动后都必须为之提交一个单独的 commit(不能分批或扎堆)将改动直接记录到版本库中;客户端则只能直接将工作区中的所有改动一次性 commit 至版本库,或丢弃工作区的改动。

这一特性,在某种意义上来说是 GitHub 为 Git 门外汉们搭设的「终南捷径」;尽管暂存区的缺失,使得仅靠 GitHub 实现精细管理变得困难,但却也同时降低了 GitHub 的使用门槛。理解这种差异,对于 GitHub 的用户来说是十分重要的;一般来说,即使是 Git 高手也偶尔会直接在 GitHub 网页端直接操作,因此理解两者的差异是必要的。

在网页端,可通过三种方式对仓库作出改动:

  • 通过仓库页面上的「Create new files」按钮创建新的代码文件,GitHub 将根据你所给定的后缀名自动确定代码所用的语言。
  • 通过仓库页面上的「Upload files」按钮上传本地文件。根据本节开头所说的原因,不推荐这种做法——超过 1M 的文件难以在国内成功上传。
  • 通过仓库内各文档页面上的 按钮编辑文档。

无论是用哪种方式,都必须在保存改动前填写 commit message。网页端的功能较为有限,故其一般只用于创建与修改 Markdown 文档这样的简单内容。

使用 GitHub 客户端是一个更好的选择。在 GitHub 客户端中登陆后,你将看到这样的页面(以 Windows 客户端为例):

GitHub Desktop under Windows System

(图片来源:GitHub Desktop | Simple collaboration from your desktop ,已修改)

  1. Files 选项:实际上这个选项卡命名为 Repository 更合适,在这里你可以从 GitHub 或其他任何地方 clone 已有的仓库,导入本地已有的版本库,或者新建一个。选项(Options)也在这里。
  2. Edit 选项:这里提供的选项不是代码的复制粘贴,而是文件级别的操作。如果你觉得系统的资源管理器更合用,这个选项卡完全可以忽略。
  3. View 选项:视图调整,不过这里的每一个选项都可以通过直接点击其他的区域来实现,可以忽略。
  4. Repository 选项:这里可以执行 pullpush 操作,还可以修改仓库的属性——就像在 GitHub 网页端一样。
  5. Branch 选项:分支管理,在这里你可以新开分支、合并等。提交 Pull Request 也是在这里,不要跑到别的地方去找。
  6. 仓库选项卡:可以在这里切换、筛选当前仓库。一般而言,你只能同时在一个仓库上工作、提交更改。
  7. 分支选项卡:可以在这里从 master 主分支切换到其他不同的分支。提交更改前,务必确认自己所在的分支。
  8. Fetch Origin:执行 fetch(取回)操作——这个操作与 pull 类似,但它不会覆盖你已在工作区作出的改动,是一个安全的操作。如果你的计算机已经联网,则每次打开 GitHub Desktop 时其都会自动同步;当然,你也需要像经常保存文件一样,有事没事 fetch 一下,以免冲突。
  9. 左栏 Changes 选项卡:切换左栏的内容为「当前工作区相对于版本库的改动」。改动信息会分别显示在中栏(文件变动状况)和右栏(文件内容具体改动)内。
  10. 左栏 History 选项卡:切换左栏的内容为「本地版本库储存的各版本历史」,以及每个版本中发生的改动。中栏与右栏仍显示文件的总体变化与具体内容改动,只不过这些改动是过去所做的,已经记录在案了。
  11. 中栏:显示文件的整体变化情况。被改动的文件以条目显示,右侧的彩色图标表示文件的改动类型: 表示此文件是新加进来的; 表示文件被删除; 表示文件被更名(但未修改内容);最常见的则是 ,表示文件内容有改动。
  12. 右栏:显示在中栏中所选的某一文件之具体变动情况,以红色(删除)与绿色(增加)的形式表现出来。在 Git 中,比较文件差异的操作被称作 diff,而 GitHub 多做的事不过是让 diff 的结果更直观了。

绝大多数文件比较工具都只能显示文本格式文件(例如最常见的 .txt 文件,以及源代码文件)的变动,而不能显示二进制文件(例如 .exe 程序、PDF 文件,以及很多人以为是文本格式的 Word 文档5)的变动。因此,如果希望用 Git 记录文件变动,务必采用纯文本格式文件。

与 GitHub 网页端相较,GitHub 客户端并不具有编辑器的功能,因此你需要先用自己最喜爱的编辑器(如系统记事本)完成所有改动之后,再用 GitHub 的客户端审阅、提交。

3.3 参与协作

GitHub 号称「世界最大同性交友网站」(当然妹子也不少),由此一点即知:GitHub 的功能绝对不限于个人仓库的管理。参与协作是 GitHub 上最有趣的一件事,而且它比你想象得更加轻松。以下三种协作方式是最为常见的。

  1. 成为协作者:个体之间的相互协作,常常通过协作者(collaborators)机制完成。在你的仓库中,可通过「Settings」选项卡下「Collaborators & Team」条目找到「Collaborators」的设置面板,进而通过用户名搜索并邀请其他用户与你一同协作。除了删除仓库等特殊操作之外,协作者拥有其他所有操作的权限。
  2. 加入组织:GitHub 上的一大亮点就是组织(organization)功能,每个人都可以创建一个组织,并邀请其他人加入其中。一个组织的性质类似于一个普通的 GitHub 用户。组织的管理者能以组织的名义新建、克隆仓库,组织的一般成员则可在组织所有的仓库中获取对应的权限、参与协作。与协作者机制相较,组织机制具有更灵活的权限机制,而且还有小组(teams)功能、团队信息公示等额外的工具。

    qyxf 即是钱院学辅在 GitHub 上的组织。

  3. Issue, Fork & Pull request:如果仅仅只是允许有权限的人参与协作,未免太过约束了——这样的协作,和封闭的开发模式差别不大。事实上,使 GitHub 社区始终活跃的,是更为灵活、自由的三项机制:问题区(Issues)、远程克隆(Fork,可译为「分叉」或「派生」)与拉取请求(Pull requests,也可译为「合并请求」)。它们的说明分别如下。

Issues. 简单来说,Issues 是每个公开的 GitHub 仓库(或谓「项目」)附属的论坛,自动生成。Issues 主要是向项目的使用者——如热心的技术 Geek,也包括一般的软件用户——开放的,他们在使用、测试程序与代码时,可以随时将自己所发现的问题、想到的改进方案挂在 issues 页面,再由仓库的管理者处理、反馈这些请求。Issues 的亮点在于:每一个问题(「帖子」)都可以与这个仓库的具体版本、改动等关联起来。一方面,在 issue 中,用户可以引用仓库的某个版本加以说明;另一方面,开发者在处理这些问题之后,可以在 commit message 中标注对应的 issue 代号,引用这些问题,表示这次改动解决了对应的问题。(例如,读者可以浏览开源文档转换软件 pandoc 的新版本发布页面,其中以 #XXXX 代号标明的链接正对应着用户所提出的 issues。)

Fork. GitHub 允许你在没有权限的情况下参与协作,只要你将他人的仓库「fork」到自己这里。Fork 与 clone 的区别在于:后者只是将版本库的数据下载到你的电脑上,而前者则完全发生在 GitHub 平台以内。例如,用户 hello-kittymicrosoft 组织在 GitHub 上发布的 vscode 仓库 fork 一下,她的 GitHub 界面上就会出现一个名为 hello-kitty/vscode 的仓库。这份仓库的内容与 microsoft 的那份将没有任何差异(不过之后的更新并不会自动同步),且她将拥有对这个复制品的一切权限。

Pull requests. 单纯把别人的仓库 fork 过来可没有什么用,你的改动并不会反映到原本的项目之上。Fork 功能必须配合着 pull requests 才能发挥作用。当在自己的那份复制品中作出相应的改动之后,你就可以向原本的那一个项目发起 pull request,要求项目的管理者将你的改动「拉取」6到他们的项目中去。这就好比你作为老师,批改了学生的作业,并要求他们订正自己的答案。在公开的仓库中,所有用户都有权 fork 和提交 pull requests,但是否接收这些 pull requests 则完全在于项目的管理者本身。他可以对这些 pull request 稍加评论,要求贡献者进一步改良;也可以假装度假,拖几天再回复;更可以毫不留情的驳回用户的请求。这样,就能够避免无聊之辈的恶意改动,更能够使开发与改进过程变得有序、可控。

在 GitHub 中,issues 与 pull requests 使用同一个计数器(counter)。例如,某个仓库中提出的第一个 issue 被记为 #1,则随后发起的第一个 pull request 将被标记为 #2。这两者虽然机制有所差异,但都是对于项目的改进建议。项目管理者在填写 commit message 时,可以用这些带 # 的标号来引用项目中的 issue 或 pull request。

采用哪种方式协作,主要取决于你的身份和需求。如果只是你和几个好朋友开发小型项目,在其中一人的旗下开辟仓库、再加 collaborators 功能即可;如果你是长期发展的团队之一员,加入对应的组织是更好的选择;如果你只是某个大型项目的「过路人」,但很想贡献自己的一点力量,提交 issue 或 pull request 自然是再好不过。

GitHub 所提供的入门教程中,精通 issues 讲解了 issues 的参与及管理方针,理解 GitHub 工作流讨论了在分支机制下协作的推荐方式,分叉他人项目则对 fork 与 pull requests 的流程进行了简明的介绍。可以一读。(此处提供的链接指向 Campfire 项目所贡献的中文翻译版本。)

4 Git 指南:进入深水区

如果你希望更加专业的组织和管理开源协作进程,GitHub 的网页端或客户端将不能满足你的需求。在此情况下,进一步学习 Git 本身的应用是非常必要的。

学习 Git,或学习其他任何的技术,都是需要花费时间成本的。如果你打算从事计算机方面的工作或研究,这些成本一般不会白费,总会有丰厚的收获;如果并非如此,则应该在开始学习之前谨慎考虑:学习这些技术对我将来的发展帮助多大?要花费多大的时间成本?是否值得?

如果你还没有打算学习 Git,点此跳到下一节

与界面精美的 GitHub 客户端不同,Git 本身并没有什么图形界面7,主要在命令行上操作。好在这些命令并不复杂,只需要尝试几次就能够基本掌握。当然,如果你希望成为一个 Git 高手,则需要相当长时间的实践与学习提升。

4.1 下载与安装 Git

在开始下面的内容之前,首先需要下载并安装最新版本的 Git。你可能需要一份安装教程)。

在 GitHub 客户端的目录中,事实上已经内置了 Git 程序(否则你也没法在客户端中提交更改),但不建议读者配置实用这里的 Git。不用担心你自己安装的 Git 会与客户端内置的 Git 冲突,他们通常是「不相往来」的。可参考 Stack Overflow 上一篇略有些过时的问答:What is the difference between Git for Windows and Github Desktop?

4.2 熟悉命令行:Git Bash

如果你已经使用过 Windows 系统的「命令提示符」(CMD)、Powershell,或者已经在 OS X 与 Linux 系统上使用过 bash,则以下的内容并不难理解。

以下仅以 Windows 系统为例介绍 Git 命令行的使用方法,其他系统上的内容将待日后更新。

安装 Git 之后,你可以在计算机的 D 盘或 E 盘中新建一个名为 Git 或 GitHub 的文件夹,专门用来存放代码仓库。在资源管理器中切换进这个文件夹内,打开右键菜单,选中其中一个名为「Git Bash Here」的条目,你就可以在这个目录下唤出 Git 命令行界面。这个命令行的界面与你安装时所做的选择有关;通常情况下,你将安装一个在 Windows 上实现的所谓 bash 的程序,以及一个显示它的终端 mintty

bash 是 Linux 与 OS X 系统上默认的命令行程序8(shell),其作用类似于 Windows 系统下的命令提示符(CMD)。采用这个程序(而非 Windows 系统),主要是基于 Git 所要求的跨平台性质——以及它来源于 Linux。mintty 则可以理解为容纳 bash 程序的平台,也即你所看到的花花绿绿的命令行窗口。

Git 的命令行界面与 Windows 的命令行差不多,不过前置的提示符号变成了一个美元号 $。在这个符号以后,你可以输入一些常用的命令,如

$ ls

可以列出当前目录下的所有文件与子目录(在 CMD 中,这命令是 dir),而命令

$ cd docs

可以将当前所在的位置切换到当前目录下名为 docs 的子目录内。这些文件级别的操作,通常可以在 Windows 系统的程序管理器中实现,所以可以不必关心。

这些命令都与 Git 没有关系,只是 bash 中已经集成的基本命令。那么,怎么调用 Git 的命令呢?只需要按这样的形式输入命令即可:

$ git <COMMAND>

其中 <COMMAND> 的位置上填上之前所提到的那些命令——如 pullpush 即可。在这里,命令 git 指明要命令行程序打开 Git 程序,而 <COMMAND> 乃至其后可能需要的参数(如文件名、附加选项等)则是赋给 Git 执行的参数。例如,如果你在命令行中输入

$ git add README.md

就意味着你要求将当前目录下名为 README.md 的文件存入暂存区。

如果你忘记 Git 的命令了,不用担心;你可以点这里回到之前的位置,也可以从这里开始阅读、浏览《Pro Git》一书中的「常用 Git 命令大全」。

不必因为记不住命令而愧疚、担忧;你随时可以查阅参考资料(这不是考试),也可以通过一段时间的实践轻松记住所有的常用命令。

使用 Git 之前,需要先利用 Git 的 config 命令配置一些基本信息。不可或缺的是这两项:

$ git config --global user.name "Zhang San"
$ git config --global user.email zhangsan@example.com

即你需要配置自己的名称与邮箱。这两条信息在之后的行为中相当于你的「身份证」。除此以外,由于需要与 GitHub 交互,你自然应该在 Git 中「登录」到 GitHub 上。最好的方式,是通过名为 SSH 公匙的机制。但对初学者而言,这个问题也可放在一边:第一次执行 push 操作时,Git 将会自动弹出询问你 GitHub 账号、密码的界面,并由此帮你配置公匙,整个流程与网页登陆几乎没有差别。

与用鼠标操作的图形化程序相较,命令行的一大妙处在于:你可以像默写作文一样轻松地完成你所需要的事情。我们不妨想象这样一个工作情景:你作为 qyxf 组织的一名成员,需要在一台刚刚安装了 Git 的电脑上开始工作,为组织旗下的 qyxf-sets 仓库提交一些改动。那么,你的整个工作流程大致是这个样子(每一个命令的反馈消息都已略去):

# 第一步:克隆 GitHub 上的远程仓库(网址外的引号是可选的)
$ git clone "https://github.com/qyxf/qyxf-sets"

# 从你的当前目录切换到仓库目录中
$ cd qyxf-sets

# 第二步:把命令行撂在一边,在外部程序中对 qyxf-sets 的文件做些修改
# 如果你熟悉在命令行中使用像 Vim 一样的编辑器,也可以直接这样
# (否则,不要这样做)
$ vim README.md

# 完成一切修改之后,先检查一下工作区中发生了哪些改动
# 此步命令将会列出你所作出的改动
$ git status

# 第三步:将你想要的改动记录到暂存区中
# 下面这条是记录所有改动
$ git add .
# 或者,你可以只加入某一个文件,例如只加入根目录下的 README.md 文件
$ git add README.md

# 你可以再一次使用 status 命令,确认改动都已被记录
$ git status

# 第四步:将暂存区中的改动提交到版本库
# 这里的 -m 参数表明:提交只有一行的 commit message,后面紧跟信息
# (建议这样去做,否则你将会与你所不熟悉的 Vim 相遇)
$ git commit -m "修改一些文件"

# 第五步:在提交到 GitHub 之前,再次同步,避免冲突
$ git pull

# 第六步:将改动发布到 GitHub 上
# 如果你是第一次这样做,可能需要按提示输入账号密码
$ git push

读者可以点此回看之前所提到的 Git 工作流程,与这里的具体代码、步骤一一对应。除此以外,在 GitHub Guides 中,Git 手册也给出了一些有参考价值的命令实例。

Git 的中的命令可远不止这些,进一步的讲解已经超出「上手教程」的范畴。读者可以在《Pro Git》中找到更多的知识,自己钻研。(不过,与啃书相较,在实践中进步也许是更好的选择!)

4.3 使用 GUI

如果你接触 Git 命令行已有一段时间了,就可以考虑安装一个图形用户界面(GUI)来提高自己的效率,并优化视觉体验。常见的 GUI 中,SourcetreeTortoiseGitFork 都是热门选项,读者可以任意选择一个;除此以外,在 Visual Studio CodeSublime Text 等新生代编辑器中都有对 Git 的内置支持或可选插件,也可以作为 Git Bash 的辅助工具。

除非你对 Git 命令行或你所使用的 GUI 之一非常熟练,否则你不太可能用其中的一个替代另一个的功能。初学之时,可以针对的两者各自的优势,在不同的情境下应用不同的工具。

5 GitHub 的其他功能

如果仅仅把 GitHub 当成一个代码托管平台,那可就是大大低估了这个网站了。GitHub 之所以能从程序员的小圈子里跳出来、成为门外汉都有所耳闻的新鲜名词,正是因为其有许多超出代码托管的新功能。这里仅对比较热门的几个应用简单介绍,读者可以对感兴趣的内容做些尝试。

5.1 GitHub Flavored Markdown

此处并不介绍 Markdown 的概念,或 GitHub Flavored Markdown (GFM) 的语法。

可以毫不夸张的说,GitHub 对 Markdown 的支持是 Markdown 得以推广的主要原因之一。在 GitHub 上,几乎所有的多行文本框都用 Markdown 渲染,以至于 GitHub 上的首要生存技能是 Markdown 而非 Git!也正因为如此,很多人以为 Markdown 就是 GFM,所以当他们到其他版本的 Markdown 中发现一些功能(例如表格、自动链接)不能实现时,甚至会认为这些 Markdown 引擎「不标准」。

Markdown 在以下几个场合是尤为重要的:

  • 文档撰写:读者最先能想到的 Markdown 文档,可能就是各个开源仓库首页上展示的 README 了。反过来,如果你发现自己电脑中某个软件里有 README.md 这样的 Markdown 文档,则它很有可能是发布在 GitHub 上的开源软件。
  • Issues:问题区当然支持 Markdown,因此你可以在帖子里轻松地插图、列表,甚至排版源代码。
  • 看板(Project):通过 GFM 拓展的复选框功能,你可以在 Project 面板中新建任务卡片,促进项目进程。

Markdown 的应用范围当然远不止这些,你可以自己发现更多的应用。

5.2 GitHub Pages

GitHub Pages 是由 GitHub 提供的一项静态网站托管服务,它可以将一个代码仓库由 Jekyll、Hexo 或 Hugo 等流行的网站/博客生成程序解析成一个网站,并发布在互联网上。与传统的网站或 Wordpress 等专业博客程序相较,GitHub Pages 的最大优势就是简单:你不需要任何网页制作、网站建设的技术,更不需要维护服务器,只要熟悉 Markdown 就能搭起一整个博客。

钱院学辅信息站正是由 GitHub Pages 托管的,由 Jekyll 生成。

借助于 GitHub 本身的强大特性与 Markdown 的诸多功能,GitHub Pages 具有诸多几乎无可替代的优点。例如,GitHub Pages 可以直接在代码仓库的文档分支下生成,由此即可一键生成项目的网站,免去了程序开发者建设、维护、美化网站的额外成本;页面全部由 Markdown 代码生成9,结构简单、改动方便,也易于同步、迁移到其他平台上;周边生态丰富,你可以很容易到找到美观的页面主题、插件,应用到你的网站中。

GitHub Guides 中的 GitHub Pages 入门是一篇很好的教程。

6 拓展阅读

如果想要系统地学习 Git,在线发布的《Pro Git》无疑是第一选择。对于初学者,此书的第一章:起步第二章:Git 基础第六章:GitHub附录 C:Git 命令是应当仔细阅读的;之后,可以再选读其他章节。

关于 GitHub,以上所提到的《Pro Git》第六章就是一份非常有水准的教程(只有页面截图版本较老)。GitHub 所提供的 GitHub Guides(你可以读中文版)则是非常适于新手入门的「食谱」(cookbook),在前面的正文中已经反复提到。除此以外,以下的这些在线教程也可供参考:

最后,在熟悉了 GitHub 的使用方法后,别忘了关注我们的作品!

对于本文档有任何意见、疑惑、改进建议,请到信息站的问题区及时反馈,我们深表感激!

  1. 想要详细的学习Git的使用,可参考Git的官方在线教程:Pro Git——这里提供的是码云上的中文翻译。 

  2. 数据来自于:GitHub自述页面,查看于2019年6月13日。 

  3. 准确地说,Git并非较早诞生的版本控制软件,GitHub也远非最早的远程开源仓库(更早者有SourceForgeLaunchpad等),但GitHub可以说是首次让开源仓库这个概念冲出了程序员的小圈子。 

  4. clone操作对本地的版本库同样有效——例如,你可以用此命令将一个在此目录下的版本库拷贝到彼目录。当然,一般并没有人做这样的事情。 

  5. Word 文档可以说是用 ZIP 方式压缩的 XML 文档(外加其所引用的一些多媒体对象)。如果你想理解前面这句话,不妨在自己的计算机上任找一个 .docx 文件,将其后缀名改成 .zip,解压缩后看看里面有些什么。 

  6. 注意,「拉取请求」是对项目管理者(而非贡献者)而言的;你所提交的更改,对你而言当然是 push,对于项目管理者而言则是 pull。 

  7. Git 自带两款分图形用户界面,分别用于查看版本历史(gitk)与提交改动(git-gui)。不过,它们的功能比较有限,界面也很不美观。可参考Pro Git - 附录 A: 其它环境中的 Git - 图形界面。 

  8. 「命令行程序」究竟是什么,这里无法解释清楚了,也没有太大的必要。 

  9. 当然,纯粹的 HTML 代码也是支持的,不过一般而言没有必要(除非是在个别页面上有特殊的样式、脚本需求)。 

参与讨论