Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【git重案组】如何逃避git blame的追踪?

【git重案组】如何逃避git blame的追踪?

作者头像
腾讯技术工程官方号
发布于 2019-09-10 04:10:10
发布于 2019-09-10 04:10:10
1.3K0
举报

导语:程序员的血腥复仇——论如何偷偷修改代码而不被别人发现...

背景介绍

上周笔者在工作中发现git仓库出现了一个奇怪的问题,master分支中某文件的一次commit丢失掉了,但diff中没有任何记录,这让笔者一度怀疑是git或者code平台自己出了问题。

在code平台一条条比对后发现变动发生在feature分支merge master分支之后。

原本SHA为8950d的edit.vue 文件最近一次修改是在一周前。

在merge之后该文件回滚到了两周前。

通过查询该文件的commit记录,可以看到最近的一次SHA为49c1a的commit确实丢掉了。

先明确前提,这是在一次merge中丢失的,而非经历了rebase或者reset操作,并没有对历史记录进行修改。

这里回顾下整个过程中的git 操作流,先从master checkout一个feature分支,在该分支提交了几次commit,merge master 到 feature,然后在master再次merge feature。

应该说这里虽然有不规范之处(没有提交merge request而是本地直接在master上merge然后push),但整体还算常规操作,即使是在merge中发生了冲突,不小心操作失误,按道理也不会没有diff记录。

merge的parent-1和parent-2

google一下找到了一篇相似的文章https://blog.laisky.com/p/git-merge/

该文章是在master分支上git pull,由于pull 的默认行为是 pull —merge,所以其实也是在merge中丢失的。

原文作者给出了一个比较清晰的解释:

众所周知,merge 是将两个 branch 合并为一个,所以每一个 merge commit 拥有两个 parents。当我们在 gitlab 或者 source tree 查看一个提交的具体修改时,其实就是将本次提交和其 parent 做 diff。而由于 merge commit 有两个 parent,并会将其排序为 1 和 2,当你试图查看一个 merge commit 的修改时,其实显示的是相对于 parent-1 的 diff。这样的一个问题是,如果 remote 不幸成为了 parent-2,那么你就可以通过巧妙的构造 parent-1 来实现一次“隐身”的代码修改。

我们提取原文核心,重点在于merge时的diff记录是相对于当前分支,假如当前分支是两周前的版本,而外来分支是一周前的版本,当merge时放弃掉一周前的版本,对原分支来说这次merge之后与之前并未发生改变,所以diff中自然也没有记录。

merge request 的不同之处

这个解释似乎也说的过去,不过在合并到master分支之前必然要本地merge一下master才可以快速合并,这个操作是逃避不了的,如果在本地merge时错误解决冲突会被隐藏下来,这岂不是git一个很大的缺陷吗?那code平台的merge request后的code review还有意义吗?

笔者自己搭建了一个测试仓库发现如果提交merge request,在code review的diff界面是看得到这次修改的,在提交之后也能在history中看到diff。难道gitlab(code平台应该是基于gitlab开发的)平台自己的diff算法更高级,所以才能发现这次错误?

笔者到这里产生了一个猜测,在本地操作的时候git 的diff算法有缺陷,它简单地把每一次commit的diff patch在一起,而code平台是老老实实做了两个文件夹的diff。

git diff的差异

在google之后,果然发现了不同(其实并不然…)!

在几个stackoverflow的问答和github的issue中笔者发现 github平台的pull request(虽然gitlab是merge request,实际上差不多)是使用了git diff的三点操作,而直接diff是两点操作,区别如下:

笔者一度以为突破口就在这里,但是仔细分析了git log —graph之后发现在merge request之前本地feature分支就已经merge了一次master,在这个情形下git diff的两点操作和三点操作根本没什么不同。

链接: What are the differences between double-dot “..” and triple-dot “…” in Git diff commit ranges? - Stack Overflow

https://github.community/t5/How-to-use-Git-and-GitHub/GitHub-pull-requests-showing-invalid-diff-for-already-merged/td-p/3000

merge的原理和fast-forward

Git merge采取三路合并策略,三路分别是基准分支(分叉的节点)、mine、theirs。

如果mine和theirs相对基准都发生了改变 那git 就报冲突,然后让你人工决断。否则,git将取相对于base变化的那个为最终结果。

一次普通的merge会新建一个commit节点(7号节点)。

而如果在feature分支从master checkout之后,master并未出现新的commit,就会出现三种策略。

默认git merge会采取第三种策略,直接将master指针移到feature的头上即可,这里不会出现一个message为“merge xxx into xxx”的commit。

回到问题发生的场景上,在feature分支上执行git merge master的时候发生了一次普通的合并,生成一个“merge xxx into xxx”的commit,由于上文说到的原因,这个commit节点没有记录diff。当checkout回master再从master merge feature分支的时候,满足了fast-forward的条件,所以没有再次进行diff操作,没有对上次失误进行再次检查。

而code平台merge request默认的操作是—no-ff(这里补充一下,github是有squash选项的,但是code平台不支持),所以会强制再次进行一次diff,这时候上次merge中隐藏的错误得到了一个再次暴露出来的机会,在code review中就可以发现了。

解决方案

这个问题出现的根本原因有两个:

  • 浅层原因:merge时错误处理了冲突
  • 深层原因:没有走code平台merge request,没有禁止master分支直接pull

笔者回顾这个问题时想到,假如别有用心的人利用这种机制上的漏洞,在merge中故意修改代码,这些修改将不会出现在git的任何一次commit diff中,除非对master分支上一个挨一个commit排查。

甚至于在merge时采取squash或者rebase等方法,把这次commit 与其他commit混淆起来,是否就可以彻底把自己隐匿起来呢?

为了避免重现此次错误,强烈建议提高master分支敏感性,设置为protected分支禁止直接操作,所有对master分支的merge统一走merge request!

额外提一句,还应该避免在公用开发机上设置code平台 ssh 密钥,防止被盗用身份提交commit。

是否真的发生过利用这种方案恶意报复公司的案例呢?笔者也是很好奇。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯技术工程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
H5微信支付、支付宝支付
1.绑定域名: 登录微信公众平台 –> 公众号设置 –> 功能设置 –> 填写“JS接口安全域名”
青梅煮码
2023/02/18
1.7K0
H5微信支付、支付宝支付
微信支付之扫码、APP、小程序支付接入详解
做电商平台的小伙伴都知道,支付服务是必不可少的一部分,今天我们开始就说说支付服务的接入及实现。目前在国内,几乎90%中小公司的支付系统都离不开微信支付和支付宝支付。那么大家要思考了,为什么微信支付和支付宝支付能作为大多数公司接入的首选呢?其实这个问题大多小伙伴应该是很清楚的,说白了就是人家有庞大的用户流量,目前微信在国内的用户已突破10亿,支付宝也接近8亿左右,如此庞大的用户群体,你还会选择其他的第三方支付(微博钱包、财付通、快钱等)吗,作为普通客户,大家都希望能方便快捷,谁会为了在一个平台买点东西下载或开通其他服务呢,除非你给他有诱惑性的好处。今天我们先说说微信支付的接入及实现。
攻城狮的那点事
2019/08/26
2K0
微信支付之扫码、APP、小程序支付接入详解
一款简单易学的支付宝开源支付项目
这两天TJ君稍微关注了一下娱乐新闻,因为知名的钢琴家李云迪出事了,铺天盖地都是其涉嫌PC被捕的事情,其中主要的一个证据,就是李云迪通过支付宝实名转账给了涉事女子,成为铁一般的犯罪事实,金额还不小,据说一次一万。
程序猿DD
2021/10/26
1K0
一款简单易学的支付宝开源支付项目
ThinkPHP 框架下支付宝支付
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/details/74747805
泥豆芽儿 MT
2018/09/11
1.7K0
ThinkPHP 框架下支付宝支付
商品下单对接支付宝/微信支付
之前我们实现了ChatGPT项目的核心问答业务, 接着为了实现项目的商业化服务和引流, 对接微信公众号实现用户扫码关注、获取验证码登录等一系列的用户引入公众号进行登录。 这样的实现让我们的项目接入微信的广大用户群体,对于以后项目的商业化发展奠定了基调。 接着, 为了项目不让有心人恶意利用以及我们自己的apiKey的额度也是有限的, 所以进行了一系列的规则过滤操作。 这样的规则过滤让我们的项目向商业化的道路上又迈进了一步。 但是, 虽然我们做了用户限流限频的操作,但是还是相当于免费的产品 。这可不是一个商业化产品应该具有的操作。 如果用户后续还想使用我们的产品, 那当然免不了给钱咯。 所以, 本章节我们通过对于ChatGPT核心业务的扩展,实现了用户支付下单的操作。 并且, 基于DDD架构, 让我们的项目变得可拓展性非常好。 我们都知道ChatGPT的更新迭代是非常快的, 所以项目的可拓展性变得至关重要了。 所以使用DDD架构的优点就体现的一览无余。
用户11097514
2024/05/31
2230
商品下单对接支付宝/微信支付
手把手教你接入支付宝支付
前一久做了支付宝支付,分享一下接入的详细步骤吧,移动端和服务端demo源码已上传至GitHub,要下载的移步至文章末尾。 先给出支付宝官方文档:https://docs.open.alipay.com/204/105051/
全栈程序员站长
2022/09/01
2.4K0
手把手教你接入支付宝支付
019:Django微信支付宝支付
本章知识点 1、Django支付 2、Django微信支付介绍 3、Django支付宝支付实施 知识点讲解 Django支付 1、银行支付 2、微信支付 3、支付宝支付 4、其他的支付平台 支付可能有的工作任务 1、开启自己的收费接口 2、开发支付平台 支付核心 1、支付通常是通过api接口开发实现的。 2、支付通常需要签证,解签来保证我们的支付安全。 公钥 私钥 Django微信支付介绍 微信支付平台,对支付的要求,相当严格。 微信支付开通地址 https://pa
李玺
2021/11/22
1.5K0
019:Django微信支付宝支付
Android十八章:5分钟接入微信支付
现在app最流行微信支付,支付宝支付,都是大部分消费类型app计费方式首选。现在5分钟教你接入微信支付。
ppjun
2018/09/05
1K0
在线要饭源码 支付宝个人免签约支付
疫情散发,日子难过,那不如来要饭吧;有人说直接挂个收款码不就完啦,但是,你考虑施舍人的感受了吗??施舍也要讲究便捷,如果能像购物一样,那也是很美的一件事情;BUT线上的支付基本都需要企业资格才能开通,最起码也要是个体工商户才可以(有营业执照),用第三方支付随时担心跑路,自架支付没那本事,还好支付宝的当面付可以个人免签约,当然有些限制,要个饭是够了!
tongyao
2022/06/09
1.7K0
在线要饭源码 支付宝个人免签约支付
移动支付新时代——低代码如何对接支付宝和微信支付
移动支付已经成为现代生活中不可或缺的一部分。随着技术的不断发展和普及,越来越多的人通过手机进行支付。支付宝和微信支付作为中国最主要的移动支付平台,已经成为人们日常生活中最常用的支付方式之一。然而,对于一些初创企业或者中小型企业来说,要接入支付宝和微信支付并不是一件容易的事情。传统的接入方式需要大量的开发工作和技术支持,对于没有相关技术背景的企业来说可能会面临很大的困难。
葡萄城控件
2024/04/08
4350
移动支付新时代——低代码如何对接支付宝和微信支付
微信支付宝支付多端总结
首先我们需要在支付宝创建一个企业账号:memberprod.alipay.com/account/reg…
玖柒的小窝
2021/11/08
5890
微信支付宝支付多端总结
微信支付宝一码付
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
逝兮诚
2019/10/30
2K0
PHP使用yansongda/pay实现支付宝和微信的支付
该文档为 v2.x 版本,如果您想找 v1.x 版本文档,请点击github.com/yansongda/p…
OwenZhang
2021/12/08
4.2K0
easyswoole对接支付宝,微信支付
所有订单配置中,客观参数均不用配置,扩展包已经为大家自动处理了,比如,product_code 等参数。
仙士可
2019/12/19
1.9K0
.Net轻松实现支付宝服务窗网页授权并获取用户相关信息
 最近在开发一个商业街区的聚合扫码支付功能,其中需要用到的有支付宝,微信两种支付方式,当然对于开发微信支付而已作为自己的老本行已经比较熟悉了,然而对于我来说支付宝支付还是头一次涉及到。这次项目中需要用到的是支付宝公众号支付这一功能,因为需要进行支付宝授权获取到用户的User_ID然后在进行支付宝公众号支付,在这里我就顺带把用户信息也获取了。因为第一次玩,大概配置支付宝开发平台的应用信息到获取到用户User_ID遇到了几个坑,今天记录一下希望能够帮助一下没有做个这样方面的同仁哪些的方有坑,并且加深一下自己的印象,最后我要声明一下我所开发语言是.net mvc 非JAVA,因为这里java和非java的秘钥生成的秘钥格式有所不同。
追逐时光者
2019/08/28
8290
.Net轻松实现支付宝服务窗网页授权并获取用户相关信息
接入微信支付的坑
官方解释:“商户证书”是指由商户申请的,包含商户的商户号、公司名称、公钥信息的证书。 新接入商户请参考什么是API证书?如何获取API证书?。 我的解释:服务商在微信支付->账户中心->API安全->API证书中申请的证书,就是商户证书。其实也是在微信支付平台申请的,但是不叫微信平台证书(大概因为这个证书是由商户保管把,而微信只是提供了一个入口供我们去申请下载)我真的是很想教写文档的好好做人。
西柚dzh
2022/06/09
1.7K0
接入微信支付的坑
微信小程序中的支付宝支付
支付宝开放平台: https://open.alipay.com , 使用支付宝扫码登录,进入控制台,找到沙箱环境
很酷的站长
2022/12/28
8.9K1
微信小程序中的支付宝支付
Go项目接入微信支付的步骤和代码详解
经过上节课的功能开发,我们成功地用自己购物车里的商品项下了单,下了单不支付,人家也不可能给你送货或者给你开会员的对吧。
KevinYan
2025/03/21
1410
Go项目接入微信支付的步骤和代码详解
【支付系统设计从0到1】支付业务调用方式有哪些?为什么微信公众号支付采用JSAPI方式?
对于大多数做支付系统设计的同学来说,对于支付渠道提供的调用方式都不陌生,相信大家对这些支付渠道的调用方式也了如指掌。
金融民工小曾
2018/09/14
2.1K0
【支付系统设计从0到1】支付业务调用方式有哪些?为什么微信公众号支付采用JSAPI方式?
前端后端集成支付宝支付功能
https://juejin.im/post/5a0c46646fb9a0451c39f07a
程序员小猿
2021/01/18
1.1K0
前端后端集成支付宝支付功能
推荐阅读
相关推荐
H5微信支付、支付宝支付
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档