搞版本管理这事,很多人第一次用 Git 的时候都挺懵的。命令行敲下去没反应、push 上去代码没了、合并分支冲突一大堆,这些我全经历过。后来用熟了才明白,Git 的基本操作其实就那么几个,只要把“提交、分支、推送、拉取”这条主线搞清楚,日常开发基本就够用了,剩下的都是遇到问题再查的高级玩法。
这篇东西不打算写成文档式的大而全,就按我实际用 Git 干活的经验来讲,从安装配置到常用命令,再把高频坑和解决方案一起放出来。适合刚接触 Git 的开发者,也适合用了一阵子但总感觉没吃透的朋友。看完你至少能独立把一个项目从零推到远程仓库,跟同事协作时不慌。
1. 环境安装与初始化配置:新机器上跑通 Git 的第一步
1.1 各平台安装与避坑细节
先解决“有没有 Git”的问题。Windows 用户直接去 Git 官网下载安装包就行,下载的时候认准 64-bit 版本。安装过程中有几个选项我建议你注意一下:
- 安装路径尽量不要带中文和空格,省得后面有些工具识别不了;
- 选择默认编辑器时,如果你不会 Vim,建议直接选 Notepad++ 或 VS Code,不然一不小心在终端里进了 Vim 界面,半天退不出来;
- “Adjusting your PATH environment”这一步,要选 “Git from the command line and also from 3rd-party software”,否则后面在终端里敲
git会提示找不到命令; - 换行符转换那个选项,Windows 用户选 “Checkout Windows-style, commit Unix-style line endings” 就好,这是最不容易出幺蛾子的方案。
macOS 用户就简单多了,装过 Homebrew 的话一条命令搞定:brew install git。没装 Homebrew 的,直接去官网下载 pkg 包安装也可以。Linux 用户更简单,apt install git 或者 yum install git,具体看发行版。
装完以后,打开终端(Windows 是 Git Bash 或 PowerShell),输入 git --version,能输出版本号就说明装好了。这一步卡住的话,99% 是 PATH 环境变量的问题,后面第 5 章会专门讲怎么处理。
1.2 装完必须做的第一轮配置
Git 装好后不是马上就能用,得先告诉它“你是谁”。这个身份信息会写进每一次提交里,以后查历史记录就知道某行代码是谁改的。
bash复制git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
--global 参数表示全局生效,也就是说这台机器上所有仓库都会用这个身份。如果你在某一个项目里有特殊需要,可以在那个项目目录下不用 --global 单独设置,这样就只对当前仓库生效。
另外建议顺手把默认分支名改成 main,因为现在新建仓库的主流做法是 main 而不是 master:
bash复制git config --global init.defaultBranch main
还有一个非常实用的配置是颜色显示,默认 Git 的输出从终端里看会非常费劲,打开颜色后文件状态、分支信息一目了然:
bash复制git config --global color.ui true
首次配置完,可以用 git config --list 检查一下所有配置项,确认 user.name 和 user.email 都正确。别小看这一步,我见过不少人提交完代码后才发现邮箱填错,历史记录里全是错误邮箱,后面想改非常麻烦。
1.3 远程认证:SSH Key 与 HTTPS 凭证
配置完身份,接下来要面对的是远程仓库的认证问题。现在主流平台(GitHub、GitLab、Gitee 等)都支持 HTTPS 和 SSH 两种方式。我个人的建议是:如果你主要用命令行,优先配 SSH,一次配置长期免密,比 HTTPS 每次输账号密码舒服太多。
生成 SSH Key 的命令:
bash复制ssh-keygen -t ed25519 -C "你的邮箱"
一路回车就行,默认路径在 ~/.ssh/id_ed25519。生成完以后,把公钥内容复制出来:
bash复制cat ~/.ssh/id_ed25519.pub
然后把这段公钥添加到你的 Git 平台账号里。GitHub 的话是 Settings → SSH and GPG keys → New SSH key,把复制的内容粘贴进去保存。添加完以后验证一下:
bash复制ssh -T git@github.com
如果看到 “Hi xxx! You've successfully authenticated” 之类的提示,就说明 SSH 认证已经通了。
如果你不想折腾 SSH,用 HTTPS 方式也完全没问题。首次 push 或 clone 的时候,Git 会弹窗让你输账号密码,选择记住凭证后,之后也不用重复输入。Windows 上 Git 自带的凭证管理器会自动帮你保存,macOS 上则走钥匙串。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 提交是 Git 的命根子:本地仓库核心操作
2.1 三个区与一次完整提交
理解 Git 的本地工作机制,最关键的是搞懂“三个区”的概念:工作区、暂存区、版本库。
工作区就是你电脑上能看到的项目文件夹,里面是你正在编辑的文件;暂存区是一个过渡区域,用来存放你准备提交的改动;版本库则是 Git 真正保存历史记录的地方。一次完整的提交,就是把工作区的改动先放到暂存区,再从暂存区写入版本库。
打个比方,工作区是你的办公桌,暂存区是整理好的文件筐,版本库是文件柜。你不可能每改一版就往文件柜里塞,通常是先在桌上改,改得差不多,挑挑拣拣放进文件筐,最后统一归档进柜子。
一次最基本的提交流程是这样的:
bash复制# 进入项目目录
cd my-project
# 初始化仓库(项目还没用 Git 管理时执行)
git init
# 查看仓库状态
git status
# 把文件加入暂存区
git add README.md
git add src/ # 也可以一次添加整个目录
# 提交到版本库
git commit -m "初始化项目,添加README和源码"
git init 只需要执行一次,它会在当前目录下创建一个隐藏的 .git 文件夹,里面装的就是 Git 的全部历史和管理信息。执行完后当前目录就变成了一个仓库。
git add 可以指定具体文件,也可以用 git add . 添加所有改动。但我建议新手少用 git add .,因为容易把不该提交的文件(比如编译产物、本地配置)也加进去。宁可多敲两下,也要让每次提交的内容是可控的。
2.2 状态与差异:git status 和 git diff 怎么看
git status 是我用得最多的命令,没有之一。每次提交前我都会执行一遍,看看当前仓库到底处于什么状态。
bash复制git status
输出结果分几种情况:
- 工作区干净:说明没有未提交的改动;
- Changes to be committed:说明有文件已暂存,等待提交;
- Changes not staged for commit:说明有文件已修改,但还没 add;
- Untracked files:说明有新文件还没被 Git 跟踪。
其中 Untracked files 值得特别说一句,这是新手的常见困惑点。新建的文件如果没执行过 git add,Git 默认是不管的,它不会自动出现在提交里。很多新手新建了一个文件,发现 commit 后远程仓库里没有这个文件,就是因为没先 add。
git diff 用来查看具体改了什么内容:
bash复制# 查看未暂存的改动
git diff
# 查看已暂存但还没提交的改动
git diff --cached
每次 commit 之前养成习惯,先用 git status 看状态,再用 git diff 看改动,确认没改错再提交。这能帮你省掉大量因为手滑误提交带来的麻烦。
2.3 删除、撤销与回滚:restore 和 reset 怎么用
用 Git 最大的安全感来自于“随时能反悔”。这里我把几个常用的撤销操作理一下。
撤销工作区的修改,也就是文件改了一半,想恢复到最近一次提交的状态:
bash复制git restore 文件名
这个命令会把你对文件的所有未暂存修改全部丢弃,且不可恢复。用之前一定想清楚,我一般会先跑一遍 git diff 再决定要不要执行。
把已暂存的内容撤回到工作区,也就是 git add 之后反悔了,不想提交这个文件:
bash复制git restore --staged 文件名
这个操作只把文件从暂存区移回工作区,文件本身的内容不会被修改。
回退提交记录,也就是 commit 之后发现提交错了,想回到之前的状态:
bash复制git reset --soft HEAD~1 # 撤销上一次提交,但保留改动
git reset --hard HEAD~1 # 撤销上一次提交,且丢弃所有改动
--soft 和 --hard 的区别非常大。--soft 相当于把提交记录回退一步,但是你的工作区改动还在,可以重新整理后再提交;--hard 会直接丢掉所有改动,包括工作区的修改,非常危险。
我的习惯是:只回退本地还没有推送过的提交,而且优先用 --soft。一旦提交已经 push 到远程,就不建议用 reset 了,老老实实用 git revert 来生成一个反向提交,这样协作时其他人的历史不会乱。
3. 多人协作流水线:clone、分支、push 与 pull
3.1 从远程仓库 clone 代码的正确方式
新同事入职、换电脑、接手别人的项目,第一件事通常就是把远程仓库的代码复制到本地,这个操作叫 clone。
bash复制git clone git@github.com:用户名/仓库名.git
执行完成后,当前目录下会多出一个以仓库名命名的文件夹,里面有完整的项目代码,同时 Git 会自动帮你关联好远程仓库地址,并把默认分支(一般叫 main)拉到本地。
clone 完成后的第一件事,我建议先执行 git branch -a 看一下所有分支,包括本地和远程的。然后根据项目情况切换到对应分支开发:
bash复制git branch -a
git checkout develop
很多 IDE 也支持直接在图形界面里 clone,比如 IntelliJ IDEA 可以选 File → New → Project from Version Control,粘贴仓库地址就能拉下来。命令行和图形界面各有各的好,后面第 4 章再细聊工具搭配的问题。
需要注意的一点是,clone 下来以后默认你在的分支是远程仓库的主分支。如果你想在另一个分支上开发,请先确保远程有那个分支,再 checkout 过去。如果直接 git checkout -b new-branch 从当前分支拉出新分支,那前提是你确实想基于当前状态开新分支。
3.2 分支管理与合并冲突处理
分支是 Git 协作的核心能力。你可以同时进行多个特性的开发,互不干扰,完成后再把代码合并回去。
常用分支操作:
bash复制# 查看分支
git branch
# 创建新分支
git branch feature/login
# 切换分支
git checkout feature/login
# 创建并切换
git checkout -b feature/login
# 合并分支
git merge feature/login
# 删除分支(已合并的)
git branch -d feature/login
合并操作是最容易出问题的地方,因为代码冲突几乎无法避免。所谓冲突,就是两个分支修改了同一个文件的同一行代码,Git 不知道该听谁的。
当合并提示 CONFLICT 时,不要慌。用 git status 查看冲突文件,打开文件你会看到类似这样的标记:
code复制<<<<<<< HEAD
当前分支的代码
=======
另一分支的代码
>>>>>>> feature/login
你需要做的就是手动编辑这些区域,保留正确的代码,删掉 <<<<<<<、=======、>>>>>>> 这些标记,然后重新 add 和 commit。
我处理冲突的经验是:不要只看冲突的那几行,最好把整个文件的上下文都看一遍,确认改动逻辑是完整的再提交。赶时间直接复制粘贴的一方代码,往往后续会出隐藏 bug。
3.3 推送拉取的日常节奏与注意事项
每天开发的循环无非就是:pull 最新代码 → 改代码 → commit → push。
git pull 是 git fetch 和 git merge 的组合,意思是先拉取远程最新代码,再合并到本地当前分支。如果在 pull 之前本地有未提交的改动,且这些改动与远程改动发生冲突,Git 会拒绝 pull 并提示你处理。
我个人的习惯是,每天坐下来写代码的第一件事就是 git pull,写完一段功能就 git commit 一次,确认可以上去了再 git push。提交要勤,但推送要等一个功能完整了再推,这样历史记录干净且方便回退。
首次 push 新分支时需要设置上游分支:
bash复制git push -u origin feature/login
-u 的作用是让本地分支和远程分支建立跟踪关系,之后在这个分支上直接敲 git push 或 git pull 就行,不需要每次加参数。
推送的时候如果提示 rejected,通常是因为远程仓库有本地没有的提交,需要先 pull 再 push。如果两个人的改动互不冲突,Git 会自动合并;有冲突就先解冲突,再推上去。
4. 效率工具箱:忽略规则、别名与 GUI 选择
4.1 .gitignore:哪些文件不该进仓库
每个项目都有一些文件是不该被 Git 管理的,比如编译产物、依赖包、本地配置文件、IDE 个人设置等。Git 提供了一种机制来忽略这些文件,就是在项目根目录放一个 .gitignore 文件。
常见的忽略规则:
gitignore复制# 编译产物
target/
dist/
build/
# 依赖目录
node_modules/
vendor/
# 个人IDE配置
.idea/
.vscode/
*.iml
# 日志和临时文件
*.log
.DS_Store
# 环境变量和密钥
.env
*.local
.gitignore 文件的写法其实不复杂,但有一个坑必须提醒你:如果你在写 .gitignore 之前已经用 git add 把某些文件加进来了,那么这些文件不会被忽略规则拦截,因为 Git 已经开始跟踪它们了。
解决办法是先移除已跟踪的文件,再重新提交:
bash复制git rm -r --cached 文件名或目录
--cached 表示只从 Git 的跟踪列表里移除,不会删除你本地的文件。这个操作处理完以后,再重新 commit,这些文件就不再被跟踪了。
4.2 配置别名与常用优化项
Git 命令虽然不难记,但高频命令敲多了也累。Git 支持给命令设置别名,这个功能我非常推荐,能明显提升日常操作效率。
bash复制# 配置别名
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.lg "log --oneline --graph --all --decorate"
配置完之后,git st 就等于 git status,git co 就等于 git checkout,git lg 能展示一个带分支图形和提交详情的日志视图,用来回顾项目历史特别好用。
还有一个优化项建议设置,就是让 pull 默认用 rebase 而不是 merge,这样可以避免很多没必要的 merge commit 把历史搞乱:
bash复制git config --global pull.rebase true
刚开始用默认 merge 也没毛病,但当你习惯了 rebase 这种线性历史的清爽感之后,就会觉得 merge commit 的图太乱了。
另外 git log --oneline --graph 这个组合命令我真的建议大家记下来,看历史记录比平铺的 log 直观太多了。嫌默认输出太长就配个 lg 别名,一劳永逸。
4.3 命令行还是 GUI:工具怎么搭配
很多人会纠结到底是用命令行还是图形界面。我的观点很简单:命令行为主,GUI 为辅。
命令行擅长的是精准操作,比如 git rebase -i 交互式改写历史、git reset 精确回退、git log 各种过滤查询,这些在命令行里效率最高。但命令行也有弱势,比如查看文件改动前后对比、浏览分支结构,图形界面确实更直观。
Windows 上曾经很流行的小乌龟(TortoiseGit)就是典型 GUI 工具,安装后会集成到右键菜单,文件状态、提交、更新都通过图标和菜单完成,完全不用记命令,适合纯初学者。但功能上跟命令行比还是有一些局限。
我自己常用的组合是:VS Code 的源代码管理面板看文件级改动,JetBrains 系列 IDE 内置的 Git 工具处理 diff 和冲突,遇到复杂的 rebase、reset、历史改写这类操作再用终端。如果电脑上有多个 IDE 项目,也可以在 IDE 里直接启用 Git GUI 中文界面,设置一下语言包就能用。
这个思路送给被命令行吓到的同学:你不一定非得背熟所有命令才能用 Git,先学会 GUI 里的提交和推送,再慢慢向命令行过渡,完全可行。
5. 高频问题与实战排查记录
5.1 “git 不是内部或外部命令”等环境问题
这个报错我看过太多次了,出现场景基本是:刚安装完 Git,然后在 PowerShell 或 CMD 里执行 git --version,系统提示“无法将‘git’项识别为 cmdlet、函数、脚本文件或可运行程序的名称”。
原因非常直接:Git 的安装目录没有被加入系统的 PATH 环境变量。安装时如果没选对选项,或者用的绿色版没有自动配置,就可能出现这种情况。
解决办法:右键“此电脑” → 属性 → 高级系统设置 → 环境变量 → 找到 Path → 编辑 → 新增一行,填入 Git 的 bin 目录路径,通常是 C:\Program Files\Git\bin。如果安装在其他盘,就填对应的路径。
配置完以后,关掉当前终端重新打开,再执行 git --version 验证。一般到这里就正常了。
另外有一个容易忽略的点:修改环境变量后,已经打开的终端窗口不会自动刷新,必须重新打开一个新终端窗口才生效。别问我为什么知道,问我就是在那原地等了十分钟那个老窗口一直不行。
5.2 fatal: not a git repository 排查思路
fatal: not a git repository (or any of the parent directories): .git 这个报错,核心含义是:当前目录或者它往上的所有父目录里,都不存在 .git 文件夹,所以 Git 不认为这是一个仓库。
新手最容易踩的坑是:在项目目录下 git init 以后创建了子文件夹,然后在子文件夹里执行 git status,照理说子目录也是仓库的一部分,应该没问题。但如果你是在初始化之前就在子目录里执行 Git 命令,那就会报这个错。
另一个常见场景是:用 git pull 或者 git push 时莫名报这个错,通常是因为当前工作目录根本不是仓库。用 pwd 看一下当前在哪个目录,确认是否真的在项目根目录或子目录里。
检查步骤:
bash复制pwd # 当前路径
ls -a # 看有没有 .git 目录
cd 到项目根目录 # 回到仓库根目录再执行
如果项目根目录确实有 .git,那就说明没有进错目录的问题。如果根本没有 .git,直接 git init 初始化一下就行。
5.3 免密登录与凭证管理
用 HTTPS 方式 clone 或 push 的时候,Git 老是提示输账号密码,特别影响效率。免密的实现路径其实有几种:
第一种是用 SSH Key。这也是我最推荐的方式,前面已经讲了如何生成和配置,配置完之后 push/pull 就不会再问账号密码了。
第二种是让 Git 记住 HTTPS 凭证。Git for Windows 自带 Git Credential Manager,一般安装时默认开启。如果你之前装的时候选了不启用,现在想补开,可以执行:
bash复制git config --global credential.helper manager
之后首次输一次账号密码,Git 会帮你存在 Windows 的凭证管理器中,之后就不需要重复输入了。
第三种是针对某些企业内部 GitLab 的场景,用带 token 的方式访问。有时候会出现类似 login failed. check api token or gitlab version 的报错。这种情况一般是 IDE 或第三方工具连接远程仓库时配置信息过期了,重新生成一个访问令牌(Personal Access Token),替换掉旧的配置信息即可。
我以前遇到过在 IDE 里 clone 公司 GitLab 仓库一直提示登录失败,密码怎么输都不对,后来才反应过来现在平台普遍要求用 token 代替密码,生成一个新的 token 填进去马上就能通。
5.4 更多典型错误速查
除了上面几个大问题,我整理了一些实际工作中经常遇到的问题,列个表方便对照。
| 报错或现象 | 原因 | 处理方式 |
|---|---|---|
Permission denied (publickey) |
SSH Key 未配置或未被平台识别 | 检查 ~/.ssh/id_ed25519.pub 是否已添加到平台 |
fatal: refuse to merge unrelated histories |
两个仓库没有共同的历史记录 | 确认确实要合并后加 --allow-unrelated-histories |
rejected - non-fast-forward |
远程有本地没有的提交 | 先 pull 再 push |
failed to push some refs |
权限不足或分支被保护 | 检查推送权限或换分支 |
LF will be replaced by CRLF |
换行符转换警告 | 保持默认处理即可,不用纠结 |
| 中文文件名乱码 | 编码设置问题 | 设置 git config --global core.quotepath false |
fatal: unable to access |
网络无法访问远程仓库 | 检查网络环境后重试 |
| 误删文件想恢复 | 还没有提交过的话恢复不了;提交过就 OK | git restore 文件名 恢复已提交的文件 |
再说一个安全提醒。如果你发现代码仓库里莫名其妙出现一个 .git 目录被部署到了服务器上,这意味着项目源码甚至历史版本可能被公开泄露。这类问题在安全圈子里叫“Git 目录泄露”。作为开发者,确保部署时不要把 .git 目录暴露到线上,打包忽略它或者配置层面直接禁止访问,这是最基本的安全素养。
5.5 一个实用的提交流程模板
最后分享一个我日常用的提交流程,当作参考。这个模板适合中小型项目的日常迭代:
bash复制# 1. 先拉取最新代码
git pull
# 2. 检查当前状态
git status
# 3. 把相关改动加入暂存区(按文件加,别一把梭)
git add src/xxx.py docs/xxx.md
# 4. 提交并写好说明
git commit -m "修复登录页按钮错位问题"
# 5. 推送
git push
提交信息我一般遵循这个规律:前缀表明类型,后面用简洁的话描述做了什么。比如 feat: 新增用户注册接口、fix: 修复订单金额计算错误、docs: 更新部署文档。这种风格现在团队里很通用,对后期翻历史记录非常有帮助。
我个人的体会是,Git 这东西不用急着把所有命令背完,先把提交、分支、推到远程这三个动作练到肌肉记忆,日常开发基本就够用了。剩下那些高级命令,都是遇到具体问题了再针对性查和学,反而记得更牢。刚开始用的时候,提交错了不要慌,回退命令就那么几个,乱敲之前记得先 git status 和 git diff 看清楚当下的状态。不用怕把仓库搞坏,等你哪一天能靠 git log --oneline --graph 从容回顾项目完整历史的时候,回头看就会发现,原来那些让新手头疼的操作,真的也就那么回事。
