我在远程存储库中有一个项目,与本地存储库(开发)和服务器存储库(prod)同步。我一直在做一些已经推送到远程和从服务器上拉出来的承诺更改。现在,我想撤销这些更改。因此,我可以在更改之前签出到提交,并提交新更改,但我猜再次将它们推到远程会有问题。我该怎么做,有什么建议吗?


当前回答

你可以这样做

git push origin +<short_commit_sha>^:<branch_name>

其他回答

你可以通过以下方法恢复单个提交:

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命令的更多信息,请参阅git-revert手册页。此外,查看这个答案,了解关于恢复提交的更多信息。

在这些情况下,我所做的是:

在服务器中,将光标移回上一次已知的正确提交: Git push -f origin <last_known_good_commit>:<branch_name> 在本地,执行同样的操作: Git重置——hard <last_known_good_commit> # ^^^^^^ # 可选




查看我为此目的创建的分支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)显示为“not staging for commit”:

$ 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

一种不保留“撤销”痕迹的解决方案。

注意:如果有人已经抽取了您的更改,则不要这样做 (我只会在个人回购时使用这个方法。)

run:

git reset <previous label or sha1>

这将在本地重新签出所有更新(因此git状态将列出所有更新的文件)

然后你“做你的工作”并重新提交你的更改(注意:这一步是可选的)

git commit -am "blabla"

此时,您的本地树与远程树不同

git push -f <remote-name> <branch-name>

将强制远程分支接受此推送并删除前一个推送(指定remote-name和branch-name不是强制的,但建议避免更新带有update标志的所有分支)。

!! 注意一些标签可能仍然指向删除提交!!how-to-delete-a-remote-tag

如果你按照下面给出的步骤通过Git命令行,你可以将Git本地和远程提交还原(或者你也可以称之为DELETE)。

运行以下命令查看要还原的提交id

git log --oneline --decorate --graph

你会得到如下截图

如果你也检查远程(通过Web接口),那么你可以看到这将是相同的如下所示

根据截图,目前你的提交id是e110322,但你想在本地和远程都恢复到030bbf6。

执行以下步骤删除/恢复本地+远程提交


首先本地恢复提交id 030bbf6

git reset --hard 030bbf6

紧随其后的是

git clean -f -d

这两个命令强制重置以提交阶段030bbf6,如下图所示

现在如果你跑了 git状态,然后你会看到你在远程分支中是TWO Commits BEHIND,如下所示

运行以下命令更新索引(如果有更新的话)。建议您要求所有开发人员不要接受主远程分支上的任何拉请求。

git fetch --all

一旦你完成了它,然后你需要在分支前面使用+符号强制推送这个提交,如下所示。我这里用的是主分支,你可以替换成任何分支

代码

git push -u origin +master

现在如果你看到远程的web界面,那么提交也应该被还原。

另一种不需要恢复(undo的痕迹)的方法:

如果其他人已经推送了其他提交,就不要这样做

创建你的分支的备份,在你的分支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

完成了!

我希望这对你有所帮助!;)