高阶 GIT 101 - 分支管理
Opened this issue · 0 comments
文档目的: 1. 让读者了解并存分支切换方式 2. 优化分支排列方式
日常小剧场:RD 开发 A 需求,产品和Server找过来说需要协助排查线上异常,排查不一会发现就是涉及 A 需求代码逻辑异常,需要紧急修复然后验证无误上线。这时候你该怎么处理目前工作现场(workspace)?
Stash
git stash
可以将本次修改内容(涉及跟踪数据)存储到 stash 中,stash 是一个存储临时修改的堆栈。
上述场景,工作流会变成:
- 直接使用
git stash
命令完成工作区暂存 - 然后切分支 => 改问题 => 发环境 => 验无误之后开始正常上线。
这时候回到开发 A 需求分支,通过 git stash list
查看 stash 堆栈信息,如果有良好工作习惯(每次使用 stash 完清空本次),就会发现堆栈中有一条记录,否则往期历史记录都还在堆栈中对你说好久不见。
这种场景你会迷糊应该用那条记录,因为所有直接提交复用是就近 commit message,如果记性好可以快速识别出来,那记性不好呢?
这时候你会说那不应该是第一条吗?因为 stash 是堆栈结构,第一条就是上次推入。
这个理解没啥问题,主要是观点无法验真。因为做需求过程中,修改好这个紧急问题,可能会有下一个而且还有可能你会忘记回去做A需求,会有B C D 需求,一旦小剧场现象串成了环,stash 中位置就不可靠了,甚至会出现两个记录 commit message 一致的情况。所以回到流程 1 中,这时候存储需要添加一些方便你回忆的标记位,像提交commit 那样。
git stash -m "<your message>"
继续回到修复完成场景,这时候查看堆栈信息就比较容易了,通过 git stash list
查看上次提交所属堆栈的位置,然后使用
# ❌
git stash apply --index <index>
# ✅
git stash pop --index <index>
Commit
git stash
需要培养良好维护习惯,但这个也太烦了,需要有好习惯好记性才行,还有没有简单方式呀,还记得上文最后说到存 stash 类似 commit 就行,那为什么不直接存 commit 呢?
Of course, yes!
既然 git stash
操作存在较多的记忆、习惯等限制,那就直接将修改提交成一条临时commit呗~
git commit -nm 'temp message'
等问题结束,然后提交从暂存区转移到工作区,后续正常工作就好了。
git reset HEAD~
空间换时间
这时候你还是会有疑问,还是太麻烦了。有没有可以保留当前工作现场,又可以切换到新分支的情况。
当然有了,重新开一个目录重新拉取仓库,这时候clone命令并不需要全量历史记录,浅克隆减少等待时长
git clone --depth 1 <repository>
# 极端浅克隆,默认 branch 通常 master / main
git clone --single-branch --depth 1 <repository>
后续排查到问题原因,想排查问题引入时机,需要将浅克隆升级为深克隆,使用git fetch --unshallow
即可。
当前方式拿大量空间换取排查和养成习惯时间,受限于磁盘空闲上限。或许会觉得空间不值钱,小小空间轻松拿下。意识到这点时候,或许还没见过 monorepo 可怕。
即便是极致浅克隆场景原本 1.6G 远程仓库还是 400MB,后续添加安装依赖和转化深克隆,轻轻松松膨胀到 10+G 不在话下。
或许会说这玩意每次删掉就好,更方便!
是滴,没有一点毛病。如果幸运的话~
所以这样空间换时间方式你还能接收吗?
Worktree
[[高阶 Git 101 - 概念篇]] 中了解到所有记录都存储在 .git/objects
当中,也是克隆耗时最长阶段(复制远程仓库数据)。既然已有所有对象,有没有什么手段新建一个目录让其共享同一个 .git
信息做到快速克隆出一个仓库呢?
有的!真是个小机灵鬼~
git worktree
是一个在 Git 2.5 版本中引入的功能,它允许在一个仓库中同时进行多份工作树的检出,使得能同时在多个分支进行工作成为可能。
使用场景:
- 并行工作 on 多个分支:当你在一个分支上工作,但突然需要切换到其他分支进行一些工作(如 bug 修复)时,你可能不想立即提交你当前的工作进度。此时,你可以使用
git worktree
创建一个新的工作树来处理新的任务,而无需离开你的当前工作标头。 - 同时进行长时间运行的操作:有时,一个长期运行的操作(如测试或编译)需要在一个分支上进行,而你想要在不同的分支并行进行其他的工作。在这种情况下,
git worktree
可以帮助你创建一个新的工作环境。
使用场景完美契合了我们的诉求,创建出来 worktree 不占用任何空间,共享.git
所有历史记录,并做到工作区完美隔离。但依旧存在缺点,依赖包无法共享,用户需要单独安装依赖,若仓库安装依赖过重,会有体验不好情况;若都是用pnpm
进行管理,对应缓存+软硬链安装依赖方式,体验良好,占空间只有部分依赖体积(预计 400 MB)。
明细命令:
git worktree add <target_dir_worktree_path>
列出所有工作树:
git worktree list
删除一个工作树:
git worktree remove <target_dir_worktree_path>
检查出一个新的分支到工作树:
git worktree add -b new-branch <target_dir_worktree_path> origin/base-branch
在这些命令中,<target_dir_worktree_path>
是新的工作树的路径,new-branch
是新工作树的分支名称,origin/base-branch
是新分支要基于的远程分支。
完成创建之后,cd <target_dir_worktree_path>
即可在新分支进行排查和开发,更多 worktree
使用小技巧请结合 man
命令查看。
参考资料
git stash - 《阮一峰 Git 教程》 - 书栈网 · BookStack
git神器-git stash使用详解 - 个人文章 - SegmentFault 思否
如何恢复丢弃的 git stash 数据 - 知乎
Git - git-stash Documentation
https://git-scm.com/docs/git-worktree
Mastering Git Worktree: A Comprehensive Guide