
1. 先把SourceTree里分支这件事说透用 SourceTree 干了几年活我发现一个挺普遍的现象很多人装了 SourceTree日常操作却还是 git 命令行那一套——打开 SourceTree 只是用来看提交图谱和 diff。问起来原因答案基本一样图形界面的分支操作看着挺花哨但不知道它背后到底在干什么怕点错。这个顾虑不算多余。分支是 Git 里最核心也最容易被误操作的东西删错一个分支、切错一个状态轻则丢几行改动重则把别人正在用的远程分支搞乱。所以这篇我就专门聊 SourceTree 里创建分支和删除分支这两件事把每个按钮、每个复选框背后的逻辑拆开讲清楚。需要说明一下我用的版本是 SourceTree 3.xWindows 和 macOS 都试过不同小版本的界面按钮位置略有差异但核心逻辑一致。如果你是刚用 SourceTree 的新手跟着走一遍就能上手如果你已经用了挺久我在后面几节里写的那些坑大概率你也踩过至少一个。分支这东西看起来只是复制一份代码,实际它是 Git 版本管理的骨架。搞懂分支在 SourceTree 里的呈现方式你才敢在团队协作里放心地开分支、合并、删分支而不是每删一个分支都心里打鼓。2. 分支在SourceTree里的真实样貌2.1 分支本质上只是一个指向提交的指针要把分支玩明白得先破除一个误解很多人以为创建一个分支是把整个代码库复制了一份出来所以觉得开分支很重。真实情况是Git 的分支只是一个 41 字节左右的文本文件里面存着一个 commit 的哈希值。打个比方把代码提交历史想成一条时间线的相册每个提交是一张照片。分支就像一个贴在相册某张照片上的便利贴上面写着当前最新在这。你新建一个分支Git 做的事情就是在当前那张照片上再贴一张便利贴两张便利贴同时指向同一张照片仅此而已。所以创建分支是毫秒级的一点不占空间。理解了这点你就能明白为什么 SourceTree 里新建分支那么快、为什么删分支不会删掉代码。删分支删掉的只是那张便利贴照片提交还在只要还有别的分支或标签指得到它它就永远存在。这也是后面讲误删分支怎么找回来的原理基础。SourceTree 的价值在于它把便利贴现在贴在哪张照片上这件事可视化了。你看图谱里那些彩色的线条和标签就是各个分支指针的实时位置及其分叉合并历史比命令行git log --graph输出看着直观得多。2.2 本地分支与远程分支是两套独立的账本新手最容易混的地方在于SourceTree 左侧边栏里的分支和远程是两个不同的节点里面列出来的东西不是一回事。本地BRANCHES存在你自己电脑.git目录里的分支你能直接在上面提交、修改、回滚。远程REMOTES比如origin/master、origin/feature-login这些是别人推送上去的分支在你本地的快照缓存你在它上面不能直接提交。最要命的是本地记录会过期。同事昨天推了一个新分支上去你本地不拉取就永远看不到它。所以 SourceTree 有个习惯动作必须先养成动手之前先点一次拉取Pull或获取Fetch让本地这份远程快照更新到最新。我在团队里见过太多次这分支怎么没了的惊慌最后发现只是没 fetch远程分支死活还在。这两套账之间靠跟踪关系tracking连接。一个本地分支通常会跟踪一个远程同名分支git status里那句 Your branch is ahead of origin/xxx by 2 commits 说的就是这种关系。创建分支时如果没建立跟踪第一次推送就得手动指定这点我在第 3 节会细讲。2.3 一个提交上可能同时贴着好几张便利贴为了让你对图谱有个心理准备这里提前说一个常见现象一个提交上同时挂着多个分支标签在 SourceTree 里就会看到好几个彩色小方块叠在一起。这通常发生在几种情况一是你从当前分支直接新建分支且没做任何新提交此时两个分支指向同一个提交二是合并之后被合并的分支指针追上了目标分支三是有人建了release-1.0和hotfix-1.0这类临时分支短时间内重合。看到标签重叠别慌这完全正常。判断当前在哪个分支看 SourceTree 工具栏最左侧那个加粗显示的分支名或者看文件列表上方那行状态说明就行。搞清楚这个显示规律你在图谱里读分支走向就顺畅多了。3. 创建分支的四种入口与实操细节3.1 从当前提交直接新建分支用得最多的一条路这是日常开发 90% 的场景你正在master上想开个功能分支干活。SourceTree 里最快的做法是点顶部工具栏那个写着分支的按钮图标是两条分叉的线或者用菜单仓库 分支 新建分支。快捷键的话Windows 上是CtrlShiftBmacOS 是CmdShiftB。弹出的对话框里只有几项要填新分支名称这里有个命名建议团队最好统一规范比如feature/用户登录、bugfix/订单金额计算、hotfix/线上支付超时。带前缀的好处是 SourceTree 左侧分支列表能按名称排序分组一眼能看出哪些是功能、哪些是紧急修复。检出分支Checkout branch这个复选框默认勾选意思是创建完立刻切过去。绝大多数情况保持勾选你建分支本来就是为了在上面干活。从哪个提交创建默认是当前 HEAD 位置一般不用改。点创建之后SourceTree 会在左侧分支列表里多出一项并且加粗高亮显示当前分支已经切到新的上面。整个过程一两秒。注意SourceTree 有时会在新建分支名里默认带一段自动生成的文本比如基于时间戳或之前的分支名别直接点确认先手动改成有意义的名字。我见过仓库里躺着一堆test、new-branch、分支2的半年后没人敢删。3.2 从历史某次提交或标签拉出新分支有些场景需要你回到过去某个节点开分支。比如线上发现一个老版本才有的 bug你要从v1.2.0那个标签位置拉一个修复分支或者要基于某个历史提交做个实验。操作方式是在 SourceTree 的提交图谱里右键点那次目标提交选择分支...然后输入新分支名。这里有个细节——从历史提交建的分支默认不会自动检出因为 SourceTree 认为你可能只是标记一下你要注意对话框里那个检出分支复选框的状态需要切过去就手动勾上。从标签建分支也类似。SourceTree 左侧有标签TAGS节点右键某个标签同样能选分支...。标签和分支在 Git 里其实是一类东西都是指向提交的引用区别只是标签通常不移动分支会随提交前移。这条路径的实用价值在于救火和实验两件事。我个人的习惯是任何要动线上代码的修复都从对应的 tag 拉分支而不是从 master 拉避免把 master 上还没发布的新代码误带进修复包里。3.3 把远程分支检出成本地分支团队协作里你的同事开了个feature/payment推上去了你要接手一部分。这时候本地还没有这个分支得从远程检出。在 SourceTree 左侧展开远程 origin找到那个分支双击它或者右键选检出 origin/feature/payment...。SourceTree 会弹个小提示大致意思是这会创建一个跟踪origin/feature/payment的新本地分支确认即可。这一步背后其实做了两件事一是创建本地分支feature/payment二是把它和origin/feature/payment建立跟踪关系。有了跟踪关系之后你git pull/git push不用每次指定远端的名字SourceTree 会自动往正确的远端同名分支推。注意双击检出是最省事的但如果你想要一个和远程不同名的本地分支比如远程叫feature/payment你想本地叫payment-dev那就得右键选那个更长的检出...并创建新分支选项手动改名字。别嫌麻烦名字对不上后面推代码时容易推错地方。3.4 新建分支时的几个隐形选项与判断依据SourceTree 新建分支对话框里还有一些不那么显眼的选项值得单独说说判断逻辑。检出分支到底勾不勾判断标准很简单你接下来是要在这个分支上写代码吗是就勾只是想先建个名字占位、稍后再切就不勾。要不要立刻推送新建分支后 SourceTree 不会自动推送到远程。你得点推送在推送对话框里确认这个新分支前面的复选框是勾选状态然后推送。第一次推送时建议同时勾选跟踪或设置上游一劳永逸。团队协作里功能分支越早推上去越好别等到攒了几十个提交才推那样一旦出问题回滚成本很高。分支名能不能带中文Git 技术上允许SourceTree 也能显示但我不建议。跨平台、跨工具链比如有些 CI 系统、脚本处理中文分支名容易出编码问题feature/用户登录这种写法在一些环境里会变成乱码。用拼音或英文更稳。4. 分支切换、贮藏与工作区状态处理4.1 工作区有未提交改动时能不能直接切分支这是被问得最多的一个问题。答案是能切但有条件。Git 切换分支时会尝试把你当前工作区的改动带过去。如果目标分支上这些文件的内容和你当前分支一样Git 就让你带过去切换顺利如果目标分支上这些文件的内容不同Git 会阻止你切换并提示类似 Your local changes to the following files would be overwritten by checkout 的错误。SourceTree 里这个错误通常弹个对话框告诉你哪些文件冲突。遇到这种情况三个处理思路提交当前改动如果改动是完整的、可以形成一次有意义的提交那就先提交再切分支。这是最干净的做法。贮藏Stash改动改动还没写完、不想形成正式提交就用贮藏把它临时收起来切过去干完活再切回来恢复。丢弃改动如果那些改动是测试用的、不要了直接丢弃。我个人的判断顺位是能提交就提交提交不成就贮藏实在不要了才丢弃。永远不要在没搞清楚改了什么的情况下点丢弃那是真的找不回来。4.2 贮藏功能的正确打开方式SourceTree 的贮藏入口在工具栏图标像个箱子或者往下压的箭头或者菜单仓库 贮藏。点开后可以给这次贮藏起个消息强烈建议起比如登录页表单校验做到一半否则过几天你看着一堆WIP on master根本分不清谁是谁。选择是否保留暂存区内容Keep staged changes。一般不用勾。贮藏后的改动会被从工作区移走你可以放心切分支了。干完活切回原分支打开仓库 贮藏列表找到那条记录右键选应用贮藏Apply stash或弹出贮藏Pop stash。这两个的区别值得记一下应用是把贮藏内容恢复到工作区但保留这条贮藏记录弹出是恢复的同时删掉这条记录。如果你不确定这次恢复会不会有冲突用应用更安全确认没问题后再手动删掉那条贮藏。注意SourceTree 有个老问题贮藏新增未跟踪的文件时默认可能不带进去需要在贮藏对话框里勾选相关选项或者在设置里开启。具体路径是工具 选项 Git里面有个关于 stash 包含未跟踪文件的选项。切分支前如果你新建了文件还没 add最好单独确认一下它有没有被收进去否则切过去它还在工作区晃荡。4.3 切换分支后本地文件到底发生了什么很多人对切换分支有点心理阴影怕切完代码就乱了。理解下面这件事你就放心了切换分支Git 更新的是工作区文件的内容让它们和目标任务分支的最新提交保持一致。你原来分支的文件不会被改只是看不见了切回去就回来。但有两个例外要记牢第一未跟踪的文件Untracked files不属于任何分支切来切去它都在。这就解释了为什么有时候你切了分支发现桌面上还留着一堆test.py、debug.log之类的垃圾文件——它们从来没被 Git 管理过。第二.gitignore规则差异会造成错觉。如果两个分支的.gitignore不一样A 分支忽略的某个文件在 B 分支可能被跟踪切过去就会凭空冒出来或者莫名消失。切换完分支我的习惯动作是看一眼 SourceTree 的文件状态面板确认工作区是干净的再开始写代码。养成这个习惯能避开后面一大堆我明明没改怎么有改动的困惑。5. 删除分支本地删、远程删与恢复5.1 删除本地分支的前提条件现在说重点——删分支。SourceTree 里删本地分支的操作路径是左侧分支列表里右键某个分支 删除分支Delete Branch。看起来简单但这里有个关键的阻拦机制。如果这个分支上还有没有被合并到其他分支的提交SourceTree 会弹出一个警告大意是这个分支含有未合并的提交确定要强制删除吗 这时候你面对的其实是一个判断题这个分支的代码已经合并进master了只是还没来得及删——放心删。这个分支是废弃的实验分支代码不要了——可以强制删。这个分支是我刚提交完还没推上去的工作——千万别删删了这些提交如果还没别的引用指着就会变成悬空提交只能靠 reflog 那种方式捞很折腾。我给自己定的规矩是删除分支前先确认它的提交要么已经进了主线要么已经推送到远程。推到远程的分支就算本地删了重新 fetch 检出随时能拿回来等于多了一层保险。注意SourceTree 里不能删除当前所在的分支。想删当前分支得先切到别的分支上去。这个限制是合理的因为没必要在一个分支上工作还把它删掉。5.2 删除远程分支的两种路径删远程分支比删本地要谨慎得多因为那会影响整个团队。SourceTree 提供了两条路。路径一右侧操作。在左侧展开远程 origin右键目标远程分支选删除 origin/xxx。SourceTree 会把一条删除指令推送到远端实际操作是git push origin --delete xxx。路径二推送时的删除。如果某次推送对话框里显示某个远程分支状态异常也可以从那里处理但不如路径一直接。无论哪条路SourceTree 一般会弹确认框让你再点一次确认。这一步别嫌烦认真读一眼分支名确认删的是origin/feature/old-login而不是origin/master这种要命的东西。这里有个团队协作的礼仪问题别随手删别人负责的远程分支。远程分支一旦被删它的最后一次提交位置如果没有单独记下来找回是有点麻烦的。要删某个功能分支通常是这个功能已经合并进主干、PR 已经关闭且确认没有人还在上面挂着工作。我一般会先在团队群里问一句或者看一眼该分支最近的提交者是谁。5.3 误删分支之后怎么把提交找回来前面说了分支只是个便利贴删掉便利贴照片还在。所以误删分支不等于提交没了前提是那个提交还能被某些东西找到。场景一本地删了远程还有。最简单直接重新检出远程分支第 3.3 节的方法本地分支就回来了。场景二远程也删了但你知道那个提交的哈希。右键那次提交选分支...输入原来的分支名重建即可。场景三忘了哈希什么都没有了。这时候就得靠git reflog。SourceTree 本身对 reflog 的可视化支持不太够我的做法是点终端按钮打开命令行或者在 SourceTree 的操作 打开终端里执行git reflog找到那次删除前后的记录拿到对应的 commit 哈希再回到 SourceTree 里右键那个提交重建分支。为了减少这种麻烦我强烈建议重要分支在合并后不要急着立刻删等一两个发布周期再删。留着它占不了多少空间但能省下你未来可能花的一两个小时去排查和恢复。5.4 清理那些已经消失的远程分支有个很隐蔽的坑同事把远程分支origin/feature/xxx删了但你本地 SourceTree 的远程列表里还是显示着它点开也能看到旧的提交。你会以为它还在。这是因为本地的远程跟踪快照没更新。解决办法是在 SourceTree 的拉取Pull对话框里勾选那个**修剪远程追踪分支Prune tracking branches** 选项再执行拉取。或者更省事工具 选项 Git里有一项可以开启拉取时自动修剪。开启后每次拉取都会把远端已经删掉的分支从本地列表里同步清掉界面清爽很多。这个设置我建议尽早开。不开的话长期项目里本地会积累几十个早已删除的远程分支引用看着乱也容易误判这个功能分支还在。6. 高频问题速查与排查技巧上面都是讲原理和操作这一节我把实际用过、被问过最多的问题整理成表方便你出问题时直接对号入座。现象常见原因处理办法新建分支后推送提示没有上游分支本地分支没建立跟踪关系推送对话框里勾选该分支并选择跟踪/设置上游或首推时加-u切换分支报 would be overwritten by checkout目标分支上这些文件内容不同冲突先提交或贮藏当前改动再切换删除分支时提示 not fully merged分支上有未合并的提交确认代码是否需要需要就先合并或推送不要直接强制删远程分支明明删了本地还显示本地远程快照未更新拉取时勾选修剪远程追踪分支或开启自动修剪双胞胎分支名一个本地一个远程看着乱本地分支和它跟踪的远程分支同时显示属于正常现象靠左侧节点的层级区分本地在分支下远程在远程 origin下切分支后文件没变化以为没切成两个分支在这些文件上内容本就相同看工具栏当前分支名确认或对比提交历史忘了自己现在在哪个分支图谱标签密集看不清看工具栏最左侧加粗的分支名或看文件状态面板顶部提示新建分支名带了一堆乱码/前缀SourceTree 默认填充或编码问题手动改名避免使用中文和特殊字符除了这张表我再补几个搜索里经常被提到的关联问题。关于当前分支未提交就 checkout 其他分支这在 SourceTree 里就是上面第 2 行那情况。它的本质不是 SourceTree 的 bug而是 Git 的保护机制。理解它是在保护你的改动就不会觉得烦躁了。关于从主干检出代码后想切 dev流程是一样的先确认工作区干净然后在左侧分支列表双击dev如果本地没有就从远程 origin里双击origin/dev。如果 SourceTree 提示找不到先 Fetch 一下。关于清理删除的分支这就是第 5.4 节说的修剪问题。顺带一提SourceTree 左侧分支列表本身没有批量清理本地分支的功能要批量删闲置分支还是得靠命令行git branch -d循环图形工具在批量操作上确实不如命令行灵活这是它的事实短板不用回避。7. 几个没人写进文档的个人经验写到最后分享几个我用了这些年 SourceTree 攒下来的、文档里基本不会提的习惯。第一动手前先 Fetch。这条我已经强调过但值得再说一遍。90% 的分支不见了代码怎么不对都源于本地视图过期。把 Fetch 变成肌肉记忆能省掉一半的困惑。第二分支名当文档用。与其在群里记这个分支是干嘛的不如把信息写进名字bugfix/20240315-订单超时、feature/积分商城-v2。SourceTree 显示全名一眼就懂半年后回来也不会认不出来。第三删除分支的时机我一般放在合并之后。合并Merge完成的当天不删等这个改动上一次测试环境或者发一次版确认没问题了再删。少删一天不占什么成本但多留一天多一份从容。第四出问题别硬刚开终端。SourceTree 的图形操作覆盖了日常 95% 的场景但 reflog、批量删分支、复杂 rebase 这些还是命令行利索。SourceTree 顶部有终端按钮能直接在当前仓库目录打开命令行两者配合着用是最舒服的姿势不用二选一。第五也是最想说的把分支当临时工作区而非固定资产。一个团队如果分支开得随性、删得犹豫仓库会越来越臃肿。理想状态是每个功能分支合并即清理保持主干和活跃分支的清爽。SourceTree 给你的是操作工具真正的规范还是得团队约定工具替代不了约定。我实际用下来最稳的一套流程就三句开分支前先 Fetch切分支前先看工作区删分支前先想清楚提交去哪了。这三句背下来SourceTree 的分支操作基本不会再出乱子。