Git:将分阶段的更改移动到不同的或新的分支
我目前可以通过以下三个步骤来完成
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
,它实际上会进行三次提交。 你可能不想要三个提交表单,这是非常棘手的。
这是怎么回事
当您进行更改时,这些更改将存储在文件中。 这些文件出现在两个地方中的一个或两个地方:
索引或分段区域是您构建下一次提交的地方。 通常情况下,它已经包含在当前提交中的所有文件中,与它们在当前提交中的格式相同(顺便说一句,它总是被称为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
(当前)提交不匹配。
假设HEAD
是develop
,您应该已经develop
了feature
。 你想要git checkout feature
。 但是README
会发生什么? 你做了一个改变。 你甚至可以把它放到索引中。
那么,事实是,Git是懒惰的。 如果您现在运行git checkout feature
将HEAD
提交移动到分支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