git 如何将 HEAD 移回以前的位置?(分离头) & 撤消提交

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34519665/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 03:48:23  来源:igfitidea点击:

How can I move HEAD back to a previous location? (Detached head) & Undo commits

gitgit-checkoutgit-resetgit-revertgit-reflog

提问by timpone

In Git, I was trying to do a squash commitby merging in another branch and then resetting HEADto the previous place via:

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

git reset origin/master

But I need to step out of this. How can I move HEAD back to the previous location?

但我需要走出这一步。如何将 HEAD 移回之前的位置?

I have the SHA-1 fragment (23b6772) of the commit that I need to move it to. How can I get back to this commit?

我有23b6772需要将其移动到的提交的 SHA-1 片段 ( )。我怎样才能回到这个提交?

回答by CodeWizard

Before answering, let's add some background, explaining what this HEADis.

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

First of all what is HEAD?

First of all what is HEAD?

HEADis simply a reference to the current commit (latest) on the current branch.
There can only be a single HEADat any given time (excluding git worktree).

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

The content of HEADis stored inside .git/HEADand it contains the 40 bytes SHA-1 of the current commit.

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



detached HEAD

detached HEAD

If you are not on the latest commit - meaning that HEADis pointing to a prior commit in history it's called detached HEAD.

如果您不在最新的提交上——这意味着它HEAD指向历史中的先前提交,则称为detached HEAD.

Enter image description here

在此处输入图片说明

On the command line, it will look like this - SHA-1 instead of the branch name since the HEADis not pointing to the tip of the current branch:

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

Enter image description here

在此处输入图片说明

Enter image description here

在此处输入图片说明



A few options on how to recover from a detached HEAD:

关于如何从分离的 HEAD 中恢复的一些选项:



git checkout

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

This will checkout new branch pointing to the desired commit.
This command will checkout to a given commit.
At this point, you can create a branch and start to work from this point on.

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

# 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>


git reflog

git reflog

You can always use the reflogas well.
git reflogwill display any change which updated the HEADand checking out the desired reflog entry will set the HEADback to this commit.

您也可以随时使用reflog
git reflog将显示更新HEAD并检出所需的引用日志条目的任何更改将设置HEAD回此提交。

Every time the HEAD is modified there will be a new entry in the reflog

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

git reflog
git checkout HEAD@{...}

This will get you back to your desired commit

这会让你回到你想要的提交

Enter image description here

在此处输入图片说明



git reset --hard <commit_id>

git reset --hard <commit_id>

"Move" your HEAD back to the desired commit.

“移动”你的 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.
  • Note: (Since Git 2.7) you can also use the git rebase --no-autostashas well.


git revert <sha-1>

git revert <sha-1>

"Undo" the given commit or commit range.
The reset command will "undo" any changes made in the given commit.
A new commit with the undo patch will be committed while the original commit will remain in the history as well.

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

# Add a new commit with the undo of the original one.
# The <sha-1> can be any commit(s) or commit range
git revert <sha-1>


This schema illustrates which command does what.
As you can see there, reset && checkoutmodify the HEAD.

这个模式说明了哪个命令做什么。
如您所见,reset && checkout修改HEAD.

Enter image description here

在此处输入图片说明

回答by amuliar

Do

git reset 23b6772

To see if you on the right position:

看看你是否在正确的位置:

git status

You will see something

你会看到一些东西

On branch master Your branch is behind 'origin/master' by 17 commits, and can be fast-forwarded.

在 master 分支上您的分支落后于 'origin/master' 17 次提交,并且可以快进。

Then rewrite history on your remote to reflect the change:

然后在遥控器上重写历史记录以反映更改:

git push --force-with-lease // a useful command @oktober mentions in comments

回答by Kay V

Quickest possible solution (just 1 step)

最快的解决方案(只需 1 步)

Use git checkout -

git checkout -

You will see Switched to branch <branch_name>. Confirm it's the branch you want.

你会看到Switched to branch <branch_name>。确认它是您想要的分支。



Brief explanation: this command will move HEAD back to its last position. See note on outcomesat the end of this answer.

简要说明:该命令会将 HEAD 移回其上一个位置。请参阅本答案末尾的结果说明。



Mnemonic: this approach is a lot like using cd -to return to your previously visited directory. Syntax and the applicable cases are a pretty good match (e.g. it's useful when you actually want HEAD to return to where it was).

助记符:这种方法很像cd -用来返回到您以前访问过的目录。语法和适用的情况非常匹配(例如,当您真正希望 HEAD 返回到原来的位置时,它很有用)。



More methodical solution (2-steps, but memorable)

更有条理的解决方案(两步,但令人难忘)

The quick approach solves the OP's question. But what if your situation is slightly different: say you have restarted Bash then found yourself with HEAD detached. In that case, here are 2 simple, easily remembered steps.

快速方法解决了 OP 的问题。但是,如果您的情况略有不同怎么办:假设您重新启动了 Bash,然后发现自己与 HEAD 分离了。在这种情况下,这里有 2 个简单易记的步骤。

1. Pick the branch you need

1. 选择你需要的分行

Use git branch -v

git branch -v

You see a list of existing local branches. Grab the branch name that suits your needs.

您会看到现有本地分支机构的列表。获取适合您需求的分支名称。

2. Move HEAD to it

2.移动头到它

Use git checkout <branch_name>

git checkout <branch_name>

You will see Switched to branch <branch_name>. Success!

你会看到Switched to branch <branch_name>。成功!



Outcomes

结果

With either method, you can now continue adding and committing your work as before: your next changes will be tracked on <branch_name>.

无论使用哪种方法,您现在都可以像以前一样继续添加和提交您的工作:您的下一个更改将在 上进行跟踪<branch_name>

Note that both git checkout -and git checkout <branch_name>will give additional instructions if you have committed changes while HEAD was detached.

请注意,如果您在 HEAD 分离时提交了更改,则git checkout -git checkout <branch_name>将给出额外的说明。

回答by antak

The question can be read as:

这个问题可以理解为:

I was in detached-state with HEADat 23b6772and typed git reset origin/master(because I wanted to squash). Now I've changed my mind, how do I go back to HEADbeing at 23b6772?

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

The straightforward answer being: git reset 23b6772

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

But I hit this question because I got sick of typing (copy & pasting) commit hashes or its abbreviation each time I wanted to reference the previous HEADand was Googling to see if there were any kind of shorthand.

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

It turns out there is!

原来有!

git reset -(or in my case git cherry-pick -)

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

Which incidentally was the same as cd -to return to the previous current directoryin *nix! So hurrah, I learned two things with one stone.

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

回答by Deepak Kumar

When you run the command git checkout commit_idthen HEAD detached from 13ca5593d(say commit-id)and branch will be on longer available.

当您运行该命令时,git checkout commit_idHEAD 脱离13ca5593d(say commit-id)并且分支将不再可用。

Move back to previous location run the command step wise -

移回上一个位置,逐步运行命令 -

  1. git pull origin branch_name(say master)
  2. git checkout branch_name
  3. git pull origin branch_name
  1. git pull origin branch_name(说师父)
  2. git checkout branch_name
  3. git pull origin branch_name

You will be back to the previous location with an updated commit from the remote repository.

您将使用来自远程存储库的更新提交返回到之前的位置。

回答by Zaid Mirza

Today, I mistakenly checked out on a commit and started working on it, making some commits on a detach HEAD state. Then I pushed to the remote branch using the following command:

今天,我错误地检查了一个提交并开始处理它,在分离 HEAD 状态下进行了一些提交。然后我使用以下命令推送到远程分支:

git push origin HEAD: <My-remote-branch>

Then

然后

git checkout <My-remote-branch>

Then

然后

git pull

I finally got my all changes in my branch that I made in detach HEAD.

我终于在我的分支中得到了我在 detach HEAD 中所做的所有更改。