git --- 基础介绍
- git 是什么
- git --- 工作区, 暂存区, 资源库
- git --- 文件状态
- git --- branch 和 HEAD
- git --- 一次正常的git提交流程
git 是什么
- Git是一款分布式源代码管理工具(版本控制工具)
- Git和其他传统版本控制系统比较:
- 传统的版本控制系统(例如 SVN)是基于差异的版本控制,它们存储的是一组基本文件和每个文件随时间逐步累积的差异,
- 优点: 节省磁盘空间,
- 缺点:耗时、效率低。在每次切换版本的时候,都需要在基本文件的基础上,应用每个差异,从而生成目标版本对应的文件
- Git 快照是在原有文件版本的基础上重新生成一份新的文件,类似于备份。为了效率,如果文件没有修改,Git不再重新存储该文件,而是只保留一个链接指向之前存储的文件。
- 缺点:占用磁盘空间较大,
- 优点:版本切换时非常快,因为每个版本都是完整的文件快照,切换版本时直接恢复目标版本的快照即可。
- 特点:空间换时间
- 在Git 中的绝大多数操作都只需要访问本地文件和资源,一般不需要来自网络上其它计算机的信息。基于这一特点,Git在断网后依旧可以在本地对项目进行版本管理,只需联网后,把本地修改的记录同步到云端服务器即可
- 被git管理的项目会有这个.git文件夹
- 里面包括了所有分支, 节点 等信息
git — 工作区, 暂存区, 资源库
工作区( Working Directory)
- 在git管理下的正常目录都算是工作区, 平时对代码的改动都在这里进行
暂存区(Index)
- 暂存区,用于临时存放你的改动. git add 或者 git stage 命令会把对代码的改动暂存在这里
- commit之前必须要将改动的文件放入暂存区 (IDE可以直接commit是因为commit的时候IDE自动add了)
资源库(Repository)
- 资源库(或版本库),就是安全存放数据的位置,这里面有提交到所有版本的数据
- commit就将代码放入资源库
远程仓库(Remote Directory)
- 远程仓库,托管代码的服务器,commit之后将本地仓库push到远程仓库
git — 文件状态
Untracked:
- 未跟踪, 此文件在文件夹中, 但并没有加入到git库, 不参与版本控制, 可以通过gitignore文件控制
Unmodify:
- 文件已经入库, 未修改, 即版本库中的文件快照内容与文件夹中完全一致. 这种类型的文件有两种去处, 如果它被修改, 而变为Modified.如果使用git rm移出版本库, 则成为Untracked文件
Modified:
- 文件已修改, 仅仅是修改, 并没有进行其他的操作. 这个文件也有两个去处, 通过git add可进入暂存staged状态, 使用git restore 则丢弃修改过,返回到unmodify状态.
Staged:
- 暂存状态。通过git add 或者 git stage 将文件变为modified状态
- 可以执行git commit则将修改同步到库中,
git — branch 和 HEAD
- branch就是分支的意思
- 在日常开发过程中, 一般分为主分支(通常叫
master
或者main
) 和其他分支,- 其他分支: 当需要开发新的功能的时候, 从主分支上新建一个分支(通常使用功能内容命名), 当功能开发完毕的时候, 把新建的分支merge回主分支
分支的本质是什么
- 分支的本质是指针, 分支的名字(包括master, main) 就是指针的名字
- 在git中, 每一次commit都会生成一个节点, 包括文件信息, 继承信息, 和 commitID
- commitID是一个hash值, 日常使用中可以直接用hash值的前四位代替
- 而branch就是指向一个节点的指针
Example:
- 下图是一个主分支
- 现在需要修改一个bug, 所以新建一个分支, 执行
git branch bugFix
- 可以看到新的分支指针和master指向同一个commit节点
- 星号表示目前所在的分支
- 现在在bugFix这个分支上进行开发, 修改bug, 然后执行
git commit
- 主分支main指向C1节点, bugFix分支指向C2节点
- 此时main有了新的代码提交(比如其他开发者), 生成了新的节点C3
- bugFix开发完成, 需要合并进主分支
- 在主分支上指向
git merge bugFix
, 主分支自动创建cmmit节点C4. Merge完成, C4就是包含了C3和C2的版本
更深一层 ---- HEAD指针
- 在git中其实我们是不能直接操控分支指针的(包括主分支main)
- git中所有对分支指针的操作都是通过操控HEAD指针完成
- HEAD指针会被attach到一个分支指针, 这样就可以对对应的分支指针进行操作
Example: 移动HEAD指针
- 执行 git checkout commitID 操作, 这里就是
git checkout C4
- 将HEAD和bugFix指针 detach
Example: 移动HEAD指针
- 在下图的状态下直接执行git checkout commitID 可以将HEAD指针直接移动到所对应的commit节点
- 执行
git checkout C3
Example: 使用HEAD移动其他分支指针
- 目前HEAD是detached状态, 现在需要将bugFix移动到C0, main移动到C6
- 执行
git checkout C0
, 将HEAD移动到C0
- 执行
git switch bugFix
切换到bugFix分支- 执行
git branch -f bugFix HEAD
将bugFix指针移动到C0
8 执行git checkout C0
, 将HEAD移动到C6- 执行
git branch -f main HEAD
将main移动到C6
- 执行
git switch main
或者git checkout main,
将HEAD attch到main
- 使用 ~N 符合可以将其他分支移动到HEAD分支的前N个节点
- 比如
git branch -f bugFix HEAD~2
就是将bugFix移动到HEAD之前的两个节点上
git — 一次正常的git提交流程
- 首先使用
git status
查看目前的git状态
- 在文件夹中创建一个新的文件, 然后查看状态, 因为是新建文件, 所以目前文件是untracked状态
- 执行
git add .
或者git add test.txt
, 然后查看状态- 文件已经加入暂存区(Index), 可以被commit
- 执行 git coomit -m “first commit” 将更改提交, 并用git log查看comit信息
- 对test内容进行更改, 查看git状态
- 因为之前已经被加入git, 所以这次不是untracked状态, 而是modified状态
- 使用
git stage test.txt
或者git add .
或者git add test.txt
将修改放入暂存区
- 使用git log查看commit信息
- 也可以使用
git log --oneline --graph
查看- 可以显式分支信息和HEAD指针信息
- 创建一个新的分支bugFix, 可以看到1730376 这个节点上有三个指针, 分别是HEAD, master, bugFix
- 切换到bugFix分支, 然后对文件进行修改
- 在bugFix分支进行commit提交, 然后查看log
- 可以看到HEAD和bugFix移动到了ddac8b1这个commit节点
- 切换回master分支, 然后进行merge, 再查看log
- 可以看到master被移动到了ddac8b1这个节点
- 注意
Fast-forward
, 说明只是简单的把master指针向前移动了一下, 而并不是生成了新的commit节点- 如果master分支在bugFix之前有了新的commit, 这时再merge bugFix就不是Fast-forward了, 而是会生成新的commit节点
- 如下: 当main分支在C3上时执行
git merge bugFix
, C4就是新创建的节点