git梳理二:特殊问题记录
1. merge部分commit:cherry-pick
如git cherry-pick e43a6fd3e9
,可以把指定的commit提交到当前分支。常用于把bug fix提交合入发布分支。
2. 拯救push -f:reflog
上面这篇文章讲的是如何撤销rebase,跟撤销push -f
原理是一样的,都是切换到之前的合适节点,剩下的就好解决了。
简单而言,git记录了每次head变化时的日志,因此可以通过这个日志找到提交记录被修改前的状态,从而回滚。
不得不感叹git的数据结构设计的灵活性。
另外注意,任何时候都不应该使用push -f
,任何已提交到远端的记录都不应该被修改。
3. 清理无效分支:git remote prune origin
远端分支被删除时,git默认并不会同步这个删除操作到本地。git remote prune origin
这个命令就是清理掉远端已经删除的分支。
通常情况下,这些无效分支并不会有什么问题,只是堆在那里塞满了分支列表有点不方便而已,但是特殊情况下回引起一些问题。
比如小明拉了个叫xiaoming
的临时分支,提交了些代码,发了个mr,回头又删掉了。下次他又拉了个临时分支xiaoming/bugfix
,做了同样的操作,此时,他本地和远端都没有xiaoming
分支,因此正常。如果这个时候有人更新代码,就会报错:xiaoming
已存在,不能创建xiaoming/bugfix
。
因此,通常需要明确分支命名规范,杜绝这种分支名冲突的情况。如果发生了,就要执行git remote prune origin
来修复了。
4. 大文件管理git-lfs
关于git的存储原理可以参考Git Internals - Packfiles
表象上来看,git每个commit都索引了完整的文件,即,每个文件的每次修改,都会生成一份全新的索引。但实际上,git在实际存储的时候,对每个文件的版本变化是进行了delta压缩的,因此实际存储时的空间占用相当于存的是diff。
但是很多二进制文件,你修改了一点东西,它并不是像文本文件一样只变化了一点点的。比如一个jpg图片,你在上面加了个黑点,在jpeg编码后,整个二进制文件发生了较大的变化,delta压缩的效率就很低。不只是图片,大部分二进制文件都有这样的问题。
因此,如果有较大的二进制文件,在仓库中经常变化,git仓库的大小很容易膨胀到恐怖的程度。
Git LFS 是 Github 开发的一个 Git 的扩展,用于实现 Git 对大文件的支持。它把大文件单独存放,git中只记录一个索引,可以大大减轻仓库容量的负担。
参考git-lfs