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
How can I move HEAD back to a previous location? (Detached head) & Undo commits
提问by timpone
In Git, I was trying to do a squash commit
by merging in another branch and then resetting HEAD
to 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 HEAD
is.
在回答之前,让我们添加一些背景,解释这HEAD
是什么。
First of all what is HEAD?
First of all what is HEAD?
HEAD
is simply a reference to the current commit (latest) on the current branch.
There can only be a single HEAD
at any given time (excluding git worktree
).
HEAD
只是对当前分支上的当前提交(最新)的引用。在任何给定时间
只能有一个HEAD
(不包括git worktree
)。
The content of HEAD
is stored inside .git/HEAD
and 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 HEAD
is pointing to a prior commit in history it's called detached HEAD
.
如果您不在最新的提交上——这意味着它HEAD
指向历史中的先前提交,则称为detached HEAD
.
On the command line, it will look like this - SHA-1 instead of the branch name since the HEAD
is not pointing to the tip of the current branch:
在命令行上,它看起来像这样 - SHA-1 而不是分支名称,因为HEAD
它没有指向当前分支的尖端:
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 reflog
as well. git reflog
will display any change which updated the HEAD
and checking out the desired reflog entry will set the HEAD
back 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
这会让你回到你想要的提交
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-autostash
as well.
- 注意:(从 Git 2.7 开始)您也可以使用
git rebase --no-autostash
。
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 && checkout
modify the HEAD
.
这个模式说明了哪个命令做什么。
如您所见,reset && checkout
修改HEAD
.
回答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 HEAD
at 23b6772
and typed git reset origin/master
(because I wanted to squash). Now I've changed my mind, how do I go back to HEAD
being at 23b6772
?
我在HEAD
at23b6772
和 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 HEAD
and 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_id
then HEAD detached from 13ca5593d(say commit-id)
and branch will be on longer available.
当您运行该命令时,git checkout commit_id
HEAD 脱离13ca5593d(say commit-id)
并且分支将不再可用。
Move back to previous location run the command step wise -
移回上一个位置,逐步运行命令 -
git pull origin branch_name
(say master)git checkout branch_name
git pull origin branch_name
git pull origin branch_name
(说师父)git checkout branch_name
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 中所做的所有更改。