静态博客隐藏着一个容易被人忽略的隐私问题,我也是刚刚遇到。
关于静态博客的搭建环境:如果你是依赖git和github的仓库进行部署的静态博客,极有可能会遇到这种情况。
如果你发表了一篇博文,已经提交github并且在服务器部署成功,这个时候你又后悔了,不想让任何人看到这篇文章,这个时候,你会选择本地删除这篇博文,然后提交新的版本,部署成功后,该博客不在显示该博文。
如果你想让这篇博文在互联网上物理消失,这么做绝对是不行的!
问题的根源是 Git,不是静态博客生成器。 任何用 Git 管理内容的博客(Astro、Hugo、Jekyll、Hexo 等),文件一旦被 git push 到远端,要彻底抹掉都得走这套流程。
具体来说,看你的文章在什么阶段,对应的方法也不同。
以下内容均为大模型编写,请谨慎使用下文的命令
几种删除方法
还没提交 git add 了
还在工作区,直接删除文件就行,连 git 操作都不需要。
已提交但还没 push
最简单的就是 git commit --amend 修改上一次提交,把不需要的文件从提交中移除。或者 git reset HEAD~1 撤销提交,删掉文件后重新 commit。
刚 push 不久,只有一次提交
git rebase -i 把包含目标文件的 commit 删掉或 squash 掉,然后 git push origin master --force。一步到位,不需要 filter-branch 那么重的操作。
文件已经产生多次提交,且推送到远端很久了
这时候就需要重写历史:
# 方案一(推荐,需安装 git-filter-repo)
pip3 install git-filter-repo
git filter-repo --path src/content/blog/xxx.md --invert-paths
# 方案二(传统方式,git 自带)
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch "path/to/file"' \
--prune-empty --tag-name-filter cat -- --all
完事后还要清理本地残留数据:
git reflog expire --expire=now --all
git gc --prune=now --aggressive
git push origin master --force
之所以这么繁琐,是因为 Git 的设计理念就是”不丢数据”,每一次提交都是不可变的快照。你后来的”删除”只是在最新快照中去掉了文件,但之前的所有快照都还在仓库里,不重写历史就永远不会消失。
几个避免以后麻烦的做法
了解这些麻烦后,我现在也养成了几个习惯:
-
发布前不 commit。文章在本地写完后先放着,等最终确认发布时再一次性提交。草稿阶段完全游离于 git 之外。
-
提交了没 push 前发现不对,立即
git commit --amend修正,或者git reset HEAD~1回退。 -
敏感文件如果只有一次提交,用
git rebase -i把对应 commit 删掉,比 filter-branch 轻太多。 -
把草稿放到 .gitignore 里。比如在
src/content/blog/下统一用.draft.md后缀,然后在.gitignore里加上*.draft.md,让草稿永远不会被误提交。 -
使用本地分支。在本地
draft分支上写文章,最终确认后再合并到主分支。即使不小心把 draft 分支 push 上去了,也不会污染主分支的历史。
当然,最根本的解法是:发布前多读两遍,别急着点提交。大部分的”想删除”其实都是”本不该发”。