luffy之git系统开发和冲突解决和pycharm操作git
一、协同开发
# 在公司中,都是多人共同开发同一个项目 -1 组长本地创建出空项目,底层代码写完---》提交到远程仓库 -2 张三,李四,王五都要共同开发这个项目 -3 我们要把代码clone到本地 -pycharm中: -找一个位置:git bash here(cmd) git clone 远程地址 使用pychrm打开 本地能够运行起项目来 项目有可能运行不起来(依赖没装好),数据库链接不对(本地) -4 写代码,提交到本地版本库,推到远端即可(推之前先pull一下) # 多人协同开发一个项目 -作为项目创建者:本地搞好,远程搞好,推上去,把别人加为开发者 -作为协同开发者:远程账号,密码---》登录进去就能看到这个项目了
二、冲突解决
2.1 多人同一分支开发出现冲突
# 出现冲突的原因 别人跟我们带的代码是一样的,但是他先提交到了远程仓库上了 我们在提交,就会提交不上了,所以我们要先拉取下来先, 因为我们改的是同样的代码,就会冲突
# 冲突的典型样子: <<<<<<< HEAD print('lqz') ======= # 上面是你的代码 print('lqz is handsome') >>>>>>> f67f73948d175b186cd5f1319d7602fe004e285c # 上面到 ===== 是别人代码 后面是别人提交的版本号 # 解决冲突 我们只需要把这些代码给改到不报错即可 然后决定是留别人的代码还是留自己的代码 然后重新提交到本地仓库,再推到远程仓库即可 如果删除的是别人的 要跟别人说一声
2.2 分支合并出现冲突
# 1 新建要给dev分支,切换过去 git branch dev git checkout dev # 2 dev分支修改dev.py 第一行,提交到版本库 # 在第一行加入print git add . git commit -m '修改了dev.py' # 3 修改dev分支的home/views.py 最后一行 # 在views.py最后一行加入注释 git add . git commit -m '最后一行加入注释' # 现在这个时候都还是提交到了dev分支的版本库 # 4 切回到master分支,修改dev.py 第一行和home/views.py 最后一行,提交到版本库 git checkout master # 在第一行加入print # 在views.py最后一行加入注释 git add . git commit -m 'master修改内容' # 5 当合并代码,会出冲突,解决,提交 # 然后在master分支中将dev分支合并过来的时候 就会有冲突 git merge dev # 有冲突,解决 git add . git commit -m '解决冲突' # 6 解决冲突 也是一样的 决定是留别人的还是留自己的 然后把代码修改到不报错 就可以合并了 然后就可以提交到远程仓库了
三、线上分支合并(pr,mr)
# 之前的操作都是在本地操作 本地的增删改查分支操作 # 现在我们可以在gitee上创建 分支 点击操作即可 # 如果本地也有 远程仓库分支名字一样的 本地分支 那么可以先把本地的分支给删除了 # 创建完成之后就可以把远程仓库的分支 给拉到本地了 git pull origin dev # 其实已经拉下来了,但是还看不到,需要切换过去 git checkout dev # 来到了本地dev分支 # 3 本地dev分支增加代码 # 然后我们可以在本地这个拉下来的远程分支修改代码了 # 修改完之后 就提交到本地仓库先 git add . git commit -m '本地dev提交' # 4 本地dev提交到远端 git push origin dev # 提交到远程仓库的分支 dev # 5 远程分支合并:把dev合并到master -你提交pull request 的申请(pr,mr)---》跟你没关系了--->[合进去了,没有合进去] 然后就可以等待领导审批了 -你领导就能看到这个pr,审核通过,点合并 -到此 dev分支就合并进master分支了
四、pycharm操作git
# 命令操作git,编辑器pycharm,可以操作git,图形化界面操作 # 以前使用的所有命令,都可以在pycharm中点点点实现 这样会方便很多
4.1 clone
4.2 git add
# 如果是项目根路径 就相当于: git add . # 如果是根路径下的其他文件 就相当于: git add 文件名称
4.3 git commit
4.4 git push
4.5 git pull
4.6 git branch操作
4.7 查看git操作记录 git log
4.8 本地代码跟版本库对比
五、为开源项目贡献代码
# 为开源项目贡献代码 1 看到开源项目,点fork,你的仓库就有这个开源项目了 2 在本地拉去【你仓库】fork的代码 3 你继续写,提交到自己远程仓库 4 提交pr合并,如果作者同意,你就可以合并进去了
六、git面试题
# 1 你们公司分组方案是什么样的? -master,dev,bug 三条分支 -master主要用来发布版本,写好了某个版本的代码合并进去,不直接在master上开发 -dev开发分支,项目的开发者,都在dev分支上开发 -bug:用来修改bug,发布小版本 # 2 使用git开发,遇到过冲突吗? -遇到过 -多人在dev分支开发,出现的冲突 -分支合并出现的冲突 -把代码拉下来,直接解决冲突,要么保留我的代码,要么保留同事的代码 # 3 你知道git变基? -分支合并:dev分支合并到master分支 -merge或rebase合并 - 把多次提交合并成一个 # 4 git pull 和 git fetch的区别 - pull和fetch都是拉取代码 - pull = fetch+合并 - pull就是拉取代码的时候自动合并了 - fetch就只是拉取代码 # 5 你知道git flwo吗? git 工作流,它是一个别人提出的分支方案 我们没有用,我们用的是就是master+dev+bug分支方案 # 6 使用git 的操作流程 - 如果是普通开发者:git clone下来, 写代码, 提交到暂存区:git add . 提交代码到本地仓库:git commit -m '' 提交到远程仓库:fit push # 7 什么是gitee,github:pr,gitlab:mr? -不同的叫法:提交分支合并的请求
七、前台首页组件编写
# 假设上面的图就是原型图 那么我们可以知道 我们需要编写 HomeView.vue 页面组件 Header.vue 头部组件 Banner.vue 轮播图组件 Footer.vue 尾部组件
7.1 HomeView.vue
<template> <div className="home"> <Header></Header> <Banner></Banner> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> <Footer></Footer> </div> </template> <script> import Header from '@/components/Header' import Banner from '@/components/Banner' import Footer from '@/components/Footer' export default { name: 'HomeView', data() { return {} }, components: { Header, Banner, Footer } } </script>
7.2 Header
<template> <div class="header"> <div class="slogan"> <p>老男孩IT教育 | 帮助有志向的年轻人通过努力学习获得体面的工作和生活</p> </div> <div class="nav"> <ul class="left-part"> <li class="logo"> <router-link to="/"> <img src="../assets/img/head-logo.svg" alt=""> </router-link> </li> <li class="ele"> <span @click="goPage('/free-course')" :class="{active: url_path === '/free-course'}">免费课</span> </li> <li class="ele"> <span @click="goPage('/actual-course')" :class="{active: url_path === '/actual-course'}">实战课</span> </li> <li class="ele"> <span @click="goPage('/light-course')" :class="{active: url_path === '/light-course'}">轻课</span> </li> </ul> <div class="right-part"> <div> <span>登录</span> <span class="line">|</span> <span>注册</span> </div> </div> </div> </div> </template> <script> export default { name: "Header", data() { return { url_path: sessionStorage.url_path || '/', } }, methods: { goPage(url_path) { // 已经是当前路由就没有必要重新跳转 if (this.url_path !== url_path) { // 传入的参数,如果不等于当前路径,就跳转 this.$router.push(url_path) } sessionStorage.url_path = url_path; }, }, created() { sessionStorage.url_path = this.$route.path this.url_path = this.$route.path } } </script> <style scoped> .header { background-color: white; box-shadow: 0 0 5px 0 #aaa; } .header:after { content: ""; display: block; clear: both; } .slogan { background-color: #eee; height: 40px; } .slogan p { width: 1200px; margin: 0 auto; color: #aaa; font-size: 13px; line-height: 40px; } .nav { background-color: white; user-select: none; width: 1200px; margin: 0 auto; } .nav ul { padding: 15px 0; float: left; } .nav ul:after { clear: both; content: ''; display: block; } .nav ul li { float: left; } .logo { margin-right: 20px; } .ele { margin: 0 20px; } .ele span { display: block; font: 15px/36px '微软雅黑'; border-bottom: 2px solid transparent; cursor: pointer; } .ele span:hover { border-bottom-color: orange; } .ele span.active { color: orange; border-bottom-color: orange; } .right-part { float: right; } .right-part .line { margin: 0 10px; } .right-part span { line-height: 68px; cursor: pointer; } </style>
7.3 Banner.vue
<template> <div class="banner"> <el-carousel :interval="5000" arrow="always" height="400px"> <el-carousel-item v-for="item in bannerList" :key="item.title"> <div v-if="item.image.indexOf('http')===-1"> <router-link :to="item.link"><img :src="item.image" alt=""></router-link> </div> <div v-else> <a :href="item.link"><img :src="item.image" alt=""></a> </div> </el-carousel-item> </el-carousel> </div> </template> <script> export default { name: "Banner", data() { return { bannerList: [] } }, created() { this.$axios.get(this.$settings.BASE_URL + 'home/banner/').then(res => { this.bannerList = res.data.result }) } } </script> <style scoped> .el-carousel__item { height: 400px; min-width: 1200px; } .el-carousel__item img { height: 400px; margin-left: calc(50% - 1920px / 2); } .el-carousel__item h3 { color: #475669; font-size: 18px; opacity: 0.75; line-height: 300px; margin: 0; } .el-carousel__item:nth-child(2n) { background-color: #99a9bf; } .el-carousel__item:nth-child(2n+1) { background-color: #d3dce6; } </style>
7.4 Footer.vue
<template> <div class="footer"> <ul> <li>关于我们</li> <li>联系我们</li> <li>商务合作</li> <li>帮助中心</li> <li>意见反馈</li> <li>新手指南</li> </ul> <p>Copyright © luffycity.com版权所有 | 京ICP备17072161号-1</p> </div> </template> <script> export default { name: "Footer" } </script> <style scoped> .footer { width: 100%; height: 128px; background: #25292e; color: #fff; } .footer ul { margin: 0 auto 16px; padding-top: 38px; width: 810px; } .footer ul li { float: left; width: 112px; margin: 0 10px; text-align: center; font-size: 14px; } .footer ul::after { content: ""; display: block; clear: both; } .footer p { text-align: center; font-size: 12px; } </style>
八、补充
1 cgi fastcig WSGI uwsgi uWSGI # cgi:通用网关接口(Common Gateway Interface/CGI)是一种重要的互联网技术,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI描述了服务器和请求处理程序之间传输数据的一种标准。 一句话总结: 一个标准,定义了客户端服务器之间如何传数据 # fastcig:快速通用网关接口(Fast Common Gateway Interface/FastCGI)是一种让交互程序与Web服务器通信的协议。FastCGI是早期通用网关接口(CGI)的增强版本 一句话总结: CGI的升级版 常用的fastcgi软件: Apache HTTP Server (部分) :LAMP LNMP Nginx(主流):nginx是一个符合fastcgi协议的软件,处于浏览器和web程序之间,主要做请求转发和负载均衡,也可以称之为服务器中间件 Microsoft IIS:windows server # WSGI:Web服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是为Python语言定义的Web服务器和Web应用程序或框架之间的一种简单而通用的接口。自从WSGI被开发出来以后,许多其它语言中也出现了类似接口 一句话总结: 为Python定义的web服务器和web框架之间的接口标准 wsgiref:性能很低,python实现的,django内置了,测试阶段用,上线不用 uWSIG:性能高,c实现的 gunicorn:python实现的 # uWSGI: 符合wsgi协议的web服务器,上面标准的具体实现 # uwsgi:uWSGI服务器,自有协议 3 Apache -Apache 公司 -Apache web服务器 -Apache 开源协议 -Kafka :apache顶级开源项目 -echars:原来是百度开发的,交给了apache孵化