第一部分:Git 是什么?为什么需要它?
版本控制系统 (VCS):
- 想象一下你在写一个重要的文档(比如论文、代码、小说)。你会手动保存
论文_v1.docx
,论文_v2.docx
,论文_最终版.docx
,论文_真的最终版.docx
… 很乱吧?- Git 就是一个超级智能的“文档保存系统”。它会自动、高效地记录你项目中每一个文件的每一次修改。 核心价值:
- 历史记录: 随时可以回滚到任何一个过去的版本,看看当时写了什么,或者找回误删的内容。
- 协作: 多人同时修改同一个项目时,Git 能帮助合并大家的改动,避免混乱和覆盖。
- 分支管理: 可以创建独立的“实验空间”(分支)尝试新功能或修复 Bug,而不影响主要(主分支)代码。测试成功后再合并回去。
- 责任追踪: 记录每次修改是谁做的、什么时候做的、为什么做(通过提交信息)。
- 备份与同步: 通过远程仓库(如 GitHub, GitLab, Gitee),你的代码不仅保存在本地电脑,也备份在服务器上,可以在不同电脑间同步。
简单比喻: Git 就像一个拥有时光机功能的超级文件管理器,专门为跟踪项目变化而设计。
第二部分:核心概念(理解这些是关键!)
仓库 (Repository / Repo):
- 你的项目目录及其内部的所有文件(包含一个隐藏的
.git
文件夹)。这个.git
文件夹就是 Git 的“数据库”,存储了所有的历史记录、配置、分支信息等。 - 初始化一个项目目录为 Git 仓库是第一步。
工作区 (Working Directory):
- 就是你电脑上看到的项目文件夹。你在这里创建、修改、删除文件。
暂存区 (Staging Area / Index):
- 一个中间区域。你把工作区里改动好的文件添加 (
git add
) 到这里,告诉 Git:“这些改动我准备要保存了”。它像一个准备打包的清单。 - 为什么需要它? 让你可以精细控制哪些修改要包含在下一次“快照”中,而不是一次性提交所有改动。比如你同时修改了两个文件,但只想提交与修复 Bug 相关的那个。
本地仓库 (Local Repository): - 存储在你自己电脑上的完整历史记录数据库(就是那个
.git
文件夹)。git commit
命令将暂存区的内容打包成一个永久的“快照”,保存到本地仓库的历史记录中。
提交 (Commit):
- 将暂存区的内容作为一个新的版本快照永久保存到本地仓库的动作。每次提交都需要一个提交信息 (Commit Message),清晰说明这次修改的目的(非常重要!)。
- 快照理解: Git 不是只记录变化的差异(虽然内部优化会用到),它更像是记录整个项目在那个时刻的状态。但非常高效,因为未修改的文件只是链接到之前的快照。 分支 (Branch):
- Git 默认创建一个叫
master
或main
的分支(主分支,通常代表稳定可用的版本)。 - 分支就像一条独立的时间线。你可以基于当前分支(如
main
)创建一个新分支(如feature-login
)来开发登录功能。在feature-login
上的所有修改都不会影响main
分支,直到你决定将它们合并 (git merge
) 回main
。 - 分支是 Git 强大协作和并行开发能力的核心。
HEAD:
- 一个特殊的指针,通常指向你当前所在的分支(比如
main
或feature-login
),进而指向该分支上最新的提交。它代表了你的工作区是基于哪个版本。
远程仓库 (Remote Repository):
- 存放在网络服务器(如 GitHub, GitLab, Gitee)上的仓库副本。用于备份、协作和同步。常见的远程仓库默认命名为
origin
。
克隆 (Clone):
- 将远程仓库完整地复制到你的本地电脑上,包括所有历史记录和分支。这是获取他人项目或开始协作的第一步。
拉取 (Pull):
- 从远程仓库获取最新的更改(别人提交的)并合并 (
git merge
) 到你当前工作的本地分支。相当于git fetch
(获取远程更新) +git merge
。
推送 (Push):
- 将你本地分支上的提交上传到对应的远程仓库分支。让你的改动能被别人看到或使用。
合并 (Merge):
- 将一个分支(如
feature-login
)的更改整合到另一个分支(如main
)。Git 会自动尝试合并。如果修改了同一文件的同一部分,则会产生冲突 (Conflict),需要手动解决。
冲突 (Conflict):
- 当 Git 无法自动合并两个分支对同一文件的同一部分所做的不同修改时发生。文件里会有特殊的标记 (
<<<<<<<
,=======
,>>>>>>>
) 标出冲突的地方,需要你手动编辑文件决定保留哪部分(或都保留),然后标记冲突已解决 (git add
),再完成合并 (git commit
)。
第三部分:Git 详细使用指南 (命令行版 – 最通用)
安装 Git
- 访问官方下载页: https://git-scm.com/downloads
- 选择你的操作系统 (Windows, macOS, Linux) 并下载安装程序。
- 运行安装程序,大部分选项保持默认即可(Windows 用户建议勾选 “Use Git from the Windows Command Prompt” 或 “Use Git and optional Unix tools from the Windows Command Prompt” 以便在 CMD/PowerShell 中使用)。
- 安装完成后,打开终端 (Windows: CMD 或 PowerShell; macOS: 终端 Terminal; Linux: 终端 Terminal)。
- 验证安装:输入
git --version
,如果显示版本号(如git version 2.37.1
)则安装成功。
配置 Git (第一次使用前必须做)
告诉 Git 你是谁,这样你的提交才会带有正确的作者信息。
git config --global user.name "你的名字" # 例如 "Zhang San"
git config --global user.email "你的邮箱" # 例如 "[email protected]" (建议使用你注册 GitHub/GitLab 的邮箱)
--global
:表示这个配置对这台电脑上你所有的 Git 仓库都生效。如果只想对某个特定仓库生效,去掉--global
并在那个仓库目录下运行命令。- 查看配置:
git config --list
核心工作流程 (日常使用频率最高)
想象一个典型的开发任务:修复一个 Bug 或添加一个小功能。
获取最新代码 (拉取):
git checkout main # 1. 确保你在主分支 (切换到 main 分支)
git pull origin main # 2. 从远程仓库 (origin) 的 main 分支拉取最新代码并合并到本地 main
- 开始工作前一定要做这一步,避免基于过时的代码修改。
创建新分支 (隔离修改):
git checkout -b fix-header-bug # 创建一个名为 fix-header-bug 的新分支并立即切换过去
# 或者分两步:
git branch fix-header-bug # 创建分支
git checkout fix-header-bug # 切换到新分支
- 分支名要有意义,比如
fix-xxx
,feature-yyy
,docs-zzz
。
在工作区修改文件:
- 用你的编辑器/IDE 修改、添加或删除项目文件。保存文件。
查看状态 (了解当前情况):
git status
- 这个命令极其常用!它会显示:
- 当前在哪个分支 (
On branch fix-header-bug
) - 哪些文件被修改了但还没暂存 (
Changes not staged for commit
) - 哪些文件已经暂存了准备提交 (
Changes to be committed
) - 哪些文件是新建的但还没被 Git 跟踪 (
Untracked files
)
将改动添加到暂存区 (准备提交):
git add <file1> <file2> ... # 添加特定文件
git add . # 添加当前目录下所有修改和新增的文件 (谨慎使用,确认你确实想提交所有)
git add -u # 添加所有被修改或删除的文件 (不包括新增的未跟踪文件)
- 使用
git status
确认你要提交的文件都已进入 “Changes to be committed” 区域。
提交到本地仓库 (创建版本快照):
git commit -m "清晰且具体的提交信息"
- 提交信息至关重要! 遵循良好实践:
- 第一行:简短总结 (不超过50字符),说明这次提交做了什么。
- 空一行
- 详细说明 (如果需要):解释为什么要这样修改,解决了什么问题。使用现在时态、祈使句(如 “Fix bug where…”, “Add feature for…”, “Update documentation about…”)。
- 例子:
Fix header alignment issue on mobile screens
The CSS rule for `.header` had an incorrect margin value causing misalignment on viewports smaller than 768px. Adjusted the margin to use a percentage instead of fixed pixels.
(可选) 多次提交:
- 在
fix-header-bug
分支上,你可能需要重复步骤 4-6 多次,完成整个修复或功能。保持每次提交都是逻辑上独立且完整的改动(原子提交)。
将本地分支推送到远程仓库 (备份与共享):
git push origin fix-header-bug # 将本地的 fix-header-bug 分支推送到远程仓库 origin,并在远程创建同名分支
- 即使工作没完全完成,也建议经常推送,作为备份。
发起合并请求 (Pull Request – PR) / 合并请求 (Merge Request – MR):
- 这不是 Git 命令,而是 GitHub/GitLab/Gitee 等平台的功能。
- 登录到代码托管平台(如 GitHub)。
- 找到你刚推送的
fix-header-bug
分支。 - 点击按钮 (通常是 “Compare & pull request” 或 “Create merge request”)。
- 填写清晰的 PR/MR 描述:说明这个分支做了什么、为什么做、测试了什么、相关 Issue 编号等。方便别人审查你的代码。
- 指定要将
fix-header-bug
合并到哪个分支 (通常是main
或develop
)。 - 等待代码审查 (Code Review)。根据同事的反馈,可能需要在你的
fix-header-bug
分支上继续修改并再次推送(步骤 4-6,然后git push origin fix-header-bug
),新的提交会自动添加到 PR/MR 中。
代码审查通过后合并到目标分支:
- 在代码托管平台上点击 “Merge” 按钮,将
fix-header-bug
分支的更改合并到main
(或develop
) 分支。 - 注意: 合并后,远程的
main
分支就包含了你的修复。
更新本地主分支并删除已完成的分支 (清理):
git checkout main # 切换回主分支
git pull origin main # 拉取远程合并后的最新 main 代码 (包含了你刚合并进去的修复)
git branch -d fix-header-bug # 删除本地已经合并的 fix-header-bug 分支 (不再需要)
- 通常也可以在代码托管平台合并 PR/MR 时勾选 “Delete source branch” 自动删除远程的
fix-header-bug
分支。
其他常用命令
- 查看历史记录:
git log # 查看详细提交历史 (按 q 退出)
git log --oneline # 查看简洁的提交历史 (只显示提交哈希和提交信息第一行)
git log --graph # 查看带分支合并图的提交历史
git log -p <file> # 查看某个文件的详细修改历史
- 查看差异:
git diff # 比较工作区和暂存区的差异 (未 add 的修改)
git diff --staged # 比较暂存区和最新提交的差异 (已 add 但未 commit 的修改)
git diff HEAD # 比较工作区和最新提交的差异 (所有未 commit 的修改)
git diff <commit1> <commit2> # 比较两个提交之间的差异
- 撤销操作 (谨慎使用!):
- 丢弃工作区的修改 (未 add):
git checkout -- <file> # 丢弃指定文件在工作区的修改,恢复到最近一次 add 或 commit 的状态
- 将文件移出暂存区 (已 add, 未 commit):
git reset HEAD <file> # 将指定文件从暂存区移回工作区 (修改还在,但状态变成未暂存)
- 修改最后一次提交 (已 commit,但还没 push):
git commit --amend # 1. 修改文件 2. git add 3. git commit --amend (会打开编辑器让你修改提交信息)
- 这会替换掉最后一次提交。如果已经 push 到远程,再 push 需要用
git push --force-with-lease
(强制推送,慎用! 会覆盖远程历史,只应在私有分支或确定无其他人协作时使用)。 - 撤销提交 (已 commit,可能已 push):
git revert <commit>
: 创建一个新的提交来反向应用指定提交的修改。这是最安全的方式,因为它不会改变历史记录,适合公共分支。撤销后需要git push
。git reset
: 更强大也更危险,直接移动HEAD
指针来“丢弃”提交。git reset --soft <commit>
: 回退到指定提交,工作区和暂存区的修改都保留。git reset --mixed <commit>
(默认): 回退到指定提交,暂存区的修改移回工作区。git reset --hard <commit>
: 危险! 回退到指定提交,丢弃工作区和暂存区所有修改!确保你真的不需要这些修改。- 如果已经 push 过,
reset
后再push
必须用--force
或--force-with-lease
,会重写远程历史。仅在私有分支或明确知道后果时使用! - 处理冲突:
- 当
git merge
或git pull
发生冲突时,Git 会标记出冲突文件。 - 打开冲突文件,找到
<<<<<<<
,=======
,>>>>>>>
标记。
<<<<<<< HEAD (或当前分支名)
当前分支的代码
=======
要合并进来的分支的代码
>>>>>>> branch-name
手动编辑文件,删除所有冲突标记,并决定保留哪部分代码,或者进行整合修改。
- 保存文件。
- 使用
git add <冲突解决后的文件名>
告诉 Git 这个文件的冲突已经解决。 - 当所有冲突文件都解决并
git add
后,完成合并:git commit
。Git 会为你生成一个合并提交信息。
- 临时保存工作现场:
git stash # 将当前工作区和暂存区的改动临时储藏起来
git stash list # 查看储藏列表
git stash apply # 恢复最近一次储藏的内容 (不删除储藏记录)
git stash pop # 恢复最近一次储藏的内容并删除该储藏记录
- 当你需要紧急切换到另一个分支修复 Bug,但当前工作还没完成不能提交时非常有用。
- 标签 (Tag):
git tag v1.0.0 # 给当前提交打一个轻量标签 (Lightweight Tag)
git tag -a v1.0.0 -m "Release version 1.0.0" # 创建带注释的标签 (Annotated Tag),推荐!
git push origin v1.0.0 # 将标签推送到远程仓库
- 常用于标记重要的里程碑,如软件版本发布。
第四部分:给新手的强烈建议 (最佳实践)
小步提交 (Atomic Commits):
- 每次提交只做一件逻辑上独立的事情(修复一个 Bug,添加一个小功能,修改一处文档)。
- 好处:历史记录清晰、易于回滚特定修改、更容易定位问题、合并冲突范围更小。
编写优秀的提交信息:
- 这是你与未来自己以及队友沟通的关键!清晰、简洁、说明“做了什么”和“为什么做”。把它当成项目日志的重要部分。差的提交信息如 “fix bug”, “update” 毫无价值。
频繁拉取 (git pull
):
- 在开始新工作前,在推送 (
git push
) 前,养成习惯先拉取远程最新代码 (git pull
)。减少冲突的可能性和解决冲突的难度。
善用分支:
- 任何新功能开发、Bug 修复都应该在独立的分支上进行。永远不要直接在
main
分支上直接开发新功能。保持main
分支的稳定性和可部署性。
勤推送 (git push
):
- 完成一个有意义的小阶段(比如修复了一个子 Bug,实现了一个小模块),就推送到远程仓库。这既是备份,也方便协作和代码审查。
理解后再操作:
- 对
git reset --hard
,git push --force
等会丢失数据或重写历史的命令保持敬畏。一定要理解它们在做什么,用在什么地方是安全的。如果不确定,先备份。
善用 git status
和 git diff
:
- 动手操作前,先用
git status
看看当前状态。修改了什么不确定?用git diff
看看具体改了哪里。这是避免误操作的好习惯。
拥抱代码审查 (Code Review):
- 使用 PR/MR 流程。让别人看你的代码可以发现你忽略的问题,分享知识,提高代码质量。认真对待他人的 review 意见。
学习 .gitignore
文件:
- 在项目根目录创建
.gitignore
文件,列出不需要 Git 跟踪的文件和目录(如编译产物*.o
,*.class
,*.exe
,日志文件,编辑器临时文件.idea/
,.vscode/
,依赖目录node_modules/
等)。避免不小心提交无用或敏感(如密码、密钥)文件。
从命令行开始:
- 虽然 GUI 工具(见第五部分)很直观,但强烈建议新手先学习命令行。命令行让你更清晰地理解 Git 的核心概念和工作流,遇到问题时也更容易搜索解决方案。掌握基础后,再结合 GUI 提高效率。
第五部分:图形界面工具 (GUI)
- 为什么用 GUI? 可视化分支、提交历史、差异等更直观;简化部分操作(如暂存、提交、解决冲突)。
- 推荐工具:
- 官方自带:
git gui
(基础操作),gitk
(历史查看)。 - 跨平台强大工具:
- Sourcetree: (免费, Atlassian) 功能全面,界面友好。
- GitKraken: (免费版功能受限,付费功能强) 界面现代,可视化极佳。
- Fork: (付费,有试用) 口碑很好,设计精良。
- VS Code / IntelliJ IDEA 等 IDE 内置 Git 功能: 对于开发者非常方便,无需切换工具。
- GUI 与 CLI 的关系:
- GUI 是命令行的包装:GUI 执行的操作最终都是在调用 Git 命令。
- 理解核心概念依然重要:即使使用 GUI,理解仓库、暂存区、提交、分支、合并、冲突等概念是有效使用 GUI 的基础。否则 GUI 的按钮可能会让你困惑。
- 结合使用:日常简单操作用 GUI 提高效率(如查看历史、暂存部分修改、解决简单冲突),复杂或需要精确控制的操作(如重置、变基、处理复杂冲突)回到命令行。
第六部分:学习资源
官方文档 (权威):
- Git Book (Pro Git): https://git-scm.com/book/zh/v2 (有中文版) – 免费,全面,深入。
- Git Reference Manual: https://git-scm.com/docs – 命令参考手册。
交互式学习:
- Learn Git Branching: https://learngitbranching.js.org/ (强烈推荐!) – 通过游戏化、可视化的方式学习分支、提交、合并、变基等核心概念,效果极佳。
- GitHub Learning Lab: https://lab.github.com/ – GitHub 官方的互动教程。
社区与问题解决:
- Stack Overflow: https://stackoverflow.com/ – 遇到具体错误或问题,几乎都能在这里找到答案。搜索时加上
[git]
标签。 - 官方社区:https://git-scm.com/community
总结
Git 是一个强大但需要学习和练习的工具。不要期望一次就掌握所有命令和概念。遵循以下路径:
- 掌握核心工作流:
clone
,checkout -b
,add
,commit
,push
,pull
,merge
(解决冲突),status
,log
。这是你 80% 时间会用到的。 - 理解核心概念:仓库、工作区、暂存区、提交、分支、远程、HEAD。这是理解命令的基础。
- 实践、实践、再实践:在自己的小项目上反复练习。犯错是学习过程的一部分(在安全的环境下犯错)。
- 善用
git status
和git diff
:时刻清楚自己在哪、做了什么。 - 写好提交信息:培养这个好习惯。
- 善用分支:保护你的
main
分支。 - 遇到问题先搜索:Stack Overflow 是你的好朋友。
- 逐步学习进阶知识:如
stash
,revert
,reset
,rebase
,.gitignore
,tag
等。