Git这个东西,属于“用起来简单,用明白不简单”的典型工具。我见过太多人,装完Git、clone完仓库,就以为万事大吉,结果第一次跟别人协作就翻车:git push被拒、冲突不会解决、或者一不小心把本不该提交的文件推了上去。我自己也经历过从“背命令”到“真正理解Git在做什么”的转变,所以这篇“自用手册”不只是罗列命令,而是把我在实际开发中真正高频使用的场景、踩过的坑、以及为什么这样做的逻辑都整理出来。适合所有想系统掌握Git、而不是只停留在add/commit/push三步走的人。
1. 装好并跑通:从安装到完成第一次clone
1.1 各平台的安装方式和安装包选择
安装Git看似简单,但我在不同系统上都遇到过问题。Windows上,我建议直接去Git官网下载Git for Windows,那个绿色图标的安装包,一路Next基本能装好。需要注意的是安装过程中那几个比较关键的选项:
- 安装路径尽量别带中文和空格,我见过有人装在
D:\Program Files (x86)\Git,虽然也能用,但后面配SSH、配证书时偶尔会遇到路径解析问题。 - “Adjusting your PATH environment”这一步,默认选“Git from the command line and also from 3rd-party software”最省心,让
git命令可以在CMD和PowerShell里直接使用。 - 换行符转换建议选“Checkout as-is, commit as-is”,或者按默认的“Checkout Windows-style, commit Unix-style”也行。团队协作时这是个大坑,后面会细说。
macOS上有好几条路:安装了Xcode Command Line Tools的话,系统自带Git;用Homebrew跑brew install git也能装到较新的版本。个人推荐Homebrew方式,方便后续升级。Linux上用各发行版的包管理器就行,apt install git、yum install git,版本可能不是最新,但稳定够用。
如果官网下载速度很慢,可以找国内高校或云厂商维护的Git镜像站,不过装完后记得验证一下版本和来源。检查安装是否成功,打开终端输入:
bash复制git --version
能正常输出版本号,说明核心程序已经就绪。很多新手在Windows上装完,打开CMD输入git却提示“无法将git项识别为cmdlet、函数、脚本文件或可运行程序的名称”,这种“git不是内部或外部命令”的报错,本质上就是环境变量没配对,后面我会单独用一节讲排查方法。
1.2 安装后的全局身份配置与验证
安装完成后,第一步不是急着clone,而是先告诉Git“你是谁”。这一步很多人会跳过,导致提交记录里的作者信息是乱的,团队协作时完全没法追溯。配置方式很简单:
bash复制git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
为什么要设置?因为Git的每一次提交都会记录作者信息,这个信息会永久留在仓库历史里。不设置的话,Git根据系统主机名猜一个,或者干脆在提交时强制要求你补上,很麻烦。而且这个信息也会出现在你的提交上,代码评审、问题定位时全靠它。
可以用git config --list查看当前所有配置,确认是否设置成功。如果只想看某个单独的项,git config user.name即可。这里有个小建议:个人项目和公司项目如果用的邮箱不一样,可以不用--global,而是在具体仓库目录下单独配置,做到局部覆盖。
注意:现在很多代码托管平台把邮箱当作账号关联的重要依据。如果你不想暴露真实邮箱,可以在平台后台开启“隐藏邮箱”并生成一个类似
username@users.noreply.github.com的替代邮箱,设置到这个值就行。
1.3 clone一个仓库,理解三个核心区域
这是理解Git底层逻辑最关键的一步。Git操作的所有复杂性,都源于它有三个既独立又关联的区域:
- 工作区:你电脑上肉眼可见的文件夹,里面是实际的文件内容。
- 暂存区:可以理解为“预备提交区”,你
git add后文件会进入这里,但还没真正记录进仓库历史。 - 版本库:
.git目录里保存的完整历史记录,每个提交点都是仓库在某时刻的快照。
用生活化的类比:工作区是你的办公桌,暂存区是待发公文筐,版本库是档案室。你先在桌上把文件改好,放进公文筐,最后归档进档案室。每一次归档都记录了一个可回溯的版本。
用一个具体命令来把这三者串起来。从代码托管平台复制仓库地址后执行:
bash复制git clone https://github.com/你的用户名/你的仓库.git
执行完,Git会做三件事:把远程仓库的完整历史下载到本地版本库,把最新版本的文件检出到工作区,同时自动建立一个名为origin的远程仓库引用。这就是为什么clone之后你可以直接git log查历史、直接git checkout切分支。
我建议你clone完成后,进入目录执行一次git status,看到“Your branch is up to date with 'origin/main'”这种提示,说明本地和远程状态是同步的。这个“远程度量”的概念贯穿后续所有操作,理解它,你就能理解push和pull的本质了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 每天都会用到的高频命令
2.1 本地提交链路:status → add → commit → reset
日常开发最核心的循环就四个命令:git status、git add、git commit、git reset。看似简单,但我见过不少人把add和commit混为一谈。
先养成一个习惯:每次准备提交前,先git status。它会告诉你当前工作区有哪些已修改文件(modified)、哪些新文件未被跟踪(untracked)、哪些已暂存等待提交(staged)。这些状态是理解Git的基础,看到Changes not staged for commit,意思就是文件改过了但还没执行git add。
git add的作用是把文件从工作区放入暂存区。常用写法:
bash复制git add . # 添加当前目录下所有改动
git add src/App.js # 添加指定文件
git add src/components/ # 添加指定目录
git add -p # 交互式选择要暂存哪些改动片段
我强烈推荐大家养成用git add -p的习惯,尤其是在大型项目里。它能让你逐个代码块决定是否暂存,避免把调试代码和正式改动混在一起提交。虽然一开始觉得麻烦,但代码评审时你会感谢自己。
提交命令:
bash复制git commit -m "feat: 添加用户登录功能"
这个-m后面跟的就是提交说明。如果不带-m,Git会打开默认文本编辑器让你写多行提交信息。这里有个坑:Windows上默认可能是Vim,很多人进去后不知道怎么保存退出。可以把默认编辑器改成VS Code:
bash复制git config --global core.editor "code --wait"
git commit -am是add和commit的合并写法,但它只对已经被Git跟踪的文件生效,新文件不行。想偷懒前先搞清楚这个边界。
提交后发现写错了或漏了文件,用git reset回退。三种模式区别很大:
| 模式 | 作用范围 | 逻辑 |
|---|---|---|
--soft |
仅移动HEAD指针 | 撤销commit,但保留暂存区内容,相当于提交没发生但文件已在暂存区 |
--mixed(默认) |
移动HEAD并重置暂存区 | 撤销commit和add,但保留工作区修改 |
--hard |
完全丢弃所有修改 | 撤销提交、暂存、工作区修改,永久不可恢复 |
git reset --hard是危险操作,执行前务必确认你不需要那些改动了。我一般只在确定要丢弃本地所有脏改动时才用它。
2.2 分支操作与合并
分支是Git的精髓,也是很多初学者最晕的地方。它的本质就是一个可移动的指针,指向某次提交。创建新分支的开销几乎为零,所以Git才鼓励“多用分支,大胆实验”。
bash复制git branch feature-login # 创建分支
git checkout feature-login # 切换分支
git switch feature-login # 新版推荐,语义更清晰
git switch -c feature-login # 创建并切换
我个人现在都习惯用git switch和git restore,这对命令从Git 2.23开始引入,职责划分更清楚:switch只管切分支,restore只管恢复文件,不像老式的checkout什么都能干但语义混乱。
合并分支时,merge和rebase是两条路线,见仁见智。我的原则是:
- 公共分支(如main、develop)多用
merge,因为会保留完整的合并历史,便于回溯“这个功能是什么时候合进来的”。 - 个人feature分支同步上游更新时用
rebase,能让自己的提交干净地排列在最新代码之后,避免无意义的“merge commit”。
merge和rebase的关键区别:
| 维度 | merge | rebase |
|---|---|---|
| 历史形态 | 分叉后汇合,保留两个分支的先后顺序 | 线性化,把当前分支的提交“搬”到目标分支最新提交之后 |
| 冲突概率 | 如果同一文件改动大,同样会冲突 | 可能每个提交都触发冲突,处理起来更痛苦 |
| 安全性 | 相对安全,不改写任何已有的提交 | 会改写提交哈希,禁止对已推送的公共分支使用 |
冲突解决是躲不过的一关。当Git提示“CONFLICT”时,打开冲突文件,里面会有类似这样的标记:
code复制<<<<<<< HEAD
这里是当前分支的内容
=======
这里是另一分支的内容
>>>>>>> feature-login
你需要手动决定保留哪一部分、怎么合并,然后把冲突标记清理干净,保存文件后执行git add,再git commit。这里有个实用技巧:在VS Code里装个GitLens插件,冲突标记会被高亮成红绿两色,还有按钮可以直接“采纳当前修改”“采纳传入修改”或“合并两者”,比手撕标记舒服很多。
2.3 与远程仓库交互:push、pull与fetch
本地操作只是单机版,跟远程交互才是团队协作的开始。git push把本地提交推送到远程,git pull把远程新提交拉下来合并到本地。
bash复制git push origin feature-login
git pull origin feature-login
pull本质上等于fetch + merge。fetch只把远程新提交下载到本地,但不改变你当前的工作区状态;pull则会把下载的内容直接合并到当前分支。所以我有时候会用git fetch先看看远程有什么变化,再用git log origin/main..比较一下差异,确认无误后才决定是merge还是rebase。
关于--force,这是最危险的一个旗标。它用于在push时强行覆盖远程历史,通常和rebase配套使用。但如果你把已经push过的分支做了rebase然后--force推送,而同事已经基于旧版本做开发,他的历史就会错乱。现代Git引入--force-with-lease来缓解这个问题,它只在远程引用仍然是你上次拉取的位置时才执行强制覆盖,比裸--force安全得多。
提醒:不要在公共分支上使用
git push --force。如果确实需要修正已推送的提交,优先使用git revert生成一个反向提交,虽然历史里多一条记录,但所有协作者都会安全同步这个变化。
2.4 查看历史与差异
git log是理解项目演进的核心命令。裸的git log信息太密,我惯用的组合是:
bash复制git log --oneline --graph --all --decorate
它会把提交历史渲染成一条ASCII图,每个点旁边标注分支标签和HEAD位置,一眼看清项目全貌。可以给这条命令起个别名,省得每次敲一长串:
bash复制git config --global alias.tree "log --oneline --graph --all --decorate"
之后就只要敲git tree了。
git diff用于查看未暂存的改动,git diff --staged查看已暂存但未提交的改动。这两个命令是提交前自检的好帮手。我一般提交前必跑一次git diff --staged,确认没有把调试语句、临时配置、敏感信息带进提交。配合IDE里逐行高亮的diff视图,可以快速发现问题。
3. 免密登录与多账号管理
3.1 HTTPS凭据缓存 vs SSH Key
每次push都输密码是个让人抓狂的体验。Git提供两种免密方案:HTTPS凭据缓存和SSH Key认证。
HTTPS方式是让Git把账号密码交给系统的凭据管理器保存。Windows上安装Git for Windows时勾选“Git Credential Manager”,macOS上默认用钥匙串,Linux上可以配置libsecret或store。首次push时输一次密码,之后Git自动从凭据管理器读取。优点是配置简单,缺点是有些平台要求使用访问令牌而不是账号密码,仍需准备token。
SSH Key是更“程序员”的解法。生成的密钥分成一对:私钥留在本地,公钥上传到代码托管平台。之后所有Git操作通过SSH协议完成,不需要每次输密码,安全性也比密码或token高。生成方式:
bash复制ssh-keygen -t ed25519 -C "你的邮箱"
一路回车生成在~/.ssh/id_ed25519,然后把.pub文件内容添加到GitHub/GitLab/Gitee的SSH Keys设置页。验证是否配置成功:
bash复制ssh -T git@github.com
看到“Hi username! You've successfully authenticated”就是成功了。
两种方式对比:
| 维度 | HTTPS + 凭据缓存 | SSH Key |
|---|---|---|
| 首次配置 | 输账号密码或token | 生成密钥并上传公钥 |
| 后续体验 | 系统自动管理凭据 | 完全免密 |
| 安全性 | 凭据存在本地,依赖系统保护 | 私钥存本地,公钥存服务端 |
| 多平台使用 | 每个平台各有一套凭据 | 可配置多个key对应不同平台 |
| 适合场景 | 个人项目、图省事 | 团队协作、长期使用、服务器部署 |
3.2 多账号的SSH配置
现实中我们经常同时使用GitHub个人账号和公司GitLab账号,如果只有一套SSH Key,会出现冲突。解决办法是配置~/.ssh/config文件,让不同域名走不同的私钥。
我个人的配置长这样:
code复制# GitHub个人项目
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_github
# 公司GitLab
Host gitlab.company.com
HostName gitlab.company.com
User git
IdentityFile ~/.ssh/id_ed25519_company
先生成两套密钥,分别上传到两个平台。然后clone时用对应的域名,Git会自动选择正确的私钥:
bash复制git clone git@github.com:yourname/project.git
git clone git@gitlab.company.com:yourname/project.git
注意仓库的remote地址要写清楚了。如果之前用的是HTTPS地址,可以用git remote set-url改成SSH格式。多账号排查问题时,ssh -T git@github.com和ssh -T git@gitlab.company.com分别测试,能准确告诉你当前生效的是哪个账号。
4. 提交规范与团队协作要点
4.1 commit message规范
“提交信息随便写”是我见过最普遍的技术债之一。git log翻出来全是“update”“fix”“修改”,一点检索价值都没有。好的提交信息应该做到:让三个月后的自己和同事,不用看代码就能明白这次提交做了什么、为什么做。
目前社区最流行的是Conventional Commits规范,格式为:
text复制<type>(<scope>): <subject>
常见type:
| type | 含义 | 示例 |
|---|---|---|
| feat | 新功能 | feat: 添加用户注册页面 |
| fix | 修复bug | fix: 修复登录后token失效问题 |
| docs | 仅文档修改 | docs: 更新README部署说明 |
| style | 格式调整,不影响逻辑 | style: 格式化代码,统一缩进 |
| refactor | 重构,不修复bug也不加功能 | refactor: 抽取公共请求封装 |
| perf | 性能优化 | perf: 优化大列表渲染速度 |
| test | 增加或调整测试 | test: 补全支付接口单元测试 |
| chore | 构建过程或辅助工具变动 | chore: 升级webpack至v5 |
如果提交涉及破坏性变更,加!或者写BREAKING CHANGE:说明。这个规范配合git log --oneline,一行就能看出项目演进脉络。
4.2 分支协作模型与code review
团队协作不是人手一个main分支直接提交,而是有一个约定俗成的分支模型。最常用的是Git Flow的简化版:
main:始终保持可发布状态,所有提交历史清晰可追溯。develop:日常集成分支,功能分支合到这里。feature/*:新功能开发分支,从develop切出,完成后再合回。hotfix/*:紧急修复分支,从main切出,修完同时合回main和develop。
开发流程大致是:创建feature/xxx分支 → 写代码提交 → push到远端 → 提交Merge Request(或Pull Request)→ 代码评审通过后合入develop → 发版时把develop合入main。
code review这一步价值巨大。它不仅是检查错误,更是知识共享的通道。提交MR前先在本地用git diff自检一遍,看有没有遗留的console.log、调试代码、硬编码的密钥,检查自己是否合理地拆分成了多个提交。MR描述里写明需求背景、改动清单、测试方法,评审人看起来不费劲,也能减少无谓的对话成本。
4.3 提交前的检查清单与.gitignore
提交前花30秒做一遍自检,能避免绝大多数事故:
git status确认没有多余文件,特别是密钥、日志、临时文件。git diff检查改动内容,确认没有误改或调试残留。- 确认提交信息符合规范,写明前置操作和影响范围。
- 如果涉及依赖变化,确认
package-lock.json或requirements.txt一并提交。
排除不需要纳入版本控制的文件,靠的是.gitignore。这个文件放在仓库根目录,每行写一条匹配规则。我见过太多人把node_modules、dist、.env、__pycache__这些目录塞进仓库,既污染历史又带来安全隐患。从项目一开始就建好.gitignore,比事后清理舒服得多。GitHub创建仓库时默认生成的一堆模板就够用,也可以参考gitignore.io按需生成。
5. GUI工具:小乌龟、VSCode与Git Graph
5.1 TortoiseGit安装与核心使用场景
很多Windows用户喜欢Sourcetree,但“小乌龟”在国内社区的特有存在感说明它是很多人熟悉的工具。它最大的优势是深度集成Windows资源管理器,不打开任何IDE就能右键操作Git。提交时能看每一行diff,日志界面能直观看出分支分叉与合并关系,冲突解决时也有图形化的合并向导。
安装小乌龟前必须先装好Git for Windows,否则它找不到底层命令,然后下载和系统位数匹配的安装包和语言包。安装完后,在文件夹右键就能看到“Git 提交”“Git 同步”“Git 显示日志”等菜单项。第一次用的时候,把小乌龟的“设置 → 常规 → Git可执行文件路径”确认一下指向正确的git.exe。
我对小乌龟的评价是:低门槛、高可视化、适合偏好界面操作的Windows开发者,以及需要快速查看diff、历史树、特定文件修改轨迹的场景。但它远程操作(如MR、PR)能力弱,那些还得回到网页端。
5.2 VSCode内置Git与Git Graph
VSCode已经成为很多人的主战场,它的内置Git支持足够覆盖日常需求。左侧源代码管理面板能看到所有改动文件,点击文件右侧就能打开diff编辑器逐行查看。提交信息可以在输入框写好,Ctrl+Enter直接提交,甚至能一行行暂存改动。
装一个Git Graph插件,左侧会渲染出完整的提交图谱,分支、合并、标签、HEAD一目了然。用它来清理混乱的本地分支很实用:看看哪些分支已经合并进主分支,果断删掉,保持本地仓库整洁。
另外,VSCode底部状态栏会显示当前分支名和同步状态。点右下角的同步按钮,本质上是先pull再push。很多人问“cursor哪里查看绑定git”,Cursor和VSCode一样,在源代码管理面板右上角的“...”菜单里选“远程”就能查看当前工作区关联的是哪个仓库、哪些remote地址,想换仓库直接git remote set-url改地址。
5.3 命令行与GUI工具的合理分工
我的习惯是:查看类操作用GUI(日志、diff、图谱),操作类命令用命令行(分支、远程、提交)。GUI适合浏览,它把复杂关系图形化,但真到了批量重命名分支、交互式变基、精细的git add -p这些场景,命令行效率明显碾压鼠标。两者不是取代关系,而是互补。
6. 常见报错排查实录
6.1 “git 不是内部或外部命令”可能不是安装问题
这是国内开发者遇到的第一道坎。在Windows的CMD或PowerShell里输入git,返回:
text复制git : 无法将“git”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
大概率是环境变量PATH缺失或顺序不对。排查路径:
- 安装时确认勾选了“Add Git to PATH”的相应选项。
- 手动验证:先找到
git.exe实际位置,默认一般在C:\Program Files\Git\bin\git.exe或cmd\git.exe。 - 打开“系统环境变量 → 编辑PATH → 新增”这两个路径。
- 保存后重新打开终端再试
git --version。
如果PATH没问题还报错,检查是不是下成了与系统位数不匹配的安装包。64位系统装32位版本也能用,但有时会出奇奇怪怪的问题,卸载重装64位版往往能解决。
6.2 证书错误:error setting certificate file
这个报错信息很有辨识度。实际遇到过:
text复制fatal: unable to access '...': error setting certificate file: d:/git/mingw64/etc/ssl/certs/ca-bundle.crt
核心原因是Git在加载CA证书文件时找不到或路径不对。常见场景是:安装目录移动过、公司网络有SSL拦截、或者某些代理工具注入了不信任的证书。排查路径:
- 确认证书文件是否存在。默认路径是Git安装目录下的
mingw64/etc/ssl/certs/ca-bundle.crt。 - 检查全局配置:
git config --global http.sslCAInfo,如果指向了不存在的路径,清掉它。 - 如果是公司内网或代理环境,需要把企业根证书追加到ca-bundle文件末尾。
- 临时验证手段:
git config --global http.sslVerify false。这能绕过问题确认是不是证书导致,但不建议长期关闭,等于放弃HTTPS的加密验证,存在安全风险,只适合定位问题的临时操作。
6.3 认证失败:Unable to access、Login failed
远程操作时报的认证类错误五花八门。比较典型的有:
Unable to access ... Could not resolve host:通常网络不通,或DNS解析不了内网域名,先ping域名看看。Login failed. check api token or gitlab version. log in via git if the version...:这是GitLab相关工具的报错,重点检查API Token是否过期、权限是否足够,以及GitLab版本是否兼容。Authentication failed for 'https://...':用户名密码错误,或平台要求使用访问令牌,而你在用账号密码。
排查这类问题的顺序我总结为:先网络,再认证,后版本。先确认能访问仓库域名,再用git ls-remote <repo-url>测试认证是否通过,最后检查本地配置的账号、token、远端地址是否有误。用git remote -v查看当前远端地址,经常能发现是地址里的用户名写错了这种低级问题。
6.4 .git目录泄露与服务器安全
看到一个热搜词“git目录泄露如何下载”,这其实是网络安全领域常提的一类风险。很多开发者把项目部署到服务器时,习惯直接把整个仓库文件传上去,结果/.git/目录也暴露在Web服务中。攻击者通过特定工具可以将.git目录内的压缩对象拉取下来,重建整个源码历史,危害极大。
作为开发者的正确做法,从源头杜绝这个问题:
- 部署时用构建产物或打包发布,不要把
.git目录一起带上服务器。 - 如果必须保留仓库在服务器上,Web服务器配置里显式禁止访问
.git路径。Nginx可以加location ~ /\.git { deny all; },Apache则用Require all denied或RedirectMatch处理。 - 检查线上站点时用
curl或浏览器访问https://你的站点/.git/config,如果返回内容而不是403或404,说明已经泄露,需要立即处理。
Git目录泄露更多是运维部署层面的安全意识问题,但它直接关系到源码安全。我建议每个用Git的人都要知道这个风险,别等到出了事才后悔。
回到Git本身,我个人的体会是:工具熟练度是积累出来的,但关键是理解它背后的模型。分支只是指针,提交是快照,远程仓库是团队协作的中枢,这些概念想透了,命令自然就能顺手。遇到问题先看状态,再想怎么解决,动手前多确认一下目标分支,能少走很多弯路。这本“自用手册”里写的是我踩过的坑和沉淀下来的方法论,希望能帮你把Git用得比之前更顺一些。
