git cherry-pick SHA
命令,没有任何冲突或问题。然后我意识到我不想做刚刚做的事情。我还没有将这个更改推送到任何地方。如何仅删除此cherry pick?
我想知道是否有一种方法可以实现以下操作:
- 当我有其他本地更改时
- 当我没有其他本地更改时
git cherry-pick SHA
命令,没有任何冲突或问题。然后我意识到我不想做刚刚做的事情。我还没有将这个更改推送到任何地方。摘取操作基本上就是一个提交(commit),所以如果您想要撤销它,只需要撤销这个提交。
当我有其他本地更改时
将您当前的更改存储起来(stash),以便在重置提交后重新应用它们。
$ 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^
git reset --hard HEAD~
。HEAD
)更加健壮:考虑 head
是现有引用的名称的不幸情况。 - jub0bsgit reflog
可以帮助你。
在控制台中输入它,你将得到一个包含 SHA-1 的 git 历史记录列表。
只需检出您想要还原的任何 SHA-1 即可。
detached HEAD
如果您不在最新的提交上 - 意思是HEAD
指向历史记录中的先前提交,它被称为detached 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 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@{...}
这将使您返回到所需的提交
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
。
git reset --hard
- wyx尽可能避免硬重置。硬重置是Git中极少数的破坏性操作之一。幸运的是,您可以通过撤消cherry-pick而不用重置来避免任何破坏性。
请注意要撤消的cherry-pick的哈希值,假设它是${bad_cherrypick}
。执行git revert ${bad_cherrypick}
。现在,您工作树的内容就像在坏的cherry-pick之前一样。
重复git cherry-pick ${wanted_commit}
,当您对新的cherry-pick满意时,执行git rebase -i ${bad_cherrypick}~1
。在rebase期间,删除${bad_cherrypick}
及其相应的还原。
您正在工作的分支上只会有好的cherry-pick。无需重置!
git log --graph --decorate --oneline
然后(使用: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 改编了此解决方案:请参见“删除整个提交”。)一条命令,而且不使用具有破坏性的 git reset
命令:
GIT_SEQUENCE_EDITOR="sed -i 's/pick/d/'" git rebase -i HEAD~ --autostash
它只是放弃了提交,使你回到了在 cherry-pick 操作之前的状态,即使你有本地更改。
git reset HEAD^
做了什么? - Timgit reset
可以撤销提交操作,而不会放弃任何更改。我建议你阅读 https://git-scm.com/docs/git-reset。OP的问题是如何撤销一个 cherry-pick。尝试两个命令,我的命令将把您带回到 cherry-pick 之前的确切状态。git reset
将破坏您的工作树,因为它会保留 cherry-pick 的更改并且它们将和您之前存在的本地更改无法区分。 - qwertzguyreset --hard
。它不会留下任何更改。 - Timgit reset --hard
是一条破坏性命令,它将删除不相关的本地更改,并以无法恢复的方式执行!所以这不是 OP 所要求的。 - qwertzguysed
命令在做什么,以及它与手动操作的区别,还有 --autostash
是干什么用的,这个答案会更有用。 - Chris Page