删除误提交的 git commit

背景描述

某次的意外 commit 中误将密码写到代码中并且 push 到了 remote repo 里面, 本文将围绕这个场景讨论如何弥补.

模拟误提交操作

  • 在 Gitee 创建一个新的 Repo, clone 到本地
git clone https://gitee.com/lpwm/myrepo.git
  • 创建两个文件, commit 后 push 到 remote 作为初始提交
cd myrepo
echo "A file" > A.txt
echo "B file" > B.txt
git add *
git commit -m "Initial commit"
git push

在 Gitee 检查提交成功:
删除误提交的 git commit_第1张图片

  • 分别修改两个文件, 模拟 A.txt 中误写入了敏感信息, B.txt 属于正常修改. commit & push
echo "Password is admin" >> A.txt
echo "Normal content appended" >> B.txt
git add *
git commit -m "Fault commit"
git push

删除误提交的 git commit_第2张图片

  • 接下来我们要实现的是从远端的 Repo 中修复(删除) A.txt 中误写入的敏感信息, 同时保留 B.txt 中正常的修改内容.

实现过程

主要思路是, 首先从当前已经误提交的状态创建一个新的 branch 作为备份, 在主 branch revert 回滚到误提交前一次的 commit, 强制 push 到 remote 端, 此时远端 repo 中就不会存在后面误提交的 commit 了. 再从备份的 branch merge 到当前 branch, 修改误操作的文件后提交新的 commit, 然后使用 squash 合并最近的两次 commit, 最后再 push 一把.

  • 检查已提交过的历史记录
git log

commit 327d1b09d7fdb43af596c05713d8424181a6b97b (HEAD -> master, origin/master)
Author: lpwm <[email protected]>
Date:   Tue Dec 5 22:21:24 2023 +0800

    Fault commit

commit 27b6ee4ed4a0ff44f2a5831fd5162075bef6a4b4
Author: lpwm <[email protected]>
Date:   Tue Dec 5 22:15:30 2023 +0800

    Initial commit
  • 创建新的 branch 作为备份, 但是不切换
git branch backup
  • 确认当前仍处于默认的 master branch
git branch

  backup
* master
  • 强制回滚到错误提交的前一次 commit, 即 Initial commit, 不保留后面做出的所有修改
git reset --hard 27b6ee4ed4a0ff44f2a5831fd5162075bef6a4b4

  • 检查确认文件内容回滚到了当时的状态
cat A.txt

A file
  • 将当前状态强制推到 remote repo, 即从远端删除后面误提交的内容
git push --force
  • 检查确认 Gitee 中误提交的那次 commit 已经被删除
    删除误提交的 git commit_第3张图片
    误提交的内容是删掉了, 但是其他正常修改的文件内容也没了, 肯定是不行的. 接下来我们继续使用前面创建的 backup branch 来进行合并恢复和修补

  • 确认当前激活的 branch 是 master

git branch

  backup
* master
  • 将 backup 合并到 master
git merge backup
  • 检查 log, 可以看到 merge 后之前的误提交也回来了
git log

commit 327d1b09d7fdb43af596c05713d8424181a6b97b (HEAD -> master, backup)
Author: lpwm <[email protected]>
Date:   Tue Dec 5 22:21:24 2023 +0800

    Fault commit

commit 27b6ee4ed4a0ff44f2a5831fd5162075bef6a4b4 (origin/master)
Author: lpwm <[email protected]>
Date:   Tue Dec 5 22:15:30 2023 +0800

    Initial commit

  • 检查 A.txt 也可以看到误提交写进去的敏感信息
cat A.txt

A file
Password is admin

  • 这时候需要注意, 虽然文件内容是回来了, 但是我们都还是在本地进行的操作, 远端的 repo 中并不受影响, 因此我们可以继续修改 A.txt 文件内容, 将敏感信息删掉, 然后再提交一个新的 commit
echo "A file" > A.txt
git add *
git commit -m "Fixed commit"
  • 检查 log
commit b71cde372e30f7bec24a7a8d9086711ab517a2ba (HEAD -> master)
Author: lpwm <[email protected]>
Date:   Tue Dec 5 22:52:32 2023 +0800

    Fixed commit

commit 327d1b09d7fdb43af596c05713d8424181a6b97b (backup)
Author: lpwm <[email protected]>
Date:   Tue Dec 5 22:21:24 2023 +0800

    Fault commit

commit 27b6ee4ed4a0ff44f2a5831fd5162075bef6a4b4 (origin/master)
Author: lpwm <[email protected]>
Date:   Tue Dec 5 22:15:30 2023 +0800

    Initial commit
  • 将 “Fixed commit” 和 “Fault commit” 合并(squash)成一个 commit
git rebase -i HEAD~2

注意这里的 HEAD~2 表示从 HEAD 位置往前倒推选择两次 commit 记录进行编辑, 从上面的 log 也可以找到 HEAD 位置就是最近提交的这次 Fixed commit. git rebase 命令执行后会进入到交互编辑模式
删除误提交的 git commit_第4张图片
注意这里的 commit 显示顺序是倒着来的, 我们想要将 Fixed commit 合并入 Fault commit 里面, 因此需要修改 Fixed commit 前面的 picksquash, :wq保存后会出现新的 commit message, 默认是将两次的 commit message 拼接到了一起, 愿意改的就改一下, 然后继续保存, 提示 rebase 成功

git rebase -i HEAD~2

[detached HEAD 2f1bc19] Fault commit
 Date: Tue Dec 5 22:21:24 2023 +0800
 1 file changed, 1 insertion(+)
Successfully rebased and updated refs/heads/master.
  • 再次检查 log, 可以看到除了最初的 Initial commit 外, 就只有一个上面合并后的 commit
git log

commit 2f1bc195739602a5d6d20e8438e143941b4e3359 (HEAD -> master)
Author: lpwm <[email protected]>
Date:   Tue Dec 5 22:21:24 2023 +0800

    Fault commit

    Fixed commit

commit 27b6ee4ed4a0ff44f2a5831fd5162075bef6a4b4 (origin/master)
Author: lpwm <[email protected]>
Date:   Tue Dec 5 22:15:30 2023 +0800

    Initial commit
  • 再 push 到 remote repo
git push
  • 检查 Gitee
    删除误提交的 git commit_第5张图片
    删除误提交的 git commit_第6张图片
    完美!

  • 最后要做的一步就是清理本地 backup branch, 注意这里要用 -D 参数, 等同于 --delete --force 强制删除, 如果是普通的 -d 删, 会提示 error: The branch 'backup' is not fully merged.

git branch -D backup

参考文档

Squash commits into one with Git

你可能感兴趣的:(软件应用,Python,运维,git,squash)