Git 入门到进阶:从安装配置到 worktree 实战避坑指南
2026/9/19 14:36:11 网站建设 项目流程

Git 这东西,刚入行那会儿我也被它折腾得够呛。第一次看到fatal: not a git repository的时候,我盯着屏幕愣了五分钟,心想“我不就在项目文件夹里吗,怎么就不是仓库了”。后来带过几个新人,发现大家卡住的地方惊人地相似:装完了不知道配置啥、clone下来不敢动、commit完了发现提交信息写错了不知道怎么改、密钥配了半天还是login failed。这篇东西就是把这些年踩过的坑、带人时被问得最多的问题,从头到尾捋一遍。不管你是刚下载完 Git 还没打开过,还是已经能敲几个命令但一遇到报错就慌,看完应该都能有点收获。我会从“Git 到底在干嘛”讲起,一直讲到worktree这种稍微进阶一点的用法,中间穿插大量实际会遇到的报错和排查思路。

1. Git 到底解决了什么问题

1.1 从“复制粘贴改文件名”说起

没有版本控制的时候,我们是怎么管理文件版本的?大概率是这样:方案.doc方案_修改版.doc方案_最终版.doc方案_最终版_真的最终.doc。这种做法的死穴在于,你根本说不清两个版本之间到底改了什么,想回退到某个中间状态基本靠猜,多人协作更是灾难——你把文件发给我,我改完发给你,你再改,最后谁的版本是对的都不知道。

Git 的核心价值就一句话:它记录的是每一次改动的快照和改动之间的差异,而不是一堆孤立的文件副本。每次你提交(commit),Git 会把当前所有文件的状态拍一张“照片”存起来,同时记录这张照片和上一张之间哪些文件变了、怎么变的。这样你随时可以回到任何一张历史照片,也可以清楚地看到某一行代码是谁在什么时候改的。

我习惯用一个类比:Git 就像给项目装了一台带时间轴的监控摄像头。你不需要手动保存“第 3 版”“第 5 版”,摄像头自动记录每一帧,你想看哪一帧就看哪一帧,还能对比两帧之间的差异。

1.2 三个区域:工作区、暂存区、本地仓库

理解 Git 最关键的一步,是搞清楚它把文件分成了三个区域。很多人命令敲得挺溜但一出问题就懵,根源就是没搞明白这三个区的关系。

  • 工作区(Working Directory):你眼睛能看到、手能直接编辑的那些文件,就是工作区。你在编辑器里改代码,改的就是工作区。
  • 暂存区(Staging Area / Index):一个中间缓冲区。你改完文件后,用git add把想提交的改动“挑”进暂存区。为什么要有这么个东西?因为一次改动可能涉及好几个文件,但你可能只想先提交其中一部分,暂存区就是让你精确控制“这次提交到底包含哪些改动”的地方。
  • 本地仓库(Local Repository)git commit之后,暂存区里的内容就被打包成一个永久的快照,存进本地仓库。这个仓库就在你项目目录下的.git文件夹里,是一个完整的、独立的历史记录库。

这三个区的流转关系是:工作区 →(git add)→ 暂存区 →(git commit)→ 本地仓库。反过来,git checkoutgit restore可以把仓库或暂存区的内容拉回工作区。搞懂这条链路,后面 80% 的命令你都能自己推导出它是干嘛的。

1.3 为什么是分布式,而不是集中式

早期的版本控制工具(比如 SVN)是集中式的:所有历史记录存在一台中央服务器上,你本地只有当前版本的文件。想提交?得联网。服务器挂了?大家都别干活了。想看历史?得从服务器拉。

Git 是分布式的,意味着你clone下来的那一刻,整个项目的完整历史就已经在你本地了。你可以在断网的情况下提交、查看历史、切换分支、对比差异,所有操作都是本地完成的。只有当你需要和别人同步时,才需要联网推送或拉取。

这个设计带来的好处是实打实的:我在高铁上改代码、提交,完全不受网络影响;服务器出问题也不影响我本地继续工作,等恢复了再推上去就行。代价是初次clone会比较慢(因为要下载全部历史),以及本地会占更多磁盘空间,但对现在的硬盘容量来说这根本不是事。

2. 安装与配置:把地基打牢

2.1 Windows 上安装 Git 的完整步骤

Windows 用户下载 Git 最稳妥的渠道是官网 git-scm.com,下载页会自动识别你的系统给出对应安装包。下载下来是一个.exe文件,双击运行。

安装过程中有一堆选项,新手最容易在这里犯迷糊。我挑几个关键的说说:

  • 选择默认编辑器:默认是 Vim,但如果你不熟悉 Vim 的操作(进去容易出来难),强烈建议改成 Notepad++ 或者 VS Code。这个编辑器是 Git 在你需要写提交信息时调用的,选一个你顺手的能省很多事。
  • 调整 PATH 环境变量:这一步选“Git from the command line and also from 3rd-party software”,这样你在 CMD、PowerShell、VS Code 的终端里都能直接用git命令。选错了的话,只有在 Git Bash 里才能用 git,会很别扭。
  • 换行符处理:选“Checkout Windows-style, commit Unix-style line endings”。Windows 和 Unix 的换行符不一样,这个选项让 Git 在检出时自动转成 Windows 格式、提交时转成 Unix 格式,能避免很多跨平台协作时的“整个文件都显示被修改了”的诡异问题。
  • 终端模拟器:选 MinTTY(默认),它比 Windows 自带的 CMD 好用得多,支持更好的颜色和字体。

装完之后,在任意文件夹右键,如果能看到“Git Bash Here”和“Open Git Bash here”,说明装好了。打开 Git Bash,敲git --version,能输出版本号就万事大吉。

2.2 装完必做的三项配置

很多人装完 Git 就直接开始用,结果第一次commit就报错说不知道你是谁。Git 需要知道每次提交是谁做的,所以装完第一件事就是配置身份。

git config --global user.name "你的名字" git config --global user.email "你的邮箱"

--global表示这是全局配置,对你这台电脑上所有仓库生效。如果你某个项目想用不同的身份,可以在那个项目目录下不加--global再配一次,项目级配置会覆盖全局配置。

第三项配置是设置默认分支名。Git 早期默认分支叫master,现在业界普遍改用main。为了避免每次新建仓库都要手动改名,可以提前设好:

git config --global init.defaultBranch main

配完之后用git config --list检查一下,能看到你刚设的三项就对了。这里有个小坑:user.name里如果带中文,在某些终端里可能显示乱码,建议用英文或者拼音,反正这只是个标识,不影响功能。

2.3 配置 Gitee 密钥:免密推送的正确姿势

每次推送都要输密码太烦,用 SSH 密钥可以免密。Gitee 和 GitHub 的配置逻辑一样,这里以 Gitee 为例。

第一步,生成密钥对。在 Git Bash 里执行:

ssh-keygen -t rsa -b 4096 -C "你的邮箱"

一路回车就行,它会默认在~/.ssh/目录下生成两个文件:id_rsa(私钥,绝对不能给别人)和id_rsa.pub(公钥,要贴到 Gitee 上去)。

第二步,查看公钥内容:

cat ~/.ssh/id_rsa.pub

把输出的那一整串(以ssh-rsa开头)复制下来。

第三步,登录 Gitee,进入“设置” → “SSH 公钥”,把刚才复制的内容粘贴进去,起个名字(比如“我的笔记本”),保存。

第四步,验证是否配置成功:

ssh -T git@gitee.com

如果看到类似“Hi xxx! You've successfully authenticated”的提示,就说明配好了。如果提示Permission denied (publickey),八成是公钥没贴对,或者你生成密钥时改了默认文件名导致 Git 找不到,检查一下~/.ssh/目录下有没有id_rsaid_rsa.pub

注意:私钥文件id_rsa千万不要发给任何人,也不要用微信、邮件传。它相当于你仓库的钥匙,泄露了别人就能以你的身份推送代码。

3. 日常使用:从 clone 到 push 的完整链路

3.1 拿到一个项目:clone 的正确打开方式

git clone是把远程仓库完整复制到本地的命令,包括所有历史记录和分支。

git clone git@gitee.com:用户名/仓库名.git

如果你用 HTTPS 地址(https://gitee.com/...),每次推送都要输账号密码;用 SSH 地址(git@gitee.com:...)则走密钥免密。所以配好密钥之后,建议统一用 SSH 地址。

clone 下来之后,进入项目目录,你会看到一个.git文件夹(默认隐藏)。这个文件夹就是本地仓库的本体,删了它项目就变成普通文件夹了,所有历史记录都没了。所以千万别手贱去删它。

有个常见报错:fatal: not a git repository (or any of the parent directories): .git。这个报错的意思是“当前目录及其父目录都找不到 .git 文件夹”,也就是说你不在一个 Git 仓库里。解决办法很简单:cd到正确的项目目录,或者确认你是不是忘了git init

3.2 改完代码怎么提交:add、commit 的配合

假设你改了两个文件:index.htmlstyle.css。现在想把它们提交上去。

第一步,看看当前状态:

git status

它会告诉你哪些文件被修改了、哪些是新增的、哪些已经进了暂存区。这个命令我建议你养成习惯,每次 add 和 commit 之前都敲一下,心里有数。

第二步,把改动加入暂存区:

git add index.html style.css

或者如果你确定所有改动都要提交,可以偷懒用git add .(注意后面有个点,表示当前目录下所有改动)。但我不太推荐无脑git add .,因为有时候你会改一些临时文件、调试代码,不小心就一起提交上去了。

第三步,提交:

git commit -m "修复首页轮播图不显示的问题"

-m后面跟的是提交信息。提交信息怎么写有讲究,我的习惯是用一句话说清楚“这次改了什么、为什么改”,不要写“更新”“修改”这种没信息量的词。因为三个月后你回头看历史,唯一能帮你回忆起来的就是这行字。

3.3 提交信息写错了怎么办:commit --amend 实战

这是被问得最多的问题之一:刚 commit 完,发现提交信息打错字了,或者漏加了一个文件,怎么办?

如果还没推送到远程,用git commit --amend就能补救。

改提交信息:

git commit --amend -m "新的提交信息"

漏加了文件:

git add 漏掉的文件 git commit --amend --no-edit

--no-edit表示沿用原来的提交信息,只把新加的文件合并进上一次提交。

这里有个关键点:--amend实际上是用一个新的提交替换掉上一个提交,提交的哈希值会变。所以如果上一次提交已经推送到远程了,你 amend 之后再推会被拒绝(因为本地和远程的历史不一致)。这时候要么用git push --force(危险,会覆盖远程历史,多人协作时慎用),要么就老老实实再提交一次。

实操心得:--amend只适合“还没推送”的场景。一旦推上去了,除非你确定这个分支只有你一个人在用,否则别 force push,容易把别人的工作覆盖掉。

3.4 推送到远程:push 与 pull 的节奏

本地提交完了,要同步到远程:

git push

如果是第一次推送这个分支,可能需要指定上游:

git push -u origin main

-u--set-upstream的简写,设置之后以后直接git push就行,不用每次指定远程和分支。

反过来,如果别人推了新代码,你要拉下来:

git pull

git pull实际上是git fetch(拉取远程最新)加git merge(合并到本地)两个操作的组合。我个人的习惯是先用git fetch看看远程有什么变化,确认没问题再git merge,这样更可控。直接git pull有时候会触发意料之外的合并冲突,尤其是在你本地有未提交改动的时候。

4. 那些让人头大的报错和疑难杂症

4.1 常见报错速查表

我把这些年遇到的高频报错整理成了一张表,遇到问题先对号入座:

报错信息原因解决办法
fatal: not a git repository当前目录不是 Git 仓库cd到项目目录,或git init初始化
Please tell me who you are没配置 user.name/user.email执行 2.2 节的两条 config 命令
Permission denied (publickey)SSH 密钥没配好检查公钥是否贴到平台、私钥是否存在
failed to push some refs远程有你本地没有的提交git pullgit push
Your local changes would be overwritten本地有未提交改动,pull 会覆盖先 commit 或 stash 再 pull
login failed. check api token认证信息过期或错误重新配置密钥或检查 token
detached HEAD处于游离头指针状态git switch -回到分支,或新建分支

4.2 密钥配置失败的排查思路

login failed. check api token or gitlab version这类报错,本质是认证没通过。排查顺序是这样的:

先确认你用的是 SSH 还是 HTTPS。如果是 HTTPS,那走的是账号密码或 token,跟 SSH 密钥没关系。很多人配了 SSH 密钥却用 HTTPS 地址 clone,然后奇怪为什么还要输密码,就是这个原因。

如果是 SSH,按这个顺序查:ssh -T git@gitee.com能不能通?不通的话,ssh -vT git@gitee.com-v看详细日志,它会告诉你用了哪个密钥文件、认证到哪一步失败了。常见原因是密钥文件权限不对(Linux/Mac 下~/.ssh应该是 700,私钥应该是 600),或者你生成密钥时自定义了文件名,但没在~/.ssh/config里配置对应关系。

还有一种情况是公司网络环境对 SSH 端口有限制,这时候可以改用 HTTPS 加 token 的方式。Gitee 和 GitHub 都支持在设置里生成个人访问令牌(token),用 token 代替密码进行 HTTPS 认证。

4.3 合并冲突:不要慌,一步步来

冲突是新手最怕的东西,但其实它没那么可怕。冲突的本质是:同一个文件的同一部分,你和别人改了不一样的内容,Git 不知道该听谁的,于是把决定权交给你。

冲突发生时,打开冲突文件,你会看到这样的标记:

<<<<<<< HEAD 你本地的代码 ======= 远程拉下来的代码 >>>>>>> branch-name

<<<<<<<=======之间是你本地的版本,=======>>>>>>>之间是远程的版本。你要做的就是手动决定保留哪个、删掉哪个,或者把两者融合。编辑完之后,把那些<<<<<<<=======>>>>>>>标记全部删掉,保存文件,然后git add这个文件,再git commit完成合并。

我的经验是,冲突文件多的时候,用 VS Code 这类编辑器打开,它会用颜色高亮冲突区域,还提供“保留当前”“保留传入”“两者都保留”的快捷按钮,比手动改快得多。

5. 进阶但实用的几个技巧

5.1 git worktree:同时处理多个分支

git worktree是我近两年用得越来越多的功能。场景是这样的:你正在feature-a分支上开发,突然线上出了个 bug 需要紧急修复。传统做法是git stash存一下当前改动,切到main修 bug,修完再切回来stash pop。但如果你当前改动很多、很杂,stash 来 stash 去很容易出错。

worktree的思路是:给同一个仓库开一个“平行工作目录”,每个目录可以检出不同的分支,互不干扰。

git worktree add ../hotfix main

这条命令会在当前目录的上一级创建一个叫hotfix的文件夹,里面检出main分支。你可以在那个文件夹里修 bug、提交、推送,完全不影响你当前目录里的工作。修完之后:

git worktree remove ../hotfix

就把那个工作目录删掉了。这个功能特别适合“手头活没干完又要紧急处理另一件事”的场景,比 stash 干净利落得多。

5.2 小乌龟(TortoiseGit):不想敲命令的替代方案

不是所有人都喜欢命令行。TortoiseGit(俗称“小乌龟”)是 Windows 上的一个 Git 图形化客户端,装完之后你的文件夹右键菜单里会多出一堆 Git 相关选项。

它的好处是直观:改了哪些文件、每个文件改了什么,都能在图形界面里看得清清楚楚;提交、拉取、推送都是点按钮;冲突了也有可视化的合并工具。对于刚入门、还没建立起命令行肌肉记忆的人来说,小乌龟能帮你快速理解 Git 的工作流。

但我的建议是:图形工具可以用,但命令行的核心操作(add、commit、push、pull、status、log)还是要会。因为一旦出问题,图形界面能给你的信息往往不够,还是得回到命令行看详细日志。而且很多服务器环境根本没有图形界面,只能敲命令。

5.3 IDEA 里怎么用 Git 提交代码

用 IDEA 开发的话,其实不太需要单独开终端敲 Git 命令,IDEA 内置了完整的 Git 集成。

提交代码的流程是:改完代码后,在左侧的 Commit 面板里能看到所有改动的文件。勾选你想提交的文件,在下方输入提交信息,点 Commit 就完成了本地提交。如果想直接推送到远程,点 Commit and Push。

IDEA 的 diff 视图很好用,双击文件就能看到左右对比,哪行改了、哪行删了一目了然。冲突的时候它也有三栏合并工具,比手动改文件舒服很多。

不过有个坑要注意:IDEA 默认可能不会自动git add新文件,你新建的文件需要手动勾选或者右键 Add 一下,否则提交的时候会漏掉。

6. 我踩过的坑和给你的建议

6.1 提交前一定要 git status

这个习惯能帮你避免 90% 的低级错误。我见过太多人git add .之后直接 commit,结果把.ideanode_modules、编译产物、甚至包含密码的配置文件一起提交上去了。这些东西一旦进了历史,清理起来非常麻烦。

正确的做法是在项目根目录放一个.gitignore文件,把不需要版本控制的东西写进去:

node_modules/ .idea/ *.log .env dist/

.gitignore要在项目初期就建好,等文件已经提交了再往.gitignore里加是没用的,Git 还是会继续跟踪那些文件。已经提交了的话,需要用git rm --cached 文件名把它从版本控制里移除(但保留本地文件),然后再提交一次。

6.2 提交粒度要小,信息要清楚

一次提交只做一件事。不要把“修复 bug”“重构代码”“调整格式”混在一个提交里。因为将来如果发现那个 bug 修复有问题想回退,你会把重构和格式调整也一起退掉,很麻烦。

提交信息我习惯用这样的格式:第一行是简短概括(不超过 50 字),空一行,然后详细说明改了什么、为什么改。虽然多写几个字,但将来查历史的时候你会感谢自己。

6.3 不要害怕犯错,Git 几乎什么都能救回来

新手最大的心理障碍是“怕把代码搞丢”。实际上 Git 的设计非常保守,只要你 commit 过的东西,基本都能找回来。git reflog记录了 HEAD 的所有移动历史,哪怕你误删了分支、reset 错了,都能通过 reflog 找到那个提交的哈希值,然后恢复。

真正会丢数据的只有两种情况:一是你改了文件但从来没 add 也没 commit,然后执行了会覆盖工作区的操作;二是你 force push 覆盖了远程历史,而本地又没有备份。除此之外,Git 都有办法救。

所以我的建议是:大胆用,多试。建个测试仓库随便折腾,把各种命令都试一遍,比看十篇教程都管用。Git 这东西,光看是学不会的,必须上手敲。

6.4 关于 git 目录泄露的提醒

最后提一个安全相关的点。有些项目在部署的时候,不小心把.git目录也一起传到了 Web 服务器上,导致别人可以通过浏览器访问你的域名/.git/config之类的路径,把整个仓库的源码和历史记录都下载下来。这是个很常见的安全疏漏。

防范方法很简单:部署的时候确保.git目录不在 Web 根目录下,或者在服务器配置里禁止访问以.git开头的路径。如果你用的是自动化部署工具,检查一下它的配置,确认没有把.git一起打包上传。这个坑一旦踩了,源码泄露是小事,如果历史提交里有过密码、密钥,那问题就大了。

我自己现在的习惯是,任何项目部署前都先确认一遍.git目录的位置,宁可多花两分钟检查,也不要事后补救。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询