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

我目前可以通过以下三个步骤来完成

  • unstage通过使用git reset HEAD <file>...
  • 结帐到分支git checkout [-b] <branchname>
  • 再次git add <file>...
  • 有没有更好的方式来推动阶段性变化?


    Edmundo的答案是正确的,但它可以使用一些关于为什么它是正确的细节。

    这里有两个有趣的案例:

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

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

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

  • 转移到其他已有的分支可能非常简单:

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

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

    你可以把这个提交作为一个普通的提交,然后你复制到新的分支并从当前分支中移除; 或者你可以使用git stash ,这实际上是两次提交。只是这两个提交不在任何分支上,这使得git stash apply更明显可以在任何地方重新应用这些提交。 (使用git stash pop只是说git stash apply && git stash drop ,也就是说,应用然后,如果Git认为这样就行了 - 不管它是否真的做得很好 - 我推荐将这两个分开,这样你就可以可以检查它是否运行良好,尽管通常情况确实如此,最终通常很小)。


  • 1这两个提交用于保存(a)索引/分段区域,以及(b)工作树中的相应文件(即所有跟踪文件)。 如果你使用git stash save --untracked或者git stash save --all ,它实际上会进行三次提交。 你可能不想要三个提交表单,这是非常棘手的。


    这是怎么回事

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

  • 你的工作树,这是你的文件以普通文件形式存放的地方,这样你就可以使用它们(因此名称为“工作树”); 要么
  • 您的暂存区,Git也称为索引。
  • 索引或分段区域是您构建下一次提交的地方。 通常情况下,它已经包含在当前提交中的所有文件中,与它们在当前提交中的格式相同(顺便说一句,它总是被称为HEAD )。 就是说,你运行:

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

    并且你的工作树和索引/登台区域都被填充,以便它们与你刚刚签出的提交相匹配,现在称为HEAD 。 (如果你签出一个分支名字,你检出的提交是该分支上的最新或提示提交。)比方说,你做了git checkout master

    如果在这一点上你没有碰到索引和工作树,那么显然你可以git checkout任何其他的提交,例如git checkout develop 。 Git在你的索引和工作树中扔掉版本是很好的,因为它们与你签出的提交相匹配。 如果它抛出一个README文件,甚至是你的整个工作文件集,那又如何? 他们仍然在那个其他的提交, master的提示。 当你想要他们回来的时候,你可以再次将git checkout master再次git checkout master

    但这不是你在乎的情况。 在这里,你修改了一些文件。 你甚至可能已经运行git add来为下一次提交阶段。 但是,所有git add README所做的就是将文件从工作树复制到索引中。 这意味着README的索引和工作树版本相互匹配。 它们都与HEAD (当前)提交不匹配。

    假设HEADdevelop ,您应该已经developfeature 。 你想要git checkout feature 。 但是README会发生什么? 你做了一个改变。 你甚至可以把它放到索引中。

    那么,事实是,Git是懒惰的。 如果您现在运行git checkout featureHEAD提交移动到分支feature的顶端,Git将不得不做一些工作。 这可能包括删除当前的README文件并将其替换为来自feature顶端的文件。

    但也许 - 也许 - feature的提示提交具有与develop提示相同的README文件。 如果是这样,Git可以很懒! Git完全README从索引/暂存区域和/或工作树中删除现有的README 。 它可以将修改后的README保留在现在的任何位置。 这正是Git所做的。

    如果Git不能懒惰的文件,它会检查。 如果你的索引和/或工作树中的文件与你试图离开的HEAD提交中的文件不匹配,那么git checkout feature失败。 (请参阅git read-tree文档及其列表-21个可能的“两棵树合并”的例子,以确切地看哪些是成功的,哪些失败了。但大多数情况下,您不必关心所有这些:如果成功了,那么你很好,如果失败了,你必须提交或存储。)

    这就是为什么git checkout -b newbranch总是成功:它使用指向当前( HEAD )提交的分支名称创建新分支。 然后它从HEAD提交切换到...以及它本身。 没有什么可切换的。 懒惰步骤适用于每个文件:没有文件必须更改,所以没有文件更改,所以git checkout -b只是起作用。

    而且,这就是为什么git checkout -b otherbranch有时会成功:它需要从HEAD提交切换到其他otherbranch的提示。 如果该提交有一些不同的文件,那么Git将不得不撕掉索引/登台区域和工作树中的文件,并将其替换为其他otherbranch尖端的otherbranch 。 只有在index / staging-area和work-tree中的版本现在与HEAD提交中的版本相匹配时,才允许这样做。


    只要检查你想移动它们的位置就足够了。 Git会执行一次检查,以查看是否可以在没有冲突的情况下检查点上应用分阶段更改。 您可以使用的另一个简单技巧是隐藏更改,然后检出分支,然后隐藏弹出窗口。


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

    git stash
    
    git checkout someBranch
    
    git stash pop
    
    链接地址: http://www.djcxy.com/p/23593.html

    上一篇: Git : Move staged changes to different or new branch

    下一篇: how to commit changes to new branch