开篇
按照惯例先说说为什么会想写这个话题,最初是因为看到公众号推送了一篇阿里的持续集成发布系统的文章让我对这个分支管理发布的CI/CD流程产生了兴趣,顺带就花了半天时间研究了一下。
在蚂蚁短暂的时间里也用过aoneflow系统但是当时没有上升到需要深入了解下分支管理的深度,来了现在的公司以后因为代码集成发布经常接触发布系统,经常有意无意就会对比几大互联网公司的发布系统,颇有种指点江山的感觉,顺便夸下我司我发布系统,在创业公司应该算首屈一指的。
毕竟不能永远指点江山不下手,所以就有了这篇《git从入门到不放弃》,按照我自己的理解,只要理解了git的三块内容基本上就能够遇到问题不慌了,git仓库基本概念,git的提交撤销,git的分支管理,其他一些常用的git命令我就不一一列举了否则就成了一篇水文了。
最后当然延伸的就是对比下各大互联网公司在分支管理方面的实践,这样子心里会更有谱一些。如果哪天面试新人的时候看到别人写着熟悉git命令,那么就问问除了git add commit pull push之外的东西,譬如给我讲讲git的仓库的概念。
git 仓库基本概念
说明:
一个完整的git仓库由以下几个区组成:
- Remote:远程主仓库;
- Repository:本地仓库;
- Index:暂存区;
- workspace:本地工作区(即你编辑器的代码)
常规的操作命令会在几个区直接进行数据的共享
- git status 查看工作区状态
- git add 将所有修改加入暂存区,实现工作区到暂存区的代码提交。
- git commit -m "提交描述" 将代码提交到本地仓库,实现暂存区到本地仓库的代码提交。
- git push将本地仓库代码更新到远程仓库,实现本地仓库到远程仓库的代码提交。
知识点划重点,要谨记有几个区,以及每个命令影响的哪几个区,如果只知道机械的敲命令执行提交,那跟咸鱼有什么区别,还是要有梦想的。
git 的提交撤销操作
git的提交动作如果细究一下,主要由git add,git commit, git push三类,每一类都会涉及到A区->B区的提交,正向的提交流程肯定就不多说了。
那么万一提交错代码该怎么办,总不能每次提交错了就慌的一笔吧。这里我会核心的讲一个撤销的点,具体的可以看下参考文章中廖雪峰的git博客,这里分场景说一下几种情况:
修改了工作区的demo文件但未提交到暂存区,那么通过git checkout -- demo命令撤销工作区的修改。注意 -- 非常重要。
修改了工作区的demo文件并且通过git add 提交暂存区但未提交本地仓库,那么通过git reset HEAD demo将暂存区的修改撤销到工作区,如果想继续撤销工作区,参考上一个git checkout -- demo命令。
修改了工作区的demo文件并且已经提交到本地仓库了,那么只能通过版本回退来解决了,那么通过git reset --hard HEAD^(版本号)来进行回退了,版本号通过git log去查询。
修改了工作的demo文件并且提交到了远程分支,那么恭喜你,老板会请你喝茶的,没有办法了。
git 分支管理部分
git的分支管理部分,直接通过官网的几张图片来进行说明,主要是包括分支提交和分支合并两个概念。
分支提交过程
说明:
原本只有一个master分支,然后通过git branch testing命令新建了一个testing分支。Git 有一个名为 HEAD 的特殊指针指向当前所在的分支,在本例中,你仍然在 master 分支上。 因为 git branch 命令仅仅 创建 一个新分支,并不会自动切换到新分支中去。
说明:
要切换到一个已存在的分支,你需要使用 git checkout 命令。 我们现在切换到新创建的 testing 分支去:git checkout testing,这样 HEAD 就指向 testing 分支了。
说明:
在testing分支上进行编辑并进行提交[vim test.rb && git commit -a -m 'made a change'],testing 分支向前移动了,但是 master 分支却没有,它仍然指向运行 git checkout 时所指的对象。
说明:
现在我们切换回 master 分支看看[ git checkout master ],这条命令做了两件事。 一是使 HEAD 指回 master 分支,二是将工作目录恢复成 master 分支所指向的快照内容。
说明:
现在我们对master分支进行编辑并提交[ vim test.rb && git commit -a -m 'made other changes' ],master分支往前迁移了一个版本。
分支合并过程
说明:
假设起始状态如上图
说明:
现在,你已经决定要解决你的公司使用的问题追踪系统中的 #53 问题。 想要新建一个分支并同时切换到那个分支上,你可以运行一个带有 -b 参数的 git checkout 命令:
git checkout -b iss53
Switched to a new branch "iss53"
说明:
你继续在 #53 问题上工作,并且做了一些提交。 在此过程中,iss53 分支在不断的向前推进,因为你已经检出到该分支(也就是说,你的 HEAD 指针指向了 iss53 分支)
vim index.html
git commit -a -m 'added a new footer [issue 53]'
现在你接到那个电话,有个紧急问题等待你来解决。 让我们建立一个针对该紧急问题的分支(hotfix branch),在该分支上工作直到问题解决,你通过下面命令切换到master分支并重新创建了hotfix分支并提交代码修改。
git checkout master
Switched to branch 'master'
git checkout -b hotfix
vim index.html
git commit -a -m 'fixed the broken email address'
说明:
紧急问题已经解决了,现在需要发布上线,通过将hotfix分支合并回你的 master 分支来部署到线上,我们可以通过以下命令实现这个功能。
git checkout master
git merge hotfix
在合并的时候,你应该注意到了"快进(fast-forward)"这个词。 由于当前 master 分支所指向的提交是你当前提交(有关 hotfix 的提交)的直接上游,所以 Git 只是简单的将指针向前移动。 换句话说,当你试图合并两个分支时,如果顺着一个分支走下去能够到达另一个分支,那么 Git 在合并两者的时候,只会简单的将指针向前推进(指针右移),因为这种情况下的合并操作没有需要解决的分歧——这就叫做 “快进(fast-forward)”。
说明:
删除 hotfix 分支并继续在iss53分支进行编辑提交代码,通过以下命令执行:
it branch -d hotfix
Deleted branch hotfix (3a0874c).
git checkout iss53
vim index.html
it commit -a -m 'finished the new footer [issue 53]'
说明:
准备将C5和C4进行分支合并,但是因为C4和C5没法快速移动实现分支合并,所以git需要新建一个分支进行合并。
说明:
和之前将分支指针向前推进所不同的是,Git 将此次三方合并的结果做了一个新的快照并且自动创建一个新的提交指向它。 这个被称作一次合并提交,它的特别之处在于他有不止一个父提交。
需要指出的是,Git 会自行决定选取哪一个提交作为最优的共同祖先,并以此作为合并的基础。
git集成发布
这块请参考在阿里,我们如何管理代码分支?,或者直接咨询武哥贝贝如何实现git分支发布的,这块是分支发布真正的落地方案,不看是对不起你自己的。