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 merge
git 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 index
Git commit
=git write-tree
+git commit-tree
Git branch -b <branch_name> <commit_hash>
=git update-ref ref/heads/<branch_name> <commit_hash>
演示实验全过程
- 版本信息
1 | ➜ Git-internal git --version |
- 创建仓库
1 | git init test |