导航
Git 基本原理
哈希算法
- 一种加密算法,将
明文
加密为密文
哈希算法特点
- 不管输入数据量多大,输入同一个哈希算法,得到的加密结果长度固定
- 哈希算法确定,输入数据确定,输出数据就保持不变
- 哈希算法确定,输入数据有变化,哪怕变化很小,输出结果页会有变化,且通常变化很大
- 哈希算法不可逆(根据密文没办法反推出明文)
Git保证数据完整性的机制
- Git底层采用
SHA-1
算法 - 当原始文件经过网络传输到目标服务器时,如果有文件的丢失,则会产生错误,那么就可以用哈希算法验证文件。
- 原始文件经过
SHA-1
生成一个结果,在网络传输后,将目标文件也采用SHA-1
生成一个结果,两个结果互相比对,如果一致,则说明文件传输未发生变化,否则说明文件在传输过程中发生了变化。
Git保存版本的机制
-
集中式版本控制工具的文件管理机制
- 以文件变更列表的方式存储信息。这类系统将他们保存的信息看做是一组基本文件和每个文件随时间逐步累积的差异
- 当文件有其他版本后,将文件中改变了的地方保存下来,当你要使用某个版本的时候,就将改版本保存的信息和初始版本相结合生成当前版本的文件
-
Git 的文件管理机制
Git把数据看做是小型文件系统的一组快照。每次提交更新时Git都会对当前的全部文件制作一个快照并保存这个快照的索引。为了高效,如果文件没有修改,Git将不再重新存储该文件,而是只保留一个链接(类似于指针)指向之前存储的文件。所以Git 的工作方式可以称之为快照流。
-
Git的提交对象
Git的每一次提交都会创建提交对象,每个文件都会经过哈希算法得到一个哈希值,所有目录内的文件的哈希值会得到一个树对象(tree),树对象就会包含每一个具体的文件及其哈希值,并且树对象本身也会有一个哈希值,提交对象中就包含着树对象的哈希值、当前提交的作者、当前提交的提交者、commit的信息,并且提交对象也会有一个自己的哈希值
-
提交对象及其父对象形成的链条
每一个快照都会包含一个父节点,保存父对象的哈希值指向该结点的父节点,形成链条(类似于链表)
Git分支管理的机制
root commit
根提交 —— 从未提交过的默认提交,当提交后,父对象即为根提交- 创建分支:也就是新建一个指针,指向某个提交对象
- 切换分支:
HEAD
指针指向某个分支,切换分支也就是移动HEAD
指针
使用步骤
初始化
- 进入目录,右键
git Bash here
mkdir
新建目录git init
初始化仓库- 设置签名
git config
项目级别的签名,即git config user.name/user.email
信息保存的是当前目录/.git/config文件
如果是系统级别,则git config --global user.name/user.email
信息保存在根目录 cd ~ 的.gitconfig目录下,需要用ls -lA查看隐藏文件 - 查看状态
git status
在本地仓库内git status
使用vim 文件名
编辑文件
按 ESC +:+wq 退出
第一次提交
-
第一次提交完成后查看状态
- git会检测到修改过的文件,会显示
modified
修改过的文件 - 提示:未准备提交的更改:
- 可以使用
git add
来更新,对暂存区做的是update
的操作,不再是之前的include
; - 用
git checkout
可以在工作目录内取消这次修改
- 可以使用
- git会检测到修改过的文件,会显示
-
修改后再第二次提交之后查看状态:
Git 结构
- 暂存区内容可在
add
后撤销,当然也可以不 add 直接commit
,只是 commit 后不可撤销 - 工作区中新建的文件必须
add
查看版本历史记录
-
git log
-
每个记录会带上提交的签名和提交的日期
-
当做版本控制前进后退的时候就是通过移动Head指针来控制
-
空格向下翻页,b向上翻页,q退出,当记录很多需要多屏显示时的控制方法
-
查看历史记录的几种不同的方式
-
git log --pretty=oneline
-
git log --oneline
-
git reflog
-
版本控制
本质
- 本质就是移动Head指针
三个方法
- 基于索引值【推荐】
git reset --hard 索引值
常与git reflog
搭配使用【能显示出局部索引值,可直接复制粘贴使用】 - 使用
^
符号
git reset --hard HEAD^
有几个^
就后退几步
常与git log --oneline
使用【只显示当前版本之后的】 - 使用
~
符号
git reset --hard HEAD~n
【n为后退的步数】
推荐直接使用索引值,短移动可使用后两种方法。
reset命令
--soft
仅在本地库移动HEAD指针本地库回退了,相对应的暂存区和工作区就提前了,status查看后会显示绿色。
--mixed
在本地库移动,并重置暂存区本地库和暂存区都后退了,那么工作区就会相对提前了
--hard
【常用】
本地库移动,重置暂存区和工作区
三者一起回退,保持一致
删除文件后找回
- 删除文件
rm filename.file
- 找回文件的前提
删除前,文件存在时的状态提交到了版本库 - 删除操作已经提交到本地库
使用git reset --hard [指针位置]
当操作已经提交到本地库后,一旦本地库记录了,就不会被抹去,Git在操作的时候,只会增加版本,不会删除版本,即使是前进后退,都不会删除版本。因此,由于版本记录的存在,只要后退到删除文件那个版本记录的之前的版本记录,就能找回删除的文件 - 删除操作尚未提交到本地库
使用git reset --hard HEAD
利用本地库当前的版本刷新工作区和暂存区
比较文件差异
git diff filename.file
是将工作区中的文件和暂存区中的文件比较git diff HEAD|Head^ filename.file
将工作区中的文件和当前本地库|本地库历史中的文件比较git diff HEAD
不带文件名比较多个文件
分支操作
常用分支操作
git branch name
创建分支git branch -v
查看分支列表git checkout name
切换分支git status
查看当前所在分支git merge name
合并分支【需先切换到被修改的分支,例:A修复了Bug,但B没有,于是B想跟A合并,那么就要先切换到B,再用merge命令合并】
合并分支后产生的冲突
- 当自动合并产生冲突后 git 会自动转为手动合并
(anotherMaster|MERGING)
CONFLICT (content): Merge conflict in filename.file
Automatic merge failed;fix conflicts and then commit the result.
- 产生冲突的原因
合并的两个分支各有更新,git 拿不定需要删除哪些,保留哪些,于是产生冲突,git 就会展示分支间的冲突,由人自行决定。<<<<<<< HEAD 此处为当前分支的冲突内容 ======= 此处为另一分支的冲突内容 >>>>>>> master
- 解决方法
当解决完毕后,查看状态git status
,根据提示使用git add filename.file
标记为已解决,但是仍处于合并过程中,再用git commit -m "日志信息"
完成合并过程
GitHub与本地Git交互
- 推荐使用码云,GitHub延迟比较大
GitHub
- 一个代码托管中心
- 交互过程:有A和B,B是A的下属;A先创建一个本地库,再在GItHub上面创建一个远程库,创建好后,A先在本地搭建好环境,并
push
上托管中心,然后B就从托管中心clone
下来,生成本地库,B修改更新后需要先加入团队才可以push
内容,紧接着A再将托管中心的内容pull
下来。
本地git仓库连接GitHub
- 先保存GitHub的仓库的连接(HTTPS/SSH)
git remote -v
查看源git remote add origin httpsLink
添加源
团队内协作
- 克隆:
clone
操作:git clone httpsLink
- 克隆的三个效果:完整地把远程库下载到本地;创建
origin
远程地址别名;初始化本地库。 - 推送:
git push origin master
origin即推送目标,master即推送的分支(必须加上) - 抓取:
git pull origin master
:抓取操作对于远程库只是一个读操作,因此不需要登陆 pull
=fetch
+merge
:fetch
仅抓取 ;merge
合并git fetch link branchName
+git merge link/branchName
- fetch 和 merge操作分开操作的好处就是在文件复杂很多的时候,我们可以先抓取下来不合并本地库,在比对好后再合并到本地库。
fetch
下来后,可以通过git checkout origin/master
查看抓取下来的文件- 如果不是基于GitHub远程库的最新版所做的修改,则不能推送 ----- 防止版本不一样导致不同的本地库推送的版本不同。
- 协作开发时发生冲突:当两人同时改同一个位置,后推送的人便不可再直接推送,必须先拉取下来才可以推送,那么拉取下来时,既有自己的修改,也有先推送的人的修改,就会产生冲突,git便不能替我们决定哪些保留哪些保存;然后就进入到本地库解决冲突的步骤,最后add标记为已解决冲突,再commit到本地库,最后再推送到远程
跨团队协作
fork
将对方的远程库复制到自己的远程库pull request
先把自己的远程库中的文件抓取到本地库,修改了后再推送上自己的远程库,然后就可以发起一个pull request
,对方在GitHub上看到该request后会审核,对方审核通过后修改的部分便会合并到对方的远程库中,至此完成跨团队协作。
SSH登陆
ssh-keygen -t rsa -C email
生成一个ssh目录- 进入到
.ssh
目录(注意日志信息,里面会提到你的.ssh
目录的位置,一般会在C:/Users/Administrator
下,也就是我的文档下面) - 打开
id_rsa.pub
文件并复制其中的内容 - 去到GitHub添加SSH key
- 回到工作区测试
- 添加origin
git remote add origin_ssh sshLink
- 做push、pull操作时使用
origin_ssh
即可