目录
1、版本控制工具应具备的特点
- 协同修改:多人并行不悖的修改服务器端的同一个文件。
- 数据备份:不仅保存目录和文件的当前状态,还能够保存每一个提交过的历史状态。
- 版本管理:在保存每一个版本的文件信息的时候要做到不保存重复数据,以节约存储空间,提高运行效率。这方面 SVN 采用的是增量式管理的方式,而 Git 采取了文件系统快照的方式。
- 权限控制:对团队中参与开发的人员进行权限控制。对团队外开发者贡献的代码进行审核——Git 独有。
- 历史记录:查看修改人、修改时间、修改内容、日志信息。将本地文件恢复到某一个历史状态。
- 分支管理:允许开发团队在工作过程中多条生产线同时推进任务,进一步提高效率
2、版本控制工具分类
- 集中式版本控制工具:服务器一旦故障则历史记录全部丢失,用户本地只有一份最终文件。例如 cvs,svn
- 分布式版本控制工具:用户本地也是一个服务器,有完整的历史记录版本控制,可以和其他用户之间进行数据的恢复。例如 Git,Mercurial
3、Git结构
先不看远程服务器,只关注自己的本地电脑。git的使用过程如下:
4、代码托管中心
- git已经实现本地的版本控制
- 代码托管中心就是去维护远程库(远程服务器,在上面也维护了一份代码,开发者可以从其中拷贝到本地,也可以从本地推送到远程服务器)
- 局域网环境下:GitLab服务器(公司内部一般使用该服务器)
- 外网环境下:GitHub(全世界的人可以在这上面共享项目,进行开源)
5、本地库和远程库的联系
- 团队内部协作
远程库由 B 创建,此时B把A也加入团队,则A就拥有了项目的权限。
- 跨团队协作
开发者C不是团队成员,不能直接修改远程库代码,则通过fork操作得到一个属于C的远程库。那么C修改了远程库后需要发起 pull request请求, 由B进行审核并merge,把 C的远程库中修改的内容合并到 远程库B。
6、安装Git
- 下载对应的安装包,如下图所示。并安装到一个非中文每空格的目录下。
- 安装成功后可以在windows任何一个目录下右键,选择 Git Bash Here 进入命令窗口。如下图所示
7、基本命令操作
鼠标右键-->Git Bash Here-->进入命令窗口-->通过命令开始使用Git(linux的命令在此处基础都适用)
初始化本地库 | git init | 操作步骤:创建文件夹gitTest,进入文件夹, 使用命令 git init 初始化本地库。 产生结果:会生成一个 gitTest/.git 目录,不要修改。 |
设置签名 | git config | 签名作用:区分开发者,在本地提交后通过查看日志,可以看到开发人员的名称和邮件。 项目级别签名:仅在当前本地库范围内有效,信息保存在 ./.git/config 文件中。 设置方式:git config user.name Tom git config user.email 123@qq.com 系统级别签名:登录当前操作系统的用户范围有效,信息保存在 ~/.gitconfig 文件中 设置方式:git config --global user.name Tom git config --global user.email 123@qq.com 签名级别优先级:项目级别优先于系统级别,不允许二则同时不存在 |
查看状态 | git status | 查看工作区,暂存区的状态 |
添加到暂存区 | git add [fileName/*] | 将工作区的 ‘新建/修改’ 添加到暂存区 git add * 表示添加所有改动的文件 |
添加操作回退 | git rm --cached [fileName] | 把未追踪的文件添加到暂存区后的还原操作,文件重新恢复到未追踪状态 |
提交到本地库 | git commit | 将暂存区的内容提交到本地库 git commit -m “msg” [fileName] 提交的时候附带说明 git commit [fileName] 进入到vim编辑器去编写提交说明 |
查看日志 | git log | 控制方式: 空格-翻页,b-向上翻页,q-退出 最全的展示:git log 一行展示日志:git log --pretty=oneline 一行展示日志简洁版: git log --oneline (会截取hash值展示) |
下图可以看到一整套操作过程:创建本地库-->新建文件-->查看状态-->添加到暂存区-->提交-->查看日志
8、版本管理
- 我们通过git reflog命令打印的日志来理解版本
如下图/表,每一次提交都会生成一个全局唯一hash值,对应到一个版本。有一个指针(HEAD) 通过移动来指向对应的版本。我们通过移动该指针可以控制版本的前进和回退,即可以进行文件的还原或恢复。
hash值的部分值 | HEAD指针指向的位置 | 回到当前版本需要回退的步数 | 提交的日志 |
---|---|---|---|
5d80a53 | (HEAD -> master) | HEAD@{0}: | commit: test2.txt第一次提交 |
a5eb47d | HEAD@{1}: | commit: test1.txt追加内容def | |
56a073a | HEAD@{2}: | commit: test1.txt追加内容abc | |
cd9ca2d | HEAD@{3}: | commit (initial): test1.txt第一次提交 |
- 前进后退操作
方法 | 命令 | 作用 |
---|---|---|
基于索引值(hash值) | git reset --hard [局部索引值] | 回到某个版本 |
使用^符号 | git reset --hard HEAD^ | 只能后退,后退一步 |
使用~符号 | git reset --hard HAED~n | 只能后退,后退n步 |
- reset命令的三个参数对比
--soft | 仅在本地库移动 HEAD 指针 | 不常用 |
--mixed | 在本地库移动 HEAD 指针 重置暂存区 | 不常用 |
--hard | 在本地库移动 HEAD 指针 重置暂存区 重置工作区 | 常用(可以通过其重置特性来恢复工作区被删除的文件) |
- 比较文件
git diff [filename] | 和暂存区的文件比较 |
git diff [本地库中历史版本] [filename]
| 和本地库中的某个版本比较 例如: git diff HEAD^ test.txt git diff 5d80a53 test.txt |
不带文件名比较多个文件 |
9、分支
项目创建之初默认有一个主干分支(master),但是多个版本无法同时在一个分支上并行开发。所以我们需要创建多个分支,来让团队并行开发,开发完成后分别再合并到主干分支上。
- 分支的操作
创建分支 | git branch [分支名] | |
查看分支 | git branch -v | |
切换分支 | git checkout [分支名] | |
合并分支 | git merge [有新内容的分支名] | 例如上图中:feature_blue分支开发完成后,我们切换到master分支,并执行命令 git merge feature_blue,把开发的内容合并到master主干。 |
解决冲突 | 合并后有的文件可能有冲突,需要我们手动修改文件。 然后添加到暂存区 git add [fileName] 最后提交 git commit -m "msg" ,注意commit 此时不能带具体文件名 |
10、Git原理
- 保证数据的完整性
保证通过网络下载的文件跟服务器上一样:Git利用哈希算法的特性,对服务器和本地同一个文件进行哈希,得到的结果一致则表示文件没有丢失或损坏。
- Git保存版本的机制
Git每次提交,都会对当前全部文件制作一个快照,并保存这个快照的索引。若相比较上个版本有改变的文件,在快照中则保存完整的文件,若没有改变则保留一个指向文件的链接即可。
- Git提交机制
每一次提交都会产生一个区块
各个提交区块之间则由父子关系连接成一条链路
类似于区块链,通过对每个数据进行哈希,且把每次的哈希值都记录到上层的区块,再对上层区块进行哈希.......依此类推。这样只要任何一个地方数据有变动,其上层的所有数据的哈希值都会有变化,校验机制就会检测不通过。
- Git分支管理机制
对于svn而言 ,创建一个分支,是直接把项目copy一份,显得太笨重。
对于git而言,创建一个分支,只需要新增一个指针,详情如下图: