实习期间git的分枝管理以及最常用的命令

各位找工作实习的友友在工作之前一定要把git的相关知识掌握呀,我实现期间被leader说过关于git规范的相关问题了

目前已更新系列:

当前::实习期间git的分枝管理以及最常用的命令

Redis高级-----持久化AOF、RDB原理

Redis高级---面试总结5种数据结构的底层实现

Redis高级----主从、哨兵、分片、脑裂原理-CSDN博客

Redis高级---面试总结内存过期策略及其淘汰策略

计算机网络--面试知识总结一

计算机网络-----面试知识总结二

计算机网络--面试总结三(Http与Https)

计算机网络--面试总结四(HTTP、RPC、WebSocket、SSE)-CSDN博客

知识积累之ThreadLocal---InheritableThreadLocal总结

并发编程之----线程池ThreadPoolExecutor,Excutors的使用及其工作原理

1、分枝迭代规范

1. 基本规范:

    • 基础分支
      • master: 主开发分支,开发新代码从master分支checkout开发分支,开发测试完成合并回master分支,master分支可以保证基本稳定,但可能会有小bug
      • release: 线上分支,基本上跟线上运行的代码版本一致(只有代码进release等待上线的短暂时间不一致),完全稳定的分支
      • integration: 集成测试分支,每个sprint上线前会从master checkout integration分支进行集成测试
      • gray-release: 灰度分支,每次集成测试通过后会从integration checkout gray-release分支进行灰度上线
    • 其中针对会进行灰度的代码服务,四个分支都会有,其他的代码服务最少有2个基础分支:master和release
    • 非灰度期间,灰度环境和线上环境的代码应该是时刻保持一致的。确保即便误操作导致流量进入到灰度环境,也不会引起问题
    • 在以上四个基础分支的操作上,只允许有merge和checkout操作,不允许cherry-pick(只有临时发版有特例,参考临时版本发布流程
    • 哪个分支发现bug就在哪个分支checkout修复分支修复,修复完成合并回该分支

2. feature开发流程(个人/团队分支)

    • 使用 git checkout master && git pull 拉取当前最新的master分支
    • 使用 git checkout -b <你的分支名> 创建新分支
    • 在新分支上进行开发,期间良好的习惯是经常性的通过git checkout master && git pull更新master并git rebase/merge master来更新你的开发分支(merge还是rebase取决于是否有代码push到remote了,详细参照),避免一次性的更新引起很多conflict
    • 开发完毕后,再次更新master并合并到开发分支
    • 使用 git push origin <你的分支名> 将其推送到远端,建立merge request(mr),目标选择master(默认)
    • 找到对应的reviewer进行code review
    • 找到对应的QA进行test
    • review以及test完成后,将代码合并到master

3. Hotfix流程(修复线上bug规范)

    • 使用 git checkout release && git pull 拉取最新的release分支
    • 使用 git checkout -b <你的分支名> 创建新分支
    • 修复完毕后,再次使用git checkout release && git pull 拉取当前最新的release分支,并通过git merge release更新修复分支
    • 确保bug修复后,使用 git push origin <你的分支名> 将其推送到远端,建立MR,目标选择release(默认)
    • 找到对应的reviewer进行code review,review完成后合并到release分支
    • hotfix发版前,由QA进行这次所有fix的统一测试,测试完成后将release发布到生产环境(QA通过jenkins上线任务执行)
    • 将release合并回master/integration/gray-release(此步骤会通过jenkins上线任务自动执行),如果出现冲突,参考4. release分支合并的冲突处理

4. release分支合并的冲突处理

  • 如果release合并回master的时候出现冲突进行如下处理
  • 使用 git checkout release && git pull 更新release
    • 在gitlab将临时分支合并到master
    • 使用 git push origin <临时分支名> 将临时合并分支推送到远端
    • 解决完全部冲突后,使用 git commit 提交
    • 根据git blame记录,找到对应的owner,进行冲突处理
    • 使用 git checkout <临时分支名> && git merge origin/release 从master checkout 临时分支,并在临时分支上执行合并,此时会出现冲突
    • 使用 git checkout master && git pull 更新master
  • release合并回其他基础分支也是同样的操作,只不过把master换成对应的integration或者gray-release

5. integration 以及 gray-release 上的fix

  • 具体流程同Hotfix流程,只是将目标分支从release变成integration / gray-release

6. Sprint发版流程

  • 双周迭代的第二周周三早9点,从master checkout integration分支开始进行集成测试,此时有3个有效分支:master/integration/release(jenkins任务定时自动执行)
    • 周四晚上集成测试通过后,进行灰度发布(服务owner通过jenkins任务执行)
      • 从integration checkout gray-release分支,进行灰度发布,同时删除integration分支,此时有三个有效分支:master/gray-release/release
      • 在jenkins上,将本次需要上线的服务根据依赖关系逐一发布,有灰度支持的发布在灰度环境,没有的发布到线上
    • 在确认发布成功后,将apollo的灰度列表设置为内部测试的几个org,进行内部验证(QA通过jenkins任务操作,周四晚上执行)
    • 在内部验证完毕后,将更多的公司置入apollo灰度列表,开放灰度测试(QA通过jenkins任务操作,周五执行,持续时间周五到下周一)
    • 在灰度测试完成后,发布代码到正式环境
      • 将gray-release分支通过MR merge到release,并通过gitlab页面删除gray-release分支(各服务owner通过gitlab执行)
      • 在jenkins上,进行release分支的发布到正式环境,并进一步发布到灰度环境,确保灰度环境和线上环境代码一致,最后将release分支合并回master(各服务owner通过jenkins任务执行)
      • 在apollo上将灰度公司列表置空(QA通过jenkins任务操作)
    • 删除分支的操作示意图如下:

7. 临时版本发布流程

    • 临时版本的意思是在正常sprint上线之外,想要发布master里面部分代码到线上环境
    • 由于在开发之初无法确定这次任务是否会临时发版,我们如果走正常流程会出现从master merge到release,将很多不希望这次上线的代码连带上线的问题,临时发版目前只能使用cherry-pick进行
    • 具体流程是(开发owner执行)
      • 测试通过后,将开发分支合并回master
      • 通过 git checkout master && git pull 更新master
      • 通过 git checkout release && git cherry-pick -m 1 #commit-id-of-merge-commit && git push 将代码push到release
      • 代码发布后,将release合并回master,如果有冲突参考4. release分支合并的冲突处理(jenkins自动执行)
  1. 带有灰度环境的开发流程示意图
  1. 无灰度的环境的开发流程示意图

rebase or merge?


  • 如果local commit没有push到remote,推荐使用git rebase,因为rebase操作可以减少commit和merge的数量,让commit history干净清爽。
  • 但如果已经push到remote上了,则只能使用git merge,禁止再rebase这个branch。这是因为rebase会修改git的commit history,导致local和remote的history不一致,你的朋友会抛弃你,你的亲人会离开你。详情可以去了解rebase的机制原理
  • 例如:如果你想要更新local branch并且你的local commit 没有push到remote,使用git checkout master && git pull && git checkout your-dev-branch && git rebase master 而不是git merge
  • rebase 操作分两种,第一种是rebase到当前分支之前的某次提交上,第二种是rebase到其他分支上。注意,第二种rebase操作只能做一次(也就是一旦rebase到某个分支上,就不能再rebase到其他分支上了),否则会引起commit记录混乱。

commit message

  • 跟命名一样,message应该尽量precise and concise

  • commit message 格式:第一行简短说明该 commit 的主题,只写一句话。如果还有详细内容,则第二行留空,从第三行开始写详细描述。可以使用Markdown语法。例如:

    Fix the bugs that can not open interview tab

    1. Change main-app route, add query string.
    2. Move 'InterviewTable' from /container to /component.
    3. Minor fix the style problem.
  • 第一个词用动词一般式,并首字母大写

  • 如果用英文不comfortable,也可以用中文

关于解conflict

  • 如果merge有冲突,应该在解决冲突后立即做一次commit,并且使用默认的commit message
  • 解决冲突时,只能修改冲突文件,不要修改非冲突文件。因为如果修改了其他文件,git会将这次提交当做一次新的commit而不是merge commit,相当于做了merge的操作但其实并没有merge,完了git强制你还得再merge一次。
  • 不要在解决冲突的过程中修复bug和功能问题,即使这是由merge导致的。应该将这部分工作放在下一次commit中。

merge request过程

  1. 更新master

git checkout master && git pull

  1. 创建本地分支

git checkout -b <your_new_branch>

  1. 写代码并在本地提交

git commit

  1. 提交远程仓库

4.1. 首先更新master

git checkout master && git pull

4.2. 将你的分支rebase到最新的master

git checkout <your_new_branch> && git rebase -i master

如果有冲突,依次修复好conflict并继续rebase(参见下文如何解conflict),直到rebase过程完成

git rebase --continue

4.3. 提交至远程仓库

git push origin <your_new_branch>

注意 一旦将你的提交push至remote,就不允许再进行rebase操作了。见上文的 rebase or merge?

  1. 去github上提PR,通知其他人review你的代码
  2. 按照review建议修改代码并再次提交至远程仓库

git commit

注意 除非特殊情况,此时即使跟master有冲突也不要管,将解决冲突放在review过程结束后(准备merge时)再做

  1. 如果还有review建议,重复上一步
  2. merge到master分支

8.1. 如果跟master有冲突,按照Gitlab上的提示解决冲突(参见下文如何解conflict),并再次提交

8.2. 合并到master分支。在Gitlab上的PR页面,点击"Merge pull request",然后再点击"Delete branch"删除你的branch

关于如何撤销已经commit过的代码

git基础知识

一般在提交代码的时候,顺序是这样的

复制代码
git status // 查看修改文件状态(已添加至暂存区还是未添加至暂存区)

git add * //将所有修改过的文件报错在暂存区

git commit -m 'xx功能全部完成' // 提交暂存区代码至仓库中
// 在仓库中创建了一个新的提交对象,并且更新了分支以指向这个新的提交对象

git push // 将代码推送至远程仓库

git add 可以看做是 "准备提交",将修改后的文件保存在暂存区中git commit 可以看做是 "执行提交",将其暂存区中保存的文件提交到本地仓库;然后git push是将本地仓库中还未推送的更新到远程仓库中

关于git的知识可以到之前的笔记:

https://www.yuque.com/wrwang/fqdmqu/qy7ygq91xgtg2tug#abfb4251

git中reset,revert,restore的使用

学习背景:今天在完成需求进行MR(gitlab中Merege Request)时

我git commit 时候发现多提交了一个配置文件信息,一般来说自己的配置文件是不能上传合并的,所以有了下面知识的学习

reset:撤销 commit

那么在执行完 commit 之后,想撤回 commit,怎么办?

复制代码
git reset --soft HEAD^

HEAD^ 意思是上一个版本,也可以写成 HEAD~1

如果进行了 2commit ,都想撤回,可以使用 HEAD~2

1. 撤销 commit、不撤销git add .

撤销commit但是对应的文件还是在暂存区中的

soft

复制代码
git reset --soft HEAD^
2. 撤销 commit、并撤销 git add. 操作、不撤销修改代码

--mixed

复制代码
git reset --mixed HEAD^

git reset HEAD^
// 效果和 git reset --mixed HEAD^ 一样,--mixed 是默认参数

以上操作将把HEAD指针移动到父提交,但不会改变工作目录中的文件,修改将被保留。

3. 撤销 commit、撤销 git add . 操作、撤销修改代码

hard

复制代码
git reset --hard HEAD^
  • 这个命令将HEAD指针移动到当前提交的父提交,并且使用--hard选项会使工作目录中的文件恢复到这个父提交的状态;
  • 这意味着所有自上次提交以来的未提交的修改都将被删除;
  • 如果想保留这些修改,可以使用git stash命令来保存它们,然后在需要的时候再应用这些修改。

顺便提一嘴,如果想要修改 commit 注释,可以执行git commit --amend,此时会进入默认vim 编辑器,修改注释完毕后保存就好了。

reset三种撤销方式小结:
  • git reset --soft HEAD^:只撤销本次提交,撤销的文件还在暂存区中的
  • git reset --mix HEAD^:撤销本次提交的同时,也将文件从暂存区中撤销,但是工作目录对于文件的修改还在
  • git reset --hard HEAD^:撤销本次提交、同时将提交的文件也从暂存区中撤销,同时工作目录修改的内容也撤销(相当于直接回到了上一次提交时拉取代码的状态,即本次新增的代码,修改的内容这些都会被撤销

revert:撤销

作用

作用:git revert 命令用于撤销一个已存在的提交,但是它会创建一个新的提交来"抵消"掉之前的那个提交所做的所有更改,而不是从版本历史中删除那个提交。这意味着,你可以保留完整的项目历史,同时撤销之前的更改。

如下图所示,我们通过git revert HEAD命令进行撤销

git revert 撤销 某次操作,此次操作之前和之后的commit和history都会保留,并且把这次撤销作为一次最新的提交比这里的C2*,这里的C2*的内容就和C1是一样的了

复制代码
git revert HEAD                  #撤销前一次 commit
git revert HEAD^               #撤销前前一次 commit

# git revert commit (比如:fa042ce57ebbe5bb9c8db709f719cec2c58ee7ff)
#撤销指定的版本,撤销也会作为一次提交进行保存。,例如:
git revert  fa042ce57ebbe5bb9c8db709f719cec2c58ee7ff #这小指定的这个版本

对于第三个操作怎样找到你想要撤销的提交版本好尼?

使用 git log命令

git log 命令会显示从最近到最远的提交日志。你可以通过添加选项来定制输出。例如:

  • 简单地运行 git log 会列出所有的提交,每个提交都会显示其哈希值、作者、日期和提交信息。
  • 使用 git log --oneline 会以更紧凑的方式显示提交日志,每个提交只显示哈希值的前几个字符和提交信息。
  • 如果你知道你想要查找的提交的某个关键字(例如,提交信息中的一部分),你可以使用 git log --grep="keyword" 来过滤结果。

git revert是提交一个新的版本,将需要revert的版本的内容再反向修改回去,版本会递增,不影响之前提交的内容

结论: 在我们要撤销的提交记录后面居然多了一个新提交!这是因为新提交记录 C2' 引入了更改 ------ 这些更改刚好是用来撤销 C2 这个提交的。也就是说 C2' 的状态与 C1 是相同的。

revert 之后就可以把你的更改推送到远程仓库与别人分享。

参考博客: 原文链接:GIT中reset, restore and revert指令的区别_git restore-CSDN博客

reset和revert异同小结:

小结:
  • git revert是用一次新的commit来回滚之前的commit,git reset是直接删除指定的commit。
  • 在回滚这一操作上看,效果差不多。但是在日后继续merge以前的老版本时有区别。因为git revert是用一次逆向的commit"中和"之前的提交,因此日后合并老的branch时,导致这部分改变不会再次出现,但是git reset是之间把某些commit在某个branch上删除,因而和老的branch再次merge时,这些被回滚的commit应该还会被引入。
  • git reset 是把HEAD向后移动了一下,而git revert是HEAD继续前进,只是新的commit的内容和要revert的内容正好相反,能够抵消要被revert的内容。
以下是AI回答的结果,具有一定参考意义:

git revertgit reset 在回滚操作上的确有着本质的区别,这些区别主要体现在它们对Git项目历史的影响上。下面我将详细解释这些区别:

Git Revert

  • 操作方式git revert 通过创建一个新的提交(commit)来"撤销"之前的一个或多个提交所做的更改。这个新的提交是之前提交的反向操作,它会在项目历史上留下一条清晰的记录,表明某个更改被撤销了。
  • 历史影响 :由于 git revert 是通过添加新的提交来工作的,因此它不会改变现有的项目历史。这意味着其他分支上的更改在将来合并到当前分支时,之前被 git revert 撤销的更改不会被重新引入,因为那个撤销操作已经成为项目历史的一部分。
  • 适用场景git revert 特别适用于需要将更改回滚到某个早期状态,但又不希望丢失这些更改历史的情况。它确保了项目的历史是线性的,易于理解和追踪。

Git Reset

  • 操作方式git reset 通过将HEAD指针移动到项目历史中的另一个位置来工作。根据使用的选项(--soft--mixed--hard),它还可以选择性地更改索引(staging area)和工作目录(working directory)以匹配新的HEAD位置。
  • 历史影响git reset 会改变项目的历史,特别是当使用 --hard 选项时。然而,需要注意的是,这种改变只会影响本地仓库。如果你已经将更改推送到远程仓库,并且其他人已经基于这些更改进行了工作,那么简单地使用 git reset 并不会改变远程仓库的历史,也不会影响其他人的工作。但是,如果你之后尝试将更改推送到远程仓库,Git会阻止你这样做,因为这会导致远程仓库和本地仓库之间的历史不一致。
  • 适用场景git reset 适用于你还没有将更改推送到远程仓库,或者你确定需要完全撤销一系列提交的情况。但是,由于它会改变项目的历史,因此需要谨慎使用,并确保你了解这种改变的影响。

总结

  • git revert 通过添加新的提交来撤销之前的更改,保留了项目的历史完整性。
  • git reset 通过移动HEAD指针来撤销之前的更改,可能会改变项目的历史(特别是当使用 --hard 选项时)。
  • 在选择使用哪个命令时,你需要考虑你的具体需求以及你想要如何影响项目的历史。如果你需要保留历史的完整性,那么 git revert 是一个更好的选择。如果你需要完全撤销一系列的提交,并且你确信这样做不会影响其他人的工作,那么 git reset 可能是一个更快捷的选择。但是,请务必谨慎使用 git reset,特别是当涉及到已经推送到远程仓库的更改时。

restore:将没加入到暂存区修改的文件还原为之前没修改时的样子

作用:将在工作空间下但是不在暂存区的文件(没有使用add命令)撤销更改(内容恢复到没修改之前的状态)等价于使用git checkout file 命令效果一样,将工作区修改的文件内容撤销掉

  • git restore --staged <file>:从暂存区中移除文件,但保留工作目录中的更改。
  • git restore <file>:将文件恢复到其最近一次提交时的状态,并丢弃工作目录中的更改。

什么叫工作目录中的修改?

就相当于git restore --staged <file>命令只是将在暂存区中的文件file移除,然后保留工作目录(平常我们使用git管理时的文件夹下所有文件都属于工作目录)下对该文件的修改内容 如果还需要撤销对文件的修改内容那么还需要依靠宇git restore file

小结:工作流程一览

相关推荐
奔跑的蜗牛ing6 小时前
CentOS Nginx 安装与静态文件服务器配置指南
前端·面试·架构
KaifuZeng9 小时前
通信与接口协议面试五、RS422
嵌入式硬件·面试·通信与接口
SamDeepThinking11 小时前
组合还是继承?我在项目里主要看这两个判断
java·后端·面试
wear工程师11 小时前
setState 到底是不是异步的?这题从 React 16 问到 18,标准答案早就变了
react.js·面试
SamDeepThinking14 小时前
为什么很多人学了Java,还是没真正理解类和对象?
java·后端·面试
阿新聊ai14 小时前
Claude Code 为什么总不懂你的项目?缺一张「项目地图」
前端·后端·面试
用户8524950718415 小时前
Promise 全解析:从三状态到 Promise.all
面试
减瓦15 小时前
Windows 环境使用 Git Bash 最佳实践
windows·git
嘟嘟071715 小时前
Node.js spawn 实现迷你 Cursor 自动化终端|子进程完整解析
前端·后端·面试