Git:将分阶段的更改移至不同的或新的分支

时间:2017-05-24 15:03:25

标签: git

我现在可以按照以下三个步骤进行操作

  1. 使用git reset HEAD <file>...
  2. 取消暂停
  3. 结帐到分行git checkout [-b] <branchname>
  4. 再次登台git add <file>...
  5. 是否有更好的方法来改变分阶段的变化?

3 个答案:

答案 0 :(得分:4)

只需检查一下你想要移动它们的位置即可。 Git执行检查以查看是否可以在您正在检出的点上应用暂存的更改而不会发生冲突。您可以使用的另一种简单技术是隐藏更改,然后签出分支,然后存储弹出窗口。

答案 1 :(得分:3)

Edmundo's answer是正确的,但它可以使用为什么它是正确的一些细节。

这里有两个感兴趣的案例:

  • 创建一个 new 分支,从您现在的提交开始,非常简单:

    $ git checkout -b newbranch
    ... continue working; git add and/or git commit as usual ...
    

    只要新分支本身正常(具有不与现有名称冲突的有效名称),git checkout -b步骤就不会失败。

  • 转移到某些其他已存在的分支可能非常简单:

    $ git checkout otherbranch
    ... continue working ...
    

    如果失败,您将需要/需要至少进行一次提交。

    您可以将此提交作为普通提交,然后将其复制到新分支并从当前分支中删除;或者你可以使用git stash,它实际上使两个提交。 1 这只是两个提交不在 any branch,这使git stash apply可以在任何地方重新应用这些提交更加明显。 (使用git stash pop只是说git stash apply && git stash drop,即申请,然后,如果Git认为这样做好了 - 无论它是否确实顺利进行。我建议将两者分开以便你可以检查它是否顺利,但通常情况确实如此,但最终通常非常小。)

1 这两个提交是保存(a)索引/暂存区域,以及(b)工作树中的相应文件(即所有跟踪文件)。如果您使用git stash save --untrackedgit stash save --all,则实际上会进行三次提交。你可能不想要三次提交表格,这实际上比较棘手。

发生了什么

进行更改后,这些更改将存储在文件中。这些文件出现在两个地方中的一个或两个地方:

  • 您的工作树,您可以使用普通文件格式存储文件,以便您可以使用它们(因此名称&#34;工作树&#34;);或
  • 您的暂存区域,Git也称之为索引

索引或暂存区域是您构建 next 提交的地方。通常,它已经在其中 - 当前提交中的所有文件开始,其格式与当前提交中的相同(顺便提一下, 总是称为HEAD)。也就是说,你运行:

git checkout <branch-name-or-commit-hash-or-similar>

两者你的工作树你的索引/临时区域被填写,以便它们匹配刚刚签出的提交,现在称为{{1 }}。 (如果您签出分支名称,那么提交您要检出的是最新的,或提示,在该分支上提交。)让我们来看看。比方说,你做了HEAD

如果此时您没有触及索引和工作树,显然您可以git checkout master 任何其他提交,例如git checkout。 Git可以丢弃索引和工作树中的版本,因为它们与 签出的提交相匹配。如果它丢弃了git checkout develop文件,甚至整个工作文件集,那又怎么样?他们还在其他提交中,README的提示提交。当你想要它们时,你可以再次master

但那不是你关心的情况。在这里,您已经修改了一些文件。您甚至可能已将git checkout master运行到阶段以进行下一次提交。但是git add所做的就是将文件从工作树复制到索引中。这意味着git add README的索引和工作树版本彼此匹配。他们匹配README(当前)提交。

让我们说HEADHEAD的提示,而您应该使用develop。你想要feature。但是git checkout feature会发生什么?你做了一个改变。您甚至可以上演,将其复制到索引中。

嗯,事实是,Git是 lazy 。如果现在运行READMEgit checkout feature提交移动到分支HEAD的提示,Git将不得不做一些工作。该可能包括删除当前feature文件并将其替换为README提示中的文件。

但也许只是可能 - feature的提示提交与feature的提示相同的相同的 README文件}。如果是这样,Git可能会很懒惰! Git可以简单地不打扰从索引/登台区域和/或工作树中删除现有的develop。它可以保留修改后的README,无论它现在在哪个位置。这正是Git所做的。

如果Git 无法对文件保持懒惰,则检查。如果您在索引和/或工作树中的文件与您尝试移动的README提交中的文件匹配,那么{{1 } 失败。 (请参阅the git read-tree documentation及其名单! - 21 possible cases for a "two tree merge",看看完全哪些成功,哪些失败。但是,大多数情况下,你都没有 care 关于所有这些:如果成功,你就会好,如果失败,你必须提交或存储。)

这就是HEAD总是成功的原因:它创建了一个新分支,该分支名称指向当前(git checkout feature)提交。然后它从git checkout -b newbranch提交切换到......好吧,本身。没有什么可以切换的。懒惰步骤适用于每个文件:不能更改任何文件,因此

而且,这就是HEAD 有时成功的原因:它需要从HEAD提交切换到git checkout -b的提示。如果该提交有一些不同的文件,Git必须立即删除index / staging-area和work-tree中的那些文件,并用git checkout -b otherbranch提示中的版本替换它们。仅当索引/暂存区域和工作树中的版本现在匹配 HEAD提交中的版本时,才允许这样做。

答案 2 :(得分:2)

在这种情况下,使用存储非常有用。

git stash

git checkout someBranch

git stash pop