再也不怕手滑丢代码!给 git 高危操作加一层安全校验

前言

相信每个用 git 的人都经历过这种绝望时刻:

bash 复制代码
# 本想切个分支,结果...
git checkout .
# 工作区所有改动瞬间消失,欲哭无泪

# 或者...
git reset --hard HEAD
# 敲完回车才想起来还有没 commit 的代码

尤其是 git checkout 和 git reset --hard 这种毁灭性操作,一旦执行就没有后悔药。每次敲回车前都像在玩俄罗斯轮盘赌。

本文教你一个简单的方法:给这两个高危命令加一层安全检查,工作区不干净就直接拦截,从根源上杜绝手滑。

原理

核心思路是覆盖原命令,在执行前先检查工作区和暂存区是否有未提交的改动:

bash 复制代码
git diff --exit-code          # 检查工作区 vs 暂存区有无差异
git diff --cached --exit-code # 检查暂存区 vs 上次 commit 有无差异

两者都返回 exit code 0(无差异)才放行,否则报错退出。

实现

将以下代码添加到你的 .zshrc 或 .bashrc 中(或者像我一样单独放在 ~/.git-aliases.zsh 再 source):

zsh 复制代码
# 安全切换分支,有已跟踪文件改动则拦截
unalias gco 2>/dev/null
gco() {
  if git diff --exit-code > /dev/null && git diff --cached --exit-code > /dev/null; then
    git checkout "$@"
  else
    echo "⛔ 工作区不干净,请先 stash 或 commit"
    return 1
  fi
}

# 安全 git reset --hard,有已跟踪文件改动则拦截
unalias grh 2>/dev/null
grh() {
  if git diff --exit-code > /dev/null && git diff --cached --exit-code > /dev/null; then
    git reset --hard "$@"
  else
    echo "⛔ 工作区不干净,禁止 reset --hard"
    return 1
  fi
}

重新加载配置后就能立即生效:

bash 复制代码
source ~/.zshrc

使用效果

工作区有改动时:

bash 复制代码
$ gco main
⛔ 工作区不干净,请先 stash 或 commit

工作区干净时正常执行:

bash 复制代码
$ gco main
Switched to branch 'main'

注意点

  1. 只保护已跟踪文件 --- 新增的未跟踪文件(untracked files)不会触发拦截,因为 git diff 默认只关注 tracked files。如果你想连 untracked files 一起保护,可以加上 git ls-files --others --exclude-standard 检查。
  2. gco 只拦截裸 checkout --- 如果 checkout 到某个分支且工作区干净则放行。如果 checkout 的分支与当前分支有冲突,git 本身会报错,不会覆盖你的文件。
  3. 建议全量覆盖 --- 如果你习惯用 git checkout 原生命令,可以用 alias 把 git checkout 也覆盖掉:
zsh 复制代码
alias git='safe_git'
safe_git() {
  if [[ "$1" == "checkout" || "$1" == "reset" ]]; then
    # 同样的安全检查...
  fi
  command git "$@"
}

不过我个人建议直接用函数覆盖 gco 和 grh 就好,保留原生 git 命令以备不时之需。

进阶:连 untracked files 一起保护

如果你连新增文件也想保护,改一下条件判断:

zsh 复制代码
gco() {
  if git diff --exit-code > /dev/null && git diff --cached --exit-code > /dev/null && [[ -z "$(git ls-files --others --exclude-standard)" ]]; then
    git checkout "$@"
  else
    echo "⛔ 工作区不干净(含未跟踪文件),请先 stash 或 commit"
    return 1
  fi
}

写在最后

这层保护我用了两年多,每天几十次 gco / grh 操作,再也没手滑丢过代码。配置简单、零依赖,强烈建议每一个开发者都安排上。

保护自己最好的方式,就是不要给自己犯错的机会。


如果你也有类似的 git 安全技巧,欢迎在评论区分享 👇

相关推荐
高调的涵涵1 天前
删了1.2GB,.git仍是1.2GB
git
程序员沉梦听雨1 天前
【Git】git-submodule子模块管理
git
全栈陈序员2 天前
Git】从入门到精通(八)—— git log:查看提交历史
大数据·git·elasticsearch
7177772 天前
Git自建用什么工具比较好:Gitea、Forgejo、GitLab CE与Gitee的选型对比
git·gitlab·gitea
lsc_blog3 天前
年底还在招的岗位,先确认缺口和到岗要求
git·缓存·ci/cd·职场和发展·github
全栈陈序员3 天前
【Git】从入门到精通(十一)—— git reset 三种模式详解
git·elasticsearch
全栈陈序员3 天前
【Git】从入门到精通(十)—— 撤销与恢复:git checkout与git restore
运维·网络·数据库·git
全栈陈序员4 天前
【Git】从入门到精通(五)—— git add:将文件加入暂存区
大数据·git·elasticsearch
全栈陈序员4 天前
【Git】从入门到精通(七)—— git status:查看仓库状态
大数据·git·elasticsearch
莫晓燚4 天前
Ansible 13 个常用模块---企业实战
git·github