Git 版本控制
Git 版本控制
1. 什么是 Git
Git 是当今世界上最先进/最好用的分布式版本控制系统,没有之一
2. 什么是版本控制系统?
版本控制 — 《维基百科》
版本控制是一种软件工程技巧,能在软件开发的过程中,确保由不同人所编辑的同一个代码文件都得到同步.
版本控制能使项目的设计者,将项目恢复到之前任意的状态,这种选择权在设计过程中特别重要.
理论上所有的信息记录都可以加上版本控制:利用版本控制来追踪、维护源码、文件以及配置文件等等的改动
3. 版本控制发展史
3.1 文件名方式
早年的软件开发过程,代码管理以手动和邮件等形式,文件命名及保存存在问题
如图 : 文件命名方式
如图 : 毕业论文版本
3.2 集中式
包括库和工作区两部分:在工作区编码,然后上传至库的方式,完成多人协作。
问题:工作机与库机,需要联网才能控制版本,传输速度较慢。

3.2 分布式
每台电脑都有,工作区和库,可以自己控制版本。数据更加安全,有逻辑上的中心。

4. 常见版本控制系统
如图 : 版本管理器的发展史

这张图上,分成了四个时期 :
● 史前时期:1982年的RCS。现在你可能还能在Unix的发布包中找到它。
● 古典时期:1990年的CVS自身缺陷已经过时;1985年的PVCS、1992年的clearcase(费用昂贵、功能复杂沿用至今);微软VVS反人类;Perforace(广泛,谷歌内部最大代码管理器)
● 中世纪时期:SVN解决了CVS的问题,集中式领域王者。AccuRev(支持分支合并让很多公司拜托cvs和clearcase)。
● 文艺复兴:BitKeeper(SUN公司大量使用),2002年Linux内核使用BitKeeper,2005年闭源时有人试图破解BitKeeper,于是出现了Git。
Git 问世
Git的第一个版本是Linux之父Linus Torvalds亲手操刀设计和实现的(两周内 用C写完),Linus不仅仅给出一个原始设计,并在向世人介绍Git时强烈批评了CVS和SVN等,Git消除了分支和合并的恐惧。很多大型开源项目由SVN迁移至Git。
2008年GitHub也成为世界最大的SCM系统(软件配置管理),它使用的就是Git版本库的技术.从此Git成为版本控制系统的主流。
GitHub上的著名项目 :
Linux内核、安卓、jQuery、Bootstrap、Ruby …
5. Git 的安装 和 基本配置
5.1 安装
Linux 安装
二进制包(在线)
yum -y install git // RedHat系列
apt-get git install // Debian系列
源码包(官网下载)
Windows 安装
Git 在 Windows 使用模拟环境 msysgit
下载地址:
https://git-for-windows.github.io/
注意:如果想让 windows 作为 git 服务器则需要搭建ssh服务。
本教程使用 windows 版本来做演示 :
安装步骤: (如果你不熟悉每个选项的意思,请保持默认的选项)
- 以
管理员方式运行安装包,选择是安装

- 同意协议条款

- 选择安装选项: 安装Git Bash和Git GUI,创建图标(可选)

- 选择 Git 的默认编辑器 (默认为vim,可选取自己熟悉的编辑器)

- 选择:
git form the command line and also form 3rd-party software(GIT命令行和第三方软件)

- 选择: 选择 OpenSSL 传输 HTTPS 的信息

- 选择 : 换行符默认为 windows 环境为主

- 选择 : MinTTY 默认终端

- 选择 : 系统文件缓存 和 git 的管理器(需要.net v4.5.1)

- 实验选项,暂不选择

- 点击 Install 安装,开始安装

- 安装完成,选择运行
git bash工具

- Git 运行界面 (命令行提示的是 你电脑的用户名)

5.2 配置
无论 Linux 还是 Windows,安装完成后都要初始化
1 | # 查看 git 版本 |
6. Git常用操作
6.1 生成新的版本库
- 新建空目录
- 进入该目录—单击右键—选择
Git Bash Here - 弹出 git 的命令行工具
- 初始化该目录为版本仓库,键入
git init - 显示
Initialized empty Git repository in xxxxxx ls -a查看该目录下出现.git的隐藏目录,即版本库- 初始化完成
6.2 添加文件到版本库
- 新建文件
1.txt - 查看当前版本状态
1 | # 查看当前版本状态 |
- 红字提示有文件未跟踪(未加入版本控制)
- 在命令行内输入以下,添加文件至版本库:
1 | # 添加文件至缓存区 |
- 执行完后,提示提交完成
- 查看提交后的版本库状态:
1 | $ git status |
- 至此,最简单的添加文件,到版本库的操作已完成
— PS部分: Git 实现原理 —
- 工作区 : 就是程序员日常编写代码的文件夹
- 版本库 : 负责代码版本控制,就是
.git隐藏目录 - 版本库原理图 :

版本库包括:暂存区(index/stage),HEAD(指针),分支(默认为 master 主分支)等。
文件提交至版本库总共分两步:
git add filename# 添加至 stage 缓存区git commit -m "描述"# 将 stage 的内容提交至版本库的 master 分支
实验:
- 修改文件 >>> 查看状态
- 添加到缓存区 >>> 查看状态
- 再次修改 >>> 提交 >>> 查看状态
实验过程如下,观察理解 Git 实现机制:
- 修改文件 >>> 查看状态:
- 修改
1.txt文件的内容,添加一行111,查看状态:git status - 提示:
Changes not staged for commit:(工作区的修改,还没有提交到缓存区) - 显示红字,
modified: 1.txt
- 修改
- 添加到缓存区 >>> 查看状态:
- 添加到缓存区
git add . - 查看状态:
git status - 提示:
Changes to be committed(要提交的修改。表示已提交到缓存区,待提交到版本库) - 显示绿字:
modified: 1.txt
- 添加到缓存区
- 再次修改 >>> 提交 >>> 查看状态
- 继续修改文件:
1.txt文件的内容,添加一行222 - 提交版本库:
git commit -m "第1次修改 1.txt" - 再次查看状态:
git status - 提示:
Changes not staged for commit(表示工作区中,还有修改记录,没有被提交到版本库之中) - 显示红字:
modified: 1.txt
- 继续修改文件:
说明:
- 第 3 步的提交,只是提交了缓存区内,已经缓存过的内容(即,第二步的
add .操作) - 第 3 步中的第二次修改文件内容的记录,并没有添加到缓存区,所以版本库与工作区文件不一致
- 此时需要将第二次的修改记录,添加到缓存区,再次提交即可
1 | git add. |
6.3 查看文件修改状态相关
1 | # 查看当前版本状态(是否修改) |
修改文件,测试区别:
1 | # 当 工作区/缓存区/版本库 都一致时,使用以下命令不会有任何提示 |
6.4 Git 日志
1 | # 查看提交历史 |
6.5 版本回退
1 | # 将当前版本重置为 HEAD(通常用于清空缓存区,或 merge 失败回退) |
6.6 撤销
目的:将尚未提交至版本库的修改撤回
- 情况一 : 文件修改后,尚未添加至缓存区
1 | # 修改 1.txt 的内容:添加一行 |
- 情况二 : 文件修改后,已添加至缓存区
1 | # 修改 1.txt 的内容:添加一行,并添加到缓存区 |
6.7 Git 删除
- 删除文件和版本库记录
1 | # `rm`命令只会删除工作区的文件,不会删除记录 |
- 删除缓存区的文件
1 | # 新建 demo.html 文件,并加入到缓存区 |
- 其他删除
1 | # 新建 aaa/111.txt |
6.8 Git 流程图

7. 远程仓库
7.1 得到远程的版本库
可以使用两种方式来得到远程版本库:
- 在某个指定的文件夹下使用,即可得到远端版本库及代码
1 | git clone <远端版本库url> <本地存放该库的文件夹名> |
- 手动添加版本库,并拉取文件
1 | # 初始化本地仓库 |
7.2 推送分支代码
得到远端版本库后,可以在本地按正常的步骤编辑 :
新建或改动文件–>添加至缓存区–>提交到版本库
此时,要想将本地版本库发给远端,只有commit提交是不够的.
还需要下面的操作 :
1 | git push <remote> <branch> |
执行以上代码,会有报错 : 无法直接推送到远端的主分支
此时,可以曲线救国,推送自己的分支到远端即可 :
1 | git push origin master:dev |
此时,推送成功!
8. Git 分支管理
8.1 查看版本库分支
1 | # 显示本地分支 |
8.2 创建分支/删除分支
1 | # 新建分支 |
8.3 合并分支
要将 B分支 合并到 A分支里
请切换到A分支内,合并B分支的操作在A分支内进行
1 | # 合并分支到当前分支 |
8.4 解决合并冲突
多分支修改同一文件,合并可能出现冲突。冲突部分用<<<===>>>表示

解决方法:
先手动修改冲突部分,再次提交即可。
8.5 分支管理策略
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
所以,团队合作的分支看起来就像这样:

8.6 多人协作
多人协作的工作模式通常是这样:
首先,可以试图用git push origin <branch-name>推送自己的修改;
如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
如果合并有冲突,则解决冲突,并在本地提交;
没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!
如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>
这就是多人协作的工作模式,一旦熟悉了,就非常简单。
9. 使用代码托管系统
市面上有名的Git托管系统 :
9.1 码云 生成SSH密钥及使用
- 本地打开git bash ,
cd切换到用户的家目录 - 使用
pwd来查看目录是否正确 - 使用
ssh-keygen.exe -t rsa来生成SHA256的SSH密钥(按回车确认即可) cd .ssh/切换至ssh目录ls查看目录下文件cat id_rsa.pub查看生成的密钥,并复制- 打开码云,登录自己的账户.点选个人资料
- 选择SSH公钥
- 在添加公钥界面,将刚刚复制好的密钥粘贴进来,再自己取一个该密钥的名字,以便于区分管理
- 本地新建一个目录,用于拉取远端版本库
- 使用
git init初始化该目录 - 使用
git remote add origin <SSH地址>来添加远程版本库 - 使用
git remote -v来查看远程版本库信息 - 使用
git pull origin marster来拉取版本库及代码
9.2 GitHub 生成SSH密钥及使用
- 运行 git Bash 客户端,输入如下代码:
$ cd ~/.ssh$ ls- 这两个命令就是检查是否已经存在 id_rsa.pub 或 id_dsa.pub 文件,如果文件已经存在,那么你可以跳过步骤2,直接进入步骤3
- 创建一个 SSH key
$ ssh-keygen -t rsa -C "your_email@example.com"- 代码参数含义:
-t指定密钥类型,默认是 rsa ,可以省略。-C设置注释文字,比如邮箱。-f指定密钥文件存储文件名。
- 添加你的 SSH key 到 github上面去
$ cat ~/.ssh/id_rsa.pub
- 测试一下该SSH key 在git Bash 中输入以下代码
$ ssh -T git@github.com- 显示类似如下,表示成功:
Hi username! You've successfully authenticated
git clone 远程git仓库地址
10. 文件忽略
想要工作区的某些文件,不受版本的控制,可使用.gitignore文件进行忽略.
!(注意, .gitignore文件 是没有名字的文件.)
规则:
- 以斜杠
/开头表示目录 - 以星号
*通配多个字符 - 以问号
?通配单个字符 - 以方括号
[]包含单个字符的匹配列表 - 以叹号
!表示不忽略(跟踪)匹配到的文件或目录
配置文件是按行 从上到下 进行规则匹配的,
这就意味着如果前面的规则匹配的范围更大,则后面的规则将不会生效.
11. 使用 TortoiseGit 操作 Git
TortoiseGit 俗称 [ GIT小乌龟 ]
Git 常用命令速查
- master 默认主分支
- dev 默认开发分支
创建版本库
1 | # 初始化本地git版本库(创建新仓库) |
修改、提交、删除
1 | # 添加index.php文件到缓存区 |
查看
1 | # 查看当前版本状态(是否修改) |
回退 与 撤销
1 | # 将当前版本重置为HEAD(通常用于merge失败回退) |
分支操作
1 | # 获取远程分支master并merge到当前分支 |
远程协作
1 | # 添加远程版本库 |
黄超.Seeker
更多信息,详见: Pro Git(中文版)

