这是我参与「第三届青训营 -后端场」笔记创作活动的的第11篇笔记
- Git是什么
- 开源分布式版本控制系统
- 版本控制
- 一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。
- 版本控制
- 集中版本控制SVN
- 基本原理
- 提供一个远端服务来保存文件,所有用户的提交都提交到该服务器中
- 增量保存每次提交的Diff,如果提交的增量中和远端现存的文件存在冲突,则需要本地提前解决冲突
- 优点
- 学习简单,更容易操作
- 支持二进制文件,对大文件支持更友好(广泛运用于美术、游戏团队)
- 缺点
- 本地不存储版本管理的概念,所有提交都只能联上服务器后才可以提交
- 分支上支持不够好,对于大型项目团队合作比较困难
- 用户本地不保存所有版本的代码,如果服务端故障容易导致历史版本丢失
- 基本原理
- 分布式版本控制Git
- 基本原理
- 每个库都存有完整的提交历史,可以直接在本地进行代码提交
- 每次提交记录的都是完整的文件快照,而不是记录增量
- 通过push等操作来完成和远端代码的同步
- 优点
- 分布式开发,每个库都是完整的提交历史,支持本地提交,强调个体
- 分支管理功能强大,方便团队合作,多人协同开发
- 校验和机制保证完整性,一般只添加数据,很少执行删除操作,不容易导致代码丢失
- 缺点
- 相对SVN更复杂,学习成本更高
- 对于大文件的支持不是特别好(git-Ifs工具可以弥补这一点)
- 基本原理
- 开源分布式版本控制系统
- Git基本命令
- 配置
git init- 其他参数
--init-branch默认master分支,可以初始化为其他分支--bare创建一个裸仓库(纯Git目录,没有工作目录)--template可以通过模板来创建预先构建好的自定义git目录
- 其他参数
- 用户名配置
- Instead of配置
- Git命令别名配置
- Git Remote
git remote -v查看远端分支git remote add origin_ssh git@github.com:git/git.gitgit remote add origin_http https://github.com/git/git.git- 同一个Origin设置不同的Push和Fetch URL
git remote add origin git@github.com:git/git.gitgit remote set-url --add --push origin git@github.com:my_repo/git.git
- 提交代码
- Git Add
- Git Commit
- Objects
- Blob
- 存储文件内容
- Tree
- 存储文件的目录信息
- Commit
- 存储提交信息,一个commit可以对应唯一版本的代码
- 串联
- 通过Commit寻找到Tree信息,每个Commit都会存储对应的Tree ID
- 通过Tree存储的信息,获取到对应的目录数信息
- 从Tree中获得Blob的ID,通过Blob ID获取对应的文件内容
- Blob
- Refs
- refs的内容就是对应的Commit ID,可以将Ref当作指针,指向对应的Commit来表示当前Ref对应的版本
refs/heads前缀表示的是分支,除此之外还有其他种类的ref,比如refs/tags前缀表示的是标签`
- 远端同步
- Branch
git checkout -b创建新分支- 分支一般用于开发阶段,是可以不断添加Commit进行迭代
- Tag
- 标签一般表示的是一个稳定版本,指向的Commit一般不会变更
- 通过
git tag命令生成tag
- Annotation Tag
- 附注标签
- 一种特殊的Tag,可以给Tag提供一些额外信息
git tag -a命令完成附注标签的创建
- 附注标签
- Branch
- 追溯历史版本
- 获取当前版本代码
- 通过Ref指向的Commit可以获取唯一的代码版本
- 获取历史版本代码
- Commit里面会存有parent commit字段,通过commit的串联获取历史版本代码
- 修改历史版本
commit --amend- 通过这个命令可以修改最近的一次commit信息,修改之后commit id会改变
- rebase
- 通过
git release -i HEAD~3可以实现对最近三个commit的修改- 合并commit
- 修改具体的commit message
- 删除某个commit
- 通过
filter --branch- 该命令可以指定删除所有提交中的某个文件或者全局修改邮箱地址等操作
- 获取当前版本代码
- Git GC
- 通过
git gc命令,可以删除一些不需要的object,以及会对object进行打包压缩来减少仓库体积 - Reflog
- reflog用于记录操作日志,防止误操作后数据丢失,通过reflog来找到丢失的数据,手动将日志设置为过期
- 指定时间
git gc prune=now指定的是修剪多久之前的对象,默认是两周前
- 通过
- 配置
- 常用命令
- Clone
- 拉取完整的仓库到本地目录,可以指定分支,深度
- Fetch
- 将远端某些分支最新代码拉取到本地,不会执行merge操作,会修改refs/remote内的分支信息,如果需要和本地代码合并需要手动操作。
- Pull
- 拉取远端某分支,并和本地代码进行合并,操作等同于
git fetch+git merge,也可以通过git pull --rebase完成git fetch+git rebase操作 - 可能存在冲突,需要解决冲突
- 拉取远端某分支,并和本地代码进行合并,操作等同于
- Push
- 将本地代码同步至远端
git push origin master- 冲突问题
- 如果本地的commit记录和远端的commit历史不一致,则会产生冲突,比如git commit --amend ir git rebase都有可能导致这个问题
- 如果该分支只有自己一个人使用,或者团队内确认过可以修改历史则可以通过git push origin master -f来完成强制推送,一般不推荐主干分支进行该操作,正常都应该解决冲突后再进行推送
- 推送规则限制
- 可以通过保护分支,来配置一些保护规则,防止误操作,或者一些不合规的操作出现,导致代码丢失
- Clone
- Git研发流程
- 集中式工作流
- 只依托于master分支进行研发活动
- 工作方式
- 获取远端master代码
- 直接在master分支完成修改
- 提交前拉取最新的master代码和本地代码进行合并(使用rebase),如果有冲突需要解决冲突
- 提交本地代码到master
- 分支管理工作流
- GitFlow
- 比较早期的分支管理策略
- 包括五种类型分支
- GithubFlow
- 只有一个主干分支,基于Pull Request往主干分支中提交代码
- 可以通过设置保护分支
- Gitlab Flow
- 原则
- upstream first 上游优先
- 只有在上游分支采纳的代码才可以进入到下游分支,一般上游分支就是master
- 原则
- GitFlow
- 代码合并
- Fast-Forward
- 不会产生一个merge节点,合并后保持一个线性历史,如果target分支更新,则需要通过rebase操作更新source branch后才可以合入
- Three-way Merge
- 三方合并,会产生合并节点
- Fast-Forward
- 集中式工作流