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

lxkprmvk  于 2022-11-27  发布在  Git
关注(0)|答案(9)|浏览(120)

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

git reset origin/master

但是我需要离开这个位置。我如何将HEAD移回之前的位置?
我有一个提交的SHA-1片段(23b6772),我需要把它移到这个提交中。

os8fio9y

os8fio9y1#

这可能不是一个技术解决方案,但它的工作.(如果任何你的队友有相同的分支在本地)
假设您的分支名称为branch-xxx
求解步骤:

  • 不执行更新或提取-不执行任何操作
  • 只需在他的计算机上从branch-xxx创建一个新分支(branch-yyy
  • 就这样,所有现有的更改都将位于此新分支(branch-yyy)中。您可以继续使用此分支。

注意:同样,这不是一个技术解决方案,但它肯定会有所帮助。

pb3s4cty

pb3s4cty2#

将最后一个非推送提交移动到新分支

如果你的问题是你在WRONG_分支上开始提交,并且想把那些最后的非推送提交移到RIGHT_BRANCH,最简单的方法是

  1. git checkout WRONG_BRANCH
  2. git branch RIGHT_BRANCH
  3. git reset —-hard LAST_PUSHED_COMMIT
  4. git checkout RIGHT_BRANCH
    此时,如果你运行git log HEAD,你会看到你所有的提交都在RIGHT_BRACH中。
    数据
  • *WRONG_分支 * 是已提交的更改(尚未推送)现在所在的位置
  • *RIGHT_分支 * 是已提交的更改(尚未推送)所在的位置
  • LAST_PUSHED_COMMIT 是要将错误分支恢复到的位置
vlf7wbxs

vlf7wbxs3#

首先,讨论有关该主题的一些基本知识。

Git中的HEAD是什么
当你运行git分支时,Git如何知道上次提交的SHA-1值?答案是HEAD文件。
通常,HEAD文件是对当前分支的符号引用,这里的符号引用是指,与普通引用不同,它包含了指向另一个引用的指针。

$ cat .git/HEAD
ref: refs/heads/master

如果运行git checkout测试,Git会将文件更新为如下所示:

$ cat .git/HEAD
ref: refs/heads/test

当你运行git commit时,它会创建一个commit对象,并指定该commit对象的父对象为HEAD中的引用所指向的任何SHA-1值。

detached HEAD是什么意思?

HEAD通常指命名分支例如,假设我们在master分支,提交有c1c2c3。现在,当创建提交时,master分支被更新以引用新提交。具体地,GIT提交创建新提交x1M11 N1 x,其父提交是先前提交x1M12 N1 x,然后更新分支x1M13 N1 x以引用新提交x1M14 N1 x。x1M15 N1 x仍然引用分支主控,因此现在间接引用提交x1M16 N1 x。
现在,如果我们 checkout 到之前的某个提交,例如:c1HEAD现在直接引用提交c1这称为处于分离的HEAD状态。这仅仅意味着HEAD引用特定提交,而不是引用命名分支。
撤销提交可以通过多种方式完成,目前最常见的方式有:

溶液1

使用git revert,此命令将撤消给定提交中所做的所有更改。
git-revert的基本功能是创建一个commit来撤销在给定commit中所做的更改,创建一个与给定commit相反的commit:

git revert <SHA-1>

另外,如果你想还原所有在HEADsha-id之间的提交,你可以向git revert传递一个提交范围:

# revert all commits between 7db02faec and HEAD 
# (excluding the start point of the range, 7db02faec)
git revert 7db02faec..HEAD

溶液2

如果你想回退到指定的提交,可以使用git-reset,因为这部分历史还没有发布。

git reset --hard <SHA-1>

同样,添加git reset --soft "HEAD{@1}"只是在调用git reset --hard <SHA-1>之前将指针移回HEAD。例如:

# Reset the index and working tree to the desired tree
# Ensure you have no uncommitted changes that you want to keep
git reset --hard 7db02faec

# Move the branch pointer back to the previous HEAD
git reset --soft "HEAD@{1}"
git commit -m "Revert to 7db02faec"
eqoofvh9

eqoofvh94#

在回答之前,让我们添加一些背景知识,解释一下HEAD是什么。
我的天啊
HEAD只是对当前分支上的当前提交(最新)的引用。
在任何给定时间只能有一个HEAD(不包括git worktree)。
HEAD的内容存储在.git/HEAD内,它包含当前提交的40字节SHA-1。
我的天啊
如果你不在最近的提交上--这意味着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 to go back

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

# 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(第一个字母)

您也可以随时使用reflog
git reflog将显示更新了HEAD的任何更改,并且检出所需的reflog条目将把HEAD设置回该提交。

    • 每次修改HEAD时,reflog中都会有一个新条目**
git reflog
git checkout HEAD@{...}

这将使您返回到所需的提交

我的天啊
将你的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.
  • 注意:(Since Git 2.7)您也可以使用git rebase --no-autostash


指令集
我的天啊
"撤消"给定的提交或提交范围。
revert命令将"撤消"在给定提交中所做的任何更改。
将提交带有撤消补丁的新提交,而原始提交也将保留在历史记录中。

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

此模式说明了哪个命令执行什么操作。
如您所见,reset && checkout修改了HEAD

ut6juiuv

ut6juiuv5#

本地第一个reset

git reset 23b6772

要查看您是否处于正确位置,请使用以下方法进行验证:

git status

您将看到类似以下的内容:
在分支master上您的分支比'origin/master'落后17次提交,可以快进。
然后在远程跟踪分支 * 上重写历史 * 以反映更改:

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

使用--force-with-lease而不是--force会引发一个错误,如果其他人同时提交到远程分支,在这种情况下,你应该先获取. More info in this article

42fyovps

42fyovps6#

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

使用git checkout -
您将看到Switched to branch <branch_name>。确认它是您想要的分支。
简要说明:这个命令会把HEAD移回它的最后一个位置。2请看这个答案后面关于结果的注解。
助记符:这个方法很像使用cd -返回到你以前访问过的目录。语法和适用的情况非常匹配(例如,当你真的想让HEAD返回到它原来的位置时,它很有用)。

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

快速的方法解决了OP的问题。但是如果你的情况稍微不同:假设你已经重新启动了Bash,然后发现自己的HEAD被分离了。在这种情况下,这里有两个简单的,容易记住的步骤。

1.选择你需要的分支

使用git branch -v
您将看到现有本地分支的列表。请获取符合您需要的分支名称。

2.将HEAD移到它上面

使用git checkout <branch_name>
您将看到Switched to branch <branch_name>。成功!

结果

使用这两种方法中的任何一种,现在都可以像以前一样继续添加和提交工作:将在<branch_name>上跟踪您的下一个更改。
请注意,如果您在分离HEAD时提交了更改,git checkout -git checkout <branch_name>都将给出附加指令。

ufj5ltwl

ufj5ltwl7#

这个问题可以理解为:

我在23b6772处与HEAD处于分离状态,并键入了git reset origin/master(因为我想挤压)。现在我改变了主意,我如何回到23b6772处的HEAD

直接的答案是:git reset 23b6772
但是我遇到这个问题是因为我厌倦了每次我想引用以前的HEAD时都要输入(复制和粘贴)提交哈希或其缩写,我正在谷歌上搜索是否有任何形式的速记。
事实证明,确实有!
git reset -(或者在我的情况下是git cherry-pick -
顺便说一句,这与cd -在 *nix中返回到以前的 current directory 是一样的!

ep6jt1vc

ep6jt1vc8#

当你运行git checkout commit_id命令时,HEAD会从13ca5593d(say commit-id)中分离出来,并且分支会在更长的时间内可用。
移回上一个位置,逐步运行命令-

  1. git pull origin branch_name(表示主机)
  2. git checkout branch_name
  3. git pull origin branch_name
    您将返回到上一个位置,并从远程资源库更新提交.
i34xakig

i34xakig9#

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

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

然后

git checkout <My-remote-branch>

然后

git pull

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

相关问题