随着对git不断使用,逐步进行学习和理解,现把学习整理成一系列基础内容,供大家参考和讨论。主要包括:
1、git工作原理
2、开展git项目
3、多人合作git操作(代码拉取,回滚和撤销,合并代码)
4、其他一些辅助工具
本节对git的工作原理进行介绍:
一、git是什么
1、git是一个分布式版本控制软件,最初由林纳斯·托瓦兹(Linus Torvalds)创作,于2005年以GPL发布。最初目的是为更好地管理Linux内核开发而设计。 ——维基百科
2、从定义可知:
-
功能:版本控制:
- 项目开发时,进行代码多版本管理
eg:多版本分支,代码共享,提示冲突等 - 一些场景下,将版本回溯到之前某个时间点的版本
eg:代码回滚等
- 项目开发时,进行代码多版本管理
-
特点:分布式:
- 每个客户端代码可以提交到本地仓库,并可本地查看提交历史记录
- 提交远程服务器端不是必须的(与svn区别)
3、优点:
- 免费,开源
- 速度更快:一切的操作基本上在本地上完成
- 分布式:服务器异常后,可继续工作
二、工作原理:
1、工作原理图,来自此处:
2、工作原理图简介:
1)有四个储存概念(除远程仓库在服务端,其他都在本地存储):
- workspace:工作目录,本地操作的文件
- index:暂存区,记录各个文件的索引
- local repository:本地仓库
- remote repository:远程仓库
2)常用场景:提交变更和同步/下载代码
提交变更
- git工作目录中,在一个分支下(branch name),进行变更操作(增删改)
- 将变更提交到index暂存区(git add [fileName])
- 再提交到本地仓库 (git commit -m [commit info])
- 最后提交到远程仓库(git push origin [branch name])
同步/下载代码
对应上面提交变更步骤,可从三处同步代码:
- index暂存区(git checkout -b [ branch Name])
- 本地仓库(git checkout HEAD)
- 远程仓库(两种场景:git clone url [local directory] / git pull )
冲突
在提交和同步时,都要进行合并(merge),或手动或git自动合并,可能引起的冲突
(冲突:即同一文件同一位置代码不一致,git不能判断最终应该以那个为准)
-
在同步git pull出现冲突,手动解决掉提示的冲突文件,然后再次提交,类似与下图的冲突:
提交时,可能有多种冲突情况,建议先从服务器端获取最新代码解决冲突,在本地运行通过,再提交
3、git版本控制的相关信息存储——所有git的操作内容都放在.git文件夹
1).git是隐藏状态,在项目根目录,使用“ll -a”可查看
2)下图是本地项目的.git文件夹下内容:
3) 查看可用官网帮组:git help gitrepository-layout
- 下面总结的具体内容简介:
COMMIT_EDITMSG——最后一次commit提交的msg信息
备注:如果 git commit时,没有加-m信息,就会进入COMMIT_EDITMSG进行信息编辑,打开此文件与编辑保存时一致-
FETCH_HEAD,记录在本地,从远程的更新所有分支最新提交信息(可使用“git fetch”更新远程所有的分支提交信息),查看文件,eg:
HEAD,当前指向的当前所在的分支(一个标记)
eg:文件内容:ref: refs/heads/branch1,是指现在指向名“branch1”的分支ORIG_HEAD,记录一些危险操作(pull,push或者reset等)前的一个head操作指针,发生错误时候可以恢复到ORIG_HEAD指向操作
config,git的一些配置文件,远程仓库的相关一些配置信息(只针对当前所在的仓库),和git的全局配置文件
description,供GitWeb(git的图形界面的web浏览)使用,不用关心
hooks,包含挂钩脚本文件,类似与监听器,在执行了某些操作(eg:push,commit等)后,就会触发执行
1)git hooks应用有具体的用法
2)定制些开发中自动化执行的流程,eg:代码规范检查,提交git规范交叉,代码提交后周知或者打包等等-
index,对应上面原理图中index,是一个二进制文件,是操作文件的所有快照(索引)(eg:git add后就向文件写入索引)
1)不实际存储内容,只是一个内容的索引(具体内容存储在objects中),可使用特定软件打开,参考官网说明
2)也可使用git ls-files --stage查看索引和工作区中文件信息, /info,存储不希望在.gitignore(包含不被git管理的文件或目录)中忽略中全局可执行的文件
logs,项目中所有的每次提交信息
objects,具体上面index指向的实际的变更内容,包括文件内容,以及内容的tree对象和提交信息
-
packed-refs,为节省空间和提高效率,对多个松散对象打包时,把.git/refs内容移动到此文件中,手动运行git gc可查看到refs内容清空,文件记录eg:
refs,存储本地和远程仓库,各分支最后一次提交信息的索引
4、git通过对.git文件下内容操作,进行版本控制的,下面以提交为例可查看到如何实现:
git是一套内容寻址文件系统,存储相关的键值对,然后通过键值对,对内容操作
1)在工作目录内容改变,首先进行提交(git add),实际进行了下列操作
- 将修改文件内容快照存储(在.git/objects)
- index文件中更新修改文件内容的索引
-
多层路径会存储修改内容的tree对象
ps:使用“git ls-files --stage ”查看index内容,eg:
2)在提交(git commit)后,生成commit对象
- 存储文件内容的快照(包括tree和上一次提交信息),操作时间,操作人和提交信息
- commit信息,保存在.git/objects中
-
使用“git cat-file -p [commit的指针]”,eg:
-
commit的指针,可使用git log获取,eg下图中commit后的索引值:
3)对于其他同步,回滚等操作,都是通过键值对不断对object中文件内容操作
tips:键值对通过哈希算法SHA-1计算,git对象存储的键值对通过文件头+文件内容进行SHA-1计算,详细请参考此处
此文章参考内容:
1.https://zh.wikipedia.org/wiki/Git
2.https://git-scm.com/book/zh/v1/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-Git-%E5%AF%B9%E8%B1%A1
3.http://gityuan.com/2015/06/27/git-notes/