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

背景 1

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

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

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

准备工作

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


rebase_token:

Bash 复制代码
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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、完成 rebase(git rebase --continue),会再次进入编辑器模式,提示为新提交提供 commit message。

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

bug复现&解决

1、进行两次提交

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

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

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

push 被 GitHub 拒绝:

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

Bash 复制代码
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。

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

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

Bash 复制代码
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) 修改完成后,将改动添加到暂存区:

Bash 复制代码
git add .

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

Bash 复制代码
git commit --amend

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

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 的内容,这是为啥呢??

Bash 复制代码
A -> ... -> E -> F (敏感信息在 E 中)

解释

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

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

举个例子:

假设有以下提交记录:

原始提交记录:

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

提交 B 的内容:

Bash 复制代码
新增 README.md:
  - API 文档说明
  - token = "abc1234"

提交 C 的内容:

Bash 复制代码
修改 README.md:
  - 调整 API 的描述文案

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

清理后记录:

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

提交 B' 的内容:

Bash 复制代码
新增 README.md:
  - API 文档说明

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

Bash 复制代码
修改 README.md:
  - 调整 API 的描述文案

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

背景 2

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

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

  • 在提交 E 中,文件包含了 GitHub 生成的 token
  • 在提交 F 中,同样包含 GitHub 生成的 token
Bash 复制代码
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。

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

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

Bash 复制代码
git rebase -i 5961957~1

终端如下图所示:

4、修改有问题的提交

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

当前,停止在提交 E 处:

删除提交 E 中含有的 token:

将修改提交

Bash 复制代码
# 先添加到暂存区
git add .

# 再提交更改,并覆盖原来的提交
git commit --amend

控制台打印如下:

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

开始 rebase 提交 F

在提交 F 中删除 token

将修改提交

Bash 复制代码
# 先添加到暂存区
git add .

# 再提交更改,并覆盖原来的提交
git commit --amend

控制台打印如下:

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

5、将最新的提交push到GitHub

成功!


参考:

相关推荐
Narutolxy1 小时前
Git Flow 工作流:保障修改不破坏主功能的完整指南20241230
大数据·git·elasticsearch
阿杰同学15 小时前
保姆级Git教程,10000字详解
大数据·git·elasticsearch
Domain-zhuo17 小时前
CSS实现无限滚动的列表
前端·css·vue.js·git·webpack·npm·vue
小龙18 小时前
本地创建了一个 Git 仓库推送到GitHub中
git·github·远程连接·团队协作
mit6.82419 小时前
[Pro Git#2] 分支管理 | branch fix_bug , feature | 处理合并冲突
开发语言·git·学习
js_user19 小时前
git将本地项目上传到远程仓库
前端·javascript·vue.js·git·html·html5
Aimin202219 小时前
Kali Linux系统上配置Git的全局代理
linux·运维·git
小白探索世界欧耶!~19 小时前
gitlab 还原合并请求
前端·经验分享·笔记·git·vue·gitlab·踩坑
代码的奴隶(艾伦·耶格尔)21 小时前
git仓库上传
git
王伯爵21 小时前
git设置项目远程仓库指向github的一个仓库
git·github