前言
本文旨在帮助没有接触过Git的同学,使用Git以及GitHub的基本功能,适用于初学者。
由于内容比较多,一次写不完,故做成连载,以后还会更新其它内容。
第一期:Git入门(一)——基本操作及理论
第二期:Git入门(二)——团队开发基本流程概述 (本期)
步骤零:把项目跑起来
分为以下两种情况:全新的项目,中途接手的项目
无论哪种情况,都应该先把GitHub仓库clone到本地,有一个区别就是,全新的项目需要先在GitHub上新建仓库。
//作用:把地址中的在线仓库clone到本地的文件夹中
git clone <仓库地址> <本地的文件夹>
请耐心等它跑完。
在本地拥有了代码之后,就开始跑项目了。
如果是已有的旧项目,接下来就是检查开发环境、数据库、Nginx、redis等等,以确保项目能成功的跑起来。
如果是新项目,仓库中只有一个readme.md,就不需要这一步(但需要额外的一步项目初始化,具体如何初始化,取决于开发使用的编程语言)。
步骤一:把本地仓库调整到工作状态
出于安全起见,一个严谨的团队,必然会制定一些合作开发的规范,比如
- 不能向主分支直接提交代码
- 不能由旧分支向新分支发起合并请求
因此,在领取一个任务时,我们本地的仓库可能刚刚完成上一个任务,因此需要进行切回主分支、同步远程仓库的代码、建立新分支等等操作。
假设我们领取了新任务,issue的编号是300,而我们本地仓库还处于上次的275分支上,并且刚刚提交完代码:
这时候需要先切换回主分支:
// 切换到主分支
git checkout master
然后把远程主分支同步到本地主分支:
(分支关系: origin/master -> master)
// 拉取远程仓库的代码
git pull
执行上一步以后,我们本地的代码已经和远程仓库完全一致了。
接下来为新领取的任务创建一个分支:
// 创建新分支
git checkout -b <分支号>
// 示例:创建分支编号为300的新分支
git checkout -b 300
到此为止,我们既更新了本地的代码为最新版本,又为新领取的任务做好了准备,因为新的issue将在300分支上完成开发,因此,在合并代码之前,不会对master分支产生影响。
接下来就开始写代码了。
步骤二、提交代码
假设现在我的代码已经写完了,在完全保存之后,终端中的分支号是黄色的,黄色表示代码有改动,但尚未提交。
我们可以查看代码变更信息(这一步不是必须的):
// 查看代码状态
git status
从返回的结果来看,有一个文件是modified状态,这说明:
Git发现了一个文件出现更改,但并没有记录这个更改,因此提示信息是红色的。
那么我们怎么让Git记录这些更改呢?
// 记录当前目前的所有文件变更
// 此命令应该在项目根目录执行
git add .
再git status 就可以看到刚刚显示红色的文件已经变成绿色:
接下来可以提交代码了(也相当于打一个保存点):
// 在本地提交代码变更,最后是备注信息
git commit -m <备注信息>
// 示例
git commit -m issue300已完成
提交完成后,原本黄色的分支号会重新变成绿色:
接下来就是把本地的代码提交到远程分支上:
(分支关系 300 -> origin/300)
// 把本地的分支推送到远程仓库
git push origin <分支号>
// 示例:把本地的300分支推送到远程的300分支
git push origin 300
在提示信息中,可以看到,希望用户访问GitHub来建立Pull Request。
至于GitHub的操作步骤,在第一期中已经讲解,本文专注于讲解Git命令。
附录一 解决冲突
冲突产生原因
只要有代码合并就不可避免的产生冲突,冲突的产生,还是要从分支说起。
刚刚我们提到了一条规范:
- 不能向主分支直接提交代码
基于这个规范,团队的成员们需要分别在自己的分支上编写,最终依次向主分支发起合并。
在提交代码时,Git会以“行”为单位,记录每一行代码的改动情况,比如,在test分支,把某一行的123改成了456,Git会记录下:
123 -> 456
合并代码时,Git会找到master分支上的123这一行,并且改成456:
123 -> 456
我们先看一种情况:
如果A把123改成了456,B更新了A修改之后的代码,又把它改成了789,
此时是不会有冲突的,因为B是把456改成了789,而不是把123改成了789。
但下面这种情况就不一样了:
A把123改成了456,并且合并到主分支,但B没有更新A的更改,而是直接把123改成了789,那么,再去合并B的分支时,就会显示冲突
那么Git到底该听谁的?
因此就需要解决冲突了。
这也就是为什么有了第二个规范:
- 不能由旧分支向新分支发起合并请求
在合并代码时,当前的改动必须基于最新的主分支
解决冲突
发生冲突时有两种解决办法,一是在线上修改,二是将冲突代码拉下来,在本地修改。
如果冲突发生在本地,合并代码时会提示conflicts,并且会提示具体哪个文件发生冲突:
示例中是test.txt文件发生冲突,所以打开文件:
会出现一排<<<<<<<和一排>>>>>>>,中间夹住的,就是冲突的代码。
图中,当前的代码是789,而300分支的成员想改成456。
解决办法:
- 将冲突的代码删掉一部分,使程序可以正常运行(比如,在示例中,我打算删掉789)
- 删掉所有的箭头、=等等
- 未发生冲突的代码不动
- 保存文件
- 重新执行git add .
- 重新执行git commit -m <备注信息>,把合并的结果提交
最终的效果如下:
代码只剩一行“456”,终端中重新显示绿色提示符。
附录二 更新代码
刚才说到第二条规范:
- 不能由旧分支向新分支发起合并请求
比如,当你还在写自己的issue时,其他成员已经成功的向主分支贡献了代码。此时,主分支发生更新,而你的分支还是基于旧的主分支,因此你需要把新的主分支拉取下来。
这个时候,如果直接用git pull,大概率会出问题。
所以需要用到下面的方案:
// 把远程仓库的所有变更同步到本地的origin镜像中
git fetch --all
此时未进行代码合并,所以本地的代码没有变化。
// 把主分支合并到当前工作的分支
git merge origin/master
此时,你当前的工作分支不再基于旧的主分支,由于合并,已经基于新的主分支了。
在合并过程中也可能出现冲突,按照附录一的方法解决即可。
附录三 重置代码
如果你的代码出现了严重错误,想放弃全部更改,重置为最新版本的主分支代码,可以在当前的工作分支上执行:
// 拉取远程仓库的所有更改
git fetch --all
// 把当前工作分支的代码,用最新的master分支完全替换
git reset origin/master
然后,本地的工作分支,就和远程仓库的主分支一模一样了,重新编写代码即可。
总结 一图胜千言
团队合作开发的泳道图大概是这样的:
成员在领取任务时,是一起进行的,谁也不知道哪个成员先提交代码。就像异步请求一样,谁也不知道哪个请求先返回。
因此,要想顺利的完成合作,有两个关键:
- 一是具备解决冲突的能力,
- 二是及时的拉取远程仓库的代码变更。
附录
git pull == git fetch all + git merge origin/branch
版权声明
本文作者:河北工业大学梦云智开发团队 - 刘宇轩
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。