将更改的文件移动到另一个分支以进行检入

630

这种情况经常发生在我身上:我写了一些代码,然后去检查我的更改,但是我意识到我不在适当的分支中进行检入。但是如果我切换到另一个分支,我的更改就会还原。有没有一种方法可以将更改移动到另一个分支以进行检入?

5个回答

1151

git stash是你的好朋友。

如果您还没有提交代码,只需运行git stash。 这将保存您所有的更改。

切换到您想要应用更改的分支,并运行git stash pop

Git stash有很多用途,这肯定是其中一个更有用的原因。

示例:

# work on some code
git stash
git checkout correct-branch
git stash pop

更新:不需要使用 stash 命令。未提交的更改不属于任何分支,因此只需使用 git checkout -b <新分支>


182
在切换分支时,不需要隐藏未提交的更改,它们会随着你一起前往新分支。隐藏更改(stash)更适用于临时存储较长时间的东西(比如你想稍后完成并提交的内容,但现在必须先处理其他事情)。 - Tekkub
3
我明白了。所以我需要将更改藏起来,切换分支,然后再恢复更改。C:\kf [develop +0 ~4 -0]> git checkout feature/customers<br/> 错误:您的本地更改会在切换分支时被覆盖:<br/> AspWebApp.vNext/global.asa<br/> RestApi/Web.config<br/> 请在切换分支之前提交您的更改或暂存它们。<br/> 中止操作。 - IsmailS
6
@Tekkub说“长期存储临时物品”这句话听起来很别扭,使用stash的另一个优点是它将其推入堆栈中,因此如果您不想将其带到其他工作上,则可以以这种方式使用它。是的,您不一定要这样做,但这样做感觉更干净、更有控制感。 - Atherion
18
只有当你要切换的分支与当前所在分支为最新版本时,这种说法才是正确的。例如,如果你无意中正在prod分支上工作,但需要切换到stage分支,但在此期间stage已经发生了变化,stash是唯一可以完成切换的方法。 - danielson317
如果出现冲突,您可能会丢失一些更改。@Atherion,我同意“stash”似乎是一个不错的命令工作流。 - xtian
显示剩余5条评论

323
如果您还没有提交更改,请使用git checkout切换到新分支,然后正常提交更改-文件的更改不会与特定分支绑定,直到您提交它们。
如果您已经提交了更改:
  1. 键入git log并记住要移动的提交的SHA。
  2. 检出要将提交移动到的分支。
  3. 键入git cherry-pick SHA,将上述步骤中的SHA替换为相应的值。
  4. 切换回原始分支。
  5. 使用git reset HEAD~1将其重置以回到错误分支提交之前的状态。
cherry-pick接受给定的提交并将其应用于当前已检出的头部,从而使您可以将提交复制到新分支。

18
你甚至不需要在这里挑选。使用 git reset HEAD~N --soft 然后使用 git checkout -b 将所有未提交的代码移动到一个新分支。 - Aaron
35
在提交更改之前,文件的更改并不与特定的分支相关联。这个答案为我解决了一个谜团。谢谢。 - Tschallacka
13
当我尝试切换分支时,出现以下错误:“将覆盖以下文件的本地更改”。因此,似乎我无法切换到另一个分支并正常提交。 - Mischa
3
@Mischa 如果你在两个历史记录不同的分支之间进行切换,它是无法工作的。 - watashiSHUN
1
@Aaron,这样更好(对于提交后的情况)!请单独回答。 - Jacktose
但在我的情况下,我无法更改分支,它会中止,并要求处理已更改的文件。“错误:检出时以下文件的本地更改将被覆盖:” - rkscodes

23

遗憾的是,这种情况对我来说也经常发生,如果在git commit之前意识到了错误,我会使用git stash,否则我会使用git cherry-pick,这两个命令在其他答案中都有很好的解释。

关于git checkout targetBranch,我想澄清一下:如果targetBranch与您当前分支具有相同的历史记录,则此命令仅保留您的工作目录和已暂存快照

如果您尚未提交更改,请使用git checkout移动到新分支,然后按常规方式提交更改。

@Amber的陈述并非不正确,当您移动到一个新分支git checkout -b newBranch时,将创建一个新指针,并指向与您当前分支完全相同的提交。
实际上,如果您碰巧拥有与您当前分支共享历史记录(两者都指向相同的提交)的另一个分支,则可以通过git checkout targetBranch“移动您的更改”。

但通常不同的分支意味着不同的历史记录,Git不允许您在存在脏的工作目录或暂存区的情况下在这些分支之间切换。此时,您可以使用git checkout -f targetBranch(清空并放弃更改)或git stage + git checkout targetBranch(清空并保存更改),仅运行git checkout targetBranch将给出错误提示:

错误:通过checkout将覆盖以下文件的本地更改: ... 请提交您的更改或将其存储在隐藏栈中,然后再切换分支。退出


11

软式git重置(Soft Git Reset)可以将已提交的更改放回索引中。然后,检出你打算提交的分支。接下来,使用新的提交信息git commit

  1. git reset --soft <commit>

  2. git checkout <branch>

  3. git commit -m "提交信息"

参考git文档:

git reset [<mode>] [<commit>]此形式将当前分支头重置为<commit>,并可能更新索引(将其重置为<commit>树)和工作树(取决于<mode>)。如果省略了<commit>,则默认为--mixed。<mode>必须是以下之一:

--soft完全不触摸索引文件或工作树(但像所有模式一样,将标头重置为<commit>)。这会将所有更改的文件保留为“将要提交的更改”,就像git status所表明的那样。


正如其他人之前指出的那样,只有在你要切换的两个分支具有相同的历史记录时,这才能起作用。 - Milo Wielondek

0
如果你创建了新文件,你可以这样做:
git checkout main
git checkout -b branch-b
git checkout branch-a :rel/path/to/yourchangedfiles
git commit -m "w"
git checkout branch-a

git checkout main :rel/path/to/yourchangedfiles

# if this happens:
error: pathspec ':rel/path/to/yourchangedfiles' did not match any file(s) known to git

# then just rm the folder
trash-put rel/path/to/yourchangedfiles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接