git 常用命令和模拟真实环境开发命令及问题

常用命令

  • git clone 克隆代码
  • git branch 查看分支,-a可查看所有分支,包括远程分支
  • git checkout 新建分支,可以指定从某个分支为基础创建新分支
  • git status 查看自上次提交后文件状态
  • git add 加入索引库
  • git commit 将索引库里面的代码提交到版本库
  • git push 将此版本库推送到远端
  • git fetch 拉取远端最新分支
  • git pull 拉取远端代码,可以指定远端分支
  • git merge 合并代码
  • git log 查看提交日志
  • git reset 恢复版本
  • git rm 删除文件
  • git rebase 补丁
  • git diff 文件对比
  • git tag 标签
  • git config 配置
    更详细的命令用法,需要在实践中自己去积累、记录,每个命令都有很多参数完成不同的功能

模拟开发

以下是我模拟多人协作开发时候的情况,有不正确或者有更好的处理,请修改或补充此文档,供大家学习

模拟了a,b用户各自开发一个模块,然后协作开发一个模块,以及协作中冲突解决,开发分支维护,提交合并等等操作


一. 环境准备

  1. 准备

     gitlab, 注册2个用户 a, b, 虚拟机2台,分别为a、b工作机
  2. 用户a创建项目,登录git创建
  3. 将b用户加入项目
  4. a、b用户各自克隆代码回本地,
git clone git@git.jz.cn:qian/test.git
  1. a用户创建远程分支 dev
git checkout -b dev
git push origin dev:dev
  1. b用户拉取dev分支作为开发分支
git checkout -b dev origin/dev

二. 测试开发情况:

  1. b用户在dev分支上开发新功能 新闻频道, 在dev分支上新建个 news分支
git checkout -b dev-news dev
  1. a用户在dev分支上开发新功能 产品频道,在dev分支上新建个 goods分支
git checkout -b dev-goods dev
  1. 用户b开发
echo 'this is news' > news.php
git add .
git commit -m 'news init' //提交
git checkout dev //切换回dev分支
git diff dev dev-news  //查看文件变化
git fetch  //合并前先检查本地dev分支是否为最新
....此时还未提交,所以是最新的,后面测试有人提交代码的情况
git merge dev dev-news //合并news新开发功能到dev下
git push origin dev //提交到dev分支
....此时假定 news已经开发完毕,删除news分支,保持分支数量
git branch -d dev-news

此时登录gitlab后台
发起一个合并请求,将提交的commit "news init"请求合并到主分支里面

  1. 用户a收到合并请求后
git fetch origin  //获取线上最新分支到本地 #此时代码并未合并,只是下载了分支#
git diff dev origin/dev  //可以先查看文件冲突情况,因为此时a用户还未开始开发,所以直接拉取线上dev覆盖本地即可
git pull origin dev  //此时可以看到news.php

....做代码审查....
第一种:
合并本地dev到master,然后提交代码到master

git checkout master
git merge dev
git push origin master

第二种:
去后台merge request 点击合并,然后更新本地master

git checkout master
git fetch
git pull
  1. b用户在后台看到以后合并到主分支或者检测主分支有冲突时,拉取master到本地
git checkout master
git fetch
git pull

此时完成了a、b用户第一次协作,b用户开发了新闻模块,并合并到了master分支
此时a用户进行goods模块开发,操作同b用户开发news相同
此时是2个用户独立开发不同模块,未涉及到修改相同文件
此时a用户发现goods模块工作量比较大,需要找b用户加入开发

  1. a用户创建个协作分支 dev-goods-group
git checkout -b dev-goods-group dev-goods  //从当前开发的dev-goods分支中,创建一个新分支来进行协作
git push origin dev-goods-group:dev-goods-group //提交本地分支并创建远程分支

此时a用户通知b用户可以进行开发了,a用户进行如下操作

git branch -a  //此时本地和远程显示并未有  dev-goods-group
git fetch      //同步分支到本地
git branch -a  //此时已经有个分支   remotes/origin/dev-goods-group
git checkout -b dev-goods-group origin/dev-goods-group   //在此分支上创建本地分支

然后就可以进行协作开发了
此时a用户写了个 goods.a.php文件

echo 'goods a' > goods.a.php
git add .
git commit -m 'add a'
git push origin dev-goods-group

b用户写了个 goods.b.php文件
此时并未修改同一个文件

echo 'goods b' > goods.b.php
git add .
git commit -m 'add b'
echo 'goods b new' > goods.b.php   //再次更改文件,但是不提交,测试堆栈
git push origin dev-goods-group  //此时会提示代码冲突,别慌,肯定是有人提交了代码,
git stash  //如果你正在修改的代码并未提交,那先将目前的代码进入堆栈
git fetch  //更新分支
git diff dev-goods-group origin/dev-goods-group  //看下是否有文件冲突
git pull origin dev-goods-group  //下载更新本地分支 (git pull --rebase  是否和这个命令一样??)
git stash pop  //将自己的代码从堆栈里面拉出来
git status //此时若堆栈有代码,会有提示
git add .
git commit -m 'add b'
git push origin dev-goods-group  //此时只要a用户未提交新版本,应该是正常状态,若还是提示有冲突,检查是否a用户又有新提交,然后再重复上面操作

此时a用户,b 用户涉及到相同代码开发
a用户

git fetch
git pull origin dev-goods-group
vim goods.b.php   //在里面加一段 edit by user a
git add .
git commit -m 'edit b'
git push origin dev-goods-group

b用户再次修改 goods.b.php

vim goods.b.php  //在里面增加一段  edit by user b
git add .
git commit -m 'edit b'
git push origin  dev-goods-group //此时会提示代码冲突

此时应该先更新本地分支
为了避免后面a用户再次修改,导致会二次合并代码,应该提醒下a用户不要修改这些文件先,减少冲突情况的复杂度

git fetch
git diff dev-goods-group origin/dev-goods-group  //查看下文件冲突情况,这时按道理应该分成2种情况

第一种,冲突文件较少

git pull  //拉取文件回来,如果有未提交的代码应该将代码加入堆栈,前面有介绍操作

手动解决冲突后

git add .
git commit -m 'edit b'
git push

此时b用户虽然已经完成了代码合并,并更新了代码,应该提醒下a用户去更新下,避免后面a用户也发生冲突,减少工作量

第二种情况,冲突文件较多,就应该新建个分支处理单独处理冲突,解决完了再合并会来

git checkout -b fix-goods dev-goods-group   //创建个新分支 fix-goods
git branch   //查看当前分支
git fetch    //更新分支
git pull origin dev-goods-group     // 拉取代码

...根据提示,修改文件,最好在图像化界面完成此操作,完成后进行如下操作,合并会开发分支

git add .
git commit -m 'edit by b'
git checkout dev-goods-group  //切换回开发分支
git merge fix-goods           //合并代码
git push                     //提交代码

此时同样应该通知a用户更新下,避免二次冲突
此时a、b用户合作开发完goods模块了,应该将dev-goods-group合并到 dev-goods分支,此时同样有2种处理方法,见上面合并到master的方法相同
a用户在确认goods模块开发完了后,将 dev-goods合并到dev
在本地公共测试环境测试完成通过后,将dev提交到master分支,线上部署
上线后应该将dev-goods和dev-goods-group分支删除掉,保持分支在一定数量,否则容易导致分支过多,很难维护
上线后bug修复,较少和容易的修改在dev分支上完成,如果涉及到改版或新模块较大改动,应该创建个分支进行开发,完成后再合并到dev,再提交到master

二. git补丁:

  1. git cherry-pick
    用于将一个分支上面的提交添加到另外一个分支上

例如a用户在dev上提交了个commit,此时会有个commit-hash (在输出信息的前几行),记录下来,切换到另外一个分支可以用此命令

git checkout -b test dev-goods-group  //创建个测试分支
git checkout dev-goods-group
echo 222 > test.php
git add .
git commit -m 'test'  //提交个测试文件,此时会提示个 commit-hash,例如[dev-goods-group b801a29] test。b801a29就是
git checkout test        //切换到test分支
echo 333 > test2.php
git add .
git commit -m 'test2'   //保存
git cherry-pick b801a29  //此时会将dev-goods-group上的这次提交更新到此分支,此分支会多一个 test.php文件
  1. git rebase
    用于把一个分支的修改合并到当前分支

例如:
a,b用户在dev-goods-group分支下开发的时候,有人在dev分支下修改了一些核心代码,此时想把dev里的代码合并到dev-goods-group分支
!这种合并情况,应该协同开发者应该先同步所有代码,保持一下,然后指定一个人来合并,其他人更新,这样减少其他人重复合并代码的工作

git checkout dev
git fetch
git pull   //更新dev分支
git checkout dev-goods-group
git rebase dev

此时会有可能有冲突文件,根据提示,处理冲突文件,完成后进行如下操作..

git rebase --contiune  //解决完冲突,继续余下的补丁,可以用git rebase --abort 终止rebase,分支将回到rebase开始之前的状态
  1. diff 和 patch 制作以及打补丁
    可以将某分支上的提交形成一个 补丁文件,其他同源分支执行此文件,可以完成打补丁的动作

区别:
diff 这种是通用类型的补丁,其他软件也可以用
git format-patch 这种是git专用补丁
例如:a用户在开发goods模块的时候,感觉某些代码需要重写,涉及文件较多,另起了个分支,fix-goods,然后在fix-goods上完成开发后,生产补丁文件,dev-goods分支执行此补丁文件进行修复
diff模式

git checkout -b fix-goods dev-goods
echo 555 > fix.php
git add .
git commit -m 'fix'
git diff dev-goods > patch
git checkout dev-goods //此时dev-goods分支里面应该有个 patch的补丁文件
git apply patch   //应用此补丁文件,但是注意,如果此分支比较重要的话,建议新建个分支,进行补丁修复,完成后,再合并回来,防止出现意外,
git status  //可以看到更新的文件

git format-patch 模式
分支操作同上

git format-patch -M dev-goods  //此时会生成一个补丁文件,例如 0001-Fix1.patch
git checkout dev-goods
git am 0001-Fix1.patch
git status  //可以看到更新的文件

文件恢复及日志查看
git log 参数较多,自行去学习
git reset [hard soft mixed merged keep]
hard --重设
soft --文件内容不变,HEAD 更改,更改文件待提交状态
mixed -- 文件内容不变,HEAD更改,但是更改文件不会变成 待提交状态,会有提示:unstanged change after reset [文件名]
....其余2个用的不多,有兴趣自己去看

请大家有任何补充或修改都提交上来,大家一起学习 -by qianjin

问题

  1. 开发中环境问题,是基于公共环境还是各自的环境,公共环境的话,代码部署如何做?如何做测试? 各自环境的话,环境的一致性如何保证
  2. 开发模式问题,目前模块之间文件混杂在一起,还是模块之间独立,公共文件如何维护?
  3. 前后端分离,是否分离?分离的情况下,前端如何调用接口?不分离的情况下,前端分支和后台分支如何开发?
  4. 线上部署代码问题,小修复是否需要提交到maseter后等专人审核后,提交给何老师部署?如果之间有人不在岗如何处理
  5. 在产品还未上线时,是否有必要在分支上开发?

备忘

git fetch -p    //更新本地远程分支内容
git push origin dev:dev  //将本地dev分支上传到远程 创建远程dev分支
git branch --set-upstream dev-wx origin/dev-wx  //将本地和远程分支关联,避免每次push都要指定上传的分支名称

标签: 无

发表评论: