ElIauk

Git 常用命令与撤销操作

先记住三个区域 Git 的很多“撤销”问题,本质是没搞清东西现在在哪个区域: 区域 说明 常用命令 工作区 你正在编辑的文件 git status、git diff 暂存区 已 add、等待提交的内容 git diff --staged 本地仓库 已 commit 的历史 git log 远程仓库

评论
Git 常用命令与撤销操作

先记住三个区域

Git 的很多“撤销”问题,本质是没搞清东西现在在哪个区域:

区域 说明 常用命令
工作区 你正在编辑的文件 git status、git diff
暂存区 已 add、等待提交的内容 git diff --staged
本地仓库 已 commit 的历史 git log
远程仓库 推送到服务器上的历史 git push / git fetch

撤销之前先执行 git status,看清楚改动处在哪一层,再选命令。上来就 reset --hard,是新手丢代码的头号原因。

HEAD 指向当前分支的最新提交,分支本身只是一个指向提交的指针。git commit 会移动当前分支指针,git switch 会移动 HEAD,理解这一点,reset 的三种模式就不难记了。

reset --soft 只移动指针,暂存区和工作区都不动;--mixed 是默认值,还会重置暂存区;--hard 三处一起重置。所以“想把提交拆成两次”用 --soft,“想重新 add”用 --mixed,“想彻底丢掉”才用 --hard。

提交之前养成两个习惯:先 git diff 看未暂存的改动,再 git diff --staged 看已暂存的内容。调试用的 System.out、注释掉的代码、临时改的配置,都能在这一步拦下来。

日常五条命令

git status                         # 看当前状态
git add src/main/java/...          # 把指定文件放入暂存区
git commit -m "fix: 修正分页参数"   # 提交到本地仓库
git pull --rebase origin main      # 拉取远程并变基
git push origin main               # 推送到远程

提交信息建议用“类型: 描述”的格式,比如 feat:、fix:、docs:、refactor:。半年后回头看历史,能一眼看出每次改动的目的,比一堆“update”有用得多。

撤销:先判断错在哪一步

情况 命令 结果
工作区改乱了,还没 add git restore 文件名 丢弃该文件的修改
已 add,想撤出暂存区 git restore --staged 文件名 改动还在工作区
已 commit,没 push git reset --soft HEAD~1 撤掉提交,改动留在暂存区
已 commit,没 push,想全撤 git reset --hard HEAD~1 提交和改动一起丢,慎用
已 push 到公共分支 git revert 提交号 生成一个反向提交,历史保留
手头改动想临时放一边 git stash / git stash pop 工作区干净,稍后恢复

原则是:只影响自己的本地历史可以用 reset,已经推给别人的历史一律用 revert。公共分支被 reset 之后强推,其他人的本地分支会直接错乱。

分支与合并

git switch -c feature/login        # 新建并切换分支(Git 2.23+)
git switch main                    # 切回主分支
git merge feature/login            # 把功能分支合进主分支
git branch -d feature/login        # 删除已合并的分支

老教程里的 git checkout -b 也能用,switch 只是把“切分支”和“恢复文件”两个职责拆开了,更不容易误操作。合并方式上,merge 会保留分支结构,rebase 会把提交接到目标分支后面、历史更线性。个人分支合并前可以 rebase 整理,公共分支不要 rebase。

常见坑

1. reset --hard 之后代码没了

--hard 会同时丢弃工作区和暂存区的改动,且没有确认提示。真丢了先别慌,用 git reflog 找到 reset 之前的提交号,再 git reset --hard 提交号 救回来。reflog 默认保留 90 天。

2. 强推覆盖别人的提交

git push -f 会把远程历史换成你本地的,别人刚推的提交直接消失。非要用不可时加 --force-with-lease,它在远程有你不知道的新提交时会拒绝推送。

3. .gitignore 对已跟踪文件无效

文件已经被提交过,再加进 .gitignore 也不会生效。要先把它们从索引里移除:

git rm --cached config/local.yml
git commit -m "chore: 移除本地配置"

4. 冲突标记没删干净

合并冲突后文件里会留下 <<<<<<<、=======、>>>>>>>。解决冲突要手动改成最终内容,再 git add。提交前全局搜一遍这些符号,避免把标记带上线。

5. 把密码和密钥提交进仓库

配置文件里写了数据库密码,提交后再删也还在历史里。正确做法是提交前就用环境变量或配置中心,发现泄露后第一时间改密码,再考虑清理历史。

排查步骤

  1. 任何操作前先 git status,确认当前分支和改动范围;
  2. 提交前 git diff 和 git diff --staged 各看一遍,防止带上调试代码;
  3. 操作失误立刻 git reflog,找到操作前的提交号;
  4. 推送被拒绝时先 git pull --rebase,不要直接强推;
  5. 合并冲突解决完,跑一遍编译和测试再提交。

参考

评论

推荐阅读

订阅邮件

订阅更新,及时收到最新文章。

作者