Skip to content

强制删除推送到git上的历史记录

1. 应用场景

通常情况下,是提交代码后,发现提交到git仓库中的某个文件存在敏感信息,此时就要将这个敏感信息的提交从git中删除掉。

现在我有一个testgit的仓库,尝试提交几次代码:

sh
$ echo 'a' > file1.txt && git add . && git commit -m "add file1.txt" && git push origin
[main 25fcda1] add file1.txt
 1 file changed, 1 insertion(+)
 create mode 100644 file1.txt
stty: standard input: Inappropriate ioctl for device
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 282 bytes | 94.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:meizhaohui/testgit.git
   0b72fe9..25fcda1  main -> main
                                                                        
$ echo 'b' > file2.txt && git add . && git commit -m "add file2.txt" && git push origin
[main fe04755] add file2.txt
 1 file changed, 1 insertion(+)
 create mode 100644 file2.txt
stty: standard input: Inappropriate ioctl for device
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 308 bytes | 102.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:meizhaohui/testgit.git
   25fcda1..fe04755  main -> main
                                                                                         
$ echo 'c' > file3.txt && git add . && git commit -m "add file3.txt" && git push origin
[main 8a91349] add file3.txt
 1 file changed, 1 insertion(+)
 create mode 100644 file3.txt
stty: standard input: Inappropriate ioctl for device
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 274 bytes | 137.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:meizhaohui/testgit.git
   fe04755..8a91349  main -> main

$

此时,提交了3个文件到git仓库。

第4次,不小心提交了一个敏感信息到git仓库:

sh
$ echo 'password:123456' > securefile.txt && git add . && git commit -m "add securefile.txt" && git push origin
[main 7ae40c0] add securefile.txt
 1 file changed, 1 insertion(+)
 create mode 100644 securefile.txt
stty: standard input: Inappropriate ioctl for device
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 299 bytes | 149.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:meizhaohui/testgit.git
   8a91349..7ae40c0  main -> main

Snipaste_2024-09-03_22-35-43.png

如果项目开源的话,别的人也能看到我提交到仓库中的密码。

为了让尽可能少的人知道这个密码文件信息,我们应该将这次提交从git仓库中删除。

以下记录处理过程。

2. 操作过程

2.1 备份本地修改

有可能在本地进行多次修改后,突然发现远程仓库中有敏感信息文件被提交了。这个时候可以将本地仓库文件夹备份一下,然后再进行后续操作。等远程仓库里面的异常提交删除后,再使用beyond compare工具将本地修改提交到git仓库中。

2.2 查看历史提交日志

sh
# 或者 git --no-pager log -n 3   就是不翻页显示的意思
$ git log -n 3|awk '{print $0}'
commit 7ae40c003a794b93867560bc887b5a40019bb3a1
Author: Zhaohui Mei <mzh.whut@gmail.com>
Date:   Tue Sep 3 22:34:58 2024 +0800

    add securefile.txt

commit 8a91349a5d4ed4f4932f59431083caf2fc94db1b
Author: Zhaohui Mei <mzh.whut@gmail.com>
Date:   Tue Sep 3 22:32:35 2024 +0800

    add file3.txt

commit fe047555bdf180576ae89525a9d58d96905118b6
Author: Zhaohui Mei <mzh.whut@gmail.com>
Date:   Tue Sep 3 22:32:15 2024 +0800

    add file2.txt           
$

现在有问题的提交的commit id是7ae40c003a794b93867560bc887b5a40019bb3a1,我们要将git仓库中记录还原到它的上一次提交,也就是add file3.txt这一次提交,对应commit id是8a91349a5d4ed4f4932f59431083caf2fc94db1b

2.3 还原本地提交到异常提交的上一次提交

使用git reset --hard <commit-hash>进行硬重置,硬重置会将 HEAD 移动到指定的提交,并清空暂存区以及恢复工作目录到指定提交的状态。

sh
$ git reset --hard 8a91349a5d4ed4f4932f59431083caf2fc94db1b
HEAD is now at 8a91349 add file3.txt
 
$ git status
On branch main
Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)

nothing to commit, working tree clean
                                                                                         
$

2.4 强制推送到git仓库

使用git push origin <branch-name> --force强制推送来更新远程git仓库记录。

在强制推送前,还可以看到git仓库中存在敏感信息的提交记录:

Snipaste_2024-09-03_22-50-30.png

进行强制推送:

sh
$ git push origin --force
stty: standard input: Inappropriate ioctl for device
Total 0 (delta 0), reused 0 (delta 0)
To github.com:meizhaohui/testgit.git
 + 7ae40c0...8a91349 main -> main (forced update)
                                                                                        
$

推送成功。

此时刷新一下git页面,可以看到有异常的的提交已经没有了。

Snipaste_2024-09-03_22-52-35.png

这就说明成功的将git仓库中有异常的提交删除了。

最后再提交一次,看看有新的提交到git仓库后,存在敏感信息的提交是否真的没有了:

sh
$ echo 'd' > file4.txt && git add . && git commit -m "add file4.txt" && git push origin
[main e290197] add file4.txt
 1 file changed, 1 insertion(+)
 create mode 100644 file4.txt
stty: standard input: Inappropriate ioctl for device
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 276 bytes | 138.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:meizhaohui/testgit.git
   8a91349..e290197  main -> main

Snipaste_2024-09-03_23-04-51.png

可以看到,文件file4.txt的提交记录有了,securefile.txt的提交记录已经没有了。

如果你本地绑定了多个远程仓库,其他仓库也需要一并强制推送过去。

sh
$ git remote -v
origin  git@github.com:meizhaohui/testgit.git (fetch)
origin  git@github.com:meizhaohui/testgit.git (push)
gitee   git@gitee.com:meizhaohui/testgit.git (fetch)
gitee   git@gitee.com:meizhaohui/testgit.git (push)

则也需要强制推送到gitee仓库:

sh
$ git push gitee --force

然后去gitee上面也检查一下。

至此,git仓库中的历史异常提交已经从仓库中删除了。

3. 注意事项

  • 在使用 git reset --hard 或者重写历史之后,一定要记得强制推送(--force),这样远程仓库的历史才会被更新。
  • 在进行任何可能影响历史记录的操作之前,请确保你已经备份了仓库,以防止数据丢失。
  • 对于公共仓库,重写历史应该谨慎使用,因为它会影响其他开发者的仓库状态。
  • 如果别人已经克隆了你推送了敏感信息的git仓库,你此时删除git仓库里面的记录,不会影响别人已经克隆好的仓库文件,因此在提交代码到git仓库时,一定要注意文件是否已经正常脱敏。

本首页参考 https://notes.fe-mm.com/ 配置而成