git checkout 是 Git 中一个功能强大且用途广泛的命令,主要用于两个核心场景:
- 切换分支或提交: 在不同的开发线(分支)或历史版本之间移动。
- 恢复工作树文件: 将工作目录中的文件恢复到特定版本(通常是最后一次提交的状态或某个分支的状态)。
重要提示: 在 Git 的较新版本(大约 2.23 及以后)中,官方引入了两个更专注的命令来分别处理 git checkout 的这两种主要职责,以减少混淆:
git switch:专门用于切换和创建分支。git restore:专门用于恢复工作树和暂存区文件。
虽然git checkout仍然有效并被广泛使用,但了解git switch和git restore是更现代的实践。
核心用法详解:
1. 切换分支:
git checkout <branch-name>
- 作用: 将你的工作目录切换到指定的分支
<branch-name>的最新提交状态。 - 要求:
- 分支
<branch-name>必须已存在于本地仓库中(通常通过git branch查看)。 - 在切换前,你当前工作目录的状态必须是“干净的”(clean):
- 所有已修改的文件都已提交(
git commit)。 - 或者,所有已修改的文件都已通过
git add暂存(staged),即使尚未提交。 - 如果工作目录有未提交且未暂存的更改,Git 会阻止切换,除非这些更改与目标分支没有冲突。你可以选择提交更改、暂存更改、贮藏更改(
git stash)或丢弃更改。
- 所有已修改的文件都已提交(
- 分支
- 效果:
- 工作目录中的文件会被替换为目标分支
<branch-name>的最新版本。 - HEAD 指针会指向
<branch-name>(表示你当前在这个分支上工作)。 - 后续的提交将发生在
<branch-name>分支上。
- 工作目录中的文件会被替换为目标分支
2. 创建并切换到新分支:
git checkout -b <new-branch-name>
- 作用: 这是一个非常常用的快捷操作。它基于你当前所在的提交创建一个名为
<new-branch-name>的新分支,并立即切换到这个新分支上。 - 等价于:
git branch <new-branch-name> # 创建分支 git checkout <new-branch-name> # 切换到新分支 - 常用变体: 从另一个分支(如
main)的当前状态创建新分支并切换:git checkout -b <new-branch-name> main
3. 切换到特定的提交(分离 HEAD 状态):
git checkout <commit-hash>
- 作用: 将你的工作目录回退到指定的历史提交
<commit-hash>(通过git log查看提交哈希)。 - 效果:
- 工作目录中的文件会变成该历史提交
<commit-hash>时的状态。 - HEAD 指针不再指向某个分支的尖端,而是直接指向这个具体的提交哈希。这称为 “分离 HEAD” 状态。
- 警告:
- 在分离 HEAD 状态下进行的新提交不会属于任何分支。如果你切换回其他分支,这些提交可能会变得难以找到(最终被 Git 垃圾回收),除非你事先为它们创建了一个新分支或标签。
- 在此状态下查看历史或调试旧代码是安全的,但通常不建议在此状态下进行常规开发或提交。如果你想基于旧提交工作,请使用
git checkout -b <new-branch-name> <commit-hash>基于该提交创建一个新分支。
- 工作目录中的文件会变成该历史提交
4. 恢复工作目录文件(丢弃未暂存的修改):
git checkout -- <file-path>
- 作用: 丢弃工作目录中指定文件
<file-path>尚未被git add暂存的修改,将其恢复到最后一次提交(也就是当前 HEAD 指向的提交)的状态。 - 关键点:
- 只影响工作目录。不会影响暂存区(Index/Stage)。
- 只丢弃未暂存的更改。如果你已经用
git add暂存了修改,这个命令不会撤销暂存区的修改。 - 使用
--是为了明确告诉 Git 后面跟的是文件路径,而不是分支名或提交哈希(尤其在文件名和分支名可能冲突时很有用)。
- 恢复所有文件(慎用!):
git checkout -- .- 这会丢弃工作目录中所有文件的未暂存修改,将其恢复到 HEAD 状态。
- 非常危险! 会永久丢失所有未暂存的改动,无法撤销。使用前务必确认。
5. 从其他分支或提交恢复特定文件:
git checkout <source> -- <file-path>
- 作用: 将工作目录和暂存区中指定的文件
<file-path>替换为<source>(可以是分支名如main、develop,也可以是提交哈希或标签名)所指向的版本。 - 效果:
- 工作目录中的
<file-path>文件立即变成<source>处的版本。 - 这个更改会自动被暂存(相当于同时执行了
git add <file-path>)。
- 工作目录中的
- 用途: 非常有用,例如:
- 从
main分支拉取一个文件来覆盖你当前分支上的修改(可能这个文件被错误修改了)。
git checkout main -- important-file.txt- 将文件恢复到某个历史提交时的状态。
git checkout a1b2c3d4 -- old-version.js - 从
总结关键点:
- 切换上下文:
git checkout <branch>/git checkout <commit>/git checkout -b <new-branch>主要用于在不同开发线或历史点之间移动。 - 丢弃工作区更改:
git checkout -- <file>用于撤销工作目录中未暂存的修改。 - 获取其他版本的文件:
git checkout <source> -- <file>用于用另一个分支或提交中的文件覆盖当前工作目录和暂存区的文件。 - 分离 HEAD 警告: 直接 checkout 到一个提交哈希会导致分离 HEAD 状态,在此状态提交需谨慎。
- 现代替代: 优先考虑使用
git switch来切换/创建分支,使用git restore来恢复文件(功能更清晰、更安全)。
选择使用 git checkout 还是更现代的 git switch/git restore 取决于你的 Git 版本和个人/团队偏好,但理解 git checkout 的传统用法对于阅读旧文档和脚本至关重要。

1012

被折叠的 条评论
为什么被折叠?



