How to commit my current changes to a different branch in git
有时我会在工作目录中进行一些更改,并且我意识到这些更改应该在与当前更改的分支中提交。 这通常发生在我想尝试新事物或进行一些测试时,我忘记事先创建一个新分支,但我不想将脏代码提交给主分支。
那么,如何将未提交的更改(或存储在索引中的更改)提交到与当前更改不同的分支?
其他答案建议检查另一个分支,然后承诺,只有在可以通过本地修改结账时才能工作。如果没有,那么您将处于git stash的最常见用例:
1 2 3
| git stash
git checkout other-branch
git stash pop |
第一个stash隐藏了您的更改(基本上是进行临时提交),随后的stash pop重新应用它们。这让git使用它的合并功能。
如果当您尝试弹出存储时,会遇到合并冲突......接下来的步骤取决于这些冲突是什么。如果所有隐藏的更改确实属于另一个分支,那么您只需要对它们进行排序 - 这是因为您在错误的分支上进行了更改。
另一方面,如果你真的搞砸了,你的工作树有两个分支的混合变化,并且冲突只是你想要在原始分支上提交的那些,你可以节省一些工作。像往常一样,有很多方法可以做到这一点。这是一个,从弹出并看到冲突后开始:
1 2 3 4 5 6 7 8 9 10 11 12 13
| # Unstage everything (warning: this leaves files with conflicts in your tree)
git reset
# Add the things you *do* want to commit here
git add -p # or maybe git add -i
git commit
# The stash still exists; pop only throws it away if it applied cleanly
git checkout original-branch
git stash pop
# Add the changes meant for this branch
git add -p
git commit
# And throw away the rest
git reset --hard |
或者,如果您事先意识到这将会发生,只需提交属于当前分支的东西。您可以随时返回并修改该提交:
1 2 3 4 5
| git add -p
git commit
git stash
git checkout other-branch
git stash pop |
当然,请记住这一切都需要一些工作,并且下次可以避免它,也许通过在您的bashrc中将$(__git_ps1)添加到PS1中,将当前分支名称添加到提示符中。 (例如参见Bash文档中的Git。)
-
当你说:Checking out the branch and then committing would only work if the checkout is possible given the local modifications。你什么意思?你会介意给出/讨论一个简单的例子吗?
-
@ user815423426如果您有未提交的更改,当且仅当您更改的文件集和两个分支之间不同的文件集不相交时,您可以签出另一个分支。也就是说,如果您修改了文件A,则只有在两个分支中文件A相同时才能检出另一个分支。
-
谢谢!当你说两个分支中的A相同时,你的意思是在我的变化之前A(即每个分支的HEAD中的A)。正确?
-
如果您只需要提交部分更改,您可以执行git stash; git checkout other_branch; git stash pop; git add -i; git commit; git stash; git checkout first_branch; git stash pop。或者不是返回第一个分支,而是可以结帐到第三个分支...这是一种在几个分支之间传播编辑的方法。
-
如果工作树中存在其他更改,则此答案非常有效,这些更改无法在我需要提交更改的分支上干净地移动。
-
@Alex如果你不能彻底解除这种不可避免的合并冲突,那就是根据错误的分支进行更改的结果。 Git无法为你神奇地解决它们。
-
@Jefromi,是的,我理解。但我希望还有另一种方法可以将选定的更改仅提交到不同的分支。
-
@AlexD您始终可以使用git add -p(或git add -i)提交所选更改;这是一个完全独立的事情。但鉴于这个问题的情况最常发生在人们根本没有意识到他们所处的分支时,通常如果存在冲突,唯一要做的就是通过他们来解决问题。所有的变化都必须得到承诺。但是对于你真的不需要将所有更改带到另一个分支的情况,我添加了答案。
-
......然后你发现你如此认真地上演的提交已经被删除了;你现在又回到了你所有的变化 - 未经演化。大骗局。是否真的没有更好的方法将分阶段更改提交给新分支?...
-
@romkyns我真的不明白你要问的是什么,所以你可能想发布另一个问题。 (也许你正试图要求git stash --keep-index?)
-
这不仅有用,如果你犯了一个错误,而且当你将你的dropbox符号链接到你的git-repo并且有人进行了不必要的更改时。例如,一个Minecraft mod的图形团队只是无法弄清楚如何使用git所以我们制作了一个Dropbox并将其符号链接到我们的本地仓库中,以便他们的更改将立即反映在构建中。
您可以创建一个新分支并切换到它。然后提交您的更改:
1 2 3
| git branch dirty
git checkout dirty
// And your commit follows ... |
或者,您也可以签出现有分支(仅git checkout )。但是,只有在没有冲突的情况下(所有已编辑文件的基础与当前分支中的相同)。否则你会收到一条消息。
-
请注意,在切换到现有的分支分支的情况下,您可以使用-m选项告诉git尝试合并更改,即git checkout -m
-
@ Jefromi的答案在我认为的每一个案例中都更好。
-
更短的版本:git checkout -b dirty
-
"the base of all edited files is the same as in your current branch"是什么意思?如果您有未提交的更改,git checkout 什么时候会出现问题?
-
@ user815423426:如果编辑文件但未提交,则无法签出文件未提交(或之前已删除)的分支。 Git将中止:错误:以下文件的本地更改将被checkout覆盖:...
-
当你提交新的分支时,这确实是更好的答案。 stash删除你上演的内容;这种方法没有。
git checkout my_other_branch
git add my_file my_other_file
git commit -m
并提供您的提交消息。
-
你可能想写co和ci是什么......虽然可以猜到它(结账,提交)^^
-
@tanascius好建议,做完了。我一直在使用别名,所以我忘记它们不是默认值。