正如其他人在答案和 cmets 中提到的那样,至少有三个选项。它们之间有相当多的重叠,并且各有利弊:
- 创建新分支es(复数)
- 存储更改
- 添加工作树(worktree)
创建新分支
分支几乎没有成本,因此最简单的选择是创建新分支,无需对现有工作流程进行真正的改变。如果您对某天是否想要某样东西有疑问,通常将其提交到“进行中的”或“实验中的”分支并没有什么坏处。
在您的特定场景中,我建议创建一个新分支来保存您的 8 个未暂存的更改(我们称它们为实验性的),并为您想要做的其他工作创建另一个新分支(我们称其为新功能):
git checkout -b experimental/foo
git add --all
git commit -m 'Trying a new structure for Foo'
git checkout master
git checkout -b feature/bar
如果您想暂时保存 8 项更改(或者如果您不确定多久会返回这些更改),我会推荐这种方法。您甚至可以将实验分支推送到上游存储库以获得额外的冗余或进行协作。
注意1最后两条命令可以合并为一行git checkout -b feature/bar master。它更聪明(并且可以说更明确),但我喜欢保持简单,并且总是在创建新分支之前检查分支
注意 2 “experimental/” 和 “feature/” 命名空间是可选的,但我发现它们有助于我将来了解过去的想法。并写一个good commit message,未来你会感谢过去的:)
隐藏更改
另一种选择是暂时“stash”更改,然后稍后将隐藏的更改重新应用到您的主分支(甚至是其他一些分支)。
在您的情况下,我会存储更改(使用描述性消息),创建新功能分支,然后稍后您可以返回并将存储的更改应用到 master:
git stash --include-untracked save 'Trying a new structure for Foo'
git checkout -b feature/bar
...
<make a few changes in feature/bar and commit or discard them>
...
git checkout master
git stash apply
存储有点复杂,但它可以非常灵活。创建分支的主要区别在于 stash 仅是本地的;他们不能被推到上游。如果您知道您需要存储提供的额外灵活性,或者存储时间很短,基本上是快速剪切和粘贴,我只会推荐此选项。
注意 1 默认情况下,存储仅包括修改后的文件,如果您的更改包含任何新文件,--include-untracked 选项很重要。你也可以使用--all(就像我们上面使用的git add),但这也会隐藏被忽略的文件。
注意 2 以上假设您在此期间没有存储任何其他东西。使用git stash list 检查您从那以后没有进行其他存储。完成此存储后,您可以使用git stash drop 将其删除。 git stash pop 让您应用并输入一个命令。
注意 3 如果您想了解更多信息,Atlassian 有一个 pretty useful tutorial on how to use git stash。
添加工作树(Worktree)
另一个(稍微)更复杂但灵活的选项是添加working tree(从现在开始,我将只使用“worktree”来反映命令的名称)。您的工作树是存在未暂存的更改的地方,在您结帐和在分支之间移动时会与您一起移动。默认情况下只有一个“主”工作树,但您可以添加一个或多个“链接”工作树,让您同时签出多个分支,并在每个工作树中进行不同的未暂存更改。
在上面的场景中,我可能会基于 master 创建一个新的工作树(和分支),然后切换到新的工作树目录。您未暂存的更改将保留在您的主工作树中,您只需切换回该目录即可重新处理它们:
git worktree add -b feature/bar ../app-name-bar
cd ../app-name-bar
因为这允许您一次签出多个分支,所以它可以实现一些非常好的工作流程。例如,您可以打开两个不同的终端和/或编辑器窗口/选项卡并并排查看两个分支。这是我会选择的解决方案,除了我可能会使用存储的非常短期的需求。
注意 1 使用此选项您还可以创建一个新分支。这基本上是选项 1 的特例。
注意 2 您不能在两个不同的工作树中激活同一个分支。如果出于某种原因需要,您需要复制分支或运行与--detach 分离的第二个分支(有关更多信息,请参阅this article)
注意 3 上述命令将在当前存储库的同一级别创建一个新文件夹“app-name-bar”。所以假设你的应用程序被称为“todos”,你最终会在你的文件系统中得到另一个名为“todos-bar”的“todos”副本(尽管你可以随意调用它)。为了让事情井井有条,我更喜欢为我的所有工作树文件夹创建一个包含文件夹。以下步骤展示了如何将当前存储库从 todos 移动和重命名为 todos/main,以便您可以在主工作树旁边拥有一个或多个附加链接工作树:
# Do these steps just once
mv todos/ main/
mkdir todos
mv main todos/
cd todos/main
# Do these steps every time you want to add a worktree...
cd todos/main
git worktree add -b feature/bar ../bar
cd ../bar
# ...and you'll end up with this directory structure
# └─ todos/
# ├─ main/
# | └─ ...
# └─ bar/
# └─ ...