Git 原理

git核心的原理:

  1. git工作目录的.git目录下存储了git仓库的所有内容
  2. git命令通过修改工作区内容和.git目录下的内容实现git的各种操作

.git 目录结构

tree1

HEAD 存放的数据有两种情况

  • Git 仓库当前的ref文件(一般为分支, 存储在.git/refs/heads/br, 其存储commit-id)
  • commit-id (checkout 到 commit-id 或 某tag)

index

Git Index,即执行git-add 后的一个index区目录结构(tree object)

objects (使用 git cat-file -t|-p object-id 查看内容)

  • 三大object
    • blob object - 存放文件内容
    • tree object - 存放目录结构, 内含其他tree object 和 blob object
    • commit object - 存放commit 信息和顶级tree object
  • pack
    • 将各种 objects 打包, xxx.idx, xxx.pack

refs

分支/标签/HEAD/远程分支 的引用,其内容为 commit-id, 对应commit-objects

logs

相关ref 日志

git 操作解析

git add

  • 创建 blob objects (添加的文件)
  • 创建 tree object, 内容指向 各 tree objects(目录), blob objects(文件)

git commit

  • 创建 tree object
  • 创建 commit object
  • 更改 HEAD 指针 (ref内容)

git reset

git reset –soft <commit/…>

  • 更改 HEAD 指向的ref内容(若HEAD 存储为ref)
  • 更改 HEAD 内容 (若HEAD 存储为 commit-it)

git reset [–mixed] <commit/…>

  • 更改 HEAD 内容或指向的ref内容
  • 更改 index 内容

git reset –hard <commit/…>

  • 更改 HEAD 内容或指向的ref内容
  • 更改 index 内容
  • 更改 工作目录

git checkout

git checkout branch

  • 更改 HEAD 指针( 指向其他 ref)
  • 更改 index 内容
  • 更改 工作目录

git checkout /tag

  • 更改 HEAD 指针(存储commit-id)
  • 更改 index 内容
  • 更改 工作目录

git checkout -b branch

  • 新增 ref (内容为当前commit-id)
  • 更改 HEAD 指针( 指向新增ref)
  • 更改 index 内容
  • 更改 工作目录

git checkout [commid-id] – file

  • 更改 index 内容
  • 更改 工作目录

git merge

fast-forward

  • 单分支合并,仅移动指针

recursive

  • 多分支合并策略:最短路径共同祖先,三向合并
  • 向后查找,生成临时节点, 三向合并

ours/theirs

  • 使用 自己/他人, 忽略其他

octopus: 多于两个分支之间合并

  • 确保每个分支是独立文件夹,一次合并多个分支

git rebase

  • git rebase -i 整理分支commit 信息