前言:版本控制是程序员的必修课。Git 是当下绝对的主流,但 SVN 仍在大量传统企业和政府项目中服役。本文不讲废话,带你同时掌握 Git 和 SVN 的核心操作,并理解它们背后的设计哲学差异。
一、核心概念对比
在开始敲命令之前,先搞清楚两种版本控制系统的本质区别:
| 仓库位置 | 只有一台中央服务器存放完整版本库 | 每个人的本地都有完整版本库 |
| 历史记录 | 存储在中央服务器,本地只有工作副本 | 本地有完整历史,可离线查看所有日志 |
| 网络依赖 | 大部分操作(log/status/blame)需联网 | 除 push/pull/fetch 外全部离线操作 |
| 分支成本 | 分支 = 目录拷贝,成本高 | 分支 = 指针移动,成本极低 |
| 提交方式 | 提交即推送到服务器 | 本地先 commit,积累多次后再 push |
| 版本号 | 全局递增数字(r1, r2, r3…) | 40 位哈希值(如 a3f2b1c…) |
| 适用场景 | 企业内部、大型二进制文件、权限精细控制 | 开源项目、互联网团队、分布式协作 |
一句话定位:
-
SVN = 一个公共笔记本,所有人写在同一本上,随时能看到最新版本。
-
Git = 每人发一个笔记本各自写,写好了再互相抄(合并)。
二、Git 完整操作手册
2.1 安装与配置
# Linux (Ubuntu/Debian)
sudo apt install git
# Linux (CentOS/RHEL)
sudo yum install git
# macOS
brew install git
# Windows: 下载 Git for Windows (https://git-scm.com)
首次使用必须配置用户名和邮箱(每次提交都会记录):
git config –global user.name "Your Name"
git config –global user.email "your_email@example.com"
# 查看所有配置
git config –list
2.2 初始化与克隆
# 方式一:从零开始,初始化本地仓库
mkdir my_project && cd my_project
git init
# 方式二:从远程仓库克隆已有项目
git clone https://github.com/user/repo.git
git clone git@github.com:user/repo.git # SSH 方式
# 关联远程仓库(本地已有项目)
git remote add origin https://github.com/user/repo.git
git remote -v # 查看远程仓库
2.3 核心工作流(三板斧)
# 1. 查看状态
git status # 红色 = 已修改未暂存,绿色 = 已暂存
# 2. 查看具体改动
git diff # 工作区 vs 暂存区
git diff –staged # 暂存区 vs 最近一次提交
# 3. 添加到暂存区
git add file.txt # 添加单个文件
git add . # 添加所有改动(慎用)
git add -p # 交互式添加(推荐,可精细选择)
# 4. 提交到本地仓库
git commit -m "feat: 添加用户登录功能"
# 5. 推送到远程
git push origin main
git push -u origin main # 首次推送并建立关联
2.4 查看历史
# 查看提交历史
git log
git log –oneline # 简洁模式
git log –graph –oneline –all # 图形化显示所有分支
# 查看某次提交的具体改动
git show commit_hash
# 查看文件每一行的责任人
git blame file.txt
2.5 分支管理(Git 最强大的特性)
# 查看分支
git branch # 本地分支
git branch -a # 所有分支(含远程)
git branch -r # 远程分支
# 创建分支
git branch feature-login
# 切换分支
git checkout feature-login
git switch feature-login # 新命令,推荐
# 创建并切换(一步到位)
git checkout -b feature-login
git switch -c feature-login
# 合并分支(将 feature 合并到当前分支)
git merge feature-login
# 变基(保持线性历史)
git rebase main
# 删除分支
git branch -d feature-login # 已合并的
git branch -D feature-login # 强制删除(未合并)
2.6 撤销操作(后悔药大全)
# 场景1:撤销工作区的修改(还没 add)
git checkout — file.txt
git restore file.txt # 新命令,推荐
# 场景2:撤销暂存区(已经 add,还没 commit)
git reset HEAD file.txt
git restore –staged file.txt # 新命令
# 场景3:修改最近一次提交(漏了文件或写错注释)
git commit –amend -m "新的提交信息"
# 将漏加的文件追加到上一次提交
git add forgotten.txt
git commit –amend –no-edit
# 场景4:回退到某次提交(git log 找 hash)
git reset –soft commit_hash # 保留改动,只移动 HEAD
git reset –mixed commit_hash # 保留改动到工作区(默认)
git reset –hard commit_hash # ⚠️ 丢弃所有改动,慎用!
# 场景5:已 push 的提交如何撤回?
git revert commit_hash # 生成一个反向提交(推荐,不删历史)
git push origin main
2.7 远程同步
# 拉取远程更新(不合并)
git fetch origin
# 拉取并合并(等同于 fetch + merge)
git pull origin main
# 拉取并变基(保持历史整洁)
git pull –rebase origin main
# 推送到远程
git push origin main
# 删除远程分支
git push origin –delete feature-login
2.8 解决冲突
# 执行 merge 或 pull 后提示冲突
git merge feature-login
# CONFLICT in src/app.js
# 手动编辑冲突文件,删除 <<<<<<< ======= >>>>>>> 标记
# 标记已解决
git add src/app.js
git commit -m "merge: 解决与 feature-login 的冲突"
# 如果是变基过程中冲突
git rebase –continue # 解决后继续
git rebase –abort # 放弃变基
git rebase –skip # 跳过当前提交
2.9 暂存工作(Stash)
# 临时保存当前未提交的改动
git stash save "正在做登录功能,先切去修bug"
# 查看暂存列表
git stash list
# 恢复最近的暂存(并删除暂存记录)
git stash pop
# 恢复最近的暂存(不删除暂存记录)
git stash apply
# 删除指定暂存
git stash drop stash@{0}
2.10 标签(Tag)
# 创建轻量标签
git tag v1.0.0
# 创建附注标签(推荐)
git tag -a v1.0.0 -m "正式发布v1.0.0"
# 推送标签到远程
git push origin v1.0.0
git push origin –tags # 推送所有标签
# 删除标签
git tag -d v1.0.0
git push origin –delete v1.0.0
2.11 .gitignore(忽略文件)
# 创建 .gitignore 文件,常见内容:
node_modules/
vendor/
.env
*.class
*.log
.idea/
.vscode/
2.12 常用工作流总结
| 开始新功能 | git checkout -b feature-xxx main |
| 日常提交 | git add -p → git commit -m "xxx" |
| 同步上游 | git fetch origin → git rebase origin/main |
| 推送 | git push origin feature-xxx |
| 放弃所有本地改动 | git reset –hard HEAD |
| 找回误删的提交 | git reflog → git reset –hard commit_hash |
三、SVN 完整操作手册
3.1 安装
| Windows | 下载 TortoiseSVN(图形界面)+ 勾选 command line client tools |
| Ubuntu/Debian | sudo apt install subversion |
| CentOS/RHEL | sudo yum install subversion |
| macOS | brew install subversion |
验证安装:
svn –version
3.2 创建本地仓库(用于练习)
如果没有现成的 SVN 服务器,可以在本地创建:
# 1. 创建仓库目录
mkdir D:\\svn_work
# 2. 初始化仓库
svnadmin create D:\\svn_work\\repo
# 如果 svnadmin 找不到,用完整路径:
# "C:\\Program Files\\TortoiseSVN\\bin\\svnadmin.exe" create D:\\svn_work\\repo
执行后,D:\\svn_work\\repo 下会出现 conf、db、hooks 等子目录,这就是仓库了。
3.3 检出(Checkout)
# 命令行检出
svn checkout file:///D:/svn_work/repo D:\\svn_work\\work
# 或者进入目标目录后使用 .(点号)
cd D:\\svn_work\\work
svn checkout file:///D:/svn_work/repo .
⚠️ 常见坑:如果 svn status 报错 is not a working copy,说明检出位置不对,检查 .svn 隐藏文件夹是否存在于工作目录中。
3.4 日常操作
# 查看状态(M=已修改,A=新增,?=未跟踪,C=冲突)
svn status
# 更新(拉取别人提交的代码)
svn update
# 添加新文件
svn add file.txt
# 提交(直接到中央仓库)
svn commit -m "添加用户登录功能"
# 查看日志
svn log
svn log -l 10
# 查看差异
svn diff file.txt
svn diff -r 100:108 # 两个版本之间的差异
# 放弃本地修改
svn revert file.txt
svn revert -R . # 递归还原整个目录,慎用!
3.5 撤销已提交的修改
# 方法1:反向合并(推荐)
svn merge -c -1234 . # 回退版本号1234的提交(负号表示反向)
svn commit -m "回退版本1234"
# 方法2:更新到旧版本,提交为最新
svn update -r 1233
svn commit -m "回退到版本1233"
3.6 分支管理(SVN 分支 = 目录拷贝)
# 创建分支(在服务器上拷贝目录)
svn copy file:///D:/svn_work/repo \\
file:///D:/svn_work/repo/branches/feature-login \\
-m "创建登录功能分支"
# 切换分支
svn switch file:///D:/svn_work/repo/branches/feature-login
# 切换回主干
svn switch file:///D:/svn_work/repo/trunk
# 合并分支到主干(站在主干目录执行)
svn merge file:///D:/svn_work/repo/branches/feature-login
svn commit -m "合并 feature-login 分支"
# 删除分支
svn delete file:///D:/svn_work/repo/branches/feature-login -m "删除已合并分支"
3.7 解决冲突
# 更新时出现冲突(状态 C)
svn update
# 手动编辑冲突文件,删除 <<<<<<< .mine 等标记
# 标记冲突已解决
svn resolved file.txt
svn commit -m "解决冲突"
# 或快速选择一方
svn resolve –accept theirs-full file.txt
svn resolve –accept mine-full file.txt
3.8 忽略文件
# 设置忽略(修改目录的 svn:ignore 属性)
svn propedit svn:ignore .
# 每行一个忽略模式,如:
# node_modules/
# *.log
# .env
# 查看忽略设置
svn propget svn:ignore .
3.9 清理与恢复
# 清理工作副本(处理未完成的操作)
svn cleanup
# 查看文件每一行的责任人
svn blame file.txt
四、Git vs SVN 核心命令对照表
| 首次获取代码 | git clone <url> | svn checkout <url> |
| 获取最新代码 | git pull | svn update |
| 查看状态 | git status | svn status |
| 查看改动内容 | git diff | svn diff |
| 添加新文件 | git add | svn add |
| 删除文件 | git rm 后 commit | svn delete 后 commit |
| 提交 | git commit(本地)→ git push(远程) | svn commit(直接到中央) |
| 查看历史 | git log | svn log |
| 查看责任人 | git blame | svn blame |
| 放弃本地改动 | git restore file / git reset –hard | svn revert file |
| 回退已提交 | git revert / git reset | svn merge -c -版本号 |
| 创建分支 | git checkout -b branch | svn copy trunk branches/branch |
| 切换分支 | git switch branch | svn switch branch |
| 合并分支 | git merge branch | svn merge branches/branch |
| 创建标签 | git tag -a v1.0.0 -m "xxx" | svn copy trunk tags/v1.0.0 |
| 暂存未完成工作 | git stash | 无直接命令 |
| 清理工作副本 | 无(分布式无需清理) | svn cleanup |
五、选择建议
| 开源项目、互联网团队 | Git | 分布式协作、分支能力强 |
| 传统企业、政府项目 | 看团队 | 很多老项目还在用 SVN |
| 文件体积大(几十GB的美术资产) | SVN | Git 对大文件支持较差(需 LFS) |
| 对目录级别权限要求精细 | SVN | SVN 支持目录级精细权限控制 |
| 需要离线查看历史日志 | Git | SVN 需联网才能查 log |
| 新人上手、团队规模小 | Git | 虽然是分布式,但基本操作并不难 |
六、给学习者的建议
先在一台电脑上把命令敲一遍:理论看再多,不如动手实际操作一次。
理解本质再记命令:SVN 是集中式,Git 是分布式——理解了这个,很多设计就自然明白了。
遇到问题先看报错信息:大多数问题(如本文提到的 "is not a working copy")都指向了操作位置错误。
不要怕搞砸:本地仓库随便折腾,删了重建也就几分钟的事。
掌握 Git 是程序员的必备技能,但多学一个 SVN 也绝不会吃亏——毕竟你不知道下一家公司的老项目用的是不是 SVN





