Pull Request完整过程【记一次给antvis:G6的PR】

news2024/11/29 1:57:02

文章目录

      • 前言
      • Bug 重现
      • 问题排查
      • 解决方案
        • old version
        • new version
        • 收到回复
      • PR提交完整过程
        • fork仓库 & clone代码仓
        • 添加upstream
        • fetch 新分支
        • 创建新分支
        • 完成修改(注意commit规范)
        • push到个人仓库
        • 创建Pull Request
        • 填写PR信息

前言

G6正在进行v4v5的版本升级,发了几个Issue Hunt,因为很喜欢G6,所以想尝试帮助完成一个矩形Item的迁移。在编写测试demo的过程中,发现了G6的一个严重bug。本文记录了我从发现bug,排查bug到给G6提PR,与仓库管理员沟通,最终PR被成功merge的过程。这是我给G6的第二个PR,给想要参与开源,为自己喜欢的项目贡献绵薄之力的朋友提供一套完整的贡献流程参考。附上两次Pull Request的链接

  • Doc fix :Fix issue#4552, another 404 not found and typo errors #4554
  • Bug fix :Fix: “Node not found” error from ‘getNode()’#4608

Bug 重现

这是我在编写测试demo时,发现G6中存在的一个bug。报错信息显示:Node not found for id: 1

image

根据字面意思,某个方法收到了id为1的节点,但是在我传入的数据中并不存在这个节点。

问题排查

我在Graph.getNode()这个方法的前后调试了很久,更奇怪的是,直接调用Graph.getNode(1)居然是能够返回节点的。由于G6的代码中写的是:

Object.keys(data).forEach((id)=>{
	//...
  const innerModel = graphCore.getNode(id);
	//...
})

我在getNode之前在控制台console.logid, 控制台输出1。这就很奇怪了,我一度怀疑是getNode这个方法出现了问题,但是getNode是一个核心方法,应该不可能出错。

如果直接调用Graph.getNode(1) 能够返回节点,那么说明id就不是1,于是我输出了id==1,果不其然控制台输出false。进一步使用typeof查看id的类型,才发现id不知道怎么已经变成了string。原来使用Object.keys()生成的数组,无论key的类型是什么,统一生成为string数组。这个bug很严重啊,如果用户在数据中定义的idnumber类型,那么将无法获取到这个Node

到这里,问题就定位完毕了。

解决方案

其实要解决这个问题很简单,有以下三种方法:

  • 在用户的id为number类型时,使用Number(id)进行一次转换,而在用户idstring类型时,不做任何处理
  • 修改getNode(),使他能够识别用户传入数据中id的类型
  • 在文档中强制限制用户输入string类型,并且使用类型检查将用户输入的data限制为string

三种方法首先排除第二种,因为getNode()是一个核心方法,是从antv的核心代码仓中import过来的一个方法,找不到修改的入口

我这里选择了第一种方法,并在PR中提示了,如果不做修改的话需要在文档中明确标注id必须为string类型

在解决这个问题的时候,我还考虑到了一种情况,如果用户比较调皮,输入的id中又有string类型,又有number类型应该怎么解决呢?这里我采用了添加try-catch代码块来进行解决。

old version

// 'id' variable is always string in here, but one in user data is number, possibly.    
Object.keys(data).forEach((id)=>{
  const innerModel = graphCore.getNode(id);
	const relatedEdgeInnerModels = graphCore.getRelatedEdges(id);
})

new version

Object.keys(data).forEach((id)=>{
  let innerModel
  try {
    innerModel = graphCore.getNode(id);
  } catch (e) {
    innerModel = graphCore.getNode(Number(id))
  }
  let relatedEdgeInnerModels;
  try {
    relatedEdgeInnerModels = graphCore.getRelatedEdges(id);
  } catch (error) {
    relatedEdgeInnerModels = graphCore.getRelatedEdges(Number(id));
  }
})

并且我在我的PR底下,做了如下说明,来询问这么做是否合理:

An error is throwed from this function ‘getNode()’; msg: “Node not found for id: 1”
After testing, I found that ‘id’ variable is always string after Object.keys(update).forEach((id)=>{...}), but one in user data is number, possibly.
I tried adding a try-catch block to fix this bug, but it doesn’t seem very reasonable to do so. I guess you can restrict the user to set the id to a string type in the document, or force the id to a string type in the transformer data layer to avoid this error.


getNode()方法抛出了一个异常; 报错信息为:“找不到 id为1的节点“
经过测试,我发现id变量在Object.keys(update).forEach((id)=>{...})之后总是字符串类型,但是这个id变量在用户数据中很有可能是数字类型。
我尝试添加一个 try-catch 块来修复这个错误,但这样做似乎不太合理。 我想你们可以在文档中说明:限制 id 为字符串类型,或者在 transformer data 层强制将 id 设置为字符串类型来避免这个错误。

收到回复

很快,我收到了仓库管理员十吾的回复,她回复了一个👍,我好开心,我问她这是可以接受的吗,如果是的话,需不需要重新创建一个PR来进行提交(因为我一开始提交的PR有其他修改,但是另外的修改无法被merge)。

image-20230608213348021

PR提交完整过程

这一部分记录完整的PR提交过程,其中包含了我遇到的问题,一并做陈述并给出解决方案。因为这是我第二次给开源仓库做贡献,所以一些看起来很简单的细节我也记录在这里,帮后面的同学少踩一些坑。

fork仓库 & clone代码仓

直接fork,选仅fork默认分支即可。fork仓库后,在自己的github主页就能看到一个一摸一样的代码仓了。这一步注意,是要clone自己fork后的代码仓,比如我需要clone的地址是:https://github.com/zqqcee/G6.git,这里zqqcee是自己的用户名,不要clone错了。

添加upstream

这一步的目的是将antvis的源仓库添加为上游仓库,不然我们无法同步它们的更新。运行:

git remote add upstream "https://github.com/antvis/G6.git"

运行完毕后,输入git remote -v ,能够看到

origin:xxxx
origin:xxxx
upstream:xxxx
upstream:xxxx

fetch 新分支

由于我是给v5分支提的PR,因此我需要先fetch v5分支。运行:

git fetch upstream/v5

输入git branch -a就可以看到有一个红色的分支upstream/v5,这说明已经fetch成功了

下一步,我们就需要把这个分支的内容在本地创建,并进行修改。

创建新分支

这一步在我执行的时候有一个很大的坑:我在master分支上直接运行:

git checkout -b v5
git rebase xxx

结果出了一堆冲突,后来才知道是我的v5分支是从master分支上创建的,而不是从远程拉过来的

应该输入:

git checkout -b origin/v5 upstream/v5

这一步的意思是从upstream/v5分支创建一个origin/v5分支。

到这里还没结束,因为这个origin/v5分支是我们从upstream中拉取出来的,我的习惯是要在这个分支上再新建一个分支做开发,分支名也有一些含义,于是接着运行

git checkout -b v5-fix#NodeNotFound

完成修改(注意commit规范)

写完代码后注意自己的commit规范,每一个commit都要让别人能看懂,不要全部修改完再做提交。这里我把每一个修改的含义都分得比较清楚,如下:

  • bug 重现 commit
  • bug 修复 commit

push到个人仓库

在这一步我遇到了大麻烦,由于G6发布了issue hunt,因此这里我push到个人仓库时,由于我的personal token没有包含workflow,因此push不成功。报错:“refusing to allow a Personal Access Token to create or update workflow .github/workflows/build.yml without workflow scope”

这一步正确的解决方案是重新创建一个Token并push,但是我为了省事,直接把workflow删掉了。结果PR就没有被合,并且收到了这个comment:

image-20230608215157196

对于这个问题,解决方案我也记录在此处:

  • 首先,创建一个token,勾选workflow,这一步在网上有很多教程,跟着做就好了,这里不做过多赘述

  • 接着,重新设置origin。运行

    git remote remove origin 
    git remote add origin https://{token}@github.com/zqqcee/G6.git
    

    {token}替换为刚刚创建的带workflow的token

  • 最后,重新push就能成功了

创建Pull Request

到fork的仓库中,push成功后,仓库中会显示有一个新的分支。然后点击Pull Request

创建一个新的Pull Request

这一步没什么好说的,重点是要选对你要修改的分支

image-20230608215845380

填写PR信息

PR信息非常关键,必须非常清楚地说明你为什么要创建这个PR ,以及这个PR修复了什么问题。这里直接贴上我的PR 说明,供参考。

iShot_2023-06-08_21.59.51


以上就是全部的解决过程了,很开心能为G6做了贡献,希望有机会能加入AntV团队,也希望自己能为更多仓库创建更优秀的PR~!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/626495.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于多能互补的热电联供型微网优化运行(matlab代码)

目录 1 主要内容 多能互补模型 算例分析 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序基本复现《基于多能互补的热电联供型微网优化运行》,在需求侧对负荷类型进行分类,利用电负荷的弹性和系统供热方式的多样性,构建含电负荷时…

淘宝618每日一猜答案(6月9日)淘宝大赢家今日答案

淘宝6月9日每日一猜答案是什么?,接下来也会给大家来介绍一下6月9日淘宝大赢家每日一猜的答案。 淘宝每日一猜6月9日答案分享 活动问题:环球影城大酒店有几种主题房? 活动答案:【2种】 注意阿拉伯数字! …

[游戏开发][Unity]Assetbundle加载篇(1)热更前准备与下载AB包清单

热更流程都不是固定的,每个人写的状态机也有所差别,但是一些必要步骤肯定不可能少,例如下载清单,对比版本,下载AB包,标记下载完成。 检查沙盒路径是否存在 public static string MakePersistentLoadPath(st…

UnityVR--组件7--动画事件BlendTree

目录 应用1:使用BlendTree实现站立和移动 应用2:人物跳跃事件&播放跳跃动画 应用3:开火动画事件&动画片段中建立事件监听 上一篇(组件5--Animation动画)已经做了2个动画片段,HeroIdle和HeroJump…

【C语言】qsort详细将解

系列文章目录 qsort目录 系列文章目录一、前言二、qosort是什么?二、qsort的使用1、原型2、参数3、头文件(1)qsort参数中的函数指针讲解 三、使用示例和运行截图1、整形例子(升序)3、字符例子(降序&#xf…

Android——使用Service服务实现通信

实验目的: (1)能创建、启动和关闭服务 (2)能实现服务的通信 实验内容及原理: 设计一个服务的具体应用,实现服务的通信 实验设备及实验步骤: 实验设备:WindowsAndro…

VPS 和GPS 、SLAM 之间的爱恨情仇

注:该文章首发3D视觉工坊,链接如下3D视觉工坊 VPS 、GPS 、SLAM 的区别与联系 首先简单的阐述一下三者的定义: VPS全称为Visual Positioning System,即视觉定位系统。手机端(移动时代)的VPS首次出现时间节点为2019年&…

Linux 负载均衡集群 LVS_NAT模式 LVS_DR模式

集群 由多台主机组成,只做一件事,对外表现为一个整体。 只干一件事 :集群 干不同的事:分布式 企业集群分类 负载均衡群集(load balance cluster) 提高系统响应效率,处理更多的访问请…

Qt6 C++基础入门3 对话框与MainWindow

目录 对话框MainWindow菜单工具栏 对话框 目前的对话框主要有以下几大类 文件对话框( QFile Dialog)消息对话框( QMessageBox)输入对话框( QInputDialog)颜色对话框( QColorDialog)字体对话框( QFontDialog) 这是七大对话框及其基本用法的实例参考,所有代码都写在…

《星岛日报》专访:欧科云链AML,助力数字资产合规及风险防控

6月1日,香港《适用于虚拟资产交易平台营运者的指引》及《打击洗钱指引》正式施行,香港虚拟资产发牌制度正式生效。作为深耕香港市场多年的Web3科技企业,欧科云链OKLink也正式推出的Onchain AML反洗钱合规解决方案,利用多年积累的海…

Windows下安装python和pip

Windows下安装python和pip 1、安装python 注意:windows10 安装时强烈建议不用使用 Windows Store 安装。避免后期python运行时牵扯权限相关问题。 具体步骤: 1、前往python官网下载windows python 安装包 下载文件 2、双击运行安装(强力…

实时日志滚动显示 springboot+vue3

-:后端使用ssemiter保持客户端链接:http 这里不用websocket的原因是,sse很轻,整合方便,可发送日志,消息,群发等都可以。 -:前端使用vue3+ansi_up做页面展示 第一: 刷新页面导致session问题 可以在java的session中记录,如果是同一个客户重新链接的话,直接返回java…

【轴承故障诊断】用于轴承故障诊断的集中时频分析研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

SQL SERVER case when的使用方法

一、case when的使用方法 Case具有两种格式。简单Case函数和Case搜索函数。 第一种 格式 : 简单Case函数 : 格式说明     case 列名     when 条件值1 then 选项1     when 条件值2 then 选项2…     else 默认值 end eg:     select     case   job…

2021年国赛高教杯数学建模B题乙醇偶合制备C4烯烃解题全过程文档及程序

2021年国赛高教杯数学建模 B题 乙醇偶合制备C4烯烃 原题再现 C4 烯烃广泛应用于化工产品及医药的生产,乙醇是生产制备 C4 烯烃的原料。在制备过程中,催化剂组合(即:Co 负载量、Co/SiO2 和 HAP 装料比、乙醇浓度的组合&#xff0…

JUC源码分析:通过ReentrantLock阅读AbstractQueuedSynchronizer源码

一、概述 ReentrantLock进行上锁的流程如下图所示,我们将按照下面的流程分析ReentrantLock上锁的流程,在此过程中阅读AbstractQueuedSynchronizer源码。 AQS 的数据结构如下图所示。 AQS大家还记得吗?最核心的是它的一个共享的int类型值叫做…

电脑自动关机是什么原因?如何解决?

案例:有时候我的电脑用着就突然关机,会导致一些没有保存的文件丢失。有没有小伙伴知道电脑为什么会自动关机?怎样做才能避免这个问题? 在使用电脑过程中,遇到电脑自动关机的问题是很常见的。当我们在进行重要任务时&a…

Netty核心源码剖析(四)

1.Netty心跳(heartbeat)服务源码剖析 1>.Netty作为一个网络框架,提供了诸多功能,比如编码解码等,Netty还提供了非常重要的一个服务–心跳机制heartbeat.通过心跳检查对方是否有效,这是RPC框架中是必不可少的功能.下面我们分析一下Netty内部心跳服务源码实现; 2>.Netty提…

电磁仿真需要牢记的内功心法

在射频、微波设计中,各种“强大”的商用电磁仿真软件的功能包罗万象,这篇“内功心法”从算法角度出发,提示大家如何谨慎选择仿真软件。 心法一:场”与“路”的区分 世上本无“路”,“场”近似得多了就变成了“路”&a…

千人规模亚马逊云科技出海日将于6月9日开启,助推企业出海出圈

向全球价值链上游奋进 中国企业增强国际竞争力的关键,是努力朝全球价值链上游奋进,发力技术出海。中国的出海新机遇,背后曾是疫情在全球按下数字互联和数字化升级的快进键,跨境电商、在线社交、移动支付、数字服务等数字经济迎来…