前言:GIT对于我们程序员来说是吃饭的工具,本篇主要是针对提交和分支以及对于大多数程序员闻风丧胆的冲突一些个人见解,如果有啥不对的或者你们公司git提交流程欢迎下方评论。
在讨论规范之前,我们需要定最基本的要求
1.团队内保持良好的代码格式便于易读和维护,最主要减少不必要的代码冲突(建议统一使用开发工具(idea)的代码格式化)。
2.提交任何代码必须确认代码可运行
3.提交的代码必须移除无用的包路径引用和无用的依赖,尽量不要使用过期的方法或者类
1 . commit message规范
规范格式:
<type>: <subject>
**type **
- feature: 新功能(feature)
- fix: 修补bug、style等
- refactor: 重构(即不是新增功能,也不是修改bug的代码变动)
- test: 增加测试 chore: 构建过程或辅助工具的变动
subject
提交目的的简短描述,描述做了啥或者改了啥,如果有团队管理工具(issue ,JIRA)或者产品需求,必须以内部命名的需求代号作为描述信息的一部分,方便查看日志,合并和cherry-pick。
举例:
- feature:开发完成#代号 XXX.XXX需求
- fix:修改 #代号 XXXX查询问题
2. 提交规范以及GIT开发流程
**Git分支 **
- master (生产环境) 部署某个uat功能到准生产的时候合并到master,只允许uat分支合并/cherry-pick。
- uat (测试环境) 部署某个feature分支到测试的时候合并到uat,只允许feature分支合并。
- feature/xxxx (特性分支) 开发一个功能或者修改bug的时候合并/提交到feature
- dev/xx (本地开发版本)
在开发之前,需要在master分支上切一个以需求,BUG,重构.......命名feature分支 ,比如 feature/项目编号(BUG的代号)
2.1 本地没有项目,克隆代码的并切换到开发分支
克隆并在需要开发的feature分支上创建本地dev开发分支,本地分支可以以dev/自己标识的英文 命名。
git clone -b dev/xx feature/项目编号
2.2 本地有项目,切换开发分支
为了避免本地分支与远程不一致,需要切换到 feature/项目编号分支,更新一下。
git checkout feature/项目编号
git pull
再在 feature/项目编号上切出自己的开发分支
git checkout dev/xx
2.3 提交代码
注意:必须把不需要提交的后缀或者文件添加到和.git同目录的 .gitignore文件中
添加修改的文件到暂存区(staging area)
git add .
将修改后的文件提交到本地的版本库中
git commit -m 'fix:修改了XXXXX'
也可以两步合成一步操作
git commit -am 'fix:修改了XXXXX'
提交代码我个人是建议最好使用idea或者其他git图形化界面来操作勾选需要添加的文件,或者操作。
git后面的图标对应的意思
- 第一个是 git 拉代码操作按钮
- 第二个是 git 提交操作按钮
- 第三个是 git log操作按钮
- 第四个是 git revert操作按钮
首先点击git提交按钮
点击提交按钮就能清楚的看到git status的情况,有修改的有哪些文件,哪些文件需要提交git,哪些文件不需要提交git。如果临时或者不小心动的地方可以使用revert恢复到修改前。
如果这个文件不需要修改,或者不小心空格等操作,直接使用 revert恢复
如果这个文件是项目启动时候生成的,比如项目导出的excel或者log日志,直接使用 delete删掉
小技巧:大家在开发过程中,可以随时进入上图的提交界面直观的看到哪些文件有变动,更方便和更高效的管理自己修改的内容,其他桌面图形化也可以,比如 TortoiseGit,Source Tree,以及git自带的两个 gitk 和 git-gui (在git目录里输入命令)。
2.4 推送到远程分支
在推送本地分支dev到远程dev的时候,需要先切换到 feature/项目编号分支,merge远程分支代码。
git checkout feature/项目编号
git pull
再切换到自己的开发分支dev/xxx
git checkout dev/xxx
rebase feature/项目编号到自己dev/xxx,主要作用就是检查是否有冲突。
git rebase feature/项目编号
没有冲突,直接push dev/xxx到远程 dev/xxx
git push origin dev/xxx
如果有冲突,可以在合并冲突后的任意时刻使用 git status 命令来查看那些因包含合并冲突而处于未合并(unmerged)状态的文件
git status
所有合并中冲突而待解决的文件,都会以未合并状态标识出来。 Git 会在有冲突的文件中加入标准的冲突解决标记,这样你可以打开这些包含冲突的文件然后手动解决冲突。
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> dev/xx:index.html
以上文件内容表示head指向的(也就是rebase的那个分支)版本和下面dev/xx指向的版本有冲突
=======为分割线,上半部分是head指向的分支的版本的代码,下半部分是dev/xx分支所指向的版本的代码
上述的冲突解决方案仅保留了其中一个分支的修改,并且<<<<<<< , ======= , 和 >>>>>>> 这些行需要被完全删除。
修改完成之后需要操作
git add .
使用 git add 命令来将其标记为冲突已解决。 一旦暂存这些原本有冲突的文件,Git 就会将它们标记为冲突已解决
然后继续rebase操作:
git rebase --continue
一直循环rebase --continue,直到rebase成功
然后push
git push origin dev/xxx
最后登录gitlab或者coding的web管理,提交合并请求,将远程分支dev/xxx和远程分支feature/项目编号分支合并,合并之后才能表示你的提交完成了。等feature分支所有的人开发完成并测试通过之后,再将feature合并到uat进行上线测试。
现在我们看看借助我们神器idea来解决冲突。
在操作 merge,rebase,cherry-pick ,当有冲突的会弹出conflicts
最好不要直接选择采用远程还是采用自己修改的代码,还是单独点击文件选择每一行的变动
解决完成之后apply之后直接push就可以了。
总结:
对于git而言,只有push和pull操作才会和远程打交道,其他的命令都是本地完成的,也就是说只有pull,push或者在git平台上直接发起远程分支和远程分支合并请求的时候才真正知道有木有冲突。即使本地rebase feature ,但还是没有办法保证dev和feature没有冲突,因为你rebase的时候不能代表你当前本地feature分支和你发起合并请求时候的feature分支的代码完全一致,所以rebase feature 只是提前降低了合并feature时候的冲突。
对于git操作的流程,大家使用习惯有些不一样,实际上怎么操作都没有错,如果公司,团队有所认可的规范,还是按照规范来。
**常见的提交方式 **:
1.直接在feature分支开发,每个人在commit之前pull(git fetch + git merge)一下新的feature的代码,然后有冲突一次性解决之后 add. commit push。
2.直接在feature分支开发,每个人先commit到本地分支,然后pull --rebase (git fetch + git rebase)当前新的feature的代码,然后有冲突解决之后 add. push。
3.就是我上面写的严格操作,每个人都有一个自己命名的本地开发分支,通过和本地的将要合并的本地分支merge或者rebase来解决冲突,然后通过web平台的请求来合并。
4.欢迎大家提供更多牛逼哄哄的方式。。。。。。。
第一种,是最简单的,最常见的操作的方式,这种方式容易在解决冲突的时候把自己修改的代码弄丢,操成无法挽回的结果。(大家可以借助idea本地的历史回滚也是可以)
第二种,先提交,再拉代码rebase,可以保证自己的代码提交到了本地分支,不管之后怎么瞎操作改代码都不会丢失这条已提交的commit。
第三种,操作有点复杂,虽然绕了一点弯路,但是和第二种相比较,主要区分就是feature分支允不允许直接提交。如果允许,那feature合并的权限控制就放在合并到uat的这个环节。
简单的理解:GIT的操作无非就****是拉代码,推代码,合并代码,在每一步和远程分支打交道的操作才会真正出现冲突。但是什么时候提前解决冲突或者以什么方式解决冲突有很多种。
不管你用什么图形化工具,但是我们需要先搞清楚git的基本命令,以及每一步图形化工具操作的背后git操作的命令。
警告:有没push的代码不要删.git目录,你懂得。
没有解决冲突然后强行push的后果,哈哈哈,我笑了
**彩蛋; **
上面提交的知识讲完了,我们拓展一下知识
1.reset怎么用?
用法:
git reset --mixed/--hard/--soft c27894c06a2cc23e4097a93013cf640cc4fd527d
git reset –mixed HEAD~1
回退一个版本,且会将暂存区的内容和本地已提交的内容全部恢复到未暂存的状态,不影响原来本地文件(未提交的也
不受影响) ,也就是恢复到add之前
git reset –soft HEAD~1
回退一个版本,不清空暂存区,将已提交的内容恢复到暂存区,不影响原来本地的文件(未提交的也不受影响),也就是恢复到commit之前
git reset –hard HEAD~1
回退一个版本,清空暂存区,将已提交的内容的版本恢复到本地,本地的文件也将被回退的版本替换,也就是恢复到没开发之前
首先强调已上线的项目reset不建议使用,也禁止使用,为啥这么说呢?
git本身就是存储代码所有历史记录,不管你是错误提交还是提交的代码有BUG,应该是在错误的基础上再commit一条你修正的提交,而不是撤销你已经提交到远程分支的代码。
如果你不小心把一部小电影提交到了GIT,或者你想“删代码跑路“,再或者你的改动操成了成千上万的BUG, reset之后,需要强制push到远程分支,reset点之后的远程分支的提交的记录将永久消失。
2.我想合并uat分支的某次提交之前的代码
git checkout -b uat20190711 c27894c06a2cc23e4097a93013cf640cc4fd527d
可以push到远程再和其他分支合并或者切换其他分支rebase直接push
3.cherry-pick这么用?
git cherry-pick -x -n 017822ece3049d3f46c72cabf32dee9f44dd15cc
将某一次提交的改动直接在当前分支上做修改,然后提交即可,所以提交的commit就需要写清楚你提交的意图。
-x 保留原作者 -n 不自动提交
图形化工具截图,自己摸索,都一个样,找到某一条commit的记录直接操作即可。
博客地址: http://www.wncode.cn