开发环境之git:团队协作git工作流与常用命令
此篇文章只是一篇傻瓜式的,记录工作中比较规范且常见的一个git工作流需要用到的命令,让你可以快速的开始工作。而不是一些长篇大论的理论知识,如果你有用过sourcetree或者其它图形化工具,结合你正在使用的工具,敲这些命令,看图形化工具中的变化,对比思考这些命令可能会更容易吸收。
1.基本配置
刚入职公司开始做项目拉代码,需要经历的第一件事。配置个人的用户名称和电子邮件地址(通常是公司邮件地址)
1.1 配置用户名和邮箱
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
1.2 设置public key
首先需要在本地生成key
ssh-keygen -t rsa -C "你的邮箱"
一路回车,接下来复制public key
cat ~/.ssh/id_rsa.pub
当然也可以去系统里找到这个文件自己手动复制,
windows用户,文件一般在
C:\Users\Administrator\.ssh\id_rsa.pub
mac用户,文件在
用户名\.ssh\id_rsa.pub
可以在命令行里输入
open ~/.ssh
有可能你的[用户名]目录下只有[公共, 图片, 文稿, 下载, 音乐,影片] 等这类文件夹,你就可以同时按下 shift command . 三个键,就可以看到里面会有一个 .ssh 文件夹了。
还有可能你的文件夹目录甚至都没有[用户名]这一栏,可以按照 访达 --> 偏好设置 --> 边栏 中勾选你的用户名就好了。
扯远了,回到主题。复制好 .ssh 下的 id_rsa.pub 文件后,打开你的gitlab 或者 其它你们公司用的git仓库管理系统,将它添加到你的账户上
右上角点击头像 --> 点击settings --> 点击 SSH KEYS --> 点击 ADD SSH KEYS --> 将获取的 id_rsa.pub 文件内容粘贴于此
2.开发阶段的实际场景与常用命令
2.1 如果是启动一个新项目,组长需要做什么?
// 2.1.1:新建gitlab仓库,复制ssh仓库地址
// 2.1.2:克隆项目到本地文件夹
git clone "复制的地址"
// 2.1.3:此时默认是在maser分支上,进到拉取的本地项目目录中去,将本地仓库与远程仓库关联起来。
git remote add origin '复制的地址'
// 2.1.4:推送本地master分支到远程master分支
git push -u origin master
// 2.1.5:新建一个本地dev分支,并切换到本地dev分支
git checkout -b dev
// 2.1.6:在此之前远程是没有dev分支的,需要推送本地dev分支到远程dev分支
git push -u origin dev
master分支将来控制着发布到线上的稳定版本代码,普通成员不可以对master分支进行操作,不然每个组员改点东西,很有可能把线上代码搞崩。组员们只能在dev分支上进行操作。
2.2 接下来组员们需要做什么
// 组员小智:
// 2.2.1 将组长建好的仓库克隆到本地
git clone "复制的地址"
// 2.2.2 默认在master分支上,需要检出远程dev分支到本地dev
git checkout -b dev origin/dev
// 2.2.3 不直接在本地dev分支上写代码,不然就跟svn没什么两样了,基于本地dev分支建一个自己的本地分支,名为xiaozhi
git checkout -b xiaozhi dev
// 2.2.4 此时,就切换到了本地xiaozhi分支上,开始写功能,比如task0001,写完后
git status
// 查看你本地做了哪些修改
git add '修改的文件名(包含目录)'
// 或者
git add *
// 来把你的修改添加到暂存区去,接下来提交代码到本地xiaozhi分支
git commit -m "task0001:基础布局功能"
// 2.2.5 建议每完成一个任务的其中一个小功能就重复一次2.2.4步骤,每天下班前至少要合并推送一次到dev分支。确保你的代码不能影响别人的运行,也不会跟最新的代码相差太远。首先,切换到本地dev分支
git checkout dev
// 2.2.6 拉取最新dev分支代码,可能在你写task0001的时候,别人提交过代码了
git pull
// 2.2.7 合并本地xiaozhi分支代码到本地dev分支
git merge xiaozhi
// 2.2.8 推送你改动的代码到远程dev分支
git push
// 2.2.9 切换到本地xiaozhi分支
git checkout xiaozhi
// 2.2.10 合并本地dev分支到本地xiaozhi分支
git merge dev
// 至此,你将你的改动推送到了远程,你的本地也是最新代码了,继续去做task0003。重复2.2.4-2.2.10步骤
...
...
...
// 当你在2.2.1步骤的时候,可能你的同事小狒也要开始做task0002,他在他的电脑上又是怎么操作的呢?
git clone '复制的地址'
git checkout -b dev origin/dev
git checkout -b xiaofei dev
git status
git commit -a -m "task0002: 基础布局功能"
git checkout dev
git pull
git merge xiaofei
git push
git checkout xiaofei
git merge dev
// 每个组员除了基于dev分支新建的本地分支命名不一样之外,其他基本一样。
2.3 此过程可能会遇到的问题
在执行 git pull 或者 git merge 操作的时候
2.3.1 如果出现这样的代码
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch。
# lines starting with "#" will be ignored, and an empty message aborts the commit
// 可以按 ESC 退出键,输入 :wq 然后敲回车就可以恢复正常,然后继续git push 即可
2.3.2 发现有冲突怎么办?
// 如果提示有冲突,在你的编辑器里看到代码是这样的
>>>>>> HEAD
// 从HEAD到下面的====之间的代码是你当前分支上的代码
function a () {
console.log('a')
}
======
// 从======到下面的>>>>>之间的代码是你要合并过来的代码
function a () {
console.log('aa')
}
>>>>>> xiaofei
// 需要小狒和小智商量,保留小智的还是保留小狒的,还是两个人的都要保留一部分。手动改好代码后,执行
git add '冲突的文件名'
git commit -m '解决冲突'
git push
2.3.2 如何放弃本地修改?
// 当小智在他的本地xiaozhi分支上加功能时,可能他开始没考虑全面,想把本地修改的内容都删掉重新来过。
// 当小智还没有 git add 缓存代码时
git checkout -- '想放弃修改的文件名(带路径)'
// 或者放弃所有文件的修改
git checkout .
// 当小智已经把想撤销修改的文件执行了 git add 的时候
git reset HEAD '想放弃修改的文件名(带路径)'
git checkout -- '想放弃修改的文件名(带路径)'
// 当小智已经把想撤销修改的文件不仅git add还git commit的时候
git reset --hard HEAD^
// 可以用这条命令来恢复至上一次commit的状态,如果发现已经提交了好几次怎么办,噗,没忍住笑出了声。如果直接回退肯定是可以的,但是这中间的几次commit可能又有你想要的代码,这个说实话,有点惨。说个比较实际的方案吧。把现在的代码文件夹先复制一份。再执行
git log
// 看看你想回退到哪次commit的状态,找到那次commit的版本号(记住关键的前几位就可以了),然后
git reset --hard e235a
// 然后再从复制的那份文件夹中去对比,看看哪些是你想要的,想要的就加进来。
3. 测试阶段的实际场景与常用命令
终于到了开发完成,要测试的时候了。此时,所有人各自对应的本地分支代码(xiaozhi分支,xiaofei分支)都应该和dev保存一致了。
其实就可以把release分支当作dev分支,只不过开始是大家都推送到dev分支上做开发,而现在是都推送到release分支上改bug。
// 组长:
git checkout -b release dev
git push -u origin release
// 组员小智:
git checkout -b release origin/release
git checkout xiaozhi
git status
git add *
git commit -m "bug0001:修复首页xxxx的问题"
git checkout release
git pull
git merge xiaozhi
git push
git checkout xiaozhi
git merge release
// 继续解决下一个bug
// 组员小狒
git checkout -b release origin/release
git checkout xiaofei
git status
git add *
git commit -m "bug0002:修复列表页的XXXX的问题"
git checkout release
git pull
git merge xiaofei
git push
git checkout xiaofei
git merge release
// 继续解决下一个bug
// 当所有测试提出的bug都解决完后,大家应该保证dev分支,release分支,各自的本地分支(xiaozhi,xiaofei)都一样
// 组长:
// 合并release分支到dev分支上
git checkout dev
git merge release
git push
// 合并release分支到master分支上并打上标签版本号
git checkout master
git merge release
git push
git tag -a v1.0.0 -m '1.0.0版本'
git push origin --tags
// 组员们继续写功能开始进行下一版本的产品迭代,重复2.2.4-2.2.10步骤
4. 上线后客户反馈有bug怎么办?
有可能当组员们已经在各自的本地分支(xiaozhi, xiaofei)上去做下一版本的开发的时候,客户反馈一些测试小姐姐们当时没有测出来的bug。此时大家肯定不会直接去把dev分支再去合并到master分支了。
// 组长:
// 4.1.1 基于master分支新建一个hotfix001分支
git checkout -b hotfix001 master
// 4.1.2 与远程hotfix001分支关联起来
git push -u origin hotfix001
// 组长将这个重大而又紧急的任务指派给小智
// 组员小智:
// 4.1.3 检出远程分支hotfix001到本地分支hotfix001
git checkout -b hotfix001 origin/hotfix001
// 4.1.2 小智一顿牛逼操作之后
git commit -a -m "hotfix001: 解决线上xxxx的问题"
git push
// 4.1.3 测试通过后组长去拉取hotfix001的代码并合并回master分支
git checkout hotfix001
git pull
git checkout master
git merge hotfix001
git push
git tag -a v1.0.1 -m '1.0.1版本:修复XXXX等一系列的问题'
git push origin --tags
// 4.1.4 接下来判断这个线上的bug下一版本是否还要处理,如果这个功能还要的话,为了避免下一版本出现同样的问题,那组长还需要把这个hotfix001分支合并到dev分支中去
git checkout dev
git pull
git merge hotfix001
git push
// 4.1.5 线上bug分支hotfix001完成了它光荣的使命,可以删除了
git branch -d hotfix001
git push origin --delete hotfix001
5.后话:
我也在用git图形化工具,比如sourcetree。相信很多人也在用,其实用命令行还是不如sourcetree那么方便而强大的。比如在撤销修改的时候,sourceTree可以只撤销这个文件你所改动的某一部分,而git命令行只能对某一个文件的所有改动撤销修改(当然,可能是我对git命令行操作还不那么深入的缘故,但是我相信就算git命令行能做到,也远没有图形化工具那么方便)。
不过我觉得我写这篇文章其实还是有意义的,工作了这么久,几乎天天都会用到git,一些常见git命令都不懂也说不过去,对自己要求并不那么高,并不是要强到什么都可以立刻想到用什么git命令去解决,而此篇文章中工作流常用到的命令还是要熟记于心的。
大家可以用自己的github账号并且找一个小伙伴去建一个仓库模拟体验一下上述多人协作的过程,如果有问题可以一起交流下。
另外,你可能会感兴趣的一些点: