本文翻译自:Git - Undo pushed commits
I have a project in a remote repository, synchronized with a local repository (development) and the server one (prod). 我在远程存储库中有一个项目,与本地存储库(开发)和服务器(产品)同步。 I've been making some commited changes already pushed to remote and pulled from the server. 我一直在进行一些已提交的更改,这些更改已推送到服务器并已从服务器拉出。 Now, I want to undo those changes. 现在,我要撤消那些更改。 So I could just git checkout
to the commit before the changes and commit the new changes, but I'm guessing that there will be problems to push them again to remote. 因此,我可以在更改之前将git checkout
到提交并提交新更改,但是我猜测将它们再次推送到远程将存在问题。 Any suggestion on how should I proceed? 关于如何进行的任何建议?
#1楼
参考:https://stackoom.com/question/1XAqk/Git-撤消推送的提交
#2楼
You can revert individual commits with: 您可以使用以下方法还原单个提交:
git revert <commit_hash>
This will create a new commit which reverts the changes of the commit you specified. 这将创建一个新的提交,该提交将还原您指定的提交的更改。 Note that it only reverts that specific commit, and not commits after that. 请注意,它仅还原特定的提交,之后不提交。 If you want to revert a range of commits, you can do it like this: 如果要还原一定范围的提交,可以这样进行:
git revert <oldest_commit_hash>..<latest_commit_hash>
It reverts the commits between and including the specified commits. 它还原指定提交之间(包括指定提交)的提交。
Look at the git-revert man page for more information about the git revert
command. 查看git-revert手册页以获取有关git revert
命令的更多信息。 Also look at this answer for more information about reverting commits. 另请参阅此答案以获取有关还原提交的更多信息。
#3楼
A solution that keeps no traces of the "undo". 一种不保留“撤消”痕迹的解决方案。
NOTE: don't do this if someone allready pulled your change (I would use this only on my personal repo) 注意:如果有人已经撤回了您的更改,请不要这样做(我只会在我的个人仓库中使用它)
do: 做:
git reset <previous label or sha1>
this will re-checkout all the updates locally (so git status will list all updated files) 这将在本地重新签出所有更新(因此git status将列出所有更新的文件)
then you "do your work" and re-commit your changes (Note: this step is optional) 然后您“完成工作”并重新提交更改(注意:此步骤是可选的)
git commit -am "blabla"
At this moment your local tree differs from the remote 此时,您的本地树与远程树不同
git push -f <remote-name> <branch-name>
will push and force remote to consider this push and remove the previous one (specifying remote-name and branch-name is not mandatory but is recommended to avoid updating all branches with update flag). 将推送并强制远程考虑此推送,并删除上一个推送(指定remote-name和branch-name不是强制性的,但建议避免使用update标志更新所有分支)。
!! !! watch-out some tags may still be pointing removed commit !! 当心一些标签可能仍指向删除提交! how-to-delete-a-remote-tag 如何删除远程标签
#4楼
git revert HEAD -m 1
In the above code line. 在上面的代码行中。 "Last argument represents" “最后一个参数代表”
1 - reverts one commits. 1-恢复一次提交。
2 - reverts last two commits. 2-恢复最后两次提交。
n - reverts last n commits. n-恢复最后n次提交。
You need to push after this command to take the effect on remote. 您需要按此命令后才能在远程上生效。 You have other options like specifying the range of commits to revert. 您还有其他选项,例如指定要还原的提交范围。 This is one of the option. 这是选项之一。
Later use git commit -am "COMMIT_MESSAGE"
then git push
or git push -f
以后使用git commit -am "COMMIT_MESSAGE"
然后使用git push
或git push -f
#5楼
What I do in these cases is: 在这些情况下,我要做的是:
In the server, move the cursor back to the last known good commit: 在服务器中,将光标移回上一个已知的良好提交:
git push -f origin <last_known_good_commit>:<branch_name>
Locally, do the same: 在本地,执行相同的操作:
git reset --hard <last_known_good_commit> # ^^^^^^ # optional
See a full example on a branch my_new_branch
that I created for this purpose: 请参阅我为此创建的分支my_new_branch
上的完整示例:
$ git branch
my_new_branch
This is the recent history after adding some stuff to myfile.py
: 这是在向myfile.py
添加一些内容之后的最新历史记录:
$ git log
commit 80143bcaaca77963a47c211a9cbe664d5448d546
Author: me
Date: Wed Mar 23 12:48:03 2016 +0100
Adding new stuff in myfile.py
commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date: Tue Mar 18 12:46:59 2016 +0100
Initial commit
I want to get rid of the last commit, which was already pushed, so I run: 我想摆脱已经被推送的最后一次提交,所以我运行:
$ git push -f origin b4zad078237fa48746a4feb6517fa409f6bf238e:my_new_branch
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:me/myrepo.git
+ 80143bc...b4zad07 b4zad078237fa48746a4feb6517fa409f6bf238e -> my_new_branch (forced update)
Nice! 真好! Now I see the file that was changed on that commit ( myfile.py
) shows in "not staged for commit": 现在,我看到在该提交( myfile.py
)上更改的文件显示在“未暂存提交”中:
$ git status
On branch my_new_branch
Your branch is up-to-date with 'origin/my_new_branch'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: myfile.py
no changes added to commit (use "git add" and/or "git commit -a")
Since I don't want these changes, I just move the cursor back locally as well: 由于我不需要这些更改,因此我也只需将光标移回本地:
$ git reset --hard b4zad078237fa48746a4feb6517fa409f6bf238e
HEAD is now at b4zad07 Initial commit
So now HEAD is in the previous commit, both in local and remote: 因此,现在HEAD在本地和远程的上一次提交中:
$ git log
commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date: Tue Mar 18 12:46:59 2016 +0100
Initial commit
#6楼
You can REVERT (or you can also call it DELETE ) the Git Commit BOTH Locally and Remotely if you follow the steps as given below via git command line. 如果您通过git命令行执行以下步骤,则可以本地(或远程 )禁止(或也可以将其称为DELETE )Git提交。
Run the following command to see the commit id that you want to revert 运行以下命令以查看要还原的提交ID
git log --oneline --decorate --graph
You will get like a following screenshot 您将获得以下屏幕截图
If you also check remote (via Web Interface) then you can see that this would be same as shown below 如果您还通过“ Web Interface”(Web界面)检查“远程”,则可以看到如下所示
As per screenshot currently you are on commit id e110322 however you want to revert back to 030bbf6 BOTH LOCALLY and REMOTELY . 根据当前的屏幕截图,您的提交ID为e110322,但是您要同时还原为030bbf6 和 LOMOTELY 。
Perform the following steps to DELETE/REVERT Commits Locally+Remotely 执行以下步骤以本地/远程删除/删除提交
First Locally Reverting to commit id 030bbf6 第一次本地还原以提交ID 030bbf6
git reset --hard 030bbf6
followed by 其次是
git clean -f -d
These two commands clean force reset to commit stage 030bbf6 as shown below in snapshot 这两个命令清除强制重置以提交阶段030bbf6 ,如下快照所示
now if you run git status then you'll see that you are TWO Commits BEHIND from the remote branch as shown below 现在,如果您运行git status,那么您将看到您是来自远程分支的两次提交行为,如下所示
Run following to update your indexes (if there are any updates). 运行以下命令更新索引(如果有任何更新)。 It is recommended that you ask all developers not to accept any pull requests on main remote branch. 建议您要求所有开发人员不要在主远程分支上接受任何拉取请求。
git fetch --all
Once you are done with it then you are required to Push this commit forcefully by using + symbol in-front of branch as shown below. 完成后,需要使用分支前面的+符号强行 推送此提交,如下所示。 I have used here as master branch, you can replace it with any 我在这里用作主分支,您可以将其替换为
git push -u origin +master
now if you see the web interface of remote then commit there should be reverted as well. 现在,如果您看到远程的Web界面,则提交也应还原。