我正在我的存储库中做一些工作,并注意到一个文件有本地更改。我不再想要它们,所以我删除了文件,以为我可以签出一个新副本。我想做的 Git 相当于
svn up .
使用 git pull
似乎不起作用。一些随机搜索把我带到了一个有人推荐做的网站
git checkout HEAD^ src/
(src
是包含已删除文件的目录)。
现在我发现我有一个分离的头。我不知道那是什么。我该如何撤消?
git checkout master
会让您回到主分支。如果您想清除任何工作副本更改,您可能需要执行 git reset --hard
。
git checkout -- src/
create temp branch - checkout temp branch - checkout master - delete temp branch
working copy changes
的评论中是什么意思?您是指在签出另一个提交后对文件所做的更改(即,您在分离头状态下所做的更改)?
分离的头意味着你不再在一个分支上,你已经签出了历史中的一个提交(在这种情况下是 HEAD 之前的提交,即 HEAD^)。
如果要删除与分离的 HEAD 关联的更改
您只需要检查您所在的分支,例如
git checkout master
下次你更改了一个文件并想将它恢复到它在索引中的状态时,不要先删除文件,只需执行
git checkout -- path/to/foo
这会将文件 foo 恢复到它在索引中的状态。
如果您想保持与分离的 HEAD 相关联的更改
运行 git branch tmp - 这会将您的更改保存在一个名为 tmp 的新分支中。运行 git checkout master 如果您想将所做的更改合并到 master 中,请从 master 分支运行 git merge tmp。运行 git checkout master 后,您应该在 master 分支上。
如果您更改了不想丢失的文件,可以推送它们。我已经在分离模式下提交了它们,之后你可以移动到一个临时分支以便稍后在 master 中集成。
git commit -m "....."
git branch my-temporary-work
git checkout master
git merge my-temporary-work
摘自:
What to do with commit made in a detached head
git stash
?因为这是我想到的第一件事。创建一个新的分支将是一个矫枉过正。
git rebase my-temporary-work
然后删除分支 git branch -d my-temporary-work
,这样看起来就好像您首先提交到了正确的分支。
git stash
听起来确实是这个案例的完美工具。您能否用建议的步骤写一个答案来实现这一目标?
无需创建临时分支的解决方案。
当您已经在此模式下更改了某些内容并且(可选)想要保存更改时,如何退出(“修复”)分离的 HEAD 状态:
提交您想要保留的更改。如果您想接管您在分离 HEAD 状态下所做的任何更改,请提交它们。像: git commit -a -m "your commit message" 放弃你不想保留的更改。硬重置将丢弃您在分离的 HEAD 状态下所做的任何未提交的更改: git reset --hard (没有这个,第 3 步将失败,抱怨在分离的 HEAD 中修改了未提交的文件。)检查您的分支。通过检查您之前工作的分支退出分离的 HEAD 状态,例如: git checkout master 接管您的提交。您现在可以通过挑选来接管您在分离 HEAD 状态下所做的提交,如我对另一个问题的回答所示。 git reflog git cherry-pick
git reset --hard
正是我需要的,因为我希望上游成为源并且应该删除本地更改。
分离头的意思:
您不再在分支上,您已在历史记录中签出单个提交
如果您没有更改:您可以通过应用以下命令切换到 master
git checkout master
如果您有想要保留的更改:
在分离 HEAD 的情况下,提交工作正常,除了没有命名分支被更新。要使用您提交的更改更新主分支,请在您所在的位置创建一个临时分支(这样临时分支将拥有您在分离的 HEAD 中所做的所有提交更改),然后切换到主分支并将临时分支与大师。
git branch temp
git checkout master
git merge temp
HEAD 是一个指针,它直接或间接地指向一个特定的提交:
附加 HEAD 表示它附加到某个分支(即它指向一个分支)。分离的 HEAD 意味着它没有附加到任何分支,即它直接指向某个提交。
https://i.stack.imgur.com/6mrfN.jpg
换句话说:
如果它直接指向提交,则 HEAD 被分离。
如果它间接指向一个提交(即它指向一个分支,该分支又指向一个提交),则附加 HEAD。
为了更好地理解附加/分离 HEAD 的情况,让我们展示导致上面四组图片的步骤。
我们从存储库的相同状态开始(所有象限中的图片都相同):
https://i.stack.imgur.com/a9uTf.jpg
现在我们要执行 git checkout
— 在各个图片中使用不同的目标(它们顶部的命令变暗以强调我们只是打算应用这些命令):
https://i.stack.imgur.com/Ph7Y5.jpg
这是执行这些命令后的情况:
https://i.stack.imgur.com/ZgKkM.jpg
如您所见,HEAD 指向 git checkout
命令的 target — 指向一个 branch(四联体的前 3 个图像),或(直接)指向一个commit(四胞胎的最后一张图片)。
工作目录的内容也被更改,以符合适当的提交(快照),即与 HEAD (直接或间接)指向的提交一致。
所以现在我们处于与此答案开头相同的情况:
https://i.stack.imgur.com/6mrfN.jpg
如果您进行了更改,然后意识到您处于超然状态,您可以执行以下操作:stash -> checkout master -> stash pop:
git stash
git checkout master # Fix the detached head state
git stash pop # Or for extra safety use 'stash apply' then later
# after fixing everything do 'stash drop'
您将拥有未提交的更改和正常的“附加” HEAD,就像什么都没发生一样。
这是我在意识到自己处于超然状态并且已经做出一些改变之后所做的事情。
我提交了更改。
$ git commit -m "..."
[detached HEAD 1fe56ad] ...
我记得提交的哈希(1fe56ad)。然后我检查了我应该在的分支。
$ git checkout master
Switched to branch 'master'
最后,我将提交的更改应用于分支。
$ git cherry-pick 1fe56ad
[master 0b05f1e] ...
我认为这比创建临时分支要容易一些。
git cherry-pick <hash>
。
当您在 git
中签出特定提交时,您最终会处于 分离头 状态...也就是说,您的工作副本不再反映命名引用的状态(如“master” )。这对于检查存储库的过去状态很有用,但如果您实际上尝试还原更改,则不是您想要的。
如果您对特定文件进行了更改并且只想丢弃它们,则可以使用 checkout
命令,如下所示:
git checkout myfile
这将丢弃任何未提交的更改并将文件恢复到它在当前分支头部的任何状态。如果您想放弃已经提交的更改,您可能需要使用 reset
命令。例如,这会将存储库重置为先前提交的状态,丢弃任何后续更改:
git reset --hard HEAD^
但是,如果您与其他人共享存储库,则 git reset
可能会造成干扰(因为它会删除存储库历史的一部分)。如果您已经与其他人共享了更改,您通常希望查看 git revert
,它会生成一个“反提交”——也就是说,它会创建一个新的提交来“撤消”相关更改。
The Git Book 有更多详细信息。
git checkout path/to/foo
可能与 git checkout some-branch
冲突,因此最好使用 git checkout -- path/to/foo
来避免这些冲突。
由于“分离头状态”使您处于临时分支上,因此只需使用 git checkout -
即可将您置于您所在的最后一个分支上。
您可能做过git reset --hard origin/your-branch
。
尝试仅git checkout your-branch
处于“分离头”意味着 HEAD 指的是特定的未命名提交(与命名分支相反)(参见:https://git-scm.com/docs/git-checkout 部分 分离头)。实际上,这意味着您已经签出了一个提交,但没有与之关联的分支名称。
您可以选择仅通过以下方式创建与您的提交相关联的新分支
git branch new-branch-name
。
这允许您将当前状态保存在名为 new-branch-name
的新分支中,而不再处于 detached head
状态。
或者如果你想回到之前的状态,你需要选择之前被选中的分支
git checkout @{-1}
为了进一步澄清@Philippe Gerber 的回答,这里是:
https://i.stack.imgur.com/Q1HKx.png
在这种情况下,在 cherry-pick
之前,需要一个 git checkout master
。此外,只有在 detached head
中的 commit
才需要它。
附录
如果您希望返回的分支是您最后一次结帐,您可以简单地使用 checkout @{-1}
。这将带您回到之前的结帐。
此外,您可以使用例如 git global --config alias.prev
为该命令设置别名,这样您只需键入 git prev
即可切换回之前的结帐。
分离的头意味着您没有正确签出您的分支,或者您刚刚签出了一个提交。
如果您遇到这样的问题,那么首先存储您的本地更改,这样您就不会丢失您的更改。
之后...使用以下命令检查您想要的分支:
假设您想要分支 MyOriginalBranch:
git checkout -b someName origin/MyOriginalBranch
这种方法可能会丢弃部分提交历史记录,但如果旧主分支和当前状态的合并很棘手,或者您只是不介意丢失部分提交历史记录,则更容易。
为了简单地保持当前状态而不合并,将当前分离的 HEAD 转换为 master 分支:
手动备份存储库,以防出现意外错误。提交您想保留的最后更改。创建一个临时分支(我们将其命名为 detached-head),它将包含处于当前状态的文件:
git checkout -b detached-head
(a) 如果不需要保留 master 分支,请删除它
git branch -D master
(b) 或者如果您想保留它,请重命名
git branch -M master old-master
将临时分支重命名为新的主分支
git branch -M detached-head master
图片来源:改编自 Gary Lai 的this Medium article。
添加到@ralphtheninja 的答案。如果您在使用 git checkout master
后收到此消息:
请在切换分支之前提交您的更改或存储它们。中止
然后,您可以简单地使用 -f 标志强制结帐,如下所示:
git checkout -f master
显然,这将导致丢失在分离模式下所做的所有更改。所以使用的时候要小心。
Git告诉我怎么做。
如果您输入:
git checkout <some-commit_number>
保存状态
git add .
git commit -m "some message"
然后:
git push origin HEAD:<name-of-remote-branch>
通常 HEAD
指向一个分支。当它不指向分支时,而是指向像 69e51
这样的提交哈希时,这意味着您有一个分离的 HEAD。您需要将它指向两个分支来解决问题。你可以做两件事来修复它。
git checkout other_branch // 当您需要该提交哈希中的代码创建一个新分支并将提交哈希指向新创建的分支时,这是不可能的。
HEAD 必须指向一个分支,而不是提交哈希是黄金法则。
我也有类似的情况。出于某种原因,我最终得到了一个分离的头——我已经在与我认为我所在的分支相同的路径上进行了提交——例如,HEAD 是分支标签的子标签,但由于某种原因,分支标签一直停留在历史上提交...可能是因为我推了??
它不会让我推动,因为我不被认为在我认为我所在的分支上。
我不想改变我的任何历史或做任何樱桃采摘,我刚刚花了大约 8 周的时间在分支上工作,所以 reset --hard
让我有点紧张!
解决方案只是执行以下操作:
git branch -f myStuckBranch HEAD
git checkout myStuckBranch
即使 HEAD 和 myStuckBranch 现在指向同一事物,您也需要进行结帐,因为您仍然被认为处于分离的头部状态(而不是在分支上)
我不是 git 专家(主要使用 mercurial,它永远不会造成这种奇怪的情况),但我对这个命令的理解是它只是说“将 myStuckBranch 更改为指向 HEAD”。
我经常发现自己使用此命令在获取后合并来自 master 的更改,而无需交换我的工作目录 - 否则它会尝试使用旧(无趣)版本的 master:
git fetch
git branch -f master origin/master -- err yeah don't just ignore what's been going on remotely - eg point my master at the real master
git merge master -- merge the changes into my local branch
不得不一直手动执行此操作有点烦人,但仍然比更改工作目录只是为了更新另一个分支以合并其中的更改要好。
master
- git pull
已经为您执行了 git fetch
和 git merge
。毫无意义地让事情变得更复杂是没有意义的(尽管了解正在发生的事情总是很好的)!
git checkout -B myStuckBranch
git pull origin master
。这不会更新您的本地存储库的 master
分支,但它会获取然后将 origin/master
合并到当前分支中。您也可以执行 git fetch; git merge origin/master
(它不会更新您的本地 master
分支)。甚至是 git fetch origin master:master; git merge master
(它会像您的代码段一样更新您的本地 master
分支,但需要更多输入)。再说一次,做你理解的事情更重要!
我想保留我的更改,所以我只是解决这个问题......
git add .
git commit -m "Title" -m "Description"
(so i have a commit now example: 123abc)
git checkout YOURCURRENTBRANCH
git merge 123abc
git push TOYOURCURRENTBRANCH
那对我有用
当您处于分离头情况并创建新文件时,首先确保将这些新文件添加到索引中,例如:
git add .
但是,如果您只更改或删除了现有文件,则可以通过以下方式同时添加 (-a) 并使用消息 (-m) 提交:
git commit -a -m "my adjustment message"
然后,您可以使用当前状态简单地创建一个新分支:
git checkout -b new_branch_name
您将拥有一个新分支,并且您的所有调整都将在该新分支中进行。然后,您可以根据需要继续推送到远程和/或结帐/拉取/合并。
意识到我有一个分离的头,不知道我是如何设法得到它的(比如三个提交),我还发现尝试 merge
、rebase
或 cherry-pick
会触发数百个合并冲突,所以我采取了不同的方法:
(假设所有内容都已提交(工作树是“干净的”))保存我的提交消息: git log > /tmp/log 保存我的工作树: mkdir /tmp/backup && cp -a all_my files_and_directories /tmp/backup 恢复为主: git checkout master 删除所有工作文件和目录:rm ... 使用备份:cp -a /tmp/backup/。 . git add 和 git commit 使用保存的 /tmp/log 中的消息,也许用不同的文件子集重复它......
缺点是如果一个文件自 master
以来多次更改,您会丢失提交历史记录,但最后我有一个干净的 master
。
分离的 HEAD 表示您当前不在任何分支上。如果您想保留当前更改并简单地创建一个新分支,您可以这样做:
git commit -m "your commit message"
git checkout -b new_branch
之后,您可能希望将此新分支与其他分支合并。总是有用的是 git "a dog" 命令:
git log --all --decorate --oneline --graph
git pull origin master
为我工作。这只是明确给出远程和分支名称。
这对我有用,它将为分离头分配一个新分支:
git checkout new_branch_name detached_head_garbage_name
使用 git rebase 您可以将 HEAD 移动到所需的提交
假设您的分支处于分离状态,如下所示:
* bfcb8f9 Commit 4
* 540a123 Commit 3
* 4356d64 Commit 2
| * fecb8d2 Commit 2
|/
| * 8012f45 Commit 2x
|/
| * 6676d15 (HEAD -> master) Commit 2 --amend
|/
* 1818f91 Commit 1
分离的头部是通过错误地变基创建的,指向一个分离的提交,该提交是先前由于 git commit --amend 命令而创建的。
如果您想将 HEAD 引用移动到最近的提交,请使用您想要指向的所需 HASH 提交应用 rebase。在此示例中,哈希是最近提交的:
git rebase bfcb8f9
这将使您的分支的 HEAD 指向所需的提交(在这种情况下是最新的):
* bfcb8f9 (HEAD -> master) Commit 4
* 540a123 Commit 3
* 4356d64 Commit 2 --amend
| * fecb8d2 Commit 2
|/
| * 8012f45 Commit 2x
|/
| * 6676d15 Commit 2
|/
* 1818f91 Commit 1
不定期副业成功案例分享
Previous HEAD position was 7426948...
中提到的 head git