如何将HEAD移回以前的位置?(独立头)和撤消提交

tim*_*one 141 git git-revert git-checkout git-reset git-reflog

在git中,我试图squash commit通过合并另一个分支然后HEAD通过以下方式重置到上一个位置:

git reset origin/master
Run Code Online (Sandbox Code Playgroud)

但我需要走出这一步.如何将HEAD移回上一个位置?

我有23b6772提交的SHA1 frag(),我需要将其移动到.
我怎样才能回到这个提交?

Cod*_*ard 322

在回答之前,我们添加一些背景,解释这是什么HEAD.

First of all what is HEAD?

HEAD只是对当前分支上当前提交(最新)的引用.在任何给定时间
只能有一个HEAD.(不包括git worktree)

内容HEAD存储在内部.git/HEAD,它包含当前提交的40字节SHA-1.


detached HEAD

如果你没有进行最新的提交 - 意味着HEAD指向历史记录中的先前提交,则调用它detached HEAD.

在此输入图像描述

在命令行上它看起来像这样 - SHA-1而不是分支名称,因为HEAD它没有指向当前分支的尖端

在此输入图像描述


关于如何从分离的HEAD中恢复的几个选项:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back
Run Code Online (Sandbox Code Playgroud)

这将检查指向所需提交的新分支.
此命令将签出到给定的提交.
此时,您可以创建一个分支,并从此开始工作.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>
Run Code Online (Sandbox Code Playgroud)

git reflog

你总是可以使用它reflog.
git reflog将显示更新的任何更改,HEAD并检出所需的reflog条目将设置HEAD回此提交.

每次修改HEAD时,都会有一个新条目 reflog

git reflog
git checkout HEAD@{...}
Run Code Online (Sandbox Code Playgroud)

这将使您回到所需的提交

在此输入图像描述


git reset --hard <commit_id>

将HEAD"移动"回所需的提交.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
Run Code Online (Sandbox Code Playgroud)
  • 注意:( 自Git 2.7起)
    您也可以使用它git rebase --no-autostash.


git revert <sha-1>

"撤消"给定的提交或提交范围.
reset命令将"撤消"给定提交中所做的任何更改.
将提交具有撤消补丁的新提交,而原始提交也将保留在历史记录中.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>
Run Code Online (Sandbox Code Playgroud)

此模式说明了哪个命令执行的操作.
正如你所看到的那样reset && checkout修改了HEAD.

在此输入图像描述

  • 我对使用标题的内联代码标记有问题:) (3认同)

Kay*_*y V 10

这是一种非常简单易记的方法.检查2个条件并完成1个命令.然后你又回到了正轨.

如果

你是'超级头'
(即类型git status;你看HEAD detached at <commit_id>)

现有的分支符合您的需求
(即类型git branch -v;您会看到一个分支名称,其中包含代表您要继续工作的相关提交消息)

然后

只需检查那个分支(即类型git checkout <branch_name>;你看Switched to branch <branch_name>).

成果

您现在可以像以前一样继续添加和提交您的工作; 将跟踪更改<branch_name>.

请注意,如果在分离HEAD时保存了工作,则在大多数情况下,工作将在上述过程中自动合并.如果您看到有关合并冲突的消息,请不要惊慌.有几个很棒的教程,包含修复冲突和完成合并的简单步骤.


amu*_*iar 8

git reset 23b6772
Run Code Online (Sandbox Code Playgroud)

查看您的位置是否正确:

git status
Run Code Online (Sandbox Code Playgroud)

你会看到一些东西

在分支母版上您的分支落后“起源/母版” 17次提交,并且可以快速转发。

然后将HEAD修复为当前提交:

git push --force
Run Code Online (Sandbox Code Playgroud)

  • 使用“git push --force”时要格外小心。在很多情况下,这会让你在一段时间内成为团队中最不受欢迎的人...... (7认同)
  • @KayV 看一下 `git push --force-with-lease` (Thoughtbot 文章:https://thoughtbot.com/blog/git-push-force-with-lease) (4认同)
  • 有用的标志,@oktober,和一篇好文章。感谢您将其添加到此处并向我询问。 (2认同)

ant*_*tak 5

这个问题可以理解为:

我在HEADat23b6772和 typed处于分离状态git reset origin/master(因为我想压扁)。现在我改变了主意,我该如何回到原来的HEAD状态23b6772

直截了当的答案是: git reset 23b6772

但是我遇到这个问题是因为我厌倦了每次我想参考以前的输入(复制和粘贴)提交哈希或其缩写,HEAD并且在谷歌上搜索是否有任何速记。

原来有!

git reset -(或在我的情况下git cherry-pick -

顺便说一下,这与cd -返回到*nix 中的上一个当前目录相同!太好了,我用一块石头学到了两件事。