如何将本地未提交的更改合并到另一个Git分支中?


621

如何在Git中执行以下操作?

我当前的分支是branch1,并且进行了一些本地更改。但是,我现在意识到我实际上打算将这些更改应用于branch2。有没有一种方法可以应用/合并这些更改,以使它们成为branch2上的本地更改,而无需在branch1上提交它们?


2
有一个伟大的Git教程正确的位置上左右。它是所有git堆栈溢出问题的中心。
Decio Lira

Answers:


896

由于您的文件尚未提交branch1

git stash
git checkout branch2
git stash pop

要么

git stash
git checkout branch2
git stash list       # to check the various stash made in different branch
git stash apply x    # to select the right one

正如评论benjohn(见git stash手册页):

要还存储当前未跟踪(新添加)的文件,请添加参数-u,因此:

git stash -u

2
别客气。可以在unethicalblogger.com/posts/2008/11/…中获取更多关于隐藏存储的示例。
VonC

2
如果您正在使用TFS寻找相同问题的解决方案,则等效的解决方案是搁置更改,然后使用TFS Power Tools通过/ migrate开关将其搁置到正确的分支上。
xr280xr 2012年

1
这对我有用。但是,我还必须创建一个本地分支才能使“隐藏弹出窗口”正常工作。如果发生类似的情况,请检出stackoverflow.com/questions/1783405/git-checkout-remote-branch
mimoralea

21
要还存储当前未跟踪(新添加)的文件,请添加参数-u,因此:git stash -u
约翰

2
@Benjohn好点。我已将您的评论包含在答案中,以提高知名度。
VonC

84

隐匿,临时提交和变基可能都是过大的。如果尚未将更改的文件添加到索引,则可以只签出另一个分支。

git checkout branch2

只要branch1和branch2之间没有要编辑的文件相同,此方法就起作用。它将保留在branch2上,并保留您所做的工作更改。如果它们不同,则可以指定要将本地更改与通过切换带有-mcheckout选项的分支引入的更改合并。

git checkout -m branch2

如果您已将更改添加到索引,则需要先通过重置来撤消这些更改。(这将保留您的工作副本,只会删除暂存的更改。)

git reset

3
我以某种方式认为隐藏是“简单的”,但是您的方法最好是考虑到跨不同分支的工作目录。+1
VonC

6
普通的传统结帐似乎更适合手头的问题。检出的重量更轻,它仅更新需要更改的文件。也许更容易理解隐藏方法,或者可能只是因为在这种用例中结帐是否“安全”还不够明显。
CB Bailey

如果checkout -m在某些情况下不是“安全的”(可能会导致合并冲突),则存储是否可以提供任何优势(例如,您可以取消弹出存储的弹出窗口)?
Craig McQueen 2012年

1
@craigMcQueen您不能取消弹出的存储的弹出,但是存储在弹出时会抱怨冲突。您可以解决冲突然后提交,但是在这种情况下,原始存储仍在堆栈中!:)
Shaun F

如果发生合并冲突,文件不是备份为.orig吗?
jocull

13

前面提到的隐藏方法的一个较短的替代方法是:

暂时将更改移到存储处。

  1. git stash

创建并切换到新分支,然后仅一步就将隐藏项弹出。

  1. git stash branch new_branch_name

然后,只需addcommit更改到这个新分支。


10

警告:不适用于git新手。

这在我的工作流中已经足够了,我几乎已经尝试为其编写新的git命令。通常的git stash流程是要走的路,但是有点尴尬。通常,我通常会先提交新的提交,因为如果我一直在查看更改,那么所有信息都是新鲜的,最好开始- git commit找到我发现的内容(通常是我在工作时发现的属于master的错误修正)功能分支)。

如果您经常遇到这样的情况,那么在当前目录旁边又有一个工作目录,该目录总是要master签出分支,这也是很有帮助的。

所以我如何做到这一点是这样的:

  1. git commit 立即进行更改,并带有良好的提交消息。
  2. git reset HEAD~1 撤消当前分支中的提交。
  3. (可选)继续使用该功能。

有时稍后(异步),或立即在另一个终端窗口中:

  1. cd my-project-master 这是另一个共享相同的WD .git
  2. git reflog 找到我刚刚做的错误修正。
  3. git cherry-pick SHA1 提交。

您可以选择(仍然异步),然后重新设置(或合并)功能分支以获取错误修正,通常是在您要提交PR并已经清理了功能分支和WD时:

  1. cd my-project 这是我正在研究的主要WD。
  2. git rebase master 获得错误修正。

这样我可以保持工作的特点不间断,而不必操心git stash-ing任何东西,或有前清理我WD git checkout(然后再有检查的特性分支退出。),而且还有我所有的错误修正去master代替隐藏在我的功能分支中。

IMO git stashgit checkout是一个真正的PIA,当你在一些大的功能工作的中间。


我的答案有趣而有效的替代方法。+1
VonC

你来自水银吗?在my-project-master共享相同.git听起来像是它使。为什么不git checkout -b bugfixABC; git commit -a; git reset HEAD^ --hard打开master,然后稍后(异步)打开git cherry-pick <SHA1 of the commit(s) in bugfixABC?(或者,甚至避免避免git rebase --onto master feature bugfixABC从您当前所在的任何分支中找到SHA1,这意味着您可以在git reset上面的位置之后直接在SHA1 上这样做feature。)
Gauthier

但是,OP听起来好像他们还没有准备好提交更改,在这种情况下checkout -m更好。
Gauthier

2

如果是关于已提交的更改,则应查看git-rebase,但正如VonC的评论所指出的那样,当您谈论本地更改时,git-stash无疑是实现此目的的好方法。


我不明白这个解决方案:它将从branch1重写branch2的提交历史记录...为什么当我们只想在branch2中获得branch1的本地未提交更改时,如何从branch2的branch1中获得所有提交的更改?
VonC

@VonC:同意,在这种情况下,rebase将获得分支之间最后合并到branch1之后的所有提交的更改。起初我没有得到这个问题的“非承诺”参数。变基不是一个好答案。
claf

@claferri:pfew ...我开始头疼;)我本来会否定您的答案的,但是由于我自己发表了一个答案,所以出现了“明显的利益冲突”。有了您更新的帖子,我现在完全不必投票。谢谢:)
VonC

@VonC:下次,只要我的回答与此错误一样,就可以自由投票;)
claf

1

到目前为止给出的答案并不理想,因为它们需要大量不必要的工作来解决合并冲突,或者它们做出了很多错误的假设。这是完美的方法。链接是到我自己的网站。

如何在git中提交到另一个分支

您尚未提交my_branch要提交的更改master,而没有提交来自的所有更改my_branch

git merge master
git stash -u
git checkout master
git stash apply
git reset
git add example.js
git commit
git checkout .
git clean -f -d
git checkout my_branch
git merge master
git stash pop

说明

从合并master到分支开始,因为无论如何最终还是要这样做,现在是解决任何冲突的最佳时机。

-u选项(又名--include-untracked中),git stash -u防止你丢失未跟踪文件,当您以后做git clean -f -dmaster

之后git checkout master,你不很重要git stash pop,因为稍后您将需要此存储。如果先弹出在其中创建的存储my_branch,然后再git stash放入master,则以后再在其中应用该存储时,将导致不必要的合并冲突my_branch

git reset使产生的一切失去舞台git stash apply。例如,在存储中已修改但不存在的文件master会因“由我们删除”冲突而上演。

git checkout .git clean -f -d丢弃所有未提交的内容:对跟踪文件的所有更改以及所有未跟踪的文件和目录。它们已经保存在存储库中,如果留在存储区中,则master切换回时会引起不必要的合并冲突my_branch

最后一个git stash pop将基于原始my_branch,因此不会引起任何合并冲突。但是,如果您的隐藏文件包含您已承诺掌握的未跟踪文件,则git会抱怨它“无法从隐藏文件恢复未跟踪的文件”。为了解决这个矛盾,从你的工作树,然后删除这些文件git stash popgit add .git reset


2
您的答案未删除,因为它已链接到您的网站,因为它与其他帐户中的其他答案相同,因此已被删除。我发现另一个帐户的个人资料与您的个人资料相同,您是否使用了两个帐户?您可以合并两个帐户。另外,标记一个mod来说明情况,您可以不删除原始答案(带有否决权)。

1
如果将它们合并在一起,则不能将它们分开,但是只要您不使用它们进行投票欺诈(或让它们通常相互交互),可以拥有多个帐户。向你的情况解释一个mod。另外,删除是一个诚实的错误,您怎么能期望有人说您使用的是两个不同的帐户?

3
您需要标记您的帖子,并使用“其他”选项来吸引国防部的注意,当您编辑已删除的答案时,他们不会关注。我已经将您的帖子标记为Mod关注,但是它们很忙,因此请耐心等待,最终他们会和您联系。

1
请勿发布重复的内容,尤其是来自不同帐户的内容。如果两个问题相同,则投票或举报以重复形式结束。
比尔蜥蜴
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.