【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

成功!


参考:

相关推荐
一念&6 小时前
Git 与 GitHub 的对比与使用指南
git·github
我是李武涯9 小时前
svn与git Merge重要区别讲解
git·svn
ん贤10 小时前
Git分支
git
迷你二鹏12 小时前
前端之Git
前端·git
哈里谢顿13 小时前
常见 git push 问题及解决方案
git
MarkGosling13 小时前
【开源项目】轻量加速利器 HubProxy 自建 Docker、GitHub 下载加速服务
运维·git·docker·容器·开源·github·个人开发
Aomnitrix18 小时前
【分布式版本控制系统】Git的使用
分布式·git
向上的车轮1 天前
SVN与GIT的区别,分别使用与哪些管理场景?
git·svn
java叶新东老师1 天前
git 提交时排除一个或多个文件
大数据·git·elasticsearch
我会冲击波2 天前
功能分支落后于develop太多,需要把开发分支合并到功能分支吗?
git·intellij idea