Git 技术内幕及团队协作
技术内幕
Git 数据存储模型
Git 内部对象
Commit
Tree
Blob
Git 引用
团队协作
分支策略
- 主线分支开发(Trunk)
- 功能分支部署(Feature)
- 状态分支(Gitlab-flow)
- 计划部署(Git-flow)
如何选择是merge 还是 rebase
有用的merge参数
git merge --no-ff
“真正”的merge,会产生merge commit。git merge --ff-only
“fast forward” 图形像reabse效果一样。git merge --squash
会将多个commit压缩为一个,然后进行合并。
其他类似的命令
git pull=git fetch+git mergegit rebase
Forward-port local commits to the updated upstream head.git cherry-pick
合并个别提交
工作流
在团队协作中使用命令
独自工作下的操作
本地仓库操作
- 创建仓库
git init - 克隆仓库
git clone - 查看仓库状态
git status - 添加文件到暂存区
git add
几个添加文件到暂存区命令参数:--all添加所有文件--update添加所有已跟踪文件修改到暂存区--patch选择文件的部分修改添加到暂存区
- 将暂存区文件提交至本地仓库
git commit - 查看提交历史
git log
几个查看命令参数:--graph以提交树的图形化方式展示--oneline以简短(只显示消息title)的方式展示--no-merges不显示merge提交
分支操作
- 查看分支
git branch
几个查看分支命令参数:--list列表形式输出--all列出所有分支(本地+远程)--verbose查看分支详细信息(最新提交hash值)
- 更新远程分支
git fetch - 检出/切换分支
git checkout
几个检出分支命令参数:--trace检出且跟踪远程分支-b创建检出一个新分支
“后悔药”操作
| 撤销场景 | 备注 | 解决方案 |
|---|---|---|
| 移除所有未被追踪的文件 | 文件未被加入暂存区和提交 | git clean -fd |
| 撤销工作目录中未暂存的修改 | 修改的文件未被暂存或提交 | git checkout --filename |
| 撤销所有本地未提交的修改 | 修改的文件已暂存但未提交 | git reset --hard |
| 撤销本地已暂存但未提交的某个文件 | 某个文件已暂存但未提交 | git reset <filename> |
| 撤销已提交变更但需要保留回滚日志场景 | 修改文件已提交且发布,工作目录是干净的 | git revert <commit-hash> |
| 修改非共享/非集成分支提交历史中移除一个单独的提交 | 已本地提交,工作目录干净,未发布 | git rebase --interactive <commit-hash> |
多人团队协作下的操作
多人团队协作及评审工作流操作
工作流最佳实践
- 使用
feature分支而不是在main或master分支上直接提交 - 测试所有提交,不仅仅是
main或master分支上的提交 - 对所有提交运行自动化测试,如果运行时间长于5分钟,考虑并行运行这些自动化测试
- 禁止在集成分支(master/develop/stg)上进行rebase操作
- 所有人需要从
master/main分支开始且最终目标回到master/main - 提交信息需要反应意图且符合规范
几个经典案例
- checkout 某个commit 后基于当前提交创建提交,chekout 到其他分支后这个新增commit还可以看到么?
关键点:分离头指针(detached head)模式,找不到的提交可以通过git reflog找回。
附录
Git 底层命令
git cat-file
git cat-file -t查看类型git cat-file -p查看内容
git hash-object 内容hash值计算
git hash-object -w <path-to-file>
git update-index 为文件创建一个暂存区
git update-index --add --cacheinfo 100644 <full-hash> <path-to-file>
git write-tree 将暂存区内容写入树对象
git commit-tree 创建一个提交对象
git update-ref 更新Git引用对象
git updte-ref ref/heads/<branch_name> <commit_hash>
Git上层命令内幕
Git add=git hash-object+git update indexGit commit=git write-tree+git commit-treeGit branch -b <branch_name> <commit_hash>=git update-ref ref/heads/<branch_name> <commit_hash>
演示实验全过程
- 版本信息
1 | ➜ Git-internal git --version |
- 创建仓库
1 | git init test |
