【问题标题】:Rolling back local and remote git repository by 1 commit通过 1 次提交回滚本地和远程 git 存储库
【发布时间】:2011-06-06 13:07:23
【问题描述】:

我已阅读有关此主题的类似帖子,但我一生都无法弄清楚如何正确执行此操作。

我签入了大约 1000 个我不想要的文件,我宁愿不必通过 1by1 将它们全部从 repo 中删除。

  • 我有一个远程master分支。
  • 我有本地master分公司。

它们都在同一个版本中。

我想通过 1 次提交回滚我的遥控器。

说我在master 上的历史记录是A--B--C--D--E
我想将我的本地回滚到D
然后将其推送到远程,这样我当前的哈希将是远程和本地的 D。

我在执行此操作时遇到问题。
我正在使用 Git Tower,但对命令行很满意。有什么帮助吗?

更新: 下面是伟大的cmets。似乎部分不鼓励使用重置,尤其是在与其他用户共享存储库的情况下。 在不使用硬重置的情况下撤消先前提交的更改的最佳方法是什么?有什么办法吗?

【问题讨论】:

  • 我已将我的答案更新为“在不使用硬重置的情况下撤消上一次提交的更改”。
  • 使用git revert 无需硬重置且不会打扰用户。
  • 不鼓励回滚遥控器,但如果这是你想做的,那就去做吧。有数百种方法可以做到这一点,但结果在服务器端是一样的。

标签: git


【解决方案1】:

如果还没有人拉取你的远程仓库,你可以改变你的分支 HEAD 并强制将其推送到所述远程仓库:

git reset --hard HEAD^ 
git push -f 

(或者,如果您可以直接访问远程仓库,则可以更改其HEAD reference even though it is a bare repo

注意,正如alien-technologythe comments below 中所评论的那样,在 Windows(CMD 会话)上,您需要 ^^

git reset --hard HEAD^^
git push -f 

然后呢?如the comments Jon Schneider 所述:

如果带有“HEAD^”的命令导致error no matches found: HEAD^,请参阅“git show HEAD^ doesn't seem to be working. Is this normal?

自 2011 年以来的更新:
使用 git push --force-with-leasethat I present here,2013 年与 Git 1.8.5 一起引入)更安全。

请参阅Schwernanswer 进行说明。


如果有人已经提取了 repo 怎么办?那我该怎么办?

那么我会建议一些不会改写历史的东西:

  • git revert 本地你的最后一次提交(创建一个新的提交来逆转之前的提交)
  • 推送git revert生成的'revert'。

【讨论】:

  • 如果有人已经拉了 repo 怎么办?那我该怎么办?
  • @gwho 创建了一个分支?不,它移动了一个分支的 HEAD,但你仍然在同一个分支中。但是,由于推动不再是快进推动,是的,您需要强制推动。
  • 有没有办法知道是否有人拉了 repo?
  • 在 Windows 中,^ 字符用于续行和转义字符,执行命令:git reset --hard HEAD^^
  • @AlienTechnology 使用 Powershell,在 Windows 10 上,我只需输入 reset --hard HEAD^ 而不是 reset --hard HEAD^^ 即可重置最后一次提交。
【解决方案2】:

将本地分支设置回一个修订版(HEAD^ 表示回一个修订版):

git reset --hard HEAD^

将更改推送到原点:

git push --force

您将不得不强制推送,否则 git 会通过一次提交识别出您落后于 origin,并且什么都不会改变。

使用--force 执行此操作会告诉 git 覆盖远程仓库中的HEAD,而不考虑那里的任何进展。

【讨论】:

  • 我建议不要将其称为还原,因为这是一个在 git 中具有非常不同含义的特定术语。
  • @Jefromi:感谢您的提示。已编辑。
  • 很好的答案。我读过似乎不鼓励使用重置,尤其是在与其他用户共享存储库的情况下。有没有更简洁的方法可以撤消您之前提交的所有更改?
  • 小心!隐藏未提交的更改或丢失的更改
  • 这很酷。那么,这是否意味着当我们执行git push origin master 时,Git 能够在远程创建一个新的提交,因为本地分支至少领先一次提交?此外,后者必须与远程仓库的负责人指向的内容有本质的不同?
【解决方案3】:

如果你想恢复上次提交,请听:

第 1 步:

使用消息检查您的本地提交

$ git log

第 2 步:

删除上次提交而不重置本地分支(或主)的更改

$ git reset HEAD^

或者,如果您不希望最后提交文件和更新监听

$ git reset HEAD^ --hard

第 3 步:

我们可以更新文件和代码,再次需要强制推送它会删除以前的提交。它将保持新的提交。

$ git push origin branch -f

就是这样!

【讨论】:

  • 这不是 reverting 提交,而是替换一个。请不要误用传统术语来迷惑我们 git 新手。
【解决方案4】:

这是一个更安全的更新版本。

git reset --hard HEAD^ 
git push --force-with-lease

git push -f 将不加选择地用您自己的更改替换远程存储库。如果其他人推送了更改,他们将丢失。 git push --force-with-lease 只会在存储库符合您预期的情况下推送您的变基。如果其他人已经推送了你的推送将失败。

–force considered harmful; understanding git’s –force-with-lease

我建议将其别名为repush = push --force-with-lease

如果有人已经提取了 repo 怎么办?那我该怎么办?

告诉他们git pull --rebase=merges。而不是git fetch origingit merge origin/master,而是git fetch origingit rebase -r origin/master。这会将他们的任何本地更改重写为 master 在新的重新定位 origin/master 之上。 -r 将保留他们可能进行的任何合并。

我建议将此作为拉取的默认行为。它是安全的,可以处理其他人的变基,并减少不必要的合并。

[pull]
        rebase = merges

【讨论】:

【解决方案5】:

通过输入下面的命令,你可以看到你的 git 提交历史 -

$ git 日志

假设您在该特定分支上的历史记录就像 - 提交_A,提交_B,提交_C,提交_D。其中,commit_D 是最后一次提交,这是 HEAD 所在的位置。现在,要从本地和远程删除上一次提交,您需要执行以下操作:

第 1 步:在本地删除最后一次提交 -

$ git reset --hard HEAD~

这会将您的提交 HEAD 更改为 commit_C

第 2 步:将新 HEAD 提交的更改推送到远程

$ git push origin +HEAD

此命令将从远程删除最后一次提交。

附注此命令在 Mac OSX 上经过测试,并且应该也可以在其他操作系统上运行(但未声明其他操作系统)

【讨论】:

    【解决方案6】:

    对于 Windows 机器,使用:

    git reset HEAD~1  #Remove Commit Locally
    

    【讨论】:

      【解决方案7】:

      有很多方法可以做到这一点。根据您的要求,从下面选择任何内容。

      1.通过 REVERTing 提交:

      如果您想恢复上次 COMMIT 的所有更改,这意味着如果您在文件中添加了某些内容,这些内容将在恢复完成后被删除。如果您删除文件中的某些内容,则还原过程将添加这些文件。

      您可以还原最后一次提交。喜欢:

      1.git revert head^
      2.git push origin <Branch-Name>
      

      或者您可以使用该提交的哈希恢复到任何先前的提交。像:

      1.git revert <SHA>
      2.git push origin  <Branch-Name>
      

      2。通过重置前一个头

      如果您只想指向任何以前的提交,请使用重置;它将您的本地环境指向之前的提交。您可以将 head 重置为之前的提交或将 head 重置为之前的任何提交。

      重置为上一次提交。

      1.git reset head^
      2.git push -f origin <Branch-name>
      

      重置为之前的任何提交:

      1.git reset <SHA>
      2.git push -f origin <Branch-name>
      

      REVERT 和 RESET 之间的交易:

      为什么您会选择还原而不是重置操作?如果您已经将提交链推送到远程存储库(其他人可能已经提取了您的代码并开始使用它),那么恢复是取消更改的更好方法。这是因为 Git 工作流非常适合在分支结束时拾取额外提交,但如果在有人重置分支指针时不再在链中看到一组提交,这可能会很有挑战性。

      【讨论】:

        【解决方案8】:

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

        git reset --hard HEAD^
        git push -f <remote> <local branch>:<remote branch> 
        

        【讨论】:

          【解决方案9】:

          您也可以这样做:

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

          并让其他所有收到最新错误提交的人重置:

          git reset --hard origin/master
          

          【讨论】:

            【解决方案10】:

            如果您可以直接访问远程仓库,您可以随时使用:

            git reset --soft HEAD^
            

            这是可行的,因为没有尝试修改不存在的工作目录。更多详情请查看原答案:

            How can I uncommit the last commit in a git bare repository?

            【讨论】:

              【解决方案11】:

              我只是想从远程删除最后一次提交并清除提交历史。 以下工作就像一个魅力

              git reset --hard HEAD^ 
              git push -f 
              

              【讨论】:

              【解决方案12】:

              重置头部并恢复到上一次提交的方法是通过

              $ git reset HEAD^ --hard
              $ git push <branchname> -f
              

              但有时它可能不会被远程分支接受:

              To ssh:<git repo>
               ! [rejected]        develop -> develop (non-fast-forward)
              error: failed to push some refs to 'ssh:<git repo>'
              hint: Updates were rejected because the tip of your current branch is behind
              hint: its remote counterpart. Integrate the remote changes (e.g.
              hint: 'git pull ...') before pushing again.
              hint: See the 'Note about fast-forwards' in 'git push --help' for details.
              

              那么另一种方法是

              git revert HEAD
              git push <remote branch>
              

              这很好用。

              注意:请记住如果git push -f &lt;force&gt; 失败,然后您尝试恢复。之前做一个git pull,让远程和本地同步,然后尝试git revert
              检查git log 以确保远程和本地在相同的提交点具有相同的 SHA1..

              git revert 
              A --> B --> C -->D
              A--> B --> C --> D --> ^D(taking out the changes and committing reverted diffs)
              

              【讨论】:

                【解决方案13】:

                在本地主机上

                git reflog
                -- this will list all last commit
                  e.g Head@{0} -- wrong push
                      Head@{1} -- correct push  
                git checkout Head@{1} .
                  -- this will reset your last modified files
                
                git status 
                git commit -m "reverted to last best"
                git push origin/master
                

                不用担心别人拉不拉。

                完成!

                【讨论】:

                  【解决方案14】:

                  如果您只想从远程存储库中删除最后一次提交而不弄乱您的本地存储库,这里有一个单行:

                  git push origin +origin/master~:master
                  

                  这使用以下语法:

                  git push <remote> <refspec>
                  

                  这里,&lt;remote&gt;origin&lt;refspec&gt; 具有以下结构:

                  +origin/master~:master
                  

                  详情请见git-push(1)。前面的+ 表示“强制推送此引用”,另一部分表示“从origin/master~master(远程origin)”。不难知道origin/master~origin/master 之前的最后一次提交,对吧?

                  【讨论】:

                    【解决方案15】:

                    对我来说,这两个命令起作用:

                    git checkout commit_id
                    git push origin +name_of_branch
                    

                    【讨论】:

                      猜你喜欢
                      • 2010-10-09
                      • 2015-04-20
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-05-09
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多