Git:“当前未在任何分支上。”有没有简单的方法回到一个分支,同时保留更改?

256

我在代码库里做了一些工作,当我准备提交时才发现我当前没有在任何分支上。

在处理子模块时,这种情况经常发生,虽然我可以解决问题,但这个过程很繁琐,我一直在想肯定有更简单的方法。

有没有一种简单的方法可以回到一个分支上,并保留更改?

10个回答

274

如果您还没有提交:

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

25
如果您已经提交了代码,请记录您所做的提交的哈希值(使用 git showgit rev-parse HEAD 命令),然后切换到目标分支,最后使用 git cherry-pick 命令加上该提交的哈希值即可。 - araqnid
7
如果已提交,请获取最后一次提交的哈希值。切换到你希望处于的分支,然后执行 git merge _hash_ - Daniel
1
如果你已经提交了你的更改,那么就没有什么需要隐藏的了,检出一个不同的分支也不是世界末日。你刚刚做的提交仍然存在,你可以使用 git merge <hash-of-the-commit-you-just-made> 将其合并到该分支中。 - Erik B
这种做法存在风险,特别是当你遇到合并冲突时,而且你还是一个 Git 初学者。我更倾向于采用 babay 的回答,因为在当前代码基础上创建一个分支是跟踪代码位置的好方法。 - Craig McQueen
我帮助了这个人。 https://dev59.com/vWw05IYBdhLWcg3wnjPC - Hartmut Pfarr
显示剩余3条评论

172

这对我很有帮助

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

28
如果你已经提交了多个版本,这是你需要做的。 - Benjamin Oakes
还没有尝试过,但看起来应该可以工作。然而,我认为这是一个不太可能的情况。我相信大多数人在提交之前会意识到他们不在任何分支上,并使用接受的答案来解决这个问题。 - Erik B
2
@ErikB 我甚至不知道有一种不在分支上的情况。这个答案对我非常有帮助。 - Konstantin Schubert
3
很棒的回答,实际上只需输入并运行即可,与作为GIT初学者遇到的几乎所有其他事物不同 - 你可能想指出newbranch是一个任意名称,而不是打算用提交哈希替换它。 - Toni Leigh
有效的解决方案截至2015年9月28日。最后一个命令是可选的 - 它会删除新创建的分支。 - user1870776

26
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
我曾经在某个时候离开了主分支,但我并不完全确定。我已经提交了我的更改,主分支上没有任何更改。这些指令将我的更改带到了主分支,一切都很好。 - Matti Jokipii
+1 我对留下提交记录并切换到另一个分支感到有些紧张,但看到这条消息后增加了信心。 - J-Dizzle

14

在从远程分支进行rebase后,有可能会陷入这种情况。在这种情况下,新的提交由 HEAD 指向,但是 master 没有指向它们——它指向了在rebase之前的位置。

你可以通过以下方式将此提交作为新的 master

git branch -f master HEAD
git checkout master

这会强制将 master 指向 HEAD(而不会让你处于 master),然后切换到 master 分支。


按照要求完美地工作了。 我已经暂存了文件并提交了,但由于上述错误无法推送。 以上两行代码完美地工作,并按预期推送了我的代码。 - invinciblemuffi

13

这里提供另一种方式

git branch newbranch
git checkout master 
git merge newbranch 

3
他可能已经进行了多次提交。如果是这种情况,请参考babay的答案。 - Benjamin Oakes
@BenjaminOakes 可能是这样,但这些 git 命令甚至都不合法。 - Erik B
@ErikB 绝对正确。 :) babay的答案是Alex似乎一直在尝试做的有效形式。 - Benjamin Oakes

10

或者,您可以设置子模块,使其不再处于默认分离的状态,而是检出一个分支。

编辑添加:

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

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

另一种方法是进入子模块目录并将其检出

git checkout master

1
你能告诉我怎么做吗? - Erik B
有没有一种方法可以在默认分支模式下更新现有的子模块?也许更新gitmodules文件? - Hertzel Guinness
@HertzelGuinness 不完全是这样。子模块被检出到特定的提交 sha。分支只是指向 sha 的指针,它所指向的 sha 可能会改变。这并不有用,因为它不能冻结已检出的子模块的状态。检出分支只是一种方便的方式,如果您要对子模块进行更改。 - Abizern

5

我最近再次遇到了这个问题。自从我上次使用子模块以来已经有一段时间了,而且通过学习更多关于git的知识,我意识到只需切换到你想提交的分支即可。Git会保留工作树,即使你不stash它。

git checkout existing_branch_name

如果您想在一个新分支上工作,以下方法适用于您:
git checkout -b new_branch_name

如果您的工作树中存在冲突,结帐将失败,但这应该是相当罕见的情况。如果出现这种情况,您可以将其stash,然后pop并解决冲突。

与被接受的答案相比,这个答案将为您节省执行两个命令的时间,这些命令实际上也不需要花费太长时间来执行。因此,除非这个答案奇迹般地获得更多的赞同(或至少接近于目前被接受的答案),否则我将不会接受这个答案。


2
以下方法可能有效:
git rebase HEAD master
git checkout master

这将使你的当前HEAD更改在主分支之上进行变基。然后你可以切换分支。


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

git checkout master

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

git cherry-pick YOURSHA1

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

git merge YOURSHA1

要查看来自不同分支的所有提交记录(以确保您已经拥有它们),请运行:git reflog


1
我知道在2012年我告诉了babay,我认为很不可能有人没有意识到他们不在分支上并提交。但这正发生在我身上,所以我想我必须承认我错了,但考虑到这直到2016年才发生在我身上,你可以说这确实是不太可能的。

无论如何,我认为创建一个新分支有点过度了。你只需要做以下几步:

git checkout some-branch
git merge commit-sha

如果在切换到其他分支之前没有复制提交的sha值,您可以通过运行以下命令轻松找到它:

git reflog

这是一个很少见(不太可能发生)的问题,对于一个人来说。自从2012年以来我就没有遇到过。但是如果你将机会乘以git用户数量......它将非常可能发生。它可能每天发生在某个人身上。 :) - babay

-1
我发现最好的方法是将我所做更改的文件复制到一个单独的文件夹中, 然后删除我目前计算机上已有的存储库文件夹, 然后克隆主要存储库并将文件放回。

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