【问题标题】:Create new branch keeping unstaged changes in Master创建新分支,在 Master 中保留未分级的更改
【发布时间】:2018-10-14 18:23:32
【问题描述】:

在正常的提交过程之外,我对 Git 相当缺乏经验。

现在我在 master 分支上,我有 8 个未暂存的更改。我想做的是用最后一次提交创建一个新分支(即没有 8 个未暂存的更改),但我想保留未暂存的更改,以便我以后可以重新访问它们。

我该怎么做?

【问题讨论】:

  • 你必须把它们藏起来,或者查看工作树。如果您两者都没有,那么您就没有 1 个工作树,更改分支不会神奇地保留您未暂存的更改以供以后使用,但会(尝试)将它们带入新分支。
  • @Lasse 您对 stash 的评论与 Mureinik 的回答有何关联?
  • 我认为您最好的选择是查看工作树,您可以为同一个存储库设置多个工作树,这意味着您有 1 个克隆,但有多个工作文件夹,您可以在其中进行暂存和未暂存的更改, 分别地。每个工作树对应一个签出的分支。要为分支添加工作树,请使用 git worktree add PATH_TO_FOLDER BRANCH_NAME

标签: git branch git-branch


【解决方案1】:

如果您还没有提交这些新更改,它们对分支是不可见的,您可以从 master 分支出来:

$ git branch newbranch

或者,更明确地说:

$ git branch newbranch master

【讨论】:

  • 在我签出新分支之前,我需要对 master 分支执行 git add . 吗?
  • @JaneDoe 没有。这将创建一个新分支,指向 master 当前指向的同一提交,并且不暂存更改。
  • 但是当我这样做并签出新分支并执行git status时,我所有的更改都在新分支中
  • @JaneDoe 他们不在任何分支中,因为他们没有提交。如果你想将它们关联到一个特定的分支,你需要在那里提交它们。
【解决方案2】:

你可以这样做

git checkout -b newbranch

这将从master 创建一个新分支,将您签出到newbranch 并且您将拥有未暂存/未提交的更改。

如果您想在分支之间切换时保留更改但不想提交,请使用git stash

【讨论】:

    【解决方案3】:

    正如其他人在答案和 cmets 中提到的那样,至少有三个选项。它们之间有相当多的重叠,并且各有利弊:

    1. 创建新分支es(复数)
    2. 存储更改
    3. 添加工作树(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/
    #     └─ ...
    

    【讨论】:

      猜你喜欢
      • 2018-09-08
      • 1970-01-01
      • 1970-01-01
      • 2019-04-12
      • 2011-02-03
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2021-08-01
      相关资源
      最近更新 更多