Git常用命令指南

Git常用命令指南

2026年1月24日
8 min read
git命令指南版本控制最佳实践

⚓️ 基础回顾:标准同步流程

我们需要先明确 Git 的常规工作流,这是理解后续“破坏性操作”的基准。

  1. 下拉代码:git pull origin main vs git fetch

    • git pull origin main
      作用:将远程 main 分支的最新代码拉取到本地,并自动尝试合并
      实质:它是 git fetch (下载远程变更到跟踪分支) + git merge (合并到当前分支) 的组合。
      适用场景:日常开发快速同步同事代码,但可能产生合并冲突或多余的 Merge 提交。
      注:推荐 git pull --rebase origin main 保持线性历史,避免 Merge 节点。

    • git fetch origin(更安全的选择)
      作用:仅下载远程仓库的最新提交和分支信息到本地远程跟踪分支(如 origin/main),不修改当前工作分支。
      后续步骤:手动查看差异(如 git log --oneline --graph --all),再决定 git merge origin/maingit rebase origin/main
      优势:预览变更,避免意外覆盖本地未提交工作;团队协作时先检查差异再合并。

    核心区别

    命令下载变更自动合并风险
    git pull中等
    git fetch❌ (手动)
  2. 上传代码:git push origin main
    作用:将本地的 commit 推送到远程仓库。
    硬性规则:Git 默认要求**“快进式”(Fast-forward)**推送。这意味着,远程仓库的最新提交必须是你本地历史的“祖先”。
    失败原因:如果远程有了新提交(别人推了代码),而你没有先 pullfetch+merge,Git 会拒绝推送并提示 fetch first。这也是后续需要 --force 的原因。


🧭 场景一:远程覆盖本地(放弃本地修改)

适用情况:

  • 本地环境乱了(比如改错了文件、测试配置搞坏了)。
  • 想完全丢弃本地未提交或已提交的修改。
  • 希望本地代码状态与远程仓库(origin)完全一致。

🚀 操作命令:

# 1. 获取远程最新状态(不合并)
git fetch --all
 
# 2. 将本地分支重置为远程分支的状态
git reset --hard origin/main
 

**

🔍 发生了什么?

  • 当前分支指针:直接移动到 origin/main 指向的提交。
  • 工作区与暂存区:所有未提交的修改、新增的文件(未追踪除外)都会被永久删除
  • 本地提交:所有本地比远程多出的 commit 都会丢失。

⚠️ 警告:这是一个破坏性操作,执行前请确认本地没有需要保留的代码。


🧭 场景二:本地覆盖远程(强制更新历史)

适用情况:

  • 远程仓库的历史“脏”了或不需要了。
  • 你进行了 rebaseamend 操作,导致本地历史与远程分叉。
  • 你确定本地版本才是正确的唯一真理。

🚀 操作命令:

git push origin main --force
 

(注:如果分支名不是 main,请替换为对应的分支名)

🔍 发生了什么?

  • 远程分支的历史会被你本地的历史完全替换
  • 远程上其他人推送的提交(如果存在)将被覆盖且不可恢复

🛠️ 场景三:只修改最近一次提交(不产生新记录)

很多时候我们并不是要重置整个仓库,只是想:“哎呀,刚才提交时漏了一个文件” 或者 “提交信息写错了”

此时不要用 git reset,也不要提交一个新的 commit(产生类似 "fix bug" 这种无意义提交),最干净的方式是 amend

**✅ 使用 git commit --amend**

  1. 将漏掉的修改加入暂存区:
git add .
 
  1. 合并到上一次提交:
# 弹出编辑器修改提交信息
git commit --amend
 
# 或者:保持原提交信息,直接合并
git commit --amend --no-edit
 

结果:你当前的修改融入了上一次提交,没有产生新的 Commit ID(但旧的 ID 变了,因为内容变了)。


🔥 核心讨论:如何安全地“强推”?

当你使用了 commit --amend 或者 rebase 后,本地历史和远程历史就不一样了。此时直接 git push 会报错,必须使用强制推送。

但是,--force 是 Git 中最危险的命令之一。

❌ 危险做法:git push --force

它的潜台词是:“我不管远程有什么,直接用我的覆盖。”

  • 风险:如果你的同事刚才推了一段代码到远程,你的操作会直接抹除他的提交,且通常没有警告。

✅ 推荐做法:git push --force-with-lease

它的潜台词是:“如果远程没人动过(和我本地缓存的远程状态一致),我就覆盖;否则报错提醒我。” **

📊 对比总结

特性git push --forcegit push --force-with-lease
行为逻辑无条件覆盖有条件覆盖(带租约检查)
是否检查远程更新❌ 不检查✅ 检查
安全性低(容易误删同事代码)高(类似于乐观锁)
推荐场景只有你一个人用的私有分支任何多人协作的分支

🧠 举个栗子

假设远程仓库是 A -> B -> C

  1. 在本地把 C 修改成了 C'(amend 操作)。
  2. 同事在远程推入了新提交 D,现在远程是 A -> B -> C -> D

此时你尝试推送:

  • 使用 --force成功。远程变为 A -> B -> C'后果:同事的 D 提交丢失了!
  • 使用 --force-with-lease失败。Git 提示远程有新内容。后果:你被拦下来了,你需要先 pull 下来解决冲突。

💡 总结与建议

  1. 想丢弃本地修改:用 git reset --hard origin/branch
  2. 想修补上次提交:用 git commit --amend
  3. 必须强制推送时永远优先使用 --force-with-lease
  4. 关于 git-filter-repo :那是用于清洗大文件或重写整个仓库历史的核武器,日常修改提交不用杀鸡用牛刀。