1. 项目概述:为什么你需要一份超详细的Git笔记?
如果你刚接触编程,或者从SVN这类集中式版本控制系统迁移过来,第一次打开Git Bash或者输入git init时,大概率是懵的。工作区、暂存区、本地仓库、远程仓库、分支、合并、冲突……这些概念一股脑涌过来,官方文档虽然详尽但过于抽象,网上教程又往往只讲单个命令,缺乏一个贯穿始终、能让你亲手“玩坏”再“救回来”的系统性指南。
这份笔记的初衷,就是解决这个问题。它不是命令的简单罗列,而是我作为一线开发者,在无数次提交、合并、回滚和解决冲突的“实战”中,总结出的一套从零到精通的Git操作心法。你会发现,Git的核心逻辑其实非常优雅,一旦理解了其设计哲学,那些看似复杂的命令就会变得顺理成章。无论你是想管理自己的个人项目代码,还是需要与团队协作,这份笔记都将为你提供一个清晰、可靠、可随时查阅的操作地图。我们将从最基础的安装配置讲起,深入到日常高频命令的每一个细节,最后攻克那些让人头疼的“疑难杂症”,确保你不仅能“用”Git,更能“懂”Git。
2. 核心概念与工作流:三棵树与三个状态
在敲下任何命令之前,我们必须先建立正确的心理模型。这是理解Git所有操作的基础,很多新手觉得Git难,就是因为跳过了这一步,直接去死记硬背命令。
2.1 Git的三种状态与三个工作区
Git管理的文件,在其生命周期中主要处于三种状态之一:已修改(modified)、已暂存(staged)、已提交(committed)。这三种状态分别对应三个工作区域:工作目录(Working Directory)、暂存区(Staging Area)、本地仓库(Local Repository)。
你可以把这三个区域想象成一个产品的生产线:
- 工作目录:这是你的“车间”。你在这里直接编辑源代码文件。此时,文件处于“已修改”状态。Git知道这些文件被改动过,但尚未决定要将其纳入下一次的“产品快照”。
- 暂存区:这是一个“质检站”或“打包区”。你使用
git add命令,将工作目录中精心修改好的文件放入这个区域。放入这里的文件,状态变为“已暂存”。这意味着你已确认这些改动是你想记录到下一个版本中的。 - 本地仓库:这是最终的“成品仓库”。当你执行
git commit时,暂存区里的所有文件快照会被永久地存储到本地仓库中,形成一个提交记录(commit)。文件状态变为“已提交”。这个仓库安全地保存在你的.git目录里。
这个“工作目录 -> 暂存区 -> 本地仓库”的流程,是Git最基础的单人工作流。暂存区的设计是Git的一大精髓,它让你可以精细地控制提交内容,而不是一次性提交所有改动。
2.2 分布式版本控制的灵魂:远程仓库
Git是分布式的。这意味着每个开发者的电脑上都有一个完整的本地仓库,包含了项目的全部历史记录。远程仓库(Remote Repository),如GitHub、Gitee或GitLab上的仓库,只是一个大家约定好用于同步和共享的中心节点。
两个核心命令连接着本地与远程:
git push:将你本地仓库中的提交,上传到远程仓库。git pull或git fetch+git merge:从远程仓库获取他人的更新,并合并到你的本地仓库。
这种分布式架构带来了巨大的灵活性:你可以在飞机上、在没有网络的地方尽情提交代码,等有网时再一次性推送。它也增强了数据安全性,每个人的本地都是一个完整的备份。
2.3 分支:Git的“杀手锏”
分支是Git的另一个核心概念,它让你能低成本地创建代码的“平行宇宙”。默认情况下,Git会创建一个名为main或master的主分支。
- 为什么需要分支?想象一下,你要开发一个新功能(比如“用户登录”),但不想影响主分支上正在稳定运行的代码。这时,你就可以创建一个新的分支,比如
feature-login,在这个分支上大胆地编写和测试代码。主分支main上的工作完全不受影响。 - 分支的本质:在Git中,分支本质上只是一个指向某个提交(commit)的轻量级可移动指针。创建新分支几乎瞬间完成,因为它只是新建了一个指针,而不是复制整个项目文件。
- 合并(Merge):当
feature-login分支上的功能开发并测试完毕后,你可以将其合并回main分支。Git会尝试自动将两个分支的修改整合到一起。分支使得团队协作、功能开发和Bug修复可以并行不悖,这是现代软件开发工作流的基石。
注意:很多新手混淆了“暂存”和“提交”。
git add只是把文件放进“准备提交”的暂存区,此时改动并未被永久记录。只有git commit才真正创建了一个历史版本。养成“小步快跑,频繁提交”的习惯,但每次提交前用git status和git diff --staged确认暂存区内容,是一个好实践。
3. 从零开始:Git安装、配置与第一个仓库
理论说再多,不如动手做一遍。我们从头开始,搭建你的Git环境并创建第一个版本库。
3.1 系统化安装Git
访问 Git 官方网站 下载对应你操作系统(Windows、macOS、Linux)的安装程序。
Windows用户:运行下载的
.exe安装包。安装过程中有几个关键选项:- 选择组件:建议勾选“Git Bash Here”和“Git GUI Here”,这会在右键菜单添加快捷入口。“Associate .git* configuration files with the default text editor”也建议勾选。
- 选择默认编辑器:新手可以选择“Use Visual Studio Code as Git‘s default editor”或“Nano”,资深Vim用户请自便。这决定了你写提交信息时弹出的编辑器。
- 调整PATH环境:选择“Git from the command line and also from 3rd-party software”。这会将Git工具添加到系统PATH,让你能在任何命令行窗口(如CMD、PowerShell)中使用Git。
- 选择HTTPS传输后端:使用默认的“OpenSSL library”即可。
- 配置行尾转换:这是非常重要的一步,尤其对于跨平台协作。Windows使用CRLF(
\r\n)作为行结束符,而Linux/macOS使用LF(\n)。选择“Checkout Windows-style, commit Unix-style line endings”(core.autocrlf设置为true)。这样,签出代码时Git会将LF转换为CRLF,提交代码时再将CRLF转回LF,保证仓库内统一使用LF。 - 后续选项使用默认设置即可,一路点击“Next”完成安装。
macOS用户:最简单的方法是安装Xcode Command Line Tools(在终端运行
xcode-select --install)。或者使用Homebrew:brew install git。Linux用户:使用你的发行版包管理器,如
sudo apt-get install git(Ubuntu/Debian) 或sudo yum install git(CentOS/Fedora)。
安装完成后,打开终端(Windows上可以是Git Bash、CMD或PowerShell),输入git --version,如果显示版本号(如git version 2.39.2),则说明安装成功。
3.2 首次使用前的必要配置
安装后第一件事是配置你的用户信息,这信息会嵌入到你每一次的提交记录中,是身份的标识。
git config --global user.name "你的姓名" git config --global user.email "你的邮箱"--global选项表示这是全局配置,对这台电脑上所有的Git仓库生效。你也可以在某个特定仓库目录下,不加--global进行局部配置,优先级更高。
一些提高效率的实用全局配置:
# 让命令行输出带颜色,更易读 git config --global color.ui auto # 设置别名,用更短的命令替代长命令 git config --global alias.st status # git st 代替 git status git config --global alias.co checkout # git co 代替 git checkout git config --global alias.br branch # git br 代替 git branch git config --global alias.ci commit # git ci 代替 git commit git config --global alias.unstage 'reset HEAD --' # git unstage file 将文件撤出暂存区 git config --global alias.last 'log -1 HEAD' # git last 查看最后一次提交 # 设置默认分支名为 main(更现代的命名) git config --global init.defaultBranch main # 推送时采用 simple 模式(新手推荐,避免混淆) git config --global push.default simple查看所有配置:git config --list。
3.3 创建你的第一个Git仓库
有两种主要场景:初始化本地新项目,或获取已有的远程项目。
场景一:本地项目初始化进入你的项目目录(比如my-project),执行:
git init这个命令会在当前目录下创建一个隐藏的.git文件夹,这就是Git仓库的所有数据所在。现在,这个目录就处于Git的管理之下了。
场景二:克隆远程仓库如果你想参与一个已在GitHub等平台上的项目,你需要“克隆”它:
git clone https://github.com/username/repository.gitgit clone命令会做几件事:1) 在远程仓库地址后创建一个同名目录;2) 初始化一个本地Git仓库(.git文件夹);3) 拉取远程仓库的所有数据(所有分支、提交历史);4) 自动将远程仓库地址命名为origin(这是默认的远程仓库别名);5) 检出(checkout)默认分支(通常是main)的最新代码到你的工作目录。
现在,你的本地环境已经就绪,并拥有了一个Git仓库。接下来,我们将进入日常开发中最频繁使用的命令环节。
4. 日常开发高频命令全解析
掌握了基本概念和仓库创建后,我们进入实战环节。下面这些命令将占据你90%的Git使用时间。
4.1 状态查看与文件追踪:git status与git add
git status是你最应该频繁使用的命令,它告诉你当前工作目录和暂存区的状态。
git status输出会清晰地将文件分为几类:
- Changes to be committed:已暂存的文件(绿色)。这些是下次提交的内容。
- Changes not staged for commit:已修改但未暂存的文件(红色)。你需要
git add它们。 - Untracked files:未被Git追踪的新文件(红色)。Git之前没见过它们。
git add命令用于将文件从工作目录放入暂存区。
git add <file> # 添加单个文件 git add . # 添加当前目录下所有修改和新文件(常用) git add *.js # 添加所有.js文件 git add src/ # 添加src目录下的所有文件实操心得:谨慎使用
git add .,尤其是项目很大时。最好先git status看一下改了哪些文件,然后用git add -p(交互式暂存)来逐一审查每个改动块(hunk),决定是否暂存。这能让你提交更干净、目的更明确的代码。
4.2 提交更改:git commit
暂存区准备好后,就可以创建提交了。
git commit -m "提交信息的简要描述"提交信息至关重要。好的提交信息应该像一句简短的命令,首字母大写,不超过50个字符,说明这次提交做了什么,而不是怎么做的。例如:“修复用户登录失败时的空指针异常” 比 “修改了LoginService.java的第45行” 要好得多。
如果需要写更详细的描述,可以不加-m参数,Git会打开你配置的文本编辑器,让你撰写多行的提交信息。第一行是摘要,空一行后是详细描述。
修改最后一次提交:如果你刚提交完发现漏了文件,或者提交信息写错了,可以这样补救:
git add forgotten_file.js git commit --amend -m “新的提交信息”--amend不是修改提交本身,而是创建一个新的提交替换掉上一次提交。注意:如果已经推送到远程,强制重写历史可能会给协作者带来麻烦。
4.3 查看历史与差异:git log与git diff
git log用于查看提交历史。
git log # 默认详细格式 git log --oneline # 单行显示,简洁 git log --graph --oneline --all # 图形化显示所有分支历史,非常直观 git log -p <file> # 查看某个文件的详细修改历史 git log --since=“2 weeks ago” # 查看最近两周的提交git diff用于查看差异。
git diff # 比较工作目录和暂存区的差异 git diff --staged (或 --cached) # 比较暂存区和上一次提交的差异(即将提交的内容) git diff HEAD # 比较工作目录和上一次提交的差异 git diff commit1 commit2 # 比较两个提交之间的差异 git diff branch1..branch2 # 比较两个分支最新提交的差异理解git diff的不同参数,能帮你精准定位代码的改动点。
4.4 分支操作:git branch与git checkout/git switch
查看、创建、删除分支:
git branch # 列出所有本地分支,当前分支前有* git branch -a # 列出所有分支(包括远程) git branch feature-xxx # 创建名为feature-xxx的新分支 git branch -d feature-xxx # 删除已合并的feature-xxx分支 git branch -D feature-xxx # 强制删除分支(即使未合并)切换分支:
git checkout feature-xxx # 切换到feature-xxx分支 git switch feature-xxx # Git 2.23+ 推荐的新命令,语义更清晰git checkout命令身兼多职(切换分支、恢复文件),容易混淆。新版本的Git引入了git switch(专用于切换分支)和git restore(专用于恢复文件),建议使用它们。创建并切换分支(常用):
git checkout -b feature-xxx # 基于当前分支创建并切换到feature-xxx git switch -c feature-xxx # 同上,使用新命令
4.5 合并与同步:git merge,git pull,git push
合并分支:假设你在
feature-xxx分支上完成了开发,想合并到main分支。git switch main # 首先,切换到要合并到的目标分支main git merge feature-xxx # 将feature-xxx分支合并到当前分支(main)如果合并过程顺利(快进合并或自动合并成功),你会得到一个合并后的提交。如果存在冲突,则需要手动解决(见下文)。
拉取远程更新:
git pull origin main # 相当于 git fetch origin main + git merge origin/maingit pull是一个组合命令:先从远程origin的main分支抓取(fetch)最新提交到本地,然后尝试将其合并(merge)到当前分支。更安全的做法是分两步:git fetch origin # 仅获取远程所有分支的最新状态,不自动合并 git merge origin/main # 手动将远程main分支合并到本地当前分支这样你可以在合并前,先用
git log origin/main或git diff origin/main查看具体有什么更新。推送本地提交:
git push origin main # 将本地main分支的提交推送到远程origin的main分支 git push -u origin feature-xxx # 首次推送本地新分支,并建立追踪关系,以后只需git push-u(或--set-upstream) 参数用于建立本地分支与远程分支的追踪关系,设置后,以后在这个分支上直接git push或git pull即可,无需指定远程和分支名。
5. 进阶操作与问题排查实战
当你熟悉了日常命令后,总会遇到一些更复杂的场景。这部分内容能让你在关键时刻从容应对。
5.1 代码回退与撤销:多种场景的救火方案
撤销操作是Git中最容易让人困惑的部分之一,因为它分几种不同的情况。
撤销工作目录的修改(未
git add):你改了一个文件,但改乱了,想恢复到上次提交的样子。git checkout -- <file> # 旧命令,仍可用 git restore <file> # 新命令(推荐),丢弃工作目录的修改警告:这个操作不可逆!修改的内容会永久丢失。
撤销暂存区的修改(已
git add, 未git commit):你把文件添加到了暂存区,但后悔了,想把它挪回工作目录。git reset HEAD <file> # 旧命令 git restore --staged <file> # 新命令(推荐),将文件从暂存区撤出,修改保留在工作目录撤销提交(已
git commit):这里有两种主要意图:- 意图A:撤销提交,但保留修改作为未提交状态(就像没提交过一样)。使用
git reset。git reset HEAD~1 # 或 git reset --soft HEAD~1, 回退到上一个提交,修改保留在暂存区 git reset --mixed HEAD~1 # 默认模式,回退到上一个提交,修改保留在工作目录 - 意图B:创建一个新的提交来抵消之前提交的更改(推荐用于已推送的提交)。使用
git revert。git revert HEAD # 撤销最近一次提交,会创建一个新的反向提交 git revert commit_id # 撤销指定的某次提交git revert是安全的,因为它不重写历史,只是新增提交。这对于团队协作的共享分支是首选。
- 意图A:撤销提交,但保留修改作为未提交状态(就像没提交过一样)。使用
核心原则:如果提交只存在于你的本地仓库,尚未推送到远程(
git push),你可以使用git reset来重写历史。如果提交已经推送到了远程仓库,为了不影响其他协作者,强烈建议使用git revert。
5.2 冲突解决:当自动合并失败时
当你在分支A修改了文件第10行,而别人在分支B也修改了同一文件的第10行,合并时Git就无法自动决定保留哪个,这就产生了冲突(Conflict)。
冲突发生时,Git会中断合并过程,并将冲突文件标记出来。打开冲突文件,你会看到类似这样的标记:
<<<<<<< HEAD 这是当前分支(例如main)的代码 ======= 这是要合并进来的分支(例如feature)的代码 >>>>>>> feature你的任务是:
- 与团队成员沟通,理解两边的修改意图。
- 手动编辑文件,删除
<<<<<<<,=======,>>>>>>>这些标记,并整合出正确的代码。可能需要保留一边,或者融合两者。 - 解决完所有冲突文件后,使用
git add <file>将解决后的文件标记为已解决。 - 最后,执行
git commit来完成这次合并提交。Git会自动生成一个提交信息,如 “Merge branch ‘feature‘ into main”。
工具推荐:对于复杂的冲突,使用图形化合并工具(如VSCode内置的冲突解决器、Beyond Compare、Meld)会直观很多。配置Git使用工具:git config --global merge.tool vscode, 解决时用git mergetool。
5.3 贮藏工作现场:git stash
你正在feature分支上开发到一半,突然需要紧急切换到main分支去修复一个Bug。但当前的工作目录是脏的(有未提交的修改),直接切换分支会失败。这时就需要git stash。
git stash # 将当前工作目录和暂存区的修改保存到一个“栈”中,并清空工作区 git stash save “描述信息” # 贮藏并添加描述 git stash list # 查看所有的贮藏列表 git stash pop # 应用最近一次贮藏并删除它(常用) git stash apply stash@{n} # 应用指定的贮藏(如stash@{0}),但不删除 git stash drop stash@{n} # 删除指定的贮藏 git stash clear # 清空所有贮藏git stash是一个临时“抽屉”,帮你把半成品代码暂存起来,让你能干净地切换上下文,处理完紧急事务后再回来继续。
5.4 后悔药:引用日志git reflog
Git几乎不会真正丢失数据。即使你使用了git reset --hard回滚,或者误删了分支,只要提交曾经存在过,你都可以通过git reflog找到它。
git reflog记录了本地仓库中HEAD和分支引用的所有变化历史(包括提交、重置、合并等)。
git reflog # 输出类似: # abc1234 HEAD@{0}: reset: moving to HEAD~1 # def5678 HEAD@{1}: commit: 添加了新功能 # ghi9012 HEAD@{2}: commit: 初始化项目假设你不小心reset --hard到了一个旧提交,丢失了最新的提交。别慌,在reflog里找到那个丢失的提交哈希(如def5678),然后:
git checkout -b recovery-branch def5678这样你就基于那个“丢失”的提交创建了一个新分支,数据就找回来了。reflog是本地操作,只记录你本地的动作,且有过期时间(默认90天)。
6. 高效协作与最佳实践
个人玩转Git只是第一步,在团队中高效协作才是更大的挑战。遵循一些约定俗成的规范,能让协作顺畅十倍。
6.1 分支管理策略:Git Flow与简化模型
一个清晰的分支模型是团队协作的基石。最著名的模型是Git Flow,它定义了严格的分支类型和合并流程:
main/master:主分支,始终保持稳定、可发布的状态。develop:开发分支,集成所有功能,用于日常开发。feature/*:功能分支,从develop拉出,开发完成后合并回develop。release/*:发布分支,从develop拉出,用于测试和修复Bug,完成后合并回develop和main。hotfix/*:热修复分支,从main拉出,用于紧急修复线上Bug,完成后合并回develop和main。
Git Flow功能强大但略显复杂。对于许多中小型团队或持续交付的项目,一个更简单的模型可能更高效:
- 主干开发(Trunk-Based Development):所有人都在
main分支上进行小颗粒度的、频繁的提交。通过功能开关(Feature Toggle)来控制未完成功能的暴露。这要求团队有高度的自动化测试和集成能力。 - Github Flow/GitLab Flow:简化版。核心是:
main分支永远可部署;任何新功能或修复都从main拉出一个描述性的分支;开发完成后,发起合并请求(Pull Request/Merge Request);经过代码审查和CI/CD流水线验证后,合并回main。
选择哪种模型取决于团队规模和发布节奏。关键是团队内部达成一致并严格遵守。
6.2 提交信息的艺术:Conventional Commits
好的提交信息能让历史记录像一本可读的日志。约定式提交(Conventional Commits)是一种广泛采用的规范,格式如下:
<类型>[可选 范围]: <描述> [可选 正文] [可选 脚注]常见类型:
feat: 新功能fix: 修复Bugdocs: 文档更新style: 代码格式调整(不影响功能)refactor: 代码重构(既非新增功能,也非修复Bug)test: 增加或修改测试chore: 构建过程或辅助工具的变动
例如:feat(login): 增加第三方微信登录功能。这种规范化的信息便于自动生成变更日志(CHANGELOG),也方便快速浏览历史。
6.3 使用.gitignore文件
千万不要把编译产物、本地配置文件、依赖包、IDE项目文件等提交到仓库。它们会使仓库臃肿,且在不同环境下会造成冲突。.gitignore文件就是用来指定哪些文件或目录应该被Git忽略。
在项目根目录创建.gitignore文件,每行写一个模式。例如一个Node.js项目的.gitignore:
# 依赖目录 node_modules/ # 构建产物 dist/ build/ # 环境变量文件 .env .env.local # 日志文件 *.log # 操作系统生成文件 .DS_Store # 编辑器目录 .vscode/ .idea/GitHub有一个非常全面的.gitignore模板库,你可以根据项目类型(Java, Python, Go等)直接选用。
6.4 图形化工具辅助
命令行是根本,但图形化工具(GUI)能提供更直观的视图,尤其在处理复杂的历史、分支和冲突时。
- IDE内置:VSCode、IntelliJ IDEA等现代IDE的Git集成已经非常强大,可以完成大部分操作。
- 独立工具:
- Sourcetree(免费, Atlassian出品):功能全面,跨平台。
- GitKraken(有免费版):界面美观,交互流畅。
- Fork(付费, 有试用期):设计精良,速度快。
我的建议是:以命令行学习为主,用GUI工具辅助查看和验证。理解命令行背后的原理,再用GUI提升效率,两者结合才是王道。
7. 疑难杂症排查手册
即使对Git了如指掌,也难免会遇到一些报错和奇怪的情况。这里记录一些常见问题的排查思路。
7.1fatal: not a git repository...
问题:执行任何Git命令都报此错误。原因:当前目录或其父目录中不存在.git文件夹。解决:
- 确认你是否在正确的项目目录下。用
pwd或ls -la查看。 - 如果你期望这是一个Git仓库,可能是
.git目录被误删了。如果有备份,恢复它。 - 如果你需要初始化,运行
git init。 - 如果你想关联一个已有远程仓库,运行
git clone <url>。
7.2error: failed to push some refs to...
问题:git push失败,提示远程包含你本地没有的工作。原因:通常是因为在你push之前,已经有其他人向远程分支推送了新的提交。你的本地历史与远程历史分叉了。解决:
- 首先,拉取远程的最新更改:
git pull origin <branch-name>。 - Git会自动尝试合并。如果合并有冲突,解决冲突后
add和commit。 - 再次执行
git push。 - 更优雅的方式是使用
git pull --rebase,它会将你的提交“变基”到远程最新提交之后,保持历史线性的整洁,然后再推送。
7.3 误删分支或提交后的恢复
- 恢复误删的本地分支:只要该分支的提交还在(比如刚删除),可以使用
git reflog找到该分支最后一次的提交哈希,然后git branch <branch-name> <commit-hash>重新创建分支。 - 恢复误删的未推送提交:同样使用
git reflog找到那个“丢失”的提交的哈希,然后git checkout -b recovery <commit-hash>。 - 恢复已推送到远程的误操作:如果误操作(如错误合并、错误重置)已经推送,为了不影响他人,不要使用
git push -f强制推送覆盖。应该使用git revert创建一个新的提交来撤销错误的更改,然后再推送这个撤销提交。
7.4 大文件误提交与清理
不小心把一个大文件(如视频、压缩包)提交到了仓库,即使后来删除了,这个文件的历史记录仍然存在于.git中,导致仓库体积巨大。解决:使用git filter-branch或更高效的第三方工具BFG Repo-Cleaner来重写历史,彻底删除该文件的所有痕迹。这是一个危险操作,会改变提交哈希,因此只适用于尚未广泛共享的仓库。操作前务必备份。
# 使用 filter-branch (慢,但原生) git filter-branch --force --index-filter \ "git rm --cached --ignore-unmatch PATH_TO_YOUR_LARGE_FILE" \ --prune-empty --tag-name-filter cat -- --all # 操作后强制推送并通知所有协作者重新克隆对于团队仓库,更安全的做法是联系管理员在服务器端进行清理。
7.5 行尾符问题(CRLF vs LF)
在Windows上开发,在Linux服务器上部署,常因行尾符不一致导致整个文件显示为“已修改”。预防:在项目根目录的.gitattributes文件中进行统一设置是最佳实践。
# 设置所有文件在仓库内使用LF,检出时自动转换 * text=auto # 对于特定文件类型,明确指定 *.sh text eol=lf *.bat text eol=crlf同时,确保所有团队成员按照本文3.1节所述,正确配置core.autocrlf。
Git的学习曲线前期可能有些陡峭,但一旦你理解了它的核心模型(三棵树、快照、分支指针),并熟练掌握了日常命令和问题排查技巧,它就会成为你手中无比强大的利器。这份笔记的目的不是让你背下所有命令,而是给你一张地图和一套工具箱。真正的熟练,来自于在真实项目中的反复使用和踩坑。遇到问题时,别怕,git status是你的第一盏指路灯,git reflog是你的后悔药,而搜索引擎和官方文档 (git help <command>) 是你永远的后盾。现在,去找一个项目,开始你的Git实践吧。