Git 从入门到精通:系统性的学习与实践指南
Git 是目前最主流、最强大的分布式版本控制系统,被广泛用于代码管理和团队协作。无论你是个体开发者还是团队成员,掌握 Git 都是必备技能。本文将从零开始,系统介绍 Git 的核心概念、常用操作、分支模型、远程协作以及高级技巧,帮助你在实际工作中游刃有余。
目录
- [Git 是什么?为什么要用?](#Git 是什么?为什么要用?)
- [安装 Git](#安装 Git)
- 初次配置与仓库初始化
- 核心概念:工作区、暂存区与版本库
- 基础操作流程
- 查看历史与版本回退
- 分支管理
- 远程仓库协作
- 高级技巧与工具
- [自定义 Git 与环境配置](#自定义 Git 与环境配置)
- 常用命令速查表
- 学习建议与资源
一、Git 是什么?为什么要用?
想象你正在写一份重要文档,每次修改前都手动复制一份备份:方案v1.doc、方案v2.doc、最终版.doc......很快你就会分不清哪个是哪个。Git 做的事情本质上是更高效地记录文件的每一次变化------它能追踪每个字符的修改,并在多人协作时自动协调。
1.1 什么是版本控制系统?
版本控制系统(VCS)可以记录文件的每次改动和版本迭代,方便回溯历史,也支持多人协作。举个例子:你每天都在写代码,某天电脑突然故障,本地文件全部丢失。如果使用了版本控制系统,你的代码已经保存在远程服务器上(如 GitLab、GitHub),只需一键克隆即可恢复,相当于多了一道保险。
版本控制系统的演进经历了三个阶段:
- 本地版本控制系统:如 RCS,只在单机上记录文件差异,但无法协同工作。
- 集中式版本控制系统(CVCS):如 CVS、Subversion,有一台中央服务器保存所有版本,开发者从中央拉取和提交。缺点是中央服务器单点故障,一旦宕机或数据损坏,整个历史可能丢失。
- 分布式版本控制系统(DVCS):如 Git、Mercurial,每个开发者本地都拥有完整的仓库副本(包括完整历史)。因此即使服务器出问题,任何本地仓库都可以恢复。这正是 Git 的优势所在。
1.2 Git 的独特优势
- 分布式:每个开发者本地都有完整的仓库副本,支持离线工作。
- 高效分支:创建、切换、合并分支极其快速,鼓励短分支、频繁合并。
- 完整性 :每个提交都有 SHA-1 哈希值(如
d670460b4b4aece5915caf5c68d12f560a9fe3e4),确保历史不可篡改。 - 只添加数据:大多数 Git 操作只向数据库添加数据,很难丢失已提交的信息。
需要注意的是,Git 主要针对文本文件(如代码、配置文件)进行精确的差异追踪;对于图片、视频等二进制文件,虽然可以管理,但只能看到文件大小变化,无法查看具体修改内容。
1.3 Git 的诞生
Git 诞生于 2005 年,由 Linux 之父 Linus Torvalds 亲自开发。当时 Linux 内核社区使用的 BitKeeper 免费授权被收回,Linus 在两周内用 C 语言写出了 Git 的雏形,并设定了目标:速度、简单设计、对非线性开发(分支)的强力支持、完全分布式、能高效管理超大规模项目(如 Linux 内核)。如今 Git 已成为版本控制的事实标准。
二、安装 Git
2.1 Windows
从 Git 官网 或 Git for Windows 下载安装包,按默认选项安装即可。安装完成后,打开 Git Bash 或 PowerShell,输入:
bash
git --version
若能显示版本号(如 git version 2.40.0),说明安装成功。
2.2 macOS
推荐使用 Homebrew 安装:
bash
brew install git
也可从官网下载安装包手动安装。
2.3 Linux
使用系统包管理器:
- Ubuntu / Debian:
sudo apt-get install git - CentOS / RHEL:
sudo yum install git - Fedora:
sudo dnf install git
验证安装同样执行 git --version。
三、初次配置与仓库初始化
3.1 配置用户信息(非常重要)

安装后第一件事是设置用户名和邮箱,每次提交都会用这些信息标记作者:
bash
# 设置用户名和邮箱(--global 表示全局配置)
git config --global user.name "Your Name"
git config --global user.email "your_email@example.com"
# 查看所有配置
git config --list
# 删除配置
git config unset [--global] user.name // 删除用户名
git config unset [--global] user.email // 删除邮箱
--global表示全局配置,作用于当前电脑的所有 Git 仓库。- 若想在某个项目中单独使用其他身份,可进入项目目录后去掉
--global重新配置。
查看所有配置:
bash
git config --list
删除某项配置:
bash
git config --unset --global user.name
3.2 设置默认编辑器
Git 需要调用编辑器让你填写提交信息。可以设置你喜欢的编辑器:
bash
git config --global core.editor "code --wait" # Visual Studio Code
git config --global core.editor "vim" # Vim
3.3 创建或获取仓库
方式一:本地初始化(从头开始)
先进入到你想要进行版本管理的文件夹当中,使用指令 git init ,即可创建一个本地仓库:
bash
mkdir my-project # 创建项目文件夹
cd my-project # 进入文件夹
git init # 初始化为Git仓库
执行后当前目录下会出现一个隐藏的 .git 文件夹,所有版本信息都存储于此。
方式二:克隆远程仓库
bash
git clone https://github.com/用户名/仓库名.git
克隆下来的仓库会自动关联远程地址,非常适合新手熟悉 Git 工作流。
四、核心概念:工作区、暂存区与版本库
理解 Git 的三个核心区域是掌握所有命令的基础:
| 区域 | 说明 | 比喻 |
|---|---|---|
| 工作区 | 你电脑上能看到的文件和文件夹,日常修改代码的地方。 | 办公桌 |
| 暂存区 | 临时存放待提交的修改(位于 .git/index 文件中),相当于"草稿箱"。 |
待办文件筐 |
| 本地仓库 | 正式保存版本历史的地方,存放所有提交记录(位于 .git/objects)。 |
文件柜 |
Git 中文件有三种状态:已修改(modified) 、已暂存(staged) 、已提交(committed) 。
标准工作流程:
- 在工作区修改文件 → 文件状态变为"已修改"
- 用
git add将改动放入暂存区 → 变为"已暂存" - 用
git commit将暂存区内容永久保存到版本库 → 变为"已提交"
记住 :真正进行版本管理的地方是版本库(本地仓库)。暂存区让你可以精细地组织下一次提交,不必将所有的修改一股脑全提交。
五、基础操作流程
5.1 查看状态与差异
bash
git status # 查看哪些文件被修改、哪些在暂存区
git diff # 查看工作区与暂存区的具体差异(修改内容)
git diff --staged # 查看已暂存但与上一次提交的差异
5.2 添加文件到暂存区
bash
git add README.md # 添加指定文件
git add . # 添加当前目录下所有变更(新增、修改、删除)
5.3 提交到仓库
bash
git commit -m "feat: 添加用户登录功能" #在这里,需要描述你的提交细节,帮助其他人看到更好的理解
提交信息建议遵循规范格式:类型: 简短描述。常用类型包括:
feat- 新功能fix- 修复 bugdocs- 文档更新style- 代码格式调整(不影响逻辑)refactor- 代码重构(不改变功能)test- 添加测试chore- 构建过程或辅助工具的变动
好的提交信息能让团队成员快速理解项目演进历程,切忌写"修复 bug""更新"这类模糊描述。
5.4 跳过暂存区直接提交(仅适用于已跟踪文件)
bash
git commit -am "提交说明"
等价于 git add -u + git commit,但不会添加新增的未跟踪文件。
5.5 删除与移动文件
bash
git rm <file> # 从版本库和工作目录中删除文件
git rm --cached <file> # 仅从版本库中删除,但保留工作目录文件(适用于误添加)
git mv <old> <new> # 移动或重命名文件(等价于 mv + git rm + git add)
5.6 忽略文件
创建 .gitignore 文件,列出不需要 Git 管理的文件模式:
bash
# 忽略所有 .o 和 .a 文件
*.o
*.a
# 但跟踪 lib.a
!lib.a
# 忽略当前目录下的 TODO 文件(不包括子目录)
/TODO
# 忽略 build 目录及其子目录
build/
# 忽略 doc/ 下所有 .txt 文件,但不忽略子目录中的 .txt
doc/*.txt
# 忽略 doc/ 及其所有子目录下的 .pdf 文件
doc/**/*.pdf
GitHub 提供了大量常见项目语言的 .gitignore 模板:github/gitignore
六、查看历史与版本回退
6.1 查看提交历史
bash
git log # 完整历史
git log --oneline # 一行简洁展示
git log --oneline -10 # 最近10条
git log --graph --all --oneline # 图形化展示所有分支历史
git log -p -2 # 显示最近两次提交的详细差异
git log --stat # 显示每次提交的文件修改统计
6.2 版本回退
Git 通过 reset 命令移动当前分支的指针来回退版本:
bash
# 回退到上一个版本
git reset --hard HEAD^
# 回退到指定 commit(可通过 git log 查看 commit-id)
git reset --hard <commit-id>
reset 的三种模式:
--soft:只移动 HEAD 指针,暂存区和工作区都不变(即所有修改仍处于暂存状态)。--mixed(默认):移动 HEAD,重置暂存区,但工作区不变(即修改变为未暂存状态)。--hard:移动 HEAD,重置暂存区 并 重置工作区(⚠️ 会丢失所有未提交的改动,慎用!)
如果希望撤销已经推送到远程的提交,更推荐使用 git revert(生成一个新的反向提交),而不是 reset,因为 reset 会改写历史,影响协作者。
6.3 撤销工作区的修改
bash
git checkout -- <file> # 丢弃工作区中对该文件的修改(不可恢复)
6.4 取消暂存
bash
git reset HEAD <file> # 将文件从暂存区移回工作区(不改变文件内容)
七、分支管理
分支是 Git 最强大的功能之一。你可以把分支理解为"平行宇宙"------在不同分支上独立开发新功能,互不干扰,最后再合并到一起。Git 的分支创建和切换成本极低(只需 41 个字节),鼓励频繁使用分支。
7.1 创建与切换分支
bash
git branch feature-login # 创建分支(但不切换)
git checkout feature-login # 切换分支
# 一步到位:
git checkout -b feature-login # 创建并切换
7.2 查看分支
bash
git branch # 本地分支列表(* 表示当前分支)
git branch -v # 显示每个分支最后一次提交
git branch --merged # 显示已合并到当前分支的分支
git branch --no-merged # 显示未合并的分支
7.3 合并分支
bash
git checkout main # 切换到目标分支(主分支)
git merge feature-login # 把 feature-login 的改动合并过来
合并有两种情形:
- 快进合并(fast-forward):当前分支是目标分支的直接祖先,只需将指针前移。
- 三方合并(3-way merge):两个分支分叉了,Git 会找到共同祖先,生成一个新的合并提交。
7.4 处理合并冲突
当两个分支修改了同一文件的同一位置时,Git 无法自动决定保留哪个版本,产生冲突。冲突文件中会插入如下标记:
<<<<<<< HEAD
当前分支的代码
=======
被合并分支的代码
>>>>>>> feature-login
解决步骤:
- 打开冲突文件,手动编辑,决定保留哪部分代码(可结合两者)。
- 删除
<<<<<<<、=======、>>>>>>>标记。 - 执行
git add <冲突文件>标记为已解决。 - 执行
git commit完成合并(Git 会自动生成合并提交信息)。
7.5 删除分支
bash
git branch -d feature-login # 删除已合并的分支
git branch -D feature-login # 强制删除(即使未合并)
7.6 变基(rebase)与合并的选择
变基是将一系列提交按照原有顺序应用到另一个分支上,使历史呈线性。例如:
bash
git checkout feature
git rebase main # 将 feature 分支的修改变基到 main 分支上
变基 vs 合并:
- 合并:保留完整的历史分叉,清晰反映实际开发过程。
- 变基:得到整洁的线性历史,但会改写提交的 SHA-1 值。
最重要的准则 :不要对已推送到公共仓库的提交执行变基。因为其他人可能基于那些提交进行了开发,变基会让他们陷入混乱。只对尚未推送的本地提交使用变基来整理历史。
7.7 远程分支与跟踪分支
远程引用以 <remote>/<branch> 形式存在,如 origin/master。当你克隆一个仓库时,Git 会自动创建 origin/master 远程跟踪分支,并创建一个本地 master 分支跟踪它。
- 查看远程分支:
git branch -r - 创建本地分支跟踪远程分支:
git checkout -b <本地名> <remote>/<branch>或git checkout --track origin/serverfix - 手动设置跟踪:
git branch -u origin/serverfix
八、远程仓库协作
远程仓库是团队共享代码的中枢,托管在 GitHub、GitLab、Gitee 等平台上。
8.1 关联远程仓库
bash
git remote add origin https://github.com/用户名/仓库名.git
origin 是远程仓库的默认别名(可自定义)。
8.2 查看远程仓库信息
bash
git remote -v # 显示 fetch 和 push 的地址
git remote show origin # 显示详细信息(包括哪些分支会被自动合并)
8.3 第一次推送并关联分支
bash
git push -u origin main
-u 会将本地 main 分支与远程 main 分支关联,之后只需输入 git push 即可。
8.4 日常推送与拉取
bash
git push # 推送本地提交到远程
git pull # 拉取远程最新代码并合并到本地(相当于 git fetch + git merge)
注意 :推送前请确保本代码基于远程最新版本,否则会被拒绝。应先执行
git pull拉取更新并处理可能的冲突。
8.5 删除远程分支
bash
git push origin --delete serverfix
8.6 利用 GitHub 进行协作
GitHub 是目前最大的 Git 托管平台,围绕它形成了一套名为 GitHub Flow 的协作流程:
- 派生(Fork)主项目到自己名下。
- 从
master分支创建一个新分支(如feature-xyz)。 - 在该分支上提交修改。
- 推送到自己 Fork 的仓库。
- 在 GitHub 上发起拉取请求(Pull Request)。
- 讨论、修改,直至项目维护者合并。
拉取请求是代码审查和讨论的绝佳工具,你可以在特定行上加评论,CI 系统会自动运行测试并显示状态。
九、高级技巧与工具
9.1 贮藏(Stash)
当你需要临时切换分支,但手头的工作还没完成时,可以用 stash 将未提交的修改暂存起来:
bash
git stash # 贮藏工作区和暂存区的修改
git stash list # 查看贮藏列表
git stash apply # 应用最近的贮藏(但保留在堆栈中)
git stash pop # 应用并删除最近的贮藏
git stash branch <分支名> # 从贮藏创建一个新分支
9.2 交互式暂存(Interactive Staging)
你可以分块暂存文件的修改,而不是整个文件:
bash
git add -i # 进入交互式模式
git add -p # 直接进入补丁模式,逐块选择要暂存的修改
这在你做了一个较大的改动但希望拆分成多个逻辑独立的提交时非常有用。
9.3 搜索
- 按内容搜索 :
git grep比普通grep更快,且可以搜索历史版本。
git grep -n "function_name"显示行号,git grep -p显示所在函数名。 - 按提交内容搜索 :
git log -S "字符串"查找添加或删除该字符串的提交。
git log -G "正则"使用正则表达式搜索。
9.4 重写历史
- 修改最后一次提交 :
git commit --amend(可修改提交信息或补充漏掉的文件)。 - 修改多个提交 :
git rebase -i HEAD~3进入交互式变基,可以reword(修改信息)、squash(压缩)、drop(删除)等。 - 全局修改 :
git filter-branch可从历史中删除大文件或替换作者信息(谨慎使用,会改写所有 SHA-1 )。官方推荐更现代的工具git-filter-repo。
9.5 子模块(Submodule)
当你的项目需要包含另一个独立的 Git 仓库作为子目录时,使用子模块:
bash
git submodule add https://github.com/xxx/lib.git
git submodule update --init --recursive # 克隆后拉取所有子模块
git submodule update --remote # 更新子模块到上游最新
注意:子模块默认处于"游离 HEAD"状态,需要进入子模块目录检出分支后方可提交。
9.6 打包与归档
git bundle create repo.bundle HEAD master:将仓库打包成一个文件,可通过邮件或 U 盘传输,对方git clone repo.bundle即可。git archive --format=zip HEAD > project.zip:生成一个不含 Git 元数据的源码快照,方便发布。
9.7 调试工具
git blame:查看每一行代码最后是谁修改的。git bisect:二分查找定位引入 bug 的提交。
用法:git bisect start,然后git bisect bad(当前有问题),git bisect good v1.0(已知正常的版本),Git 自动切换到中间提交让你测试,根据结果标记good或bad,最终找到第一个坏提交。
十、自定义 Git 与环境配置
10.1 别名(Alias)
为了避免输入长命令,可以设置别名:
bash
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
10.2 配置颜色和分页器
bash
git config --global color.ui auto # 自动着色输出
git config --global core.pager less # 分页器
10.3 合并与比较工具
可以配置外部合并/比较工具,如 P4Merge、KDiff3:
bash
git config --global merge.tool kdiff3
git config --global diff.tool kdiff3
10.4 钩子(Hooks)
Git 可以在特定事件发生时触发自定义脚本(位于 .git/hooks/)。常见钩子:
pre-commit:提交前运行测试或检查代码风格。commit-msg:校验提交信息格式。pre-receive(服务器端):拒绝不符合策略的推送。post-receive:推送后通知 CI 或发送邮件。
10.5 Git 属性(Attributes)
在 .gitattributes 文件中可以为特定文件定义行为,例如:
*.txt text:自动处理行尾转换。*.png binary:视为二进制文件。*.docx diff=word:使用自定义 diff 程序。
10.6 Git 内部原理简介(可选理解)
Git 本质上是一个内容寻址文件系统。核心对象包括:
- Blob:文件内容。
- Tree:目录结构和文件名。
- Commit:指向一个 tree 和父提交,包含作者、时间、注释。
- Tag:指向一个 commit,可附带签名。
所有对象都通过 SHA-1 哈希值存储在 .git/objects 目录中。当对象数量过多时,Git 会将其打包成 packfile 并使用差异压缩节省空间。
十一、常用命令速查表
| 分类 | 命令 | 说明 |
|---|---|---|
| 配置 | git config --global user.name "名字" |
设置用户名 |
git config --global user.email "邮箱" |
设置邮箱 | |
git config --global core.editor "code" |
设置默认编辑器 | |
| 初始化 | git init |
初始化本地仓库 |
git clone <url> |
克隆远程仓库 | |
| 日常操作 | git status |
查看状态 |
git add <file> |
添加文件到暂存区 | |
git add . |
添加所有变更 | |
git commit -m "说明" |
提交到仓库 | |
git commit -am "说明" |
跳过暂存区直接提交(仅已追踪文件) | |
git diff |
查看工作区与暂存区的差异 | |
git diff --staged |
查看暂存区与上一次提交的差异 | |
| 历史 | git log --oneline |
简洁提交日志 |
git log --graph --all --oneline |
图形化分支历史 | |
git log -p -2 |
最近两次提交的详细差异 | |
| 撤销 | git checkout -- <file> |
丢弃工作区修改 |
git reset HEAD <file> |
取消暂存 | |
git reset --hard <commit> |
回退到指定提交(危险) | |
git revert <commit> |
生成一个反向提交来撤销 | |
| 分支 | git branch |
列出本地分支 |
git branch <分支名> |
创建分支 | |
git checkout <分支名> |
切换分支 | |
git checkout -b <分支名> |
创建并切换分支 | |
git merge <分支名> |
合并分支到当前分支 | |
git branch -d <分支名> |
删除已合并分支 | |
git merge --abort |
取消合并 | |
| 远程 | git remote -v |
查看远程仓库信息 |
git remote add origin <url> |
关联远程仓库 | |
git push |
推送到远程 | |
git pull |
拉取并合并远程更新 | |
git push -u origin main |
首次推送并关联远程分支 | |
git push origin --delete <branch> |
删除远程分支 | |
| 贮藏 | git stash |
贮藏当前修改 |
git stash apply |
应用贮藏 | |
git stash pop |
应用并删除贮藏 | |
git stash list |
列出所有贮藏 | |
| 调试 | git blame <file> |
查看每行代码的最后修改者 |
git bisect start / good / bad |
二分法查找 bug 引入点 | |
| 高级 | git rebase -i HEAD~3 |
交互式变基,整理历史 |
git cherry-pick <commit> |
拣选某个提交到当前分支 | |
git submodule add <url> |
添加子模块 |
十二、学习建议与资源
学习路径建议
- 理解核心概念:搞懂工作区、暂存区、版本库的区别,以及 Git 的数据模型(快照而非差异)。
- 动手操作基础命令 :
init,add,commit,status,log,diff,在本地测试仓库中反复练习。 - 掌握分支:每天创建新分支做实验,直到分支的创建、切换、合并、删除形成肌肉记忆。
- 体验远程协作:注册 GitHub 账号,将本地仓库推送到远程,再尝试克隆、拉取、推送。
- 学习高级功能 :
rebase,stash,cherry-pick,bisect,submodule等,根据实际需求深入。 - 了解内部原理:阅读《Pro Git》最后几章,理解对象、引用、包文件等,这将极大提升你解决问题的能力。
推荐资源
- 廖雪峰的Git教程:史上最浅显易懂的Git教程,绝对面向初学者,边学边练,图片+文字+视频,非常友好(地址:liaoxuefeng.com/wiki/896043488029600)
- Git官方文档:最权威的参考资料,适合深入理解Git原理并查阅特定命令(地址:git-scm.com/book/zh/v2)
- Git GUI客户端:如果不想记命令行,推荐GitHub Desktop(新手入门)、Sourcetree(免费功能全)、GitKraken(团队协作支持好),这些工具通过可视化界面操作提交、分支、推送/拉取。Visual Studio Code和JetBrains系列IDE也都内置了Git工具,已经使用这些IDE的开发者无需额外安装工具。
- 在线练习平台 :Learn Git Branching 通过游戏方式直观学习分支操作。
Git 上手不难,关键是多动手。现在就可以打开终端,敲下第一行命令:
bash
git init
祝你顺利学会 Git,享受版本控制带来的高效与安心!