VCS简介
一、三类版本控制系统
1、本地版本控制系统
1)机制:通过数据库记录文件历次更新的差异,差异以补丁的形式记录对应文件修订前后的内容变化。
2)不足:不支持多开发者协同工作。
3)典型软件:rcs。
2、集中化版本控制系统
1)机制:单一的集中管理的服务器保存所有文件的修订版本,协同工作的人们通过客户端连到该服务器,取出最新的文件或提交更新。
2)不足:中央服务器的单点故障可能导致数据丢失。
3)典型软件:CVS,Subversion,Perforce等。
3、分布式版本控制系统
1)机制:每个客户端都拥有独立且完整的版本仓库,且客户端地位相等(类似P2P网络),它们之间可相互获取、推送更新。
2)优点:
- 消除集中版本控制系统的单点故障;
- 协作开发时,允许单个客户端在本地版本仓库独立提交更新,并在合适时推送给其他客户端或某个约定为中央仓库的客户端。
3)典型软件:Git,Mercurial,Bazaar,Darcs等。
二、Git基础
1、Git优势
速度
简单的设计
对非线性开发模式的强力支持(允许上千个并行开发分支)
完全分布式
有能力高效管理类似Linux内核一样的超大规模项目(速度和数据量)
2、Git特性
1)保存快照,而非差异
Git关心文件整体内容的变化,而大多数其他系统则关心文件内容的差异。
此特性为多分支并行开发提供了支持。
2)几乎所有操作都是本地操作
- 速度快
- 客户端离线时也可进行更新操作
3)时刻保持数据完整性
- 保存到Git之前,所有数据都要经过Hash运算,并将Hash值作为数据的唯一标识和索引,而非文件名。
- Git采用SHA-1算法来生成文件或整个目录的杂凑值,并作为唯一标识。该算法输出160bit哈希值,即40个16进制字符(0-9及a-f)。类似
24b9da6552252987aa493b52f8696cd6d3b00373
。
4)多数操作仅添加数据
- 保证历史版本的可回溯
5)三种状态(git status
命令当前状态)
原理:通过比较相同文件名所对应的SHA-1值是否相同,来判断文件是否更新。
I、已修改(modified)
- 状态:工作区的文件已修改,还未暂存。
- 系统通过比较工作区和暂存区(对应.git/index)内相同文件名的文件的SHA-1值,来判定文件是否更新。
- 用户可通过
git diff
命令查看工作区和暂存区内容的具体差异。
II、已暂存(staged)
- 状态:工作区修改的文件已保存至暂存区,但还未提交。
- 系统通过比较暂存区(对应.git/index)和Git仓库(对应.git/HEAD)内相同文件名的文件的SHA-1值,来判定文件是否更新。
- 用户可通过
git diff --cached
命令查看暂存区和Git仓库的具体内容差异。
III、已提交(committed)
- 状态:暂存区的文件已提交至版本库。
- 系统通过比较暂存区和Git仓库内相同文件名的文件的SHA-1值,来判定文件是否更新。(同上)
6)单向性
I、当差异发生时提示已修改,已暂存,已提交三种状态,这暗示了Git中更新并提交文件的单向性,工作区 → 暂存区 → Git目录。
II、Git中的版本回退命令git reset
和git revert
在各自不同参数下的执行结果都满足工作区的版本不旧于暂存区,暂存区的版本不旧于Git目录。
Note:git reset
和git revert
命令在提交层面上实现回退的思路不同,前者做减法(适合在私有分支上回退),而后者做加法(适合在公共分支上回退)。
III、本质上讲:
git不关心文件新旧,只关心文件是否相同(通过相同文件名的SHA-1值判断)。
- 若相同,直接引用已有文件的SHA-1值,Git仓库内也只会保留一份文件;
- 若不同,则引用更新后文件的SHA-1值,Git仓库会保有不同版本的文件。
约定更新和提交是单向的。
Note:git add
命令后,新增或更新的文件会以blob对象(blob、tree、commit、tag四大对象之一)的形式首次进入./git/objects目录。
三、Git操作清单
接下来的文章将针对不同的场景需求,对Git的命令和操作进行解析和实践。本文依据不同场景对操作进行归类,以此对Git的功能有个全面的认识。
Git自助服务:
git help 命令
可获取命令详情
1、Git配置
- 配置基本信息
git config
- 配置用户信息
- 配置工具:文本编辑器、差异分析工具
- 配置忽略文件
vim file
- .gitignore
- .git/info/exclude
- $HOME/.config/git/ignore
2、Git基础操作
- 获取项目Git仓库
- 当前目录初始化
git init
- 现有仓库克隆
git clone
- 当前目录初始化
- 提交更新至Git仓库
- 跟踪新文件
git add
- 暂存已修改文件
git add
- 提交文件
git commit [-a]
- 撤销操作
- 修改最后一次提交
git commit --amend
- 回退Git仓库
git revert
|git reset --soft
- 回退暂存区
git reset [--mixed]
|git reset [commit] file
- 回退工作区
git reset --hard
|git checkout [commit] file
- 储藏与恢复
git stach
|git stash pop
- 查看提交记录
git fsck
|git log
|git log -g
|git reflog
- 清除未跟踪文件和目录
git clean -df
- 查看操作
- 储藏与恢复
- 修改最后一次提交
- 查看当前状态
git status
- 查看文件差异
git diff
|git diff [commit]
|git diff --cached commit
|git diff [commit] [commit]
- 查看完整提交历史
git log [-g]
|git reflog
- 跟踪新文件
3、Git远程仓库操作
- 管理远程仓库
- 查看
git remote [-v]
- 增加
git remote add
- 修改
git remote rename old-name new-name
- 删除
git remote rm name
- 查看
- 远程仓库交互
- 抓取数据
git fetch
|git pull
- 推送数据
git push
- 抓取数据
4、Git标签/分支
- 标签
- 标签类型
- 查看标签
git tag
- 管理标签
git tag
- 分支
- 分支概念和原理
- 远程分支/跟踪分支
- 创建分支
git branch
|git checkout -b
- 删除分支
git branch -d
- 合并分支
git merge
- 衍合分支
git rebase
- 开发中的分支工作流程
5、其他补充内容
- 祖先引用
- 提交范围
- 双点语法
- 三点语法
- 多点范围
- 补丁
- 挑拣(cherry-pick)
- git调试
- 文件标注
- 二分查找
- 重写历史
- 修改最近一次提交
- 修改多个提交
- 重排提交
- 压制提交
- 拆分提交
- 子模块