【Git_bugs】remote error GH013 Repository rule violations found for.md

news/2024/12/29 9:56:46/

背景 1

在一个分支上的提交顺序如下:-> 代表新的提交

  • 在提交 E 中,文件包含了 GitHub 生成的 token
  • 提交 F 是一次普通的提交,不包含 token
A -> ... -> E -> F (敏感信息在 E 中)

附:给提交起名是为了方便说明问题。在 Git 中是用 Hash 值来表示一个提交的。

准备工作

在 GitHub 生成 1 个 token,用于复现 bug。

在这里插入图片描述
在这里插入图片描述

rebase_token:

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

解决方案

1、根据控制台错误信息或查看提交日志(git log --oneline),确定包含 token 的第一次提交。

2、启动交互式 rebase,在编辑器中将第一个包含 token 的提交的状态由 pick 修改为 edit。

3、在停止状态下,删除提交中包含的 token。

4、(1 ) 将变更添加到暂存区(git add .);(2) 将这次修改作为新的提交(git commit --amend),并覆盖之前的提交。

5、完成 rebasegit rebase --continue),会再次进入编辑器模式,提示为新提交提供 commit message。

6、提供提交信息后,由于后续的提交都需要基于当前的新提交,可能会有冲突,需要先解决冲突。解决冲突也会发生变基。最后,完成 rebase,push 代码到 GitHub。

bug复现&解决

1、进行两次提交

提交 E:在提交的文档中插入一个 token,用来演示后续的 push 操作被 GitHub 拒绝

在这里插入图片描述

提交 F:提交 F 相较于提交 E 是增量修改。

在这里插入图片描述

F 提交完以后,要将本地代码 push 到 GitHub,push 被 GitHub 拒绝:

在这里插入图片描述

push 被 GitHub 拒绝:

在这里插入图片描述

在控制台查看细节,如下:

14:30:47.941: [JavaWiki] git -c credential.helper= -c core.quotepath=false -c log.showSignature=false push --progress --porcelain origin refs/heads/master:master
Enumerating objects: 11, done.
Counting objects:   9% (1/11)
Counting objects:  18% (2/11)
Counting objects:  27% (3/11)
Counting objects:  36% (4/11)
Counting objects:  45% (5/11)
Counting objects:  54% (6/11)
Counting objects:  63% (7/11)
Counting objects:  72% (8/11)
Counting objects:  81% (9/11)
Counting objects:  90% (10/11)
Counting objects: 100% (11/11)
Counting objects: 100% (11/11), done.
Delta compression using up to 8 threads
Compressing objects:  12% (1/8)
Compressing objects:  25% (2/8)
Compressing objects:  37% (3/8)
Compressing objects:  50% (4/8)
Compressing objects:  62% (5/8)
Compressing objects:  75% (6/8)
Compressing objects:  87% (7/8)
Compressing objects: 100% (8/8)
Compressing objects: 100% (8/8), done.
Writing objects:  12% (1/8)
Writing objects:  25% (2/8)
Writing objects:  37% (3/8)
Writing objects:  50% (4/8)
Writing objects:  62% (5/8)
Writing objects:  75% (6/8)
Writing objects:  87% (7/8)
Writing objects: 100% (8/8)
Writing objects: 100% (8/8), 866 bytes | 866.00 KiB/s, done.
Total 8 (delta 6), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas:   0% (0/6)        
remote: Resolving deltas:  16% (1/6)        
remote: Resolving deltas:  33% (2/6)        
remote: Resolving deltas:  50% (3/6)        
remote: Resolving deltas:  66% (4/6)        
remote: Resolving deltas:  83% (5/6)        
remote: Resolving deltas: 100% (6/6)        
remote: Resolving deltas: 100% (6/6), completed with 3 local objects.        
remote: error: GH013: Repository rule violations found for refs/heads/master.        
remote: 
remote: - GITHUB PUSH PROTECTION        
remote:   —————————————————————————————————————————        
remote:     Resolve the following violations before pushing again        
remote: 
remote:     - Push cannot contain secrets        
remote: 
remote:             
remote:      (?) Learn how to resolve a blocked push        
remote:      https://docs.github.com/code-security/secret-scanning/working-with-secret-scanning-and-push-protection/working-with-push-protection-from-the-command-line#resolving-a-blocked-push        
remote:             
remote:             
remote:       —— GitHub Personal Access Token ——————————————————————        
remote:        locations:        
remote:          - commit: 5b8f49aca4ce563a463a6750222692724ae2f0f7        
remote:            path: 玩转MacBook/PicGo + Typora + GitHub搭建图床.md:112        
remote:          - commit: a6d81c0aff0efc8b8a8db1b8e6a2d731dd33820c        
remote:            path: 玩转MacBook/PicGo + Typora + GitHub搭建图床.md:112        
remote:             
remote:        (?) To push, remove secret from commit(s) or follow this URL to allow the secret.        
To github.com:Acura-bit/JavaWiki.git
remote:        https://github.com/Acura-bit/JavaWiki/security/secret-scanning/unblock-secret/2qph1YYqOWV1XcOtE5UkX42tUh2        
!        refs/heads/master:refs/heads/master        [remote rejected] (push declined due to repository rule violations)
remote:             
remote: 
Done
remote: 
error: failed to push some refs to 'github.com:Acura-bit/JavaWiki.git'

由标红处可以看到,GitHub 拒绝 push 的原因是提交中包含 secret,也就是 token。标绿处提示我们移除 token 后再尝试提交。

思考:我们检查代码,然后把代码中的 token 删掉后再提交、再 push,能通过吗?

  • 答案是不可以。因为报错信息明确要求我们要将提交历史中包含的 token 移除,因此需要修改之前的提交。

这时候,rebase 就要登场了。

2、定位第一次包含 token 的提交

控制台的报错信息给出了包含 token 的两次提交:

在提交 E 中包含 token,因为提交 F 是基于提交 E 创建的,所以 F 中也被认为含有 token。但由于 F 是在 E 的基础上做了增量修改,所以在变基编辑时只需要修改提交 E

在这里插入图片描述

其实在背景中已经说明了,提交 E 是第一次包含 token 的提交。问题是控制台显示的两个提交那个是第一次提交呢?

查看提交日志:git log --oneline

在这里插入图片描述

由提交日志可知,提交 E 的哈希值为 a6d81c0;提交 F 的哈希值为 5b8f49a。

rebase_token__169">3、启动交互式 rebase,列出所有包含 token 的提交

执行如下命令,从提交 E 的前一个提交开始 rebase。之所以从前一次开始,是为了包含提交 E。

git rebase -i a6d81c0~1

执行命令后,IDEA 的终端进入了交互时状态,如下图所示:

在这里插入图片描述

4、修改有问题的提交

将目标提交 E 从 pick 改为 edit,然后保存:

  • 英文输入模式下,输入 i 进入 insert 模式
  • 将第一行的 pick 修改为 edit
  • 按 ESC,退出 insert 模式
  • 输入 :wq,然后回车

将提交 E 由 pick 状态修改为 edit 状态:

在这里插入图片描述

当前,控制台打印如下:

在这里插入图片描述

这样,Git 会暂停在这个提交上,让你对其内容进行修改。如下所示:

在这里插入图片描述

这时,我们记录一下提交 E 和 F:

(1) 提交 E 的现状:

在这里插入图片描述

(2) 提交 F 的现状:

在这里插入图片描述

开始编辑,如下图所示,当前确实暂停在了提交 E 上:

在这里插入图片描述

删除代码中的 token:

在这里插入图片描述

5、提交修改

(1) 修改完成后,将改动添加到暂存区:

git add .

将当前修改(删除了 token)提交以覆盖之前的提交:

git commit --amend

执行上述两步后,控制台打印如下:

在这里插入图片描述

rebase_247">6、完成 rebase

输入命令 git rebase --continue,完成 rebase

如下所示,终端又进入了编辑器模式:在上面的变基编辑(删除 token)后,执行 git commit --amend 是为了覆盖提交 E,所以会出现如下界面,提示你修改 commit message,当然也可以不用修改。

在这里插入图片描述

这里我们使用全新的 commit message,进行如下操作:

  • 英文输入模式下,输入 i 进入 insert 模式
  • 修改提交说明
  • 按 ESC,退出 insert 模式
  • 输入 :wq,然后回车

在这里插入图片描述

如上图所示,在编辑器中修改了 commit message。

但是,退出编辑器,提交 E 被全新的提交 G 覆盖,提交 G 的哈希值为 7f41eb9。然而,发生了冲突,

在这里插入图片描述

冲突原因:在提交 E 中编辑(删除 token)后,使用 git commit --amend 覆盖提交 E,生成了新的提交 G,如上图粉色框。因为,提交 F 是基于原来的提交 E 的,在 E 被 G 覆盖后,需要基于 G。然而,不能直接将 G 的内容应用于 F 如上绿色框,因为缺少内容。如下图所示:

在这里插入图片描述

解决冲突:
在这里插入图片描述

将修改添加到暂存区 git add .,然后执行 git rebase – continue,弹出了终端编辑模式:

在这里插入图片描述

7、将最新的提交push到GitHub

执行 push 操作时可以看到,原来的提交 E 和 F 都发生了编辑,都被新的提交覆盖了:

在这里插入图片描述

查看提交状态:

(1) 提交 E 被新的提交 7f41eb9f(G)覆盖:因为提交 E 相较于之前的提交只是新增了几行,所以在变基编辑(删除)后,新的提交没有相较于之前的更改。

在这里插入图片描述

(2) 提交 F 被新的提交 a594d2f0(H)覆盖了

在这里插入图片描述

思考

在背景 1 中,E 是包含 token 的第一个提交,提交 F 没有改动提交 E 关于 token 的内容,只是另外添加了一些内容。我们在交互式变基时,只修改了提交 E 的内容,而没有修改提交 F 的内容,这是为啥呢??

A -> ... -> E -> F (敏感信息在 E 中)

解释

Git 的提交记录是一个链式的结构,每次新的提交都会基于上一提交的快照创建。提交 F 本身只记录了在提交 E 的基础上新增或修改的内容,但并不会重复记录提交 E 的全部内容。

  • 如果提交 F 本身没有显式地重新添加该 token,则 token 实际上仍是提交 E 中的遗留问题。
  • 当通过 rebase 修改提交 E 时,Git 会重新生成基于修改后提交 E 的新历史,而提交 F 也会被重新基于这次修改后的记录进行构建。

举个例子:

假设有以下提交记录:

原始提交记录:

A: 初始化项目
B: 不小心加入了 token
C: 修改代码

提交 B 的内容:

新增 README.md:- API 文档说明- token = "abc1234"

提交 C 的内容:

修改 README.md:- 调整 API 的描述文案

如果只清理提交 B 中的 token,Git 在重构历史时会自动保证提交 C 基于清理后的提交 B:

清理后记录:

A: 初始化项目
B': 删除 token(修订的提交 B)
C': 修改代码(基于提交 B' 重构)

提交 B’ 的内容:

新增 README.md:- API 文档说明

提交 C’ 的内容,或者说相对于提交 B’ 不同的内容:

修改 README.md:- 调整 API 的描述文案

由于 token 已在 B’ 中被移除,C’ 不会再继承该敏感信息。

背景 2

由上面的思考引出了下面的新问题。

在一个分支上的提交顺序如下:-> 代表新的提交

  • 在提交 E 中,文件包含了 GitHub 生成的 token
  • 在提交 F 中,同样包含 GitHub 生成的 token
A -> ... -> E -> F (敏感信息在 E 中)

解决方案

1、逐一 rebase:可以参考背景 1 中的解决方案,先解决提交 E;然后,以同样的方式解决提交 F。

2、一同 rebase。(演示这种方案)

bug 复现&解决

1、进行两次提交

提交 E:在提交的文档中插入一个 token,用来演示后续的 push 操作被 GitHub 拒绝

在这里插入图片描述

提交 F:在另一份文档中添加 token

在这里插入图片描述

效果:提交 E 中含有 token;提交 F 相较于 E,除了含有 E 添加的 token 外,还含有自身添加的其他 token。

F 提交完以后,要将本地代码 push 到 GitHub,push 被 GitHub 拒绝:

在控制台找到被拒绝 push 的提交的信息:

在这里插入图片描述

2、定位第一次包含 token 的提交

查看日志:

在这里插入图片描述

第一个包含 token 的提交的哈希值为 5961957。

rebase_token__426">3、启动交互式 rebase,列出所有包含 token 的提交

执行如下命令,从提交 E 的前一个提交开始 rebase。之所以从前一次开始,是为了包含提交 E。

git rebase -i 5961957~1

终端如下图所示:

在这里插入图片描述

4、修改有问题的提交

将提交 E 和 F 的状态都修改为 edit:

在这里插入图片描述

当前,停止在提交 E 处:

在这里插入图片描述

删除提交 E 中含有的 token:

在这里插入图片描述

将修改提交

# 先添加到暂存区
git add .# 再提交更改,并覆盖原来的提交
git commit --amend

控制台打印如下:

在这里插入图片描述

执行 git rebase --continue,继续 rebase。如下图所示,停止在了提交 F 上:

在这里插入图片描述

开始 rebase 提交 F

在提交 F 中删除 token

在这里插入图片描述

将修改提交

# 先添加到暂存区
git add .# 再提交更改,并覆盖原来的提交
git commit --amend

控制台打印如下:

在这里插入图片描述

执行 git rebase --continue,继续 rebase。如下图所示,变基成功:

在这里插入图片描述

5、将最新的提交push到GitHub

在这里插入图片描述

成功!


参考:

  • GitHub Docs:https://docs.github.com/en/code-security/secret-scanning/working-with-secret-scanning-and-push-protection/working-with-push-protection-from-the-command-line#resolving-a-blocked-push

http://www.ppmy.cn/news/1559039.html

相关文章

【蓝桥杯——物联网设计与开发】拓展模块5 - 光敏/热释电模块

目录 一、光敏/热释电模块 (1)资源介绍 🔅原理图 🔅AS312 🌙简介 🌙特性 🔅LDR (2)STM32CubeMX 软件配置 (3)代码编写 (4&#x…

Docker--Bitnami/mysql

Bitnami package for MySQL What is MySQL? MySQL is a fast, reliable, scalable, and easy to use open source relational database system. Designed to handle mission-critical, heavy-load production applications. Overview of MySQL⁠ Trademarks: This software l…

梳理你的思路(从OOP到架构设计)_设计模式Template Method模式

目录 1、Template Method模式 2、范例: Android TM模式 3、基于TM模式的扩充:以游戏的绘图循环(Game Loop)为例 4、Android中处处可见TM模型的应用 1、Template Method模式 在前面各节里,我们介绍过,控制反转(IoC:Inversion…

`we_chat_union_id IS NOT NULL` 和 `we_chat_union_id != ‘‘` 这两个条件之间的区别

文章目录 1、什么是空字符串?2、两个引号之间加上空格 好的,我们来详细解释一下 we_chat_union_id IS NOT NULL 和 we_chat_union_id ! 这两个条件之间的区别,以及它们在 SQL 查询中的作用: 1. we_chat_union_id IS NOT NULL 含…

设计模式——装饰模式

文章目录 1.定义2. 结构组成3. 组合模式结构4. 示例代码5. 模式优势6. 应用场景 1.定义 装饰模式就像是给你的对象穿上不同的 “时尚服装”,在程序运行时,你可以随意地给对象搭配各种 “服装” 来增加新的功能,而且完全不用对对象本身的 “身…

PyAudio库基本知识详解——为自制PCM音频播放器做准备

前言 结合前段时间我们做的音频编解码器,这样我们就可以将获取到的ADPCM数据,转换成PCM数据,然后播放出来,得到一个完整的音频数据,因此,接下来几篇文章中,我们想做一个播放PCM格式的音频播放器…

嵌入式硬件面试题

1、请问什么是通孔、盲孔和埋孔?孔径多大可以做机械孔,孔径多小必须做激光孔?请问激光微型孔可以直接打在元件焊盘上吗,为什么? 通孔是贯穿整个PCB的过孔,盲孔是从PCB表层连接到内层的过孔,埋孔…

路由器RIP动态路由配置

路由器RIP动态路由配置 目录 实验目的 实验背景 技术原理 配置RIP动态路由的一般步骤 学习任务 实验设备 实验拓扑 实验步骤 实验目的 掌握RIP协议的配置方法:掌握查看通过动态路由协议RIP学习产生的路由;熟悉广域网线缆的链接方式;…