一、Git 是干什么的
官网是 git-scm.com。一句话概括:免费的、开源的分布式版本控制系统,快,而且从小项目到大项目都带得动。周边的生态也大,GUI、托管服务、命令行工具一大堆。
版本控制这件事本身很简单,就是记录版本变化,记录文件修改的历史。多人协作的时候如果各存各的副本,版本一多就乱了:每个人都可能建副本,谁也说不清哪份是最新的,而且存这么多版本本身就很麻烦。
Git 的做法是把两边的修改合并到一起,而不是拿一份去覆盖另一份:

版本控制系统分两类,先说老的那一类。
集中式版本控制工具:历史版本都放在中央服务器上。好处是每个版本、每个人改的代码都清清楚楚;坏处是单点故障 —— 中央服务器一坏就完蛋,更新不了,也看不到别人的代码。

分布式版本控制工具,Git 就是其中之一。它没有中央服务器这回事,每个人都在自己的本地库做版本控制,然后提交到远程库;别人想改代码,直接从远程库下载,改完再推回去。这样就没有单点故障了,而且远程库一般是其他公司提供的服务,基本不会出事。

二、代码托管中心
远程库就是代码托管中心,按开源不开源分两种用法:
- 不开源、走内网:用 GitLab,公司自己搭
- 开源、能联网:用 GitHub,或者国内的 Gitee(码云,相当于 github 国内版)
三、工作区、暂存区、本地库
这三层是 Git 最核心的概念,先把图记住:

- 工作区:写代码的地方,就是在文件夹里看到的东西
- 暂存区:
add之后文件先放这儿,属于临时存储,可以用命令删掉 - 本地库:
commit之后进到这里就变成历史版本了,历史版本删不掉,除非删库跑路
本地库还能 push 到远程库,整条链路画出来是这样:
你的电脑(本地) 公司服务器(远程)
↓ commit ↓
[本地库] --git push--> [远程库]
<-git pull--
git add 文件名 # 工作区 → 暂存区
git commit -m "备注" # 暂存区 → 本地库
git push 远程地址 # 本地库 → 远程库
四、安装和 git bash 客户端
安装路径不要带中文,新的安装包会自动覆盖旧的。
图形化界面我都不用,用的是 git bash 客户端。它和 linux 的命令行很像,但是只有基本的操作命令。
圣果@shengguo MINGW64 ~
$ git --version
git version 2.55.0.windows.3
五、全局配置
装完第一件事是配用户签名,这个是必须设置的,用来区分不同操作者的身份:
# 设置用户签名(全局配置,只需设置一次)
git config --global user.name 用户名
# 设置用户邮箱(全局配置,只需设置一次)
# 可以设置虚拟邮箱,git不会验证邮箱
git config --global user.email 邮箱
我当时是这么配的:
圣果@shengguo MINGW64 /demo
$ git config --global user.name shengguo
圣果@shengguo MINGW64 /demo
$ git config --global user.email shengguo
想验证的话,去 win 的家目录看 .gitconfig 文件:

有一点得说清楚:用户签名和登录代码托管中心的账号没有任何关系,它只是本机提交时署的名字。
六、初始化本地库
git init 的作用是把一个普通文件夹变成 git 能管理的仓库(不是赋予权限),执行完会多出一个隐藏的 .git 文件夹:
圣果@shengguo MINGW64 /demo
$ git init
Initialized empty Git repository in F:/git/demo/.git/
圣果@shengguo MINGW64 /demo (master)
$
# master是 git 仓库的默认主分支
# F:/git/demo/.git/ ← 这个隐藏文件夹被创建了

ls -a 也能看到隐藏文件。另外提一句:.git 里面的东西不要手动改。
建一个本地文件夹放测试项目就行。git 可以随便切目录,不过直接在项目文件夹里打开 git 更方便。
七、克隆别人的项目
第一次拿别人的项目用 git clone 远程地址。它不需要登录账号(和在浏览器下载项目差不多),会自动初始化本地库,还会自动把远程地址命名成 origin。
顺手区分两个命令:pull 是下载 + 合并,clone 是完整下载。具体操作放在第 4 篇。
八、两种协作模式
一种是团队内协作:团队共享一个远程库,成员各自 push、clone、pull(更新本地库)。

另一种是跨团队协作:团队之间的远程库是独立的,两个库之间通过 fork 拷一份项目文件出来,对方 clone 到本地改完,push 回自己的远程库,最后发起 Pull request(拉取请求)给对方,对方审核通过再 merge,代码才算传过去。

这两块的具体操作都在第 4 篇讲。