流畅的Git

Binjian Xin | 2023-09-18

Table of Contents

常见场景

关于submodule一个例子

台盆命令

  • 查手册:

            git submodule foreach --recursive 'git log'
    
  • debugged:

            git submodule foreach --recursive 'git log --oneline'
    
  • 更多功能:

            git submodule foreach --recursive 'git log --oneline HEAD...HEAD~5'
    

水管命令

  • stack overflow:
        git submodule foreach --recursive '
        REV1=HEAD;
        REV2=HEAD~10;
        SHA1=$(cd $toplevel && git ls-tree $REV1 $sm_path | \
            grep -E -o "[0-9a-f]{40}");
        SHA2=$(cd $toplevel && git ls-tree $REV2 $sm_path | \
            grep -E -o "[0-9a-f]{40}");
        git log --oneline $SHA1...$SHA2'
  • debug:
        git submodule foreach --recursive '
        SHA1=$(cd $toplevel && cd $sm_path && git log | \
            grep -E -o "[0-9a-f]{40}" | head -1);
        SHA2=$(cd $toplevel && cd $sm_path && git log | \
            grep -E -o "[0-9a-f]{40}" | head -10 | tail -n1);
        git log --oneline $SHA1...$SHA2'

台盆命令类型:

  • git commandline
  • git lens
  • gitkraken
  • emacs magit

哈希值,四类对象

哈希(计算机世界的暗物质)

  • 高效
    • 快速的哈希函数计算,索引~O(1) (数组 O(N))
    • 冲突概率极低,最坏 O(N)
  • sha-1(20byte, 40hex, 160 位, 8 位 用于目录)
    • 更高安全性 -> sha256(32bit), sha512(64bit)
    • $2^{160}\approx 3\times 10^{38}$(宇宙总原子数 $\approx 10^{80}$)
  • 哈希表的广泛应用
    • 编程语言的数据结构:Python dict(json),set
    • 数据库:Mongodb object
    • 云存储:Object Storage System

四个对象

  • tree 树 (空间/拓扑关系)
  • blob 文件
  • commit (时间顺序)
  • annotated tag
  • 树对象,文件对象 的实例:HEAD,
    • git cat-file -p HEAD
    • git ls-tree -r HEAD
    • head 内一个文件对象

抽象的力量

  • 内容可编址的文件系统/数据库
  • 所有对象平等, 不分优先级

版本选择 git revisions

  • 应用于 cherry-pick, reset, log, merge
  • 特定单个版本
    • head^^/head^2
    • head@{2}
    • head~~/head~2

版本的范围

  • master..experiment (from master to experiment): D, C
  • master A ^experiment (from experiment to master or feature): F, E
  • master…experiment (from master to experiment or vice versa): F,E,D,C
  • @: HEAD

版本关系语法

Figure 1: 多分支的版本历史
Figure 1: 多分支的版本历史
AA^0
BA^A^1A~1
CA^2
DA^^A^1^1A~2B^1
EB^2A^^2
FB^3A^^3
GA^^^A^1^1^1A~3D^1
HD^2B^^2A^^^2A~2^2
IF^B^3^A^^3^
JF^2B^3^2A^^3^2

范围选择的语法 1

Figure 2: 多分支的版本历史
Figure 2: 多分支的版本历史

版本范围语法

输入分解结果
DG H D
D FG H I J D F
^G DH D
^D BE I J F B
^D B CE I J F B C
CI J F C
B..C^B CC

范围选择的语法 2

Figure 3: 多分支的版本历史
Figure 3: 多分支的版本历史
B…CB ^F CG H D E B C
B^- (merge)B^..B
^B^1 BE I J F B
C^@C^1, FI J F
C^!C ^C^@, C ^FC
F^! DF ^I ^J DG H D F

典型场景中的工具和操作

模拟场景及对策 (后悔药)

  • 在已有代码仓库开创一个特征分支
  • 增加变更 (git add)
  • 提交变更 (git commit)
  • 撤回最近提交变更 (git commit,马上反悔)
  • 撤回一长串变更 (在一个分支上多次提交以后反悔,reset)
  • 撤回远程仓库(git push 给所有人后反悔)
  • 变更整个分支 (git rebase)
  • 在错误分支上提交变更(把相关变更推到正确分支上,cherrypick)
  • 头脑风暴!

常规应用命令

  • git branch (off, out): 添加变更
  • git commit -a: 反悔最近变更, git push -f 选项.
  • git reset
    • soft, mixed, hard 如果 hard 更干净,为何 mixed 是默认选项?
    • hard 很危险 (detached/isolated commit,没有后悔药!)
    • soft, mixed 更保守,防卫性回退
  • git remote
    • 可以对应多个远端仓库? 比如 ros 的 github 仓库和公司内网有特殊配置的仓库

复杂命令

  • git rebase
    • git push –force (没有后悔药!)
    • git merge

git reflog 的视角

  • 头部分支的历史 (head & branches)