【发布时间】:2014-05-06 03:30:45
【问题描述】:
我在远程存储库中有一个项目,与本地存储库(开发)和服务器(生产)同步。我一直在进行一些已提交的更改,这些更改已经推送到远程并从服务器中拉出。现在,我想撤消这些更改。所以我可以在更改之前git checkout 提交新更改并提交新更改,但我猜测将它们再次推送到远程会有问题。关于我应该如何进行的任何建议?
【问题讨论】:
标签: git
我在远程存储库中有一个项目,与本地存储库(开发)和服务器(生产)同步。我一直在进行一些已提交的更改,这些更改已经推送到远程并从服务器中拉出。现在,我想撤消这些更改。所以我可以在更改之前git checkout 提交新更改并提交新更改,但我猜测将它们再次推送到远程会有问题。关于我应该如何进行的任何建议?
【问题讨论】:
标签: git
您可以通过以下方式恢复单个提交:
git revert <commit_hash>
这将创建一个新的提交,它会还原您指定的提交的更改。请注意,它只恢复该特定提交,而不是之后的提交。如果你想恢复一系列提交,你可以这样做:
git revert <oldest_commit_hash>..<latest_commit_hash>
它会还原 <oldest_commit_hash> 之后的所有提交,包括 <latest_commit_hash>。在某些版本的 git 上,它还会还原 <oldest_commit_hash>,因此请仔细检查该提交是否被还原。您始终可以使用g reset --hard HEAD~ 删除最新的还原提交(还原最旧的提交)。
要知道提交的哈希值,您可以使用git log。
查看git-revert man page 以获取有关git revert 命令的更多信息。另外,请查看 this answer 了解有关恢复提交的更多信息。
【讨论】:
<oldest_commit_hash> 包含在还原列表中
一个不保留“撤消”痕迹的解决方案。
注意:如果有人已经提取了您的零钱,请不要这样做 (我只会在我的个人仓库中使用它。)
运行:
git reset <previous label or sha1>
这将在本地重新签出所有更新(因此 git status 将列出所有更新的文件)
然后你“做你的工作”并重新提交你的更改(注意:此步骤是可选的)
git commit -am "blabla"
此时您的本地树与远程树不同
git push -f <remote-name> <branch-name>
将强制远程分支接受此推送并删除前一个(指定远程名称和分支名称不是强制性的,但建议避免使用更新标志更新所有分支)。
!!注意一些标签可能仍然指向删除提交! how-to-delete-a-remote-tag
【讨论】:
git push -f 的最后一次正确提交和远程历史清理!谢谢!
git revert HEAD -m 1
在上面的代码行中。 "最后一个参数代表"
1 - 恢复一个提交。
2 - 恢复最后两次提交。
n - 恢复上一个 n 提交。
你需要在这个命令之后 push 才能远程生效。您还有其他选项,例如指定要还原的提交范围。这是选项之一。
以后用git commit -am "COMMIT_MESSAGE"
然后git push 或git push -f
【讨论】:
git revert ref1..ref2
在这些情况下我要做的是:
在服务器中,将光标移回上次已知的良好提交:
git push -f origin <last_known_good_commit>:<branch_name>
在本地,做同样的事情:
git reset --hard <last_known_good_commit>
# ^^^^^^
# optional
查看我为此目的创建的分支 my_new_branch 的完整示例:
$ git branch
my_new_branch
这是在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
我想摆脱已经推送的最后一次提交,所以我运行:
$ 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)
不错!现在,我看到在该提交 (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")
由于我不想要这些更改,我也只是将光标移回本地:
$ git reset --hard b4zad078237fa48746a4feb6517fa409f6bf238e
HEAD is now at b4zad07 Initial commit
所以现在 HEAD 在本地和远程的上一次提交中:
$ git log
commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date: Tue Mar 18 12:46:59 2016 +0100
Initial commit
【讨论】:
如果您通过 git 命令行按照下面给出的步骤操作,您可以恢复(或者您也可以将其称为 DELETE)Git 提交 本地和远程。
运行以下命令以查看要还原的提交 ID
git log --oneline --decorate --graph
如果您还检查了远程 (通过 Web 界面),那么您可以看到这将如下所示
根据屏幕截图,您目前处于提交 ID e110322,但是您想恢复到 030bbf6 BOTH LOCALLY 和 REMOTELY。
执行以下步骤来删除/恢复本地+远程提交
首先本地恢复到提交 id 030bbf6
git reset --hard 030bbf6
紧随其后
git clean -f -d
这两个命令清除强制重置到提交阶段030bbf6,如下图所示
现在如果你跑 git status 然后你会看到你是来自远程分支的两个提交,如下所示
运行以下以更新您的索引(如果有任何更新)。建议您要求所有开发人员不要在主远程分支上接受任何拉取请求。
git fetch --all
完成后,您需要在分支前使用 + 符号Push 强制,如图所示以下。我这里用的是 master 分支,你可以用任何替换它
git push -u origin +master
现在,如果您看到远程的 web 界面,那么提交也应该被还原。
【讨论】:
git push -u origin +YourBrandName
这将删除您推送的提交
git reset --hard 'xxxxx'
git clean -f -d
git push -f
【讨论】:
clean 很危险。它会删除不受版本控制的文件!
这是我的方式:
假设分支名称是develop。
# Checkout a new temp branch based on one history commit
git checkout <last_known_good_commit_hash>
# Delete the original develop branch
git branch -D develop
# Create a new develop branch based on the temp branch
git checkout -b develop
# Force update this new branch
git push -f origin develop
【讨论】:
你可以这样做
git push origin +<short_commit_sha>^:<branch_name>
【讨论】:
2020 简单方法:
git reset <commit_hash>
(您要保留的最后一次提交的哈希)。
您将在本地保留现在未提交的更改。
如果你想再次推送,你必须这样做:
git push -f
【讨论】:
重置对我来说很辛苦: 谢谢@Mo D Genensis 和@vibs2006
git reset --hard 'your last working commit hash'
git clean -f -d
git push -f
【讨论】:
另一种无需还原(撤消痕迹)的方式:
如果其他人推送了其他提交,请不要这样做
创建分支的备份,位于您的分支my-branch 中。因此,如果出现问题,您可以重新启动该过程而不会丢失任何已完成的工作。
git checkout -b my-branch-temp
回到你的分支。
git checkout my-branch
重置,放弃你的最后一次提交(撤消它):
git reset --hard HEAD^
删除远程分支(例如origin 远程)。
git push origin :my-branch
将您的分支(没有不需要的提交)重新推送到远程。
git push origin my-branch
完成!
希望对您有所帮助! ;)
【讨论】:
假设61234 是您要保留的最后一个良好提交的 sha-number。
git reset --hard 61234
git push -f
将完全删除所有错误的提交而不留任何痕迹。
注意:如果您想将(您重置的提交)推送到特定分支,您可以使用 git push -f origin branch-name。
【讨论】:
git push -f origin master 时出现remote: GitLab: You are not allowed to force push code to a protected branch on this project. 错误。我想我必须在我的 gitlab 服务器上更改一些配置。
git push -f origin master——很高兴它没有成功!
干净利落:
git rebase -i <hash of last good commit, 9 chars is enough>
现在您将获得从最后一次良好提交到HEAD 的提交列表,其中包含如何处理每个提交的选项。 DROP 将丢弃该提交。保存文件。
现在修复上游做:
git push --force-with-lease
(With lease 这样您就不会意外地给处理您推送更新的其他人带来问题)
这通过删除错误的提交而不是引入新的提交来修复早期的错误提交来保持日志清洁。
【讨论】: