文章目录
  1. 1. 技术内幕
    1. 1.1. Git 数据存储模型
      1. 1.1.1. Git 内部对象
      2. 1.1.2. Git 引用
  2. 2. 团队协作
    1. 2.1. 分支策略
      1. 2.1.1. 如何选择是merge 还是 rebase
    2. 2.2. 工作流
    3. 2.3. 在团队协作中使用命令
      1. 2.3.1. 独自工作下的操作
        1. 2.3.1.1. 本地仓库操作
        2. 2.3.1.2. 分支操作
        3. 2.3.1.3. “后悔药”操作
      2. 2.3.2. 多人团队协作下的操作
      3. 2.3.3. 多人团队协作及评审工作流操作
    4. 2.4. 工作流最佳实践
  3. 3. 几个经典案例
  4. 4. 附录
    1. 4.1. Git 底层命令
      1. 4.1.1. git cat-file
      2. 4.1.2. git hash-object 内容hash值计算
      3. 4.1.3. git update-index 为文件创建一个暂存区
      4. 4.1.4. git write-tree 将暂存区内容写入树对象
      5. 4.1.5. git commit-tree 创建一个提交对象
      6. 4.1.6. git update-ref 更新Git引用对象
    2. 4.2. Git上层命令内幕
    3. 4.3. 演示实验全过程
  5. 5. 参考资料

技术内幕

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分支而不是在mainmaster分支上直接提交
  • 测试所有提交,不仅仅是mainmaster分支上的提交
  • 对所有提交运行自动化测试,如果运行时间长于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
2
➜  Git-internal git --version
git version 2.32.0 (Apple Git-132)
  • 创建仓库
1
git init test

参考资料

文章目录
  1. 1. 技术内幕
    1. 1.1. Git 数据存储模型
      1. 1.1.1. Git 内部对象
      2. 1.1.2. Git 引用
  2. 2. 团队协作
    1. 2.1. 分支策略
      1. 2.1.1. 如何选择是merge 还是 rebase
    2. 2.2. 工作流
    3. 2.3. 在团队协作中使用命令
      1. 2.3.1. 独自工作下的操作
        1. 2.3.1.1. 本地仓库操作
        2. 2.3.1.2. 分支操作
        3. 2.3.1.3. “后悔药”操作
      2. 2.3.2. 多人团队协作下的操作
      3. 2.3.3. 多人团队协作及评审工作流操作
    4. 2.4. 工作流最佳实践
  3. 3. 几个经典案例
  4. 4. 附录
    1. 4.1. Git 底层命令
      1. 4.1.1. git cat-file
      2. 4.1.2. git hash-object 内容hash值计算
      3. 4.1.3. git update-index 为文件创建一个暂存区
      4. 4.1.4. git write-tree 将暂存区内容写入树对象
      5. 4.1.5. git commit-tree 创建一个提交对象
      6. 4.1.6. git update-ref 更新Git引用对象
    2. 4.2. Git上层命令内幕
    3. 4.3. 演示实验全过程
  5. 5. 参考资料