【问题标题】:Resetting remote to a certain commit将远程重置为某个提交
【发布时间】:2011-08-14 13:45:17
【问题描述】:

我想放弃在提交 <commit-hash> 之后所做的所有更改。 所以我做了:

git reset --hard <commit-hash>

现在我想对我的遥控器做同样的事情。我怎样才能做到这一点?我在&lt;commit-hash&gt; 之后做了一些提交(和推送),我只想将它们全部丢弃。只是在路上出了点非常错误,我不想让它变得比现在更糟。 ;(

我基本上想把我的origin/master倒回&lt;commit-hash&gt;

【问题讨论】:

  • 你确定你的origin/master没有被其他用户拉推吗?始终要避免更改公共(即非本地)存储库的历史记录。

标签: git


【解决方案1】:

我最近遇到了同样的问题,通过两个步骤解决了:

  1. 使用git reset --hard HEAD~1 将其重置为本地 git,此处 HEAD~1 是最近的提交。
  2. 强制将其推入所需的分支git push -f origin main

就是这样。

【讨论】:

    【解决方案2】:

    使用其他一些答案可能会导致不必要的本地状态丢失。本地更改并非天生就需要更改遥控器。如果您选择返回错误的提交,这种方法仍然会破坏您的遥控器,但即便如此,您通常也可以找到正确的提交并重试。

    必须在您希望远程匹配的本地存储库中的某处具有所需的提交。

    1. 不要不要进行任何重置。
    2. 使用git log 查找您希望远程执行的提交。使用 git log -p 查看更改,或使用 git log --graph --all --oneline --decorate 查看紧凑树。
    3. 复制提交的哈希、标记或(如果是提示)其分支名称。
    4. 运行如下命令:
      git push --force <remote> <commit-ish>:<the remote branch>
      
      例如
      git push --force origin 606fdfaa33af1844c86f4267a136d4666e576cdc:master
      
      要么
      git push --force staging v2.4.0b2:releases
      

    如果强制推送失败,很可能是被遥控器禁用了。这可以通过临时更改receive.denyNonFastForwards and receive.denyDeletes 之一或两者来解决。如果您的远程托管在没有 shell 访问权限的服务上,它可能具有您可以更改以允许强制推送的设置。


    我使用方便的别名 (git go) 来查看第 2 步中的历史记录,可以这样添加:

    git config --global alias.go 'log --graph --all --decorate --oneline'
    

    【讨论】:

    • 该图是一个非常好的提示,我只是添加了 -5 以仅获取最后 n 次提交,否则它是一棵巨大的树。避免重置正是我想要的。很棒
    • 这是完美的。我总是搞砸我的本地人。这正是我意外推动我的舞台生活后所需要的:(谢谢!
    • 在Windows上,输入q退出git日志。 2 分钟,我再也回不来了。
    • @dst3p 每个平台都有,伙计。寻呼程序通常是lessq 是正常的退出方式。 Git Bash 就像一个 *nix 终端。
    • @Walf 谢谢!当时我在 Windows 上,所以不想做任何假设。 :)
    【解决方案3】:

    假设您的分支在本地和远程都称为 ma​​ster,并且您的 remote 称为 origin,您可以这样做:

    git reflog 获取所有提交历史记录,您的commit hash 格式如下:e34e1ff

    git reset --hard <commit-hash>
    
    git push -f origin master
    

    【讨论】:

      【解决方案4】:

      Sourcetree:将远程重置为某个提交

      1. 如果您向遥控器 (origin/feature/1337_MyAwesomeFeature) 推送了错误的提交,如下图所示

      1. 转到遥控器 > 原点 > 功能 > 1337_MyAwesomeFeature
      2. 右键单击并选择“Delete origin/feature/1337_MyAwesomeFeature”(如果您需要备份,请更改其名称并跳过第 4 步。)
      3. 单击“强制删除”和“确定”。

      1. 选择您的旧提交并选择“将当前分支重置为此提交”
      2. 选择您想要的模式(如果您不想进行最后的更改,则选择硬模式)和“确定”。

      1. 将此提交推送到新的原点/功能/1337_MyAwesomeFeature

      2. 您的本地功能分支和远程功能分支现在位于上一个(您选择的)提交上

      【讨论】:

        【解决方案5】:

        假设您的分支在此处和远程都称为master,并且您的远程称为origin,您可以这样做:

         git reset --hard <commit-hash>
         git push -f origin master
        

        但是,如果其他人正在使用您的远程存储库并提取了您的更改,您应该避免这样做。在这种情况下,最好将您不想要的提交 revert 提交,然后正常推送。

        更新:您在下面解释说,其他人已经撤消了您推送的更改,因此最好创建一个新的提交来还原所有这些更改。在this answer from Jakub Narębski 中有一个很好的解释你这样做的选项。哪一种最方便取决于您要还原多少次提交,以及哪种方法对您最有意义。

        由于您的问题很明显您已经使用git reset --hard 重置您的master 分支,您可能需要首先使用git reset --hard ORIG_HEAD 将您的分支移回原来的位置。 (与git reset --hard 一样,确保git status 是干净的,您在正确的分支上,并且您知道git reflog 作为恢复明显丢失的提交的工具。)您还应该检查ORIG_HEAD 指向正确的提交,git show ORIG_HEAD

        疑难解答:

        如果您收到类似“! [remote denied] a60f7d85 -> master (pre-receive hook denied)”之类的消息

        那么你必须允许特定分支的分支历史重写。例如,在 BitBucket 中,它说“不允许重写分支历史记录”。您必须检查一个名为 Allow rewriting branch history 的复选框。

        【讨论】:

        • 危险危险:此重置假定当前已签出相应的 (tracking) 分支并且没有您想要保留的未提交更改. 使用git update-ref 代替reset --hard;它将允许您在没有工作树/签出分支的情况下做同样的事情
        • 我明白了。它已被其他人推动和改变。所以我应该使用revert ,但假设我想恢复过去的4次提交,所以我应该使用git revert comit1; git push; git revert comit2; git push; ...或者干脆git revert commit4; git push
        • @nacho4d:您不需要在每次还原后推送 - this answer from Jakub Narębski 中有一个很好的说明。您确实需要将每个提交还原 - 只需执行 git revert commit4 创建一个仅撤消在 commit4 中引入的更改的新提交。不过,正如我所链接的答案所指出的,您可以将它们整合到一个提交中。
        • @Mark 我已经运行了git reset --hard,但我已经删除了我的本地并再次从原点拉出,所以我可以这样做git revert ...我现在的疑问是:我是否必须恢复每个提交和推送(一个接一个)还是仅在正确提交后恢复第一个提交?
        • @sehe:它很难使用,因为您需要使用完整的引用名称,因此人们很容易在他们的.git 目录中乱扔他们无意创建的引用。不过,我说没有安全检查是错误的。您可以在git man page 中找到“管道”和“瓷器”命令的分类。
        【解决方案6】:

        如果您的分支不是开发或生产,实现此目的的最简单方法是在本地重置为某个提交并从那里创建一个新分支。你可以使用:

        git checkout 000000

        (其中 000000 是您想要去的提交 ID)在有问题的分支中,然后简单地创建一个新分支:

        git 远程添加 [name_of_your_remote]

        然后你可以创建一个新的 PR,一切都会正常工作!

        【讨论】:

          【解决方案7】:

          在 GitLab 上,您可能需要先将您的分支设置为 unprotected。您可以在 [repo] > Settings > Repository > Protected Branches 中执行此操作。然后马克答案中的方法有效。

          git reset --hard <commit-hash>
          git push -f origin master
          

          【讨论】:

          • 在gitlab中解除对分支的保护是非常重要的一步!
          【解决方案8】:

          做一件事, 获取提交的 SHA 号。比如 87c9808 然后,

          1. 移动你自己,即你的头到指定的提交(通过做 git reset --hard 89cef43//在此处提及您的号码)
          2. 接下来对随机文件进行一些更改,这样 git 会要求您在本地提交,然后远程提交 因此,您现在需要做的是。 应用更改后 git commit -a -m "试用提交"
          3. 现在推送以下提交(如果已在本地提交) 经过 git push origin master
          4. 现在 git 会问你什么

          错误:未能将一些引用推送到 'https://github.com/YOURREPOSITORY/AndroidExperiments.git' 提示:更新被拒绝,因为您当前分支的尖端落后 提示:它的远程对应物。集成远程更改(例如 提示:'git pull ...') 在再次推送之前。**

          1. 因此现在您可以做的是

          git push --force origin master

          1. 因此,我希望它有效:)

          【讨论】:

            【解决方案9】:

            如果你想要以前版本的文件,我建议使用 git checkout。

            git checkout <commit-hash>
            

            这样做会及时送你回来,不会影响你项目的当前状态,你可以来主线 git checkout 主线

            但是当您在参数中添加文件时,该文件会返回给您 从以前的时间到您当前的项目时间,即您当前的项目已更改并需要提交。

            git checkout <commit-hash> -- file_name
            git add .
            git commit -m 'file brought from previous time'
            git push
            

            这样做的好处是它不会删除历史记录,也不会还原特定的代码更改(git revert)

            在此处查看更多信息https://www.atlassian.com/git/tutorials/undoing-changes#git-checkout

            【讨论】:

            • 这是一个很好的答案:它有效,经期而且非常安全;如果你搞砸了,很容易回去。
            • 这应该添加到接受的答案中。好多了。
            【解决方案10】:

            我对前面答案的两分钱:如果

            git push --force <remote> <the-hash>:<the remote branch>
            

            还是不行,你可能要编辑&lt;your-remote-repo&gt;.git/config文件的接收部分:

            [receive]
              #denyNonFastforwards = true
              denyNonFastforwards = false
            

            【讨论】:

            • 了解如何配置远程以允许非快进推送会很有帮助,因为大多数答案似乎都假设使用 github 或 bitbucket 等远程服务。
            【解决方案11】:

            我通过这个命令解决了像你这样的问题:

            git reset --hard <commit-hash> 
            git push -f <remote> <local branch>:<remote branch> 
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2015-05-08
              • 2018-02-28
              • 2018-07-04
              • 1970-01-01
              • 2014-01-05
              • 2019-09-16
              • 2021-12-18
              相关资源
              最近更新 更多