一、什么是 Git?
Git 是一个分布式版本控制系统,它可以追踪文件的每一次变更,让你可以随时回到历史版本、多人协作开发而不冲突。
核心概念
- 仓库(Repository):存放项目代码和所有历史版本的地方
- 提交(Commit):一次代码变更的快照,相当于"存档点"
- 分支(Branch):独立的开发线,互不干扰
- 远程仓库(Remote):托管在服务器(如 GitHub)上的仓库
二、Git 与 GitHub 的关系
| Git | GitHub | |
| 是什么 | 版本控制工具 | 代码托管平台 |
| 功能 | 本地管理代码版本 | 云端存储、协作 |
| 是否需要网络 | 本地就能用 | 需要网络 |
| 类似 | 你的本地笔记本 | 云盘 |
工作流程: 本地用 Git 管理 → 推送到 GitHub 备份/协作 → 从 GitHub 拉取更新
三、分支(Branch)详解
什么是分支?
分支就是从主线上分出来的一条独立开发线。想象你在写一本书:
- main/master 分支 = 已经出版发行的正式版本
- feature 分支 = 你单独开一个草稿本写新章节,不影响已经出版的书
为什么需要分支?
main: A---B---C---D---E
\
feature: X---Y---Z
- 多人同时开发不同功能,互不干扰
- 实验性代码不会破坏稳定版本
- Bug 修复可以独立进行
分支操作命令
# 查看所有分支 git branch # 创建新分支 git branch feature-login # 切换到某个分支 git checkout feature-login # 或(新版推荐) git switch feature-login # 创建并切换到新分支(一步到位) git checkout -b feature-login # 或 git switch -c feature-login # 合并分支(先切回目标分支,再合并) git checkout main git merge feature-login # 删除分支 git branch -d feature-login
分支合并示意图
合并前:
main: A---B---C
\
feature: D---E
执行 git merge feature 后:
main: A---B---C---F
\ /
feature: D---E
F 就是合并产生的新提交,包含了 main 和 feature 的所有变更。
四、git pull 详解(核心重点)
git pull 的本质
git pull = git fetch + git merge
也就是说:
- git fetch:从远程仓库下载最新数据(但还不动你的本地代码)
- git merge:把下载的数据合并到你当前的分支
三种场景详解
场景一:本地没有未提交的修改(最顺利)
你本地: A---B---C 远程: A---B---C---D---E
执行 git pull 后:
你本地: A---B---C---D---E
结果:直接快进(fast-forward),远程的新提交 D、E 接在你的提交后面,历史的线性关系完全保留。
场景二:本地有未提交的修改
# 方法1:先暂存,再拉取,再恢复 git stash # 把本地修改暂存起来 git pull # 拉取远程更新 git stash pop # 恢复本地修改 # 方法2:先提交本地修改 git add . git commit -m "本地修改" git pull # 正常拉取
场景三:本地和远程都修改了同一文件(需要合并)
你本地: A---B---C---D ← 你提交了 D 远程: A---B---C---E ← 别人提交了 E
执行 git pull 后,Git 会自动尝试合并:
- ✅ 没有冲突:自动创建合并提交 F
A---B---C---D---F
\ /
E
- ❌ 有冲突(同一行被双方修改):
# Git 会提示 CONFLICT,并暂停合并 # 你需要手动编辑冲突文件 # 冲突部分会显示为: # <<<<<<< HEAD # 你的修改 # ======= # 远程的修改 # >>>>>>> branch-name # 解决冲突后: git add 文件名 # 标记冲突已解决 git commit # 完成合并提交
git pull 的安全操作建议
# 推荐:先看远程有什么变化,再决定怎么拉 git fetch # 只下载,不合并 git log --oneline HEAD..origin/main # 看远程新增了哪些提交 # 确定没问题再拉 git pull # 或者用 rebase 让历史更干净(进阶用法) git pull --rebase
五、本地修改与远程版本的关系处理
常见的版本关系图
情况 1:你领先于远程(已提交未推送)
本地: A---B---C---D(你提交的 D) 远程: A---B---C
→ 执行 git push 推送 D
情况 2:远程领先于你(别人先推送了)
本地: A---B---C 远程: A---B---C---D---E(别人推送的)
→ 执行 git pull 拉取更新
情况 3:分叉了(你和别人都提交了)
本地: A---B---C---X(你的) 远程: A---B---C---Y(别人的)
→ 执行 git pull → 自动合并或解决冲突 → git push
情况 4:着急推送但远程有新提交
# 错误做法:强制推送(会丢失别人的代码!) git push --force # ❌ 不要这样做 # 正确做法: git pull --rebase # 把你的提交"挪"到远程提交后面 # 解决可能出现的冲突 git push # 推送成功
六、日常 Git 工作流
单人开发
# 早上开始工作 git pull # 拉取最新代码 # ... 写代码 ... git add . # 暂存所有修改 git commit -m "完成了XX功能" # 提交 git push # 推送到 GitHub
团队协作(推荐工作流)
# 1. 从 main 创建功能分支 git checkout -b feature/user-login # 2. 在功能分支上开发 git add . git commit -m "添加登录表单" git commit -m "实现登录逻辑" # 3. 定期同步主分支的更新到你的分支 git fetch origin git rebase origin/main # 用 rebase 保持历史整洁 # 4. 功能开发完成,合并回 main git checkout main git pull # 确保 main 是最新的 git merge feature/user-login git push
撤销操作
# 还没 git add,放弃工作区修改 git checkout -- 文件名 # 已经 git add 了,取消暂存 git reset HEAD 文件名 # 已经 git commit 了,撤回这次提交(保留修改) git reset --soft HEAD~1 # 彻底撤回提交且丢弃修改(慎用) git reset --hard HEAD~1
七、GitHub 协作常见操作
克隆仓库
# HTTPS 方式 git clone https://github.com/用户名/仓库名.git # SSH 方式(推荐,免密码) git clone git@github.com:用户名/仓库名.git
关联远程仓库
# 查看远程仓库 git remote -v # 添加远程仓库 git remote add origin https://github.com/用户名/仓库名.git # 修改远程仓库地址 git remote set-url origin 新地址
Pull Request(PR)流程
你 Fork 仓库 → 克隆到本地 → 创建功能分支 → 提交代码 → 推送到你的 GitHub → 发起 PR → 项目维护者 Review → 合并 PR
八、常用命令速查表
| 命令 | 作用 |
git init | 初始化仓库 |
git clone <url> | 克隆远程仓库 |
git status | 查看当前状态 |
git add <文件> | 暂存文件 |
git commit -m "消息" | 提交暂存内容 |
git push | 推送到远程 |
git pull | 拉取远程更新 |
git fetch | 只下载不合并 |
git branch | 查看分支 |
git checkout -b <分支> | 创建并切换分支 |
git merge <分支> | 合并分支 |
git log --oneline --graph | 图形化查看提交历史 |
git diff | 查看未暂存的修改 |
git stash | 暂存当前修改 |
git stash pop | 恢复暂存 |
git reset HEAD~1 | 撤回上次提交 |
九、避坑指南
❌ 常见错误
- 直接在主分支上开发 → 应该在功能分支上开发
- git push --force → 会覆盖远程代码,团队协作中绝对不要用
- 长时间不 git pull → 会导致跟远程差异太大,合并时冲突多
- 提交大文件 → GitHub 有文件大小限制(单个文件 ≤ 100MB)
- 把敏感信息提交上去 → 密码、API Key 永远不要提交到 Git
✅ 最佳实践
- 经常
git pull,保持本地与远程同步 - 每次提交写清晰的 commit message
- 一个功能一个分支,一个分支一个 PR
- 推送前先
git status确认没有误加文件 - 用
.gitignore排除不需要追踪的文件