如何撤销一个成功的“git cherry-pick”?

xdnvmnnf  于 2023-08-01  发布在  Git
关注(0)|答案(7)|浏览(675)

在本地存储库上,我刚刚执行了git cherry-pick SHA,没有任何冲突或问题。然后我意识到我不想做我刚才做的事。我没有把它推到任何地方。
我怎么才能把这颗樱桃摘下来呢?
我想知道有没有办法做到这一点:

  • 当我有其他本地更改时
  • 当我没有其他本地变化时

如果可能的话,最好用一个命令来处理两种情况。

cig3rfwq

cig3rfwq1#

cherry-pick基本上就是一个提交,所以如果你想撤销它,你只需撤销提交。
当我有其他本地更改时
保存当前更改,以便在重置提交后重新应用它们。

$ git stash
$ git reset --hard HEAD^
$ git stash pop  # or `git stash apply`, if you want to keep the changeset in the stash

字符串
当我没有其他本地变化时

$ git reset --hard HEAD^

scyqe7ek

scyqe7ek2#

要撤消上次提交,只需执行git reset --hard HEAD~

编辑:此答案适用于未提及保留本地更改的问题的早期版本;蒂姆给出的公认答案确实是正确的。感谢qwertzguy的提醒。

2hh7jdfx

2hh7jdfx3#

git reflog可以来救你。
在控制台中输入它,你会得到一个git历史记录的列表,沿着代表它们的SHA-1。
只需 checkout 您希望恢复到的任何SHA-1
在回答之前,让我们添加一些背景知识,解释什么是HEAD

First of all what is HEAD?

HEAD只是对当前分支上的当前提交(latest)的引用。
在任何给定时间只能有一个HEAD。(不包括git worktree
HEAD的内容存储在.git/HEAD中,它包含当前提交的40字节SHA-1。

detached HEAD

如果你不是在最近的提交上-这意味着HEAD指向历史中的前一个提交,它被称为 * detached HEAD *。
x1c 0d1x的数据
在命令行中,它看起来像这样- 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

字符串
这将 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的更改,并检查出所需的refog条目将设置HEAD回此提交。

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

git reflog
git checkout HEAD@{...}


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


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.

您也可以使用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>


此模式说明了哪个命令执行哪些操作。
如你所见,reset && checkout修改HEAD
x1c4d 1x的

igetnqfo

igetnqfo4#

如果可能,避免硬复位。硬重置是git中极少数破坏性操作之一。幸运的是,您可以在不重置的情况下撤销樱桃采摘,并避免任何破坏性的操作。
注意你想要撤销的cherry-pick的哈希值,比如${bad_cherrypick}。做一个git revert ${bad_cherrypick}。现在,你的工作树的内容就像你的坏樱桃采摘之前一样。
重复您的git cherry-pick ${wanted_commit},当您对新的cherry-pick满意时,执行git rebase -i ${bad_cherrypick}~1。在变基过程中,删除${bad_cherrypick}及其对应的revert。
你正在处理的分支只会有好的樱桃。无需重置!

qlzsbp2j

qlzsbp2j5#

面对同样的问题,我发现,如果你已经提交和/或推到远程,因为你成功的cherry-pick,你想删除它,你可以找到cherry-pick的SHA运行:
第一个月
然后,(在使用:wq退出日志之后)可以使用
git rebase -p --onto YOUR_SHA_HERE^ YOUR_SHA_HERE
其中YOUR_SHA_HERE等于精心挑选的提交的40或缩写的7个字符的SHA。
首先,您将无法推送更改,因为您的远程存储库和本地存储库将具有不同的提交历史。你可以强制你的本地提交替换你的远程提交
git push --force origin YOUR_REPO_NAME
(我从Seth Robertson中改编了这个解决方案:请参阅“删除整个提交”。)

gijlo24d

gijlo24d6#

一个命令,并且使用破坏性的git reset命令:
GIT_SEQUENCE_EDITOR="sed -i 's/pick/d/'" git rebase -i HEAD~ --autostash
它只是删除提交,将您完全放回cherry-pick之前的状态,即使您有局部更改。

guykilcj

guykilcj7#

我刚刚做了3个git cherry-pick。要保留我的前2个樱桃选择,但删除我的第3个,最简单的答案是git cherry-pick --abort

相关问题