git 原理
一、git 原理图
二、初始同步状态
远程仓库 (origin/main): A---B ← 指向 B 本地版本库 (main): A---B ← 指向 B 本地工作区: 文件和 B 提交时完全一致三、本地一个文件中添加了"bbbb"
| 你的操作 | 执行前状态 | `git reset --hard` 结果 | bbbb 还在吗? |
| `add` + `commit` | `A---B---D` (D含bbbb) | 不变,还是 `A---B---D` | ✅ 在(已提交) |
| 只 `add` | `A---B`,暂存区有bbbb | `A---B`,暂存区清空 | ❌ 没了 |
| 什么都没做 | `A---B`,工作区有bbbb | `A---B`,工作区恢复 | ❌ 没了 |
四、正常提交流程
1. 修改 a.c(在工作区) ↓ 2. git add a.c → 改动进入暂存区 ↓ 3. git commit -m "xxx" → 暂存区内容打包成提交,进入版本库 ↓ 4. git push → 版本库的提交推送到远程仓库五、本地修改远程也修改不同文件
# 1. 你在本地修改 a.c vim a.c # 工作区:a.c 加了 bbbb # 2. 加入暂存区 git add a.c # 暂存区:a.c (staged) # 3. 提交到本地版本库 git commit -m "a.c加bbbb" # 本地:A---B---D # 4. 推送到远程?先 pull! git push # ❌ 失败!提示:reject non-fast-forward # 远程有 C,你的历史不是 C 的后代 # 5. 先拉取远程最新代码 git pull # 内部执行: # git fetch origin main → 下载 C 到 origin/main # git merge origin/main → 合并 C 和 D,产生 merge commit E # 结果: # 本地变成:A---B---C---E---D (merge 方式) # 6. 现在可以 push 了 git push # ✅ 成功!远程也更新到包含你的提交# 1. 你在本地修改 a.c vim a.c # 工作区:a.c 加了 bbbb # 2. 加入暂存区 git add a.c # 暂存区:a.c (staged) # 3. 提交到本地版本库 git commit -m "a.c加bbbb" # 本地:A---B---D # 4. 推送到远程?先 pull! git push # ❌ 失败!提示:reject non-fast-forward # 远程有 C,你的历史不是 C 的后代 # 5. 先拉取远程最新代码 git pull --rebase origin main #A---B---C---D' (rebase 方式) # 6. 现在可以 push 了 git push # ✅ 成功!远程也更新到包含你的提交五、本地修改远程也修改(不同文件) 现在不管git add 和git commit 都不要了就是和远程一样
git fetch origin main git reset --hard origin/main六、已经push 成功现在要取消
情况一:还没人拉取(紧急撤销)
# 本地先回退到上一个提交 git reset --hard HEAD~1 # 强制推送到远程(覆盖远程历史) git push --force origin main结果:
远程原来: A---B---C---D (D是你的提交) 远程现在: A---B---C (D被删掉了) 本地: A---B---C⚠️危险!如果同事已经pull了 D,他们下次 push 会冲突或把 D 又带回来。
情况二:已经有人拉取了(安全撤销)
不要 force push!用 revert 生成一个"反向提交":
# 生成一个新提交,内容刚好抵消 D git revert HEAD # 正常 push git push origin main结果:
远程: A---B---C---D---D' (D' 是 revert 提交,内容和 D 相反) # 比如 D 是 "加了 a.c 一行 bbbb" # D' 就是 "删了 a.c 那行 bbbb"七、Git 冲突标记
// 原始文件 int a = 10; // 你改成 int a = 20; // 远程改成 int a = 30;<<<<<<< HEAD int a = 20; // 你的修改 ← "HEAD 指向的提交"里的代码 = 你的本地代码 ======= int a = 30; // 远程的修改 >>>>>>> origin/main // "origin/main 指向的提交"里的代码 = 远程代码八、解决冲突
git pull # Auto-merging a.c # CONFLICT (content): Merge conflict in a.c # Automatic merge failed; fix conflicts and then commit the result.Git 会在工作区生成带冲突标记的文件,你直接用编辑器打开修改:
vim a.c # 或 VS Code、IDEA 等文件里长这样
<<<<<<< HEAD int a = 20; // 你的代码 ======= int a = 30; // 远程代码 >>>>>>> origin/main手动编辑,三选一:
// 方案1: 保留你的 int a = 20; // 方案2: 保留远程的 int a = 30; // 方案3: 合并两者 int a = 25; // 或者别的处理方式改完后的流程
git pull # 拉取,产生冲突 vim a.c # 手动解决冲突 # 1. 保存文件 # 2. 告诉 Git 冲突已解决 git add a.c # 3. 完成合并提交 git commit -m "解决a.c冲突" # 或直接用 git merge --continue # 4. # 现在才能推送到远程 git push