适用场景
面向内部的那种需求不是很频繁的内部系统,5人以内的项目。
本地开发
首先,在第2节的基础上张三和李四各先修改下代码并完成一次 commit
。
-
张三
- 先拉取最新的代码
git pull origin master
- 写代码
- 提交到远程
- 先拉取最新的代码
-
李四
-
拉取最新的
master
分支
-
写代码
-
提交到远程
-
-
张三
- 拉取最新的
master
分支
- 存在冲突则解决冲突
当前master
指向的是最新的一个 commit。HEAD
指向master
。
- 拉取最新的
此时需要开发一个新的功能,由张三认领,他从 master分支
拉一个特性分支。比如 feature/001分支
。
git checkout -b feature/001
这个命令在创建分支的同时也切换到这个分支上去,相当于 git branch feature/001
+ git checkout feature/001
此时 master
继续指向 750
,但是多了一个 feature/001
指针,指向 750
,同时 HEAD
切换为指向了 feature/001
。
接着就可以在 feature/001
分支上做一些开发了,主要是为了新功能写代码,而且一般每天都会执行一次提交,保证工作内容不会丢失。
commit
之后会长出来一个新的 commit 记录
然后 feature/001
指向了这个 commit,HEAD
继续指向 feature/001
。
假如此时突然接到一个通知,需要解决一个线上的 bug。此时就需要切换到 master分支
,然后基于当前的 master分支
拉一个新的分支专门修复当前线上的这个 bug。比如 hotfix分支
。
注意在切换到 master分支
之前,需要先提交 feature/001分支
的所有代码,否则是不允许切换分支的。
git add --all .
git commit -m "xxx"
git checkout master
git checkout -b hotfix/001
一旦切换到 master分支
,工作区的所有代码会给 git 还原为 master 指针指向的那个commit object
的所有快照,git 会负责对代码文件进行新增、修改或者删除,彻底还原到那个快照版本。
接着拉取并且切换到 hotfix/001
之后,就可以基于 master 的代码来进行 bug 修复了,修改代码,解决 bug,进行测试,然后在 hotfix/001
上可以提交代码。这里假设 hotfix/001
分支的代码和 feature/001
分支的代码,都对同一行(图中第12行)进行了不同的修改,为了后面的合并冲突解决进行准备。
这个时候,master
继续指向 750
,feature/001
指向 67a
,然后从 750
长出来一个新的 commit object——e69
,hotfix/001
指向 e69
。也就是说,从 750
之后,分叉长出来两个commit object
:67a
和 e69
。
接着,对 hotfix/001
的代码需要进行测试,然后测试通过之后,就可以将 hotfix/001分支
合并到 master分支
,准备上线了。注意切换前要先 commit
当前分支。
git add --all .
git commit -m "xxx"
git checkout master
git merge hotfix/001
这次 merge 被称之为 fast-forward
(快进式的merge),为啥呢?因为看一下此时的 commit 树,master 指针只要直接移动到指向 e69
,就可以完成本次合并了,这就是 fast-forward
。但是此时 HEAD
就是指向 master
的。
此时就可以用 master 代码来部署解决 bug 了。
同时由于已经合并到 master分支
了,所以可以删除 hotfix/001分支
。
git branch -d hotfix
然后切换回 feature/001分支
,继续新功能的开发
git checkout feature/001
完成代码,然后最终 commit
一次,结束 feature/001
的代码开发,同时基于这个分支的代码完成测试。
此时会从 c3
长出来一个 commit——589
,feature/001
指向 589
,而且 HEAD
指向 feature/001
。
接着就要将 feature/001分支
合并到 master分支
了,完成功能的合并
git checkout master
git merge feature/001
解决冲突后 commit
此时,因为 master
指向的 commit e69
,是不能直接移动到 feature/001
指向的 589
的,因此需要执行一个 3-way merge
。此时会创建一个新的 commit object——182,它的 父commit
是 e69
和 589
。此时,master
会指向最新的 commit 即 182
,feature/001
继续指向 589
,同时 HEAD
指向 master
。
接着就可以删除 feature/001
分支了
git branch -d feature/001
推送远程
张三要将自己本地的 master 代码推送到远程去。
此时本地的 master
跟远程分支 origin/master
是关联起来的,origin/master
就对应着远程仓库的master分支
功能分支工作流28
执行上述命令之后,实际上会做两件事情:
-
修改本地的
origin/master
分支,移动到和本地的master
分支一样 -
将本地的
commit
提交历史推送到远程仓库,使远程仓库的master
是指向最新的那个commit
之后,李四也要push代码
会发现程的仓库里的 master分支
代码已经有人提交过了,此时是不能直接推送新的代码到 master分支
的。并且要求先执行 git pull
命令
该命令实际上会做如下两件事:
- 将远程仓库的 commit 提交历史拉取下来跟自己本地的提交历史进行合并
- 将本地的 master 分支对应的 commit 跟远程仓库的 master 分支对应的 commit 进行合并
之后再推送到 远程master
git push origin master
张三做最后一个操作,就是执行一次 git pull
,将远程仓库的提交历史拉取到本地进行合并,同时将远程仓库的 master
跟本地的 master
进行合并,让本地仓库跟远程仓库保持一致。