参考
版本控制系统的基本需求
将版本控制比作一个时间机器,将项目放到这样一个时间轴上,我们可以随时回到任何一个特定的版本。

版本控制时间轴
为了实现这一点,需要记录每个版本的完整信息,方便快速回到对应版本,这种方式称为全量方案。

全量方案
对于代码和文本这类字符型内容,全量方案更为适用,因为它们占用的空间相对较小。而对于视频和大型二进制内容,增量方案能更好地节省空间。
Git选择将所有版本信息放在项目根目录的 .git 文件夹中。
[!WARNING] > 发布网站时,不要将
.git目录发布出去,因为.git文件夹中包含着整个版本信息,包括源代码和可能存在的账号密码,都可以通过这个.git目录访问到。
Git使用文件的 SHA1 值作为文件名,SHA1 和 MD5 都是哈希函数,通过计算文件内容提取较短的哈希值,保证版本库中所有相同内容的文件只保存一份。
tree结构和暂存区
tree 结构
在Git中,标记为 tree 的是目录,blob 是文件。

tree结构
如果子目录中的文件修改了,文件的 SHA1 值会发生变化,那么文件夹的 SHA1 值也会发生变化,这些值的变动会保存到新的文件中,从而完成更新内容的信息存储。

子目录变化
文件内容会保存到 Objects 目录中。对于内容非常大的文件,Git使用哈希值的前两位来管理文件。

Objects管理
如果自动提交会生成很多无用版本,因此建议使用手动操作。

手动操作
暂存区

暂存区操作
文件状态判断:
- 如果文件在代码和暂存区中,但SHA1值不匹配,则文件已修改。
- 如果文件不在代码中但在暂存区中,则文件已删除。
- 如果文件在代码中但不在暂存区中,则文件是新增的。

文件状态判断
对比暂存区和 .git 也能知道文件的状态。

暂存区与 .git 对比
文件从暂存区提交到Git中会产生一个快照,描述当前文件夹下所有文件的状态。

快照生成
不断提交操作会产生多个快照,形成一个链表。使用指针 HEAD 指向最新快照,当需要某个快照时,将 HEAD 指针指向该快照,然后 checkout 即可恢复工作区内容。

指针与快照
协同和分支
网络问题
团队环境下,代码仓库应放在服务器上,集中访问。若网络出现问题,无法同步版本管理,可以在主机上放置一个Git版本管理软件,待网络恢复后再将本地版本上传至服务器。

网络问题
如果服务器上有不同部分需要分别修改,两个工程师将文件同步到本地仓库后,根据需求修改文件,服务器端可以很容易同步不同文件的修改。

文件同步
文件问题
若同时修改相同文件,会产生冲突。第一位同事先提交,服务器正常接受,第二位同事提交时,产生冲突,需手动解决冲突后再提交。

冲突解决
分支
为了管理不同功能或开发者的工作,可以使用分支。假设生产环境是 online,开发环境是 dev,在开发分支内测公测完后合并到 online,保证线上代码的稳定性,同时能将测试代码 checkout 到分支环境。

分支管理
合并
Merge
找到两个分支的共同祖先,进行三方合并,合并后的提交叫 Merge。

Merge
Rebase
Git会找到共同提交,撤销微博线的提交并保存到临时目录,将 wechat 的提交应用到 weibo 分支中,形成新的 weibo 分支。

Rebase
Cherry-pick
在 wechat 分支上只想合并 weibo 分支的某些特定提交,可以使用 cherry-pick。

Cherry-pick
回顾
Git采用全量存储方式保存历史文件,历史版本库中包含完整信息,存储在 .git 目录中。文件内容的 SHA1 值作为名称,相同文件只存储一份,通过内容寻址。Git定义了 tree 目录结构描述和容纳目录及文件的 SHA1 值,暂存区作为源代码和版本库之间的中间层,当暂存区内的代码上传到版本库时,会产生新的提交(commit),多个提交形成链表,使用 checkout 对应的链表值,可以回到对应的版本。Git提供了分支概念,支持在不同分支下进行工作,最终合并到 master 上。在本地仓库和远程仓库之间,网络状态良好时提交到远程仓库中。对于合并,使用 Merge 和 Rebase 两种方式,Rebase 修改提交历史,建议在本地使用。通过分支管理,可以实现不同功能或开发者的独立工作,并在最终合并到主分支当中。

总结
Git 常用命令
本地仓库相关

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png