一, 问题场景
正常我们使用 Git, 比如 Git add ,Git commit , Git push 这些完成个人的代码暂存, 修改, 提交和推送操作.
在多人协作下, 你提交的文件修改可能对方也在修改同一个文件, 并且比你先修改完先 push 到远程. 这时候你不得不 pull 下别人的分支, 在重新 push, 如果有 confilict, 还需要手动修改冲突文件, 该是你的保留, 不想要的删除, 最终再提交.
这些是最基本的场景, 但是你有没有遇到过以下棘手的场景:
1.1, 别的同事提交了 master(或者 dev 分支), 但是下一个临时发布版本需要暂时剔除这个代码, 并且需要合并你自己负责的那部分代码提交.
当然你可以说先找到别的同事提交之前的那个版本, 然后在 branch 一个分支, merge 上你的代码. 但是问题是如果 master 已经提交了很多个 commit, 而别的同事提交的那个暂时不想要(比如说他提交的是一个大功能模块, 上线可可能需要比较谨慎, 所以这次不发表), 其他的还是要一起发布.
- --C----D---- some commit must kick off
- / \<merge>
- ----A----B----C----D----E master
- \
- --O----P----Q my branch
- \
- --B----E release brance
这个时候如果想要制造出像 release branch 那样子的提交. 可以这么做:
可以先从 my branch 中 rebase 一个 release branche. 然后 Git cherry-pick B, Git cherry-pick E 即可. 其中 B 和 E 是 commit log md5 串. 这个 commit id 可以通过 Git log 查看, 这个 commit id 是一串很长的字符串, 但是其实只需要前面几个字母组成的字符串, 只要这个字符串是能让 Git 联想到唯一的 commit id 就可以. 需要注意的是 cherry-pick 保持原来的 B 和 E 提交顺序.
和 SVN 不一样, Git 的 commit id 不是 1,2,3...... 递增的数字, 而是一个 SHA1 计算出来的一个非常大的数字, 用十六进制表示, 因为 Git 是分布式的版本控制系统, 多人在同一个版本库里工作, 如果都用 1,2,3...... 作为版本号, 那肯定冲突了.
二, 学会查看, Git log 的线条, 形状和颜色
Git 初学者或者从 SVN 刚切换到 Git 的使用者, 一开始就敲复杂的命令可能会有点困难. 这时候如果使用跟 tortoise SVN 类似的 Git 软件, 会比较好上手 Git.
Git log 日志每条记录有三栏, 第一栏是分支图, 第二栏是代表提交是否修改, 新增和删除文件. 第三轮是 Git 分支 (或 tag) 加上本 commit 的提交日志.
2.1. Git 上的版本线
每一条版本线代表着一个分支.
还有有些颜色会中断, 然后在另外一个地方继续, 这里其实已经是不同的分支, 也就是 Git log 的颜色同样, 如果遇到分支, 或者断续 可能代表的是另一个分支
这里有分叉, 有断线再接上, 同一个颜色 (绿色) 代表了 5 个不同的分支.
图 1. 某个 repo 的版本记录图
2.2 版本线交叉上的形状
四方块代表 merge, 圆形代表一个提交. 每条横线记录代表着一个事件. 形状记录了是什么事件, merge 或者哪个版本提交 commit 事件.
Git log 的 Walk Behaviour 里面有一堆按钮: 注意下如果只是想看分支间的关系, 可以把 compressed graph, 而如果还想看清每个分支的提交, 就把这个按钮关掉.
图 2. 简略版本(多次提交被只显示一条)
图 3. 完整的提交
2.3 提交记录的版本 / 分支信息
由于 log 显示的是所有分支, 所有需要在第三栏, messege 那栏有显示当次更改涉及的分支或者 tag.Git log 上有 tag 比如这种,
图 4 修改的 tag
还有 branch
图 5. 修改的 branch
来源: https://www.qcloud.com/developer/article/1468104