我该如何从本地仓库撤销这些提交?
这是一个网站:Oh shit, git!
。
这里有许多关于如何撤销 Git 操作的技巧。其中一些包括:
天啊,我需要修改上一个提交的信息!
git commit --amend
# follow prompts to change the commit message
糟糕,我不小心把一些本应该在全新分支上的内容提交到了主分支!
# Create a new branch from the current state of master
git branch some-new-branch-name
# Remove the commit from the master branch
git reset HEAD~ --hard
git checkout some-new-branch-name
# Your commit lives in this branch now :)
您可以从本地仓库撤销提交。请按照以下步骤进行操作。
在下面的图片中,我使用 Git 命令 git checkout -b test
检出了 'test' 分支作为本地分支,并检查了本地分支的状态(使用 Git 命令 git status
),确认没有需要提交的内容。
在下一张图片中,您可以看到我对 Filter1.txt 进行了一些更改,并将该文件添加到暂存区,然后使用一些消息提交了我的更改(使用 Git 命令 git commit -m "Doing commit to test revert back"
)。
"-m 是提交消息的缩写"
在下一张图片中,您可以看到提交日志,了解您所做的每个提交(使用 Git 命令 git log
)。
因此,您可以在上面的图像中看到每个提交的提交 ID 和提交消息,现在无论您想要还原或撤消哪个提交,请复制该提交 ID 并使用下面的 Git 命令:git revert {"paste your commit id"}
。例如:
git revert 9ca304ed12b991f8251496b4ea452857b34353e7
我已经撤销了上一次提交。现在,如果您检查Git状态,您会看到修改过的文件,即Filter1.txt,尚未提交。
撤销最后一次提交的最简单方法是
git reset HEAD^
这将使项目回到您提交之前的状态。
为了完整起见,我将提供一个之前的答案中被忽略的明显方法。
由于提交未推送,远程没有更改,因此:
如果您的Git客户端消失不见了(看着你,egit),这有时是必要的。
别忘了重新提交上次推送以来的保存更改。
git commit --amend # Change last commit
git reset HEAD~1 --soft # Undo last commit
如果您已经安装了 Git Extensions,则可以轻松地撤消/还原任何提交(可以从这里下载 Git Extensions)。
打开 Git 扩展,右键单击要还原的提交,然后选择“还原提交”。
将打开一个弹出窗口(请参见下面的截屏)
如果想直接提交被还原的更改,请选择“自动创建提交”,如果想手动提交被还原的更改,请勿选择该框,并单击“还原此提交”按钮。
HEAD
。
首先,什么是HEAD?
HEAD
只是当前分支上最新提交的引用。在任何给定时间只能有一个HEAD
(不包括git worktree
)。
HEAD
的内容存储在.git/HEAD
中,其中包含当前提交的40个字节SHA-1值。
分离的 HEAD
如果你不在最新的提交上 - 意味着 HEAD
指向历史中的先前提交,这被称为分离的 HEAD
。
在命令行中,它看起来是这样的 - SHA-1而不是分支名称,因为 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 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>
撤销指定的提交或提交范围。
重置命令将“撤消”给定提交中所做的任何更改。
一个包含撤消补丁的新提交将被提交,而原始提交也将保留在历史记录中。
# 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
。
前提条件: 如果在你的库中对现有文件进行修改,这个更改最初被视为未暂存。要提交更改,需要将其暂存,也就是使用
git add
将其添加到索引中。在提交操作期间,已暂存的文件会被添加到索引中。
让我们举个例子:
- A - B - C (master)
HEAD
指向 C
,索引与 C
匹配。
git reset --soft B
的时候,意图是移除提交C并将主分支/HEAD 指向B。 git status
命令时,你可以看到被索引的文件是提交C中的,并且被标记为暂存状态。 git commit
命令会创建一个新的提交,它具有和C相同的更改。git reset --mixed B
命令。git add
将其添加到索引中,然后像平常一样提交。git reset --hard B
命令。希望这些可以使用的标记与 git reset 命令的比较有助于某人明智地使用它们。有关进一步详细信息,请参阅链接1和链接2。
我验证了一种高效的方法,并且这里提供一个具体的使用示例:
如果您想永久撤销/取消最后一次提交(以及之前的每个提交,数量不限),请按以下三个步骤操作:
1:获取要到达的提交的id = SHA,当然。
$ git log
2:使用以下命令删除之前的提交记录:
$ git reset --hard 'your SHA'
3:使用-f
选项将新的本地历史记录强制推送到您的起源 GitHub(最后提交跟踪将从 GitHub 历史记录中删除)
$ git push origin master -f
$ git log
撤销上次提交
commit e305d21bdcdc51d623faec631ced72645cca9131 (HEAD -> master, origin/master, origin/HEAD)
Author: Christophe <blabla@bla.com>
Date: Thu Jul 30 03:42:26 2020 +0200
U2_30 S45; updating files package.json & yarn.lock for GitHub Web Page from docs/CV_Portfolio...
现在我们想要提交到HEAD
commit 36212a48b0123456789e01a6c174103be9a11e61
Author: Christophe <blabla@bla.com>
Date: Thu Jul 30 02:38:01 2020 +0200
First commit, new title
$ git reset --hard 36212a4
HEAD is now at 36212a4 First commit, new title
$ git log
commit 36212a48b0123456789e01a6c174103be9a11e61 (HEAD -> master)
Author: Christophe <blabla@bla.com>
Date: Thu Jul 30 02:38:01 2020 +0200
First commit, new title
$ git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
nothing to commit, working tree clean
$ git push origin master -f
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/ GitUser bla bla/React-Apps.git
+ e305d21...36212a4 master -> master (forced update)
$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
git reflog
已经接近你所描述的内容,但它给用户更多的控制权来确定需要(撤销)做的事情。但是请注意,“撤销”在各个地方的工作方式不同,人们会期望这个功能实现许多不同的事情。撤销上一个提交?撤销上一个操作?如果最后一个操作是推送,如何撤销,(重置并推送)还是(撤销并推送)? - Romain Valeri