- 小程序模板消息能力调整通知
小程序模板消息能力在帮助小程序实现服务闭环的同时,也存在一些问题,如: 1. 部分开发者在用户无预期或未进行服务的情况下发送与用户无关的消息,对用户产生了骚扰; 2. 模板消息需在用户访问小程序后的 7 天内下发,不能满足部分业务的时间要求。 为提升小程序模板消息能力的使用体验,我们对模板消息的下发条件进行了调整,由用户自主订阅所需消息。 一次性订阅消息 一次性订阅消息用于解决用户使用小程序后,后续服务环节的通知问题。用户自主订阅后,开发者可不限时间地下发一条对应的服务消息;每条消息可单独订阅或退订。 [图片] (一次性订阅示例) 长期性订阅消息 一次性订阅消息可满足小程序的大部分服务场景需求,但线下公共服务领域存在一次性订阅无法满足的场景,如航班延误,需根据航班实时动态来多次发送消息提醒。为便于服务,我们提供了长期性订阅消息,用户订阅一次后,开发者可长期下发多条消息。 目前长期性订阅消息仅向政务民生、医疗、交通、金融、教育等线下公共服务开放,后期将逐步支持到其他线下公共服务业务。 调整计划 小程序订阅消息接口上线后,原先的模板消息接口将停止使用,详情如下: 1. 开发者可登录小程序管理后台开启订阅消息功能,接口开发可参考文档:《小程序订阅消息》 2. 开发者使用订阅消息能力时,需遵循运营规范,不可用奖励或其它形式强制用户订阅,不可下发与用户预期不符或违反国家法律法规的内容。具体可参考文档:《小程序订阅消息接口运营规范》 3. 原有的小程序模板消息接口将于 2020 年 1 月 10 日下线,届时将无法使用此接口发送模板消息,请各位开发者注意及时调整接口。 微信团队 2019.10.12
2019-10-13 - 你根本不懂rebase-使用rebase打造可读的git graph
git graph 可读指什么? 这里的可读,主要指的是能够通过看git graph了解每一次版本更迭,每一次hotfix的修改记录.反映到分支上面,有两个要求: 每个分支的历史修改可读(单个分支的层面) 每个分支的分叉合并可读(多个分支的层面) rebase是什么,它是更优雅的merge吗? rebase翻译做[代码]变(re)基(base)[代码]. 讲rebase的文章经常会引用三张图: [图片] 原本的两个分支 [图片] 通过merge的结果 [图片] 通过rebase的结果 用来说明git rebase和git merge的区别的时候确实是足够了,但是 git rabase的用途并非是合并分支,它与merge根本不是同样的性质.(注意,这里的说法是[代码]并非是[代码],不是[代码]并非只是[代码],因为虽然有时rebase替代了merge的工作,但其原理和性质完全不一样.) rebase还有以下几种用处: [代码]git pull —-rebase[代码]处理同一分支上的冲突(如果你能理解其实这是[代码]git fetch&&git rebase[代码]两个操作,并且理解远程分支和本地分支的区分的话,那么其实他跟单纯的rebase用法没什么区别,但是因为其场景不一样,所以单独拆分出来讲) [代码]git rebase -i[代码]修改commit记录 实质上: merge是对目前分叉的两条分支的合并 rebase是对[代码]当前分支[代码]记录基于任何[代码]commit节点[代码](不限于当前分支上的节点)的变更. rebase的[代码]base[代码]不能理解为分叉的基点,而是整个git库中存在的所有commit节点: 在[代码]git pull —-rebase[代码]的时候,这个[代码]当前分支[代码]是本地分支,[代码]commit节点[代码]是远程分支的head 在[代码]git rebase master[代码]的时候,这个[代码]当前分支[代码]是feature分支,[代码]commit[代码]节点是master分支的head 在[代码]git rebase -i[代码]的时候,这个[代码]当前分支[代码]就是当前工作分支,[代码]commit节点[代码]是在 -i后注明的commit rebase是怎么工作的? 上面我们已经说到了: [代码]rebase[代码]是对[代码]当前分支[代码]记录基于任何[代码]commit节点[代码](不限于当前分支上的节点)的变更. 怎么做到呢?我没有深入研究它真的是如何实现的,以下步骤一定是不对的,但足够让你理解rebase干了什么. 我们标注出了两个重点,[代码]当前分支[代码]和[代码]commit节点[代码]. 把[代码]当前分支[代码]branch-A从头到尾列出来,从数据结构的角度来说这是一个链表 把[代码]commit节点[代码]所在的分支branch-B从头到尾列出来,同样是一个链表 找到这两个链表最近相同的节点n 把A在n之后的所有节点拆下来构成L 把B在n之后的所有节点中存在的diff信息都汇总起来构成d 对于L中的每一个节点,把他的diff信息拿出来,看看d中有没有冲突,如果有没法自动处理的冲突抛出错误,等待用户自己处理 可选地,对于[代码]rebase -i[代码]来说,还可以一次取多个节点或者按照不同顺序取,你有更大的处理自由 没冲突和处理完冲突的节点,改一个hash放到branch-B的[代码]commit节点[代码]之后 你可以把之前我们说到的三种rebase用处套在以上步骤看看,是否能够理解. rebase很危险对吗? 对,很危险. 不过就像小马过河一样,光听别人说是没用的,我们需要明白为什么有人说危险,有人说不危险.我看到很多文章说rebase有问题,但他们的说法其实并不让人信服,很多时候只是他们不会用. 很多人听说过一个golden rule,在文末有链接,但是很少有人会明白真正的原因.让我们一层层地剖析: 其他人git push的时候会对比较本地分支和远程分支的区别,把不同的地方推上去 如果远程分支被修改了,那么其他人的本地分支和远程分支就会出现分叉(另外还可能造成其他人之前已经推送的工作被覆盖) 当出现分叉的时候,意味着其他人需要处理冲突,也就是说,你对于远程历史记录的修改使得[代码]冲突扩散到了其他人身上[代码] 所以我们尽量不能修改远程分支,不能[代码]把别人fetch回去的改掉[代码],因为他们的工作就是基于fetch回去的分支开展的(往前推进是必须的,其实也修改了远程分支,所以才会merge产生冲突,但是这个冲突是无法避免的) 针对上面说的这一条,git也做了限制,如果你触犯了上面的原则,会在push的时候被阻挡,但是通过加一个[代码]-f[代码]可以强推 实际上不止rebase这样,任何修改远程分支历史的操作都会造成冲突,并且这个冲突需要所有人都解决一遍. 但是分析还是太长了,记不住怎么办? 只需要记住[代码]-f[代码],只要你不使用[代码]-f[代码],那么就是安全的. 不过仅是安全,并不能保证优雅,如果要使git graph可读,那你还得多想想: 怎么让自己的commit历史清晰(每个commit反应了一个单位的工作,前后顺序合理) 怎么让每次hotfix和feature所做的工作和顺序清晰 rebase如何让git graph可读? 我们还是说回之前提到的三个用法: git rebase master 在把分支合并回master的时候,用[代码]git rebase master[代码]代替[代码]git merge master[代码].(注意,只在合并之前使用,否则多人协作会遇到冲突) 这样的好处有两个: log里不会出现一个[代码]Merge branch 'master' into hotfix/xxx[代码]的节点 master分支上在这次merge之前已经被提交的[代码]上一次工作[代码]和这一次工作的顺序更清晰,因为rebase会让这次feature的分叉节点改到上一次工作后.对于master分支来说,我们并不关心checkout新的feature的顺序,我们[代码]更关心merge新的feature的顺序[代码]. [图片] 比如这里,使用merge master导致的紫色的分叉在提交之前与master多了一次连接,而且主线上在紫色分叉合并之前还经历了一次合并,这个时间顺序并不清晰. 那么在master分支上合并也用rebase吗?不是.因为我们需要master上的分叉让我们更明白master上的改变(所以使用-no-ff).实际上,不管你采用任何git flow模型,我都建议你对不太重要的分支合并采用rebase,对重要的分支合并采用merge.这样会让主干的更改更清晰,而分支不会扩散地太远. git pull —-rebase 多人在同一分支上工作的时候(包含master分支和多人合作的feature等分支),在git pull的时候会遇到冲突,git pull的默认行为是[代码]git fetch&git merge[代码],merge的对象是远程分支和本地分支. 它的好处基本上与上一条无异,还多了一条: 使用merge行为的pull会将其他人的工作作为外来的分叉,从而在graph上产生一个新的分叉, 并且其他人这一段时间所做的所有的工作都会在graph上被抬升出去,如果这段时间其他人做的工作很多,graph的主线会变得丧失了主线的意义(因为它太单薄了,很多工作根本没反应上来). [图片] 比如这里,本来左数第二条玫红色的才是主线,因为不规范地在master上直接提交了一次commit并且采用merge方式的pull做了合并导致主线被抬升到了外层.而这次不规范的commit却成了主线. git rebase -i 使用这条命令可以修改分支的记录,比如觉得之前的commit修改内容不够单元化,像是[代码]修改了文案1为文案2[代码],[代码]修改了文案2为文案3[代码],这种记录对于master分支来说是没必要关注的信息,最好通过[代码]git commit --amend[代码]或者rebase的方式修改掉. 不过并不推荐在提交之前手动做一次整个分支的squash,如果是rebase方式合并的话,也许更有意义.工蜂(腾讯内部的code平台)提供了merge request的标题和内容功能,所以没必要做squash,完全可以不必太聚合,以便反应真实的信息. 为了不影响别人,只用它修改未push的commit,或者如果一条分支只有一个人,你也可以修改已经push的commit. 对于这条命令的更多功能,可以再去查阅其他文章. 可读的graph应该长什么样? 先说一个原则,看graph要先看主线,主线要清晰,再看分叉上信息,这与我们的工作流程是一致的. [图片] 绿色的hotfix或者feature分支每次不是只允许提交一次commit,只是这一段都是一些小更改. 这看起来有点可笑,一点都不高级.说了这么多做了这么多难道只是为了得到这么简单的图? 没错,[代码]为了让东西变简单,本来就要付出很多代价[代码],我们所做的就是要让东西变简单,比如努力工作是为了让赚钱变简单,努力提升是为了让工作变简单.让事情变复杂只会让事情不可控. 当然具体如何还是要取决于你采用的git flow,但是原则很简单: [代码]每个分叉的子分叉尽量是一个串联一个,内部尽量不要再有自己的提交.[代码] 为什么我认为这样的git graph可读性好,因为它把我们的工作也拍平了,不在乎每个工作的开始时间和持续时间,只关心这个工作的完成时间. 假如一个项目需求1是1月1号启动,2月1号上线,需求2是1月20号启动,2月10号上线.1月10号修了一个bug,2月3号修了一个bug. 听起来是不是很绕? 如果你的git graph显示的也是这样的信息,可读性一定不好,所以我们要做的git graph应该反应的是如下信息: 1月10号修补bug 2月1号上线需求1 2月3号修补bug 2月10号上线需求2 rebase的缺点是什么? (这里并不讨论rebase可能带来的冲突问题,有很多文章都会讲,上面也已经提到了rebase的危险性,这里只讨论rebase对于git graph的缺点.实际上,冲突只是rebase不恰当使用导致的问题,而非rebase本身的问题.) 当然也有人会说,工作的开始时间也很重要呀,因为它反映了当时工作开展的基础条件.对,这是rebase master的弊端.他让记录清晰,也让记录丢失了一些信息.记录的加工让可读性变得更好,也让信息量变少了. git rebase 让git graph发生了变化,[代码]每次分叉的检出和并入之间不会再有任何节点[代码].(因为合并到master采取的是merge行为.否则根本没有分叉) [图片] 也就是这种情况不会再出现.因为每次总是[代码]rebase master[代码],把自己的起点抬了上去.[代码]git rebase实际上让检出信息没有意义,换取了主分支分叉的清晰.[代码] 另外值得注意的是,不要在同一个分支上混用[代码]rebase[代码]和[代码]merge[代码](包括pull 的默认merge行为),因为rebase之后的[代码]commit hash[代码]被改变了,再merge的时候两个分支的共同起点被提前了,merge之后的git graph上会出现一左一右两串同样commit信息的一段历史. 如果rebase没有缺点,那么也就没有争议.是否使用rebase也要看真实的需求是什么. 这篇文章要干什么? 通过rebase让git graph更可读.目的和原则我们都已经说过了,没必要再重新说一遍. 多有谬误之处,还望不吝赐教!
2019-04-29