TortoiseGit 是 TortoiseSVN 的同胞兄弟,界面风格、右键菜单的位置、设置对话框的组织方式几乎一模一样。正因为长得像,从 SVN 转过来的第一周最容易出事——它们看着像同一套工具,底下的模型却完全不同。
最典型的一次翻车是这样的:改完代码,右键 → Git Commit,填了日志点确定,界面报提交成功。然后同事说「你昨天那个提交我没看到」。因为 Git 的 Commit 只写到本地仓库,根本没碰服务器,还得再点一次 Push 才上去。TortoiseSVN 的 Commit 是直接提交到服务器,这个直觉在 TortoiseGit 上是错的。
这篇按「装 → 配 → 日常操作 → 避坑」的顺序捋一遍,重点放在 TortoiseGit 特有的那几处:SSH 密钥的两套体系、Win11 的右键菜单折叠、以及三个名字相近但语义完全不同的回退操作。
一、先分清模型:本地提交 vs 服务端提交
这是所有困惑的根源,先把这张对照表记住,后面看菜单才不会迷路:
| 你想做的事 | TortoiseSVN 里的操作 | TortoiseGit 里的操作 |
|---|---|---|
| 把改动送上去 | Commit(一次到位) | Commit + Push(两步) |
| 把别人的改动拿下来 | Update | Pull(取回并合并)/ Fetch(只取回不合并) |
| 看历史 | Show log(要联网或读缓存,别人刚提交的看不到) | Show log(读本地库,秒开、离线可用;但看不到你还没 fetch 的新提交) |
| 建分支/标签 | Branch/Tag(服务端复制,瞬间完成) | Create Branch / Create Tag(本地创建,推不推由你决定) |
| 切换分支 | Switch(换 URL) | Switch/Checkout(换本地分支的检出对象) |
两条推论值得单独强调:
- Push 是有「出口」的动作,其他操作都是本地的。 Commit、Branch、Reset、Revert 全都只动你机器上的
.git目录,做错了基本都能救回来;只有 Push(以及 Fetch/Pull 之外的上行操作)会把东西发到服务器,Force Push 更是能覆盖掉别人的提交。在做任何「推送」相关操作之前停顿一秒,是使用 Git 最重要的习惯。 - Fetch 和 Pull 的关系要理清。 Fetch 只把服务器的更新取到本地(更新远程分支指针),不改你的工作区;Pull 等于 Fetch + 合并进当前分支。不确定远程改了什么的时候,先 Fetch 再在 Show log 里看一眼,比直接 Pull 稳当。TortoiseGit 的 Sync 对话框把 Pull 和 Push 放在一个窗口里,是日常最常用的入口。
二、安装:TortoiseGit 不含 Git,必须单独装
当前稳定版 TortoiseGit 是 2.19.x,提供 32 位、64 位、ARM64 三种安装包(64 位系统只装 64 位包即可,32 位的 shell 扩展已经打包在 64 位安装程序里)。系统要求:
| 项目 | 要求 |
|---|---|
| 操作系统 | Windows 10 1607 及以上 |
| 老系统对应版本 | Windows 7 SP1 → 2.17.0;Vista SP2 → 2.4.0;XP → 1.8.16.0 |
| 运行库 | Microsoft Visual C++ Redistributable 2015–2022;x64 系统上为了 32 位程序的右键菜单还需要 x86 版本 |
| Git | Git for Windows 2.24+,必须单独安装 |
| 权限 | 安装需要管理员权限 |
关键点:TortoiseGit 只是一套图形外壳,它自己不包含 git.exe,所有实际工作都是调用命令行的 Git 完成的。所以装完 TortoiseGit 如果不去装 Git for Windows,右键菜单点了会报错找不到 git。
官方 FAQ 给的推荐顺序是先装 TortoiseGit、再装 Git for Windows,理由是让 Git for Windows 的安装程序被 TortoiseGit 感知到。实际两种顺序都能工作,真正决定成败的是 TortoiseGit 能不能定位到 git.exe——装完在 Settings → General → git.exe Path 里确认路径(一般指向 C:\Program Files\Git\bin,注意不是 cmd 目录),点 Check now 能显示出 Git 版本号就算通了。
Git for Windows 安装向导里选什么
FAQ 说预选(默认)选项即可,可以跳过「Windows Explorer integration」(那是 Git 自带的右键菜单,和 TortoiseGit 重复,装了会让右键菜单出现两套)。
有一个选项值得停下来想一下:换行符处理。默认是「Checkout Windows-style, commit Unix-style」(等价 core.autocrlf=true),官方 FAQ 反而建议选 Checkout as-is, commit as-is(不做任何转换),前提是你清楚换行符这回事并且编辑器用对了。这两种选法各有拥趸,唯一不能接受的是团队里不一致——那会让 diff 里全是假的改动。稳妥的做法是选默认,然后在仓库里放一个 .gitattributes 把它钉死(见第五节)。
装完右键菜单里找不到 Git
两种情况,先分清是哪一种:
- Windows 11 上菜单被折叠了。 Win11 的新版右键菜单只放常用项,shell 扩展都被挪进了「显示更多选项」(快捷键 Shift+F10)。这不是没装上,翻进去就能看到完整的 TortoiseGit 菜单。
- shell 扩展没加载。 装完要重启资源管理器或重启机器;确认在跑的是
TGitCache.exe(TortoiseGit 的状态缓存进程,图标覆盖靠它算)。
图标覆盖:和 TortoiseSVN 抢同一批槽位
图标覆盖不显示的原因和 TortoiseSVN 那篇里写的完全一样——Windows 一共只认 15 个覆盖图标,其中 4 个被系统预留,第三方只能用 11 个,且按注册表键名的 ASCII 顺序取前 11 个。TortoiseGit 官方 FAQ 也确认了这一点,并说明 TortoiseGit 和 TortoiseSVN 都刻意限制自己占用的槽位数(做个「好公民」)。
麻烦的是这两个工具用的是同一套机制。如果同时装了 TortoiseSVN 和 TortoiseGit,再加上 OneDrive、网盘客户端,11 个槽位很容易不够用,表现出来就是「装了 TortoiseGit 但 SVN 的图标消失了」或者反过来。
处理顺序:TortoiseGit → Settings → Icon Overlays → Overlay Handlers,把不用的覆盖状态取消勾选并应用(这个动作会重排它的注册表键);数量还是不够再考虑清理别的软件。TortoiseSVN 和 TortoiseGit 各自只保留你在用的那几种状态,是两者共存时最省事的做法。
三、SSH 密钥:两套体系,别混着用
这是 TortoiseGit 上最容易卡住新人的地方,根源在于它有两条互不相通的 SSH 路线:
| OpenSSH(ssh.exe) | TortoiseGitPlink(PuTTY 系) | |
|---|---|---|
| 谁是默认 | 否 | 是,TortoiseGit 默认用它 |
| 认的密钥格式 | ssh-keygen 生成的 id_rsa / id_ed25519 | 只认 .ppk,不认 id_rsa |
读 ~/.ssh/config | 是 | 否,配置存在 Windows 注册表里 |
| 密钥代理 | ssh-agent | Pageant(必须常驻后台) |
| 和命令行 Git | 完全一致,一套密钥走天下 | 不一致,命令行那边还得另配 |
大多数人踩的坑是:用 ssh-keygen 生成了 id_rsa,命令行 git clone 一切正常,换到 TortoiseGit 就报 No supported authentication methods available——因为默认的 TortoiseGitPlink 根本读不懂 OpenSSH 格式的私钥。
推荐:直接换成 OpenSSH
如果你已经在用命令行 Git,最省事的做法是让 TortoiseGit 也用同一套:
- TortoiseGit → Settings → Network
- 把 SSH Client 填成 Git 自带的 ssh:
C:\Program Files\Git\usr\bin\ssh.exe - 应用即可。之后它会自动去
~/.ssh找id_rsa,并读取标准的~/.ssh/config
改成 OpenSSH 之后还有一个额外好处:~/.ssh/config 里的高级写法全都生效了。国内网络访问 GitHub 时很实用的一个配置——把 22 端口换成 443:
Host github.com
HostName ssh.github.com
User git
Port 443
IdentityFile ~/.ssh/id_rsa
IdentitiesOnly yes
这样写还有一个副作用值得注意:用 OpenSSH 之后就不要再指望 .ppk + Pageant 的组合了,它读不了 PuTTY 的密钥和会话。
另一条路:沿用 TortoiseGitPlink + .ppk
如果你习惯 PuTTY 工具链,或者必须用 .ppk,那就把 OpenSSH 格式的私钥转一下:
- 打开随 TortoiseGit 安装的 PuTTYgen(
C:\Program Files\TortoiseGit\bin\puttygen.exe) - Load 时把文件类型选成 All Files,选中
C:\Users\你\.ssh\id_rsa(默认类型是*.ppk,不改就看不到文件,这一步经常把人卡住) - 点 Save private key,存成
id_rsa.ppk - 让 TortoiseGit 用它:要么启动 Pageant(
pageant.exe)把 .ppk 加进去并保持常驻,要么在仓库的 Settings → Remote 里为origin指定这个 .ppk 文件
注意 Pageant 必须一直开着,关掉它就又认证失败了——「昨天还好好的今天就报错」多半是这个原因。
HTTPS 方式下反复提示输密码
用 HTTPS 而不是 SSH 时,认证交给 Git 的凭据 helper(Git for Windows 自带 Git Credential Manager),登录一次通常会存进 Windows 凭据管理器,之后免输。如果每次都问,按这个顺序查:
- 凭据是按「协议 + 主机」分别保存的,同一个服务器用不同域名访问(比如
gitlab.com和公司内网域名指向同一台机器)会各问一次;http和https也是分开的。 - 检查 Settings → Git → Credential 里的凭据 helper 有没有被设成
none。 - 到 Windows 的「凭据管理器 → Windows 凭据」里看看有没有对应的记录,有的话删掉重新输一次。
四、日常操作:三个名字相近、语义完全不同
Git 里「撤销」这件事有三套完全不同的机制,TortoiseGit 把它们都做成了菜单,名字还都带着 revert/reset 字样,这是仅次于「Commit 没上传」的第二大误操作来源。
| 菜单项 | 实际等价于 | 作用 | 危险程度 |
|---|---|---|---|
| Revert… (右键工作区 → TortoiseGit) |
git restore / git checkout -- |
丢弃工作区未提交的修改,恢复到已提交的样子 | 不可恢复,没有回收站 |
| Reset "master" to this… (在 Show log 里右键某个提交) |
git reset |
把当前分支指针挪到某个提交,分 Soft / Mixed / Hard 三档 | Hard 最危险,会连工作区改动一起丢弃 |
| Revert change by this commit (在 Show log 里右键某个提交) |
git revert |
生成一个新提交来反做目标提交的改动,历史完整保留 | 安全,撤销已推送的提交只能用它 |
记法:要「撤销已经推送到服务器的某个提交」,只有第三行那条路——它不改写历史,只是加了一个反向提交。前两条都只动本地,而且第二条的 Hard 档是真的会把改动删掉。
Reset 的三档也值得记住,因为 TortoiseGit 的对话框里就是这个措辞:
| 档位 | 分支指针 | 暂存区 | 工作区文件 |
|---|---|---|---|
| Soft | 移动 | 保留 | 保留 |
| Mixed(默认) | 移动 | 重置 | 保留 |
| Hard | 移动 | 重置 | 丢弃 |
其他高频操作的位置
| 操作 | 位置与要点 |
|---|---|
| Sync | 一个窗口里同时做 Pull 和 Push,日常主要入口;顶部能看到领先/落后多少个提交 |
| Fetch | 只取回不合并;配合 Show log 看远程分支的动向 |
| Commit | 对话框里能勾 Amend Last Commit 修改上一次提交(已推送的提交不要 Amend,会改写历史,别人拉取时会冲突) |
| Push | Force 相关选项会覆盖服务器上的提交,除非你明确知道远程没有别人的新提交,否则不要碰 |
| Stash Save | 把当前未提交的改动临时收起来(工作区变干净),处理完别的事再 Stash Pop 出来。典型用途:想 Pull 但本地有冲突改动时先收起来 |
| Show log → RefLog | RefLog 记录了本地分支指针的每一次移动,是「重置错了/提交丢了」的救命入口 |
| Blame | 逐行看最后修改人与提交,支持「Blame 到上一个提交」继续往前追 |
| Revision Graph | 可视化分支和合并关系,分支多了之后必用 |
| Create Patch / Apply Patch | 把改动导成 .patch 文件,用于跨机器搬运未提交的改动——工作区出问题要重拉之前,先用它把改动带出来 |
| Submodule Update | 仓库带 submodule 时,克隆后或别人更新了 submodule 指针后要跑一次 |
换成你顺手的 diff / 合并工具
TortoiseGit 默认用自己带的 TortoiseGitMerge,三方合并和冲突解决都够用。但它允许替换:Settings → Diff Viewer → External Program 可以指定 VS Code(code --diff %base %mine)或 Beyond Compare 之类,合并工具在 Settings → Merge Tool 里配。团队里如果大家平时就在 VS Code 里看代码,把 diff 指到 VS Code 会顺手很多。
五、忽略文件、换行符、冲突
忽略文件:Git 只有一层是要提交的
比 SVN 的三层机制简单一些,但「对已跟踪文件无效」这个坑完全一样:
| 机制 | 生效范围 | 是否提交到仓库 |
|---|---|---|
仓库根目录的 .gitignore | 该仓库(可放在子目录,规则向下作用) | 是,团队共享 |
.git/info/exclude | 仅本仓库、仅本机 | 否 |
core.excludesFile 指定的全局忽略文件 | 本机所有仓库 | 否 |
规则本身要注意两点:bin/ 带斜杠只匹配目录,bin 不带则文件和目录都匹配;另外用 ! 开头的行可以反向排除(!keep.txt),但如果父目录已经被忽略,子文件的反向排除是不生效的——这是很多人都撞过的一堵墙。
已经提交过的文件再加进 .gitignore 不会有任何效果,得先让它脱离跟踪:
# 从版本控制中移除但保留本地文件,然后提交这次删除
git rm -r --cached bin obj .vs
git commit -m "停止跟踪编译产物"
换行符:diff 里整个文件都变了
「我什么都没改,怎么整个文件都是红的」——九成是换行符或文件编码被改了。Git for Windows 默认开启 core.autocrlf=true,检出时转成 CRLF、提交时转回 LF,一旦某个文件在某个环节被转错,就会出现整个文件每一行都算改动的情况。
可靠的做法是在仓库里放一个 .gitattributes 把它钉死,让所有人一致:
# 文本文件统一按 LF 存储,检出时按平台自动处理
* text=auto
# Windows 下必须用 CRLF 的文件
*.bat text eol=crlf
*.cmd text eol=crlf
# 二进制文件不要做任何转换
*.png binary
*.jpg binary
*.xlsx binary
这个文件要提交进仓库才有意义,只放本地没用。加完之后可能还需要把已经乱掉的文件重新规范化一次,那一步涉及清空缓存重写索引,做之前先确认工作区干净。
文件编码是另一回事:如果文件被编辑器偷偷存成了带 BOM 的 UTF-8 或者 GBK,Git 会当成二进制或整文件变更,diff 里看不到逐行差异。这种要看 TortoiseGit → Settings → Diff Viewer 的编码设置和编辑器本身的保存编码。
冲突:先弄清楚是「本地没提交」还是「远程有更新」
Pull 或 Merge 报冲突时的标准处理:
- 冲突文件会显示为冲突状态(红色覆盖图标),文件里出现
<<<<<<</=======/>>>>>>>标记。 - 右键 → Edit conflicts,用 TortoiseGitMerge 三方对比逐个区块选,或者手工改。
- 改完删掉冲突标记,右键 → Resolve 标记为已解决(这一步会把文件加入暂存区)。
- 全部解决后提交,出现冲突的合并会生成一个合并提交。
有一个 Git 特有的情况要先分清:如果报的是「本地有未提交的改动,Pull 被拒绝」,那不是冲突,是 Git 在保护你的工作区。正确反应是先 Commit 或 Stash,而不是强行 Pull。判断口诀是——报错里出现「uncommitted changes」就先处理本地,出现「conflict」才是真的打起来了。
六、避坑清单
- Commit 之后一定要记着 Push。 这是从 SVN 过来的头号误解,TortoiseGit 的 Commit 对话框下面虽然也能勾选推送,但默认只提交到本地。
- Force Push 之前先想三秒。 它会覆盖服务器上的提交,如果同事在此期间推过东西,那些提交在远程分支上就没了。
- 不要 Amend 已经推送过的提交。 Amend 等于改写历史,别人拉取时会撞上分叉。
- Revert 就是真删了。 工作区未提交的改动被 Revert 之后没有回收站,重要改动先 Create patch 导出。
- Reset 默认选 Mixed、手别滑到 Hard。 Hard 会连工作区一起丢弃,是这三个操作里最容易造成实际损失的。
- SSH 客户端要么全用 OpenSSH、要么全用 TortoiseGitPlink。 混用就是「命令行能拉、TortoiseGit 报认证失败」的固定成因。
- Pageant 要常驻。 用 .ppk 方案时关掉 Pageant,认证立刻失效。
- 别把
.git目录放进网盘同步或杀毒实时扫描范围。 它内部有大量小文件和索引,同步工具和实时扫描会争抢文件锁,症状是索引损坏、报index.lock存在。真出问题时,先看有没有残留的index.lock,确认没有 Git 进程在跑再删掉它,不要整个删掉.git。 - 工作区不要放网络共享盘。 和 SVN 一样,SMB 上的文件锁和权限语义会让 Git 频繁报错。仓库裸库放服务器上是一回事,工作区必须在本地磁盘。
- Show log 看不到同事的新提交? 因为它读的是本地库,先 Fetch 一下。
小结
| 环节 | 关键点 |
|---|---|
| 模型差异 | Commit 是本地操作,要 Push 才上服务器;Fetch 只取不合并 |
| 安装 | TortoiseGit 2.19.x + Git for Windows 2.24+(必须单独装);Win10 1607+;确认 git.exe 路径 |
| 右键菜单 | Win11 在「显示更多选项」里;图标覆盖和 TortoiseSVN 抢同样 11 个槽位 |
| SSH | 默认 TortoiseGitPlink 只认 .ppk;改用 C:\Program Files\Git\usr\bin\ssh.exe 才能用 id_rsa 和 ~/.ssh/config |
| 撤销三兄弟 | Revert=丢工作区改动;Reset=挪分支指针(Hard 会删文件);Revert this commit=生成反向提交(撤销已推送的只能用它) |
| 忽略与换行 | .gitignore 对已跟踪文件无效;用 .gitattributes 把换行符钉死并存进仓库 |
一句话总结:TortoiseGit 的菜单几乎和 TortoiseSVN 一一对应,但每一条背后的语义都被 Git 的「本地库 / 远程库」模型改变了。把 Commit 与 Push 的分工、SSH 的两套密钥体系、以及 Revert/Reset/Revert-commit 这三兄弟搞清楚,剩下就是熟练度问题。
评论区