跳至主要内容

Git 切换分支:实用示例指南

了解如何使用 git switch 切换分支,并理解 git switch 与 git checkout 之间的差异。
· 8分钟 阅读

使用 AI 探索

在 Git 中,分支代表独立的开发线路,使开发者能够同时处理项目的多个功能或版本。

Git 分支为管理代码变更提供了结构化方式,能平滑集成新功能、缺陷修复和实验性想法,而不干扰主代码库。

展示一个包含三个分支的项目的示意图

传统上,我们使用 git checkout 命令在分支之间移动。然而,checkout 命令的功能远不止切换分支,这会带来一些混淆,甚至可能导致误操作。

自 2019 年 8 月的 Git 2.23 起,git switch 命令提供了一种更直观的方式来切换和创建新分支。

使用 Git Switch 切换与创建分支

在复杂项目中,优先级不断变化,工作流也常常不是线性的。通常,每个分支聚焦于特定改动,使我们能够同时推进多个新功能或缺陷修复,并各自在其所属分支上实现。

我们可能需要暂停某个功能的开发并转到另一个分支,原因包括:

  • 等待代码评审。
  • 遇到阻塞并需要同事的帮助。
  • 需要立即处理的紧急修复(hotfix)。

高效地在分支间切换是保持开发顺畅、确保变更正确落位的关键。面对多任务与团队协作,拥有一种简单可靠的分支切换方式至关重要。

要使用 switch 命令切换到已有分支,可执行:

git switch <branch-name>

上述命令中的 <branch_name> 应替换为要切换的分支名。比如我们想在名为 feature-x 的现有分支上开发新功能,则使用:

git switch feature-x

查看现有分支的名称

若要列出可用分支,使用 git branch 命令。当前分支会在名称前以星号标示。例如,如果我们有三个本地分支 main、feature-x 和 bug-z,且当前位于 main 分支,则输出为:

* main
feature-x
bug-z

切换到远程分支

前述命令允许我们切换到本机已有的分支。若要切换到远程仓库的分支,需要先用以下命令创建其本地版本:

git switch -c <local-branch-name> origin/<remote-branch-name>

其中,<local-branch-name> 是我们希望在本地使用的分支名,<remote-branch-name> 是远程分支名。一般建议使用相同名称以避免混淆。假设我们本地没有 feature-x 分支,则可创建其本地版本并切换过去,如下:

git switch -c feature-x origin/feature-x

当本地与远程使用相同名称时,Git 提供了 --track 选项的简写形式。因此,上述命令等价于:

git switch --track origin/feature-x

要列出远程分支,可使用 git branch -r 命令。

本地仓库不会自动跟踪远程分支。因此,在列出或切换到远程分支之前,务必先使用 git fetch 更新本地仓库。

创建新分支并切换到该分支

如果我们想从零开始创建一个新分支以开发新功能,可以使用 -c 标志:

git switch -c <new-branch-name>

将 <new-branch-name 替换为分支名称。例如,要创建名为 feature-y 的分支,可执行:

git switch -c feature-y

切换回上一个分支

很多时候,我们在切换分支做完一些工作后,希望回到之前工作的分支。Git 提供了一个简写命令:

git switch -

Git Switch 与 Git Checkout

git checkout 自 Git 诞生起便存在。在 2019 年引入 git switch 之前,切换分支一直使用 git checkout。然而,git checkout 的范围不仅是分支间导航。以下是两者差异的概览:

  • git switch:旨在提供更直观的分支切换与创建方式,简化命令集并减少混淆。
  • git checkout:更通用的命令,既可用于切换分支,也可用于检出文件、从不同提交或分支恢复内容。

git switch 的设计让意外覆盖改动更不容易发生,并以更明确的语法进行分支切换与创建。

由于 git checkout 身兼多职(切换分支、恢复文件等),误用的可能性更高。

Git Switch:常见错误

在管理分支时,您可能会遇到一些常见问题。其中之一是尝试创建一个在本地已存在的分支。另一个常见问题是当前分支存在未提交更改时尝试切换分支。我们先解释第一种情况。

该分支在本地已存在

每个本地分支都需要唯一的名称。您可以通过两种方式使用 git switch 创建本地分支:

1. 跟踪远程分支:

git switch --track origin/<branch-name>

2. 创建新的本地分支:

git switch -c <branch-name>

这两种情况下,如果本地已存在名为 <branch-name> 的分支,Git 会报错:

fatal: a branch named '<branch-name>' already exists

我们无法创建与另一本地分支同名的分支

此时可直接使用 git switch <branch-name> 切换到该分支,而无需创建。

当前分支存在未提交更改

如果当前分支存在未提交的更改,且切换会覆盖这些更改,Git 将不允许我们切换分支。在这种情况下,Git 会报错:

Please commit your changes or stash them before you switch branches.

<code data-mce-selected=

如提示所示,要解决这一情形,需要先提交更改或暂存(stash)它们。若更改已准备好提交到仓库,应使用:

git commit -m "Commit message"

如果想保留更改但暂时不提交,可使用 git stash 命令临时保存:

git stash

如果在切换分支前进行了 stash,回到原始分支后想要重新应用这些更改,可使用 git stash pop 命令。

或者,也可以使用 --discard-changes 标志丢弃更改:

git switch --discard-changes <branch-name>

使用上述选项前请务必谨慎,因为更改将被永久删除。

Git Switch 进阶用法

当您需要从项目历史中的特定位置创建分支,或处理一些特殊场景时,git switch 提供了相应的高级功能。

从特定位置分支

默认情况下,使用 git switch 创建分支时,新分支的初始状态为我们当前所在分支的 HEAD。

默认情况下,从当前 HEAD 开始创建分支

设想我们希望从某个之前的特定提交开始一个新分支。每个提交都有唯一的 <hash>,我们可以在 git switch 命令中使用该值,从该提交创建新分支。操作如下:

switch -c feature-y <hash>

将 <hash> 替换为实际的提交哈希。

通过提供提交哈希,我们可以从特定提交处分支

切换到分离的 HEAD

如果我们想在不影响当前分支、也不创建新分支的情况下,探索或试验某个特定提交,可以使用以下命令进入分离的 HEAD 状态:

git switch --detach <hash>

切换到分离的 HEAD

通过分离 HEAD,我们可以安全地在特定提交处检查仓库状态、运行测试或进行临时修改,而不必担心这些更改会被误提交到当前工作分支。常见用例如下:

  • 查看旧状态: 若要在不修改当前分支的情况下检查或测试较早的提交,可在分离状态切换到该提交。
  • 临时更改: 若想进行实验性更改且不影响任何分支,可在分离的 HEAD 状态下操作。注意,在此状态下产生的新提交不隶属于任何分支,若需保留这些提交,可能需要新建分支。
  • 构建/测试用途: 有时我们需要在特定提交上进行构建或测试。切换到该提交的分离 HEAD 状态可在不影响仓库分支结构的情况下完成这些操作。

强制切换

我们已经了解到,如果存在可能与目标分支冲突的未提交更改,Git 将不允许切换分支。若我们确定要丢弃这些更改并继续切换,可使用 -f 选项强制执行,如下:

git switch -f <branch-name>

需要注意以下重要警示:

  • 所有未提交更改将不经警告即被丢失,若这些更改未在其他地方保存,可能造成工作丢失。
  • 不加选择地使用 -f 会削弱开发纪律,促使开发者绕过如暂存或提交进行中(WIP)更改等规范做法。这可能导致仓库历史混乱,增加协作难度。因此,尽管 git switch -f 便捷高效,也务必谨慎使用,清楚了解风险并尽量规避潜在问题。

结语

与较早的 git checkout 命令相比,git switch 让切换与创建分支更为简便。

它简化了流程并有助于减少错误,使开发者更轻松地管理代码库。

该命令有助于避免常见问题,例如意外覆盖更改,或将 git checkout 的不同功能混为一谈。

采用这一命令可让 Git 分支的导航更直观,并增强开发团队的协作。

François Aubry

作者

François Aubry

全栈工程师,CheapGPT 创始人。我一直热爱教学。从学生时代起,我就积极寻找机会为同学提供辅导与帮助。这份热情促使我攻读博士学位,并在此期间担任助教,以支持我的学术追求。那些年里,我在传统课堂环境中收获了极大的成就感,既建立联系也促进学习。随着在线学习平台的兴起,我也看到了数字教育的变革潜力。事实上,我曾参与我们大学一款此类平台的建设。我致力于将传统教学理念与创新的数字方法相融合。我的热情在于打造既有吸引力、信息量充足,又能让当代学习者轻松获取的课程。

主题