Git - Undo推送提交

时间:2014-03-27 09:11:43

标签: git

我在远程存储库中有一个项目,与本地存储库(开发)和服务器(prod)同步。我一直在做一些已经推送到远程的提交更改并从服务器中提取。现在,我想撤消这些更改。所以我可以在更改之前git checkout提交并提交新的更改,但我猜测将它们再次推送到远程会有问题。有关如何进行的任何建议?

13 个答案:

答案 0 :(得分:499)

您可以使用以下命令还原单个提交:

git revert <commit_hash>

这将创建一个新的提交,它会恢复您指定的提交的更改。请注意,它只会还原该特定提交,而不会在此之后提交。如果要还原一系列提交,可以这样做:

git revert <oldest_commit_hash>..<latest_commit_hash>

它恢复指定提交之间的提交。

查看git-revert man page以获取有关git revert命令的更多信息。另请查看this answer以获取有关还原提交的更多信息。

答案 1 :(得分:247)

不会留下“撤消”痕迹的解决方案。

注意:如果有人已经撤消了您的更改,请不要这样做 (我只会在我的个人回购中使用它)

做的:

git reset <previous label or sha1>

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

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

git commit -am "blabla"

此时您的本地树与远程

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

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

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

答案 2 :(得分:122)

我在这些案件中所做的是:

  • 在服务器中,将光标移回上一次已知的良好提交:

    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)显示在“not staged 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

答案 3 :(得分:58)

如果您通过git命令行执行以下步骤,则可以撤销(或者您也可以将其命名为 DELETE )Git Commit BOTH本地和远程。 / p>

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

git log --oneline --decorate --graph

您将获得以下屏幕截图 enter image description here

如果您还检查了远程(通过Web界面),那么您可以看到这与下面显示的相同

enter image description here

根据屏幕截图,您目前处于提交ID e110322 但是您希望恢复为 030bbf6 本地和远程

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

首先在本地恢复提交ID 030bbf6

git reset --hard 030bbf6

接着是

git clean -f -d

这两个命令清理强制重置为提交阶段 030bbf6 ,如下面快照中所示

enter image description here

现在如果你跑了 git status然后你会看到你是远程分支的两个提交者,如下所示 enter image description here

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

git fetch --all

完成后,您需要在分支前面使用 + 符号推送此提交强制,如图所示下面。我在这里用作 master 分支,你可以用任何

替换它

enter image description here 代码

git push -u origin +master

现在,如果您看到远程的Web界面然后提交,那么也应该还原。

enter image description here

答案 4 :(得分:24)

假设 61234 是您要保留的最后一个好的提交的 sha 编号。

    git reset --hard 61234
    git push -f origin master 

将完全删除所有错误的提交,没有任何痕迹。

注意:示例假定 master 分支位于 'origin' 远程。

答案 5 :(得分:19)

2020简单方法:

import math

start = 0; chunkSize = 100
chunkNo = math.ceil(df.index.size / chunkSize)
for n in range(1, chunkNo + 1):
    varName = f'df{n}'
    endNo = start + chunkSize
    globals()[varName] = df.iloc[start : endNo]
    print(f'Created: {varName}, rows [ {start:4} : {endNo:4} )')
    start += chunkSize

(您要保留的最后一次提交的哈希值)。

您将在本地保留现在尚未提交的更改。

如果要再次推动,则必须执行以下操作:

git reset <commit_hash>

答案 6 :(得分:18)

git revert HEAD -m 1

在上面的代码行中。 “最后一个论点代表”

  • 1 - 恢复一次提交。

  • 2 - 恢复最后两次提交。

  • n - 恢复最后一个n 提交。

您需要在此命令后按下以对远程执行效果。您还有其他选项,例如指定要还原的提交范围。这是其中一个选择。

稍后使用git commit -am "COMMIT_MESSAGE" 然后是git pushgit push -f

答案 7 :(得分:7)

重置为我辛苦了: 谢谢@ Mo D Genensis和@ vibs2006


git reset --hard 'your last working commit hash'

git clean -f -d

git push -f

答案 8 :(得分:2)

这将删除您的推送提交

git reset --hard 'xxxxx'

git clean -f -d

git push -f

答案 9 :(得分:0)

这是我的方式:

假设分支名称为develop

# Create a new temp branch based on one history commit
git checkout <last_known_good_commit_hash>
git checkout -b develop-temp

# Delete the original develop branch and 
# create a new branch with the same name based on the develop-temp branch
git branch -D develop
git checkout -b develop

# Force update this new branch
git push -f origin develop

# Remove the temp branch
git branch -D develop-temp

答案 10 :(得分:0)

您可以做类似的事情

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

答案 11 :(得分:0)

另一种无需还原(撤消痕迹)的方式:

如果其他人推送了其他提交,请勿这样做

在分支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

完成!

希望对您有所帮助! ;)

答案 12 :(得分:0)

干净利落:

git rebase -i <hash of last good commit, 9 chars is enough>

现在您将获得从最后一次良好提交到 HEAD 的提交列表,其中包含对每次提交执行的操作的选项。 DROP 将丢弃该提交。保存文件。

现在修复上游做:

git push --force-with-lease

With lease 这样您就不会不小心给处理您推送更新的其他人造成问题)

通过删除错误的提交而不是引入新的提交来修复早期的错误提交,从而保持日志干净。