Git:“目前不在任何分支上。” 是否有一种简单的方法可以使分支返回并保留更改?


201

因此,我在存储库中做了一些工作,当我要提交时,我意识到我目前不在任何分支上。

使用子模块时,这种情况经常发生,我能够解决,但是过程很繁琐,而且我一直认为必须有一种更简单的方法来做到这一点。

是否有一种简单的方法可以使分支返回并保留更改?

Answers:


213

如果您尚未提交:

git stash
git checkout some-branch
git stash pop

如果您已做出承诺,但自以下以来未做任何更改:

git log --oneline -n1 # this will give you the SHA
git checkout some-branch
git merge ${commit-sha}

如果您已做出承诺,然后做了额外的工作:

git stash
git log --oneline -n1 # this will give you the SHA
git checkout some-branch
git merge ${commit-sha}
git stash pop

16
如果您已经做出承诺,那么这将无济于事。虽然没有在问题中未指定,但不能投票。
Dean Rather 2012年

24
如果您已经提交:请记下所做的提交的哈希值(使用git showgit rev-parse HEAD),切换到分支,然后git cherry-pick是提交哈希值。
araqnid 2012年

7
如果已提交,则获取上次提交的哈希。签出您想去的分支机构,以及git merge _hash_
Daniel

务必小心。如果您已做出更改,并按照以下步骤操作...您将看到消息...“您的分支机构与原产地/母公司已分离”。
thinkanotherone 2012年

1
@thinkanotherone如果您已经提交了更改,则没有什么可存储的,而签出其他分支也不是世界末日。您刚才所做的提交仍然存在,您可以使用将其合并到该分支git merge <hash-of-the-commit-you-just-made>
Erik B

160

这帮助了我

git checkout -b newbranch
git checkout master
git merge newbranch
git branch -d newbranch

25
如果您已经进行了多次提交,这就是您需要做的。
本杰明·奥克斯

还没有尝试过,但是看起来可以用。但是我认为这是一个不太可能的情况。我相信大多数人会在提交并使用公认的答案来解决该问题之前意识到自己不在任何分支上。
Erik B

49
您会感到惊讶。
艾瑞克(Eric)

@ErikB我什至不知道有没有不在分支上的事情。这个答案对我非常有帮助。
康斯坦丁·舒伯特

2
一个可爱的答案,实际上只是键入它并起作用,与GIT初学者遇到的几乎所有其他东西不同-您可能要指出,newbranch是一个任意名称,并不打算用提交哈希代替
Toni Leigh

22
git checkout master

结果是这样的:

Warning: you are leaving 2 commits behind, not connected to
any of your branches:

1e7822f readme
0116b5b returned to clean django

If you want to keep them by creating a new branch, this may be a good time to do so with:
git branch new_branch_name 1e7822f25e376d6a1182bb86a0adf3a774920e1e

所以,让我们做吧:

git merge 1e7822f25e376d6a1182bb86a0adf3a774920e1e

我没有尝试过,但似乎可以正常工作。我猜如果您git gc在运行这两个命令之间运行会丢失那些提交,但是除非您git gc自动运行,否则这应该是一种完全无风险的方法。我仍然会接受babay的回答,但是如果您想避免自己编写两个额外的命令,我想这就是要走的路。
Erik B

我在某个时候离开了master分支,我不确定。我已经提交了更改,但主服务器上没有更改。这些说明将我的更改带到了master分支,一切都很好。
Matti Jokipii 2013年

+1我很担心在退出提交后又签出另一个分支,看到此消息增加了继续前进的信心。
J-Dizzle,2015年

11

离开这里

git branch newbranch
git checkout master 
git merge newbranch 

3
@ErikB他可能已经进行了多次提交。在这种情况下,请参见babay的答案。
本杰明·奥克斯

@BenjaminOakes可能是这样,但是这些git命令甚至无效。
Erik B

@ErikB绝对正确。:) babay的答案是Alex似乎一直试图做的有效形式。
本杰明·奥克斯

9

另外,您可以设置子模块,以便签出分支而不是处于其默认的分离头状态。

编辑添加:

一种方法是在使用-b标志添加子模块时检出子模块的特定分支:

git submodule add -b master <remote-repo> <path-to-add-it-to>

另一种方法是直接进入子模块目录并签出

git checkout master

1
你能告诉我怎么做吗?
Erik B

有没有办法在默认的分支模式下更新现有子模块?更新gitmodules也许?
Hertzel Guinness 2012年

@HertzelGuinness不是。子模块在特定的提交位置签出。分支只是指向sha的指针,它指向的sha可以更改。这没有用,因为它不会冻结检出子模块的状态。如果要更改子模块,检出分支只是一种方便。
阿比森

5

解决这种情况的一种方法是在从远程分支进行了基础更改之后。在这种情况下,新的提交由指向,HEADmaster不指向它们-指向重新建立另一个分支之前的位置。

您可以master通过执行以下操作使此提交成为您的新提交:

git branch -f master HEAD
git checkout master

这会强制更新master为指向HEAD(不带您master),然后切换为master


按要求完美工作。我已经暂存了文件并提交了文件,但是由于上述错误而无法推送。上面两行代码运行得很好,并按预期方式推送了我的代码。
invinciblemuffi

4

我最近又遇到了这个问题。自从我上次使用子模块并了解了git以来,已经有一段时间了,我意识到只需签出要提交的分支就足够了。即使您不隐藏它,Git也会保留工作树。

git checkout existing_branch_name

如果您想在新分支上工作,则应该适合您:

git checkout -b new_branch_name

如果您在工作树中存在冲突,则签出将失败,但这应该是非常不寻常的,如果发生,您可以将其隐藏,弹出并解决冲突。

与已接受的答案相比,此答案将为您节省两条命令的执行,无论如何它们实际上并不需要花费很长时间。因此,我不会接受这个答案,除非它奇迹般地获得(或至少接近)比当前接受的答案更多的投票。


2

以下方法可能有效:

git rebase HEAD master
git checkout master

这会将您当前的HEAD更改重新建立在主数据库之上。然后,您可以切换分支。


另一种方法是先签出分支:

git checkout master

然后,Git应该显示您的分离提交的SHA1,然后您可以选择它们,例如

git cherry-pick YOURSHA1

或者,您也可以合并最新的:

git merge YOURSHA1

要查看来自不同分支的所有提交(确保已提交),请运行:git reflog


0

我知道我在2012年告诉babay,我认为有人不太可能不会意识到自己不在分支机构并承诺。这只是发生在我身上,所以我想我不得不承认我错了,但是考虑到这种情况直到2016年才发生在我身上,你可以说这实际上是不可能的。

无论如何,我认为创建一个新分支是过大的。您要做的就是:

git checkout some-branch
git merge commit-sha

如果在签出另一个分支之前没有复制提交sha,则可以通过运行以下命令轻松找到它:

git reflog

对于一个人来说,这是一个罕见的(不太可能)的问题。自2012年以来我就没有发生过这种情况。但是,如果您乘以git-users数量的机会……这很有可能。它可能每天都发生在某人身上。:)
babay
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.