将远程重置为特定提交


709

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

git reset --hard <commit-hash>

现在,我想对遥控器执行相同的操作。我怎样才能做到这一点?之后,我做了一些提交(和推送)<commit-hash>,我只想丢弃它们。只是方式出了什么问题而已,我不想使其变得比现在更糟。;(

我基本上想倒origin/master带到<commit-hash>


3
您确定您origin/master没有被其他用户所吸引和推崇吗?您始终希望避免更改公共(即非本地)存储库的历史记录。
vindia 2011年

Answers:


1251

假设您的分支master在这里和远程都被调用,并且您的远程被调用origin,则可以执行以下操作:

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

但是,如果其他任何人正在使用远程存储库并撤消更改,则应避免这样做。在这种情况下,最好还原不需要的提交,然后按正常方式推送。

更新:您已经在下面说明其他人撤消了您已推送的更改,因此最好创建一个新的提交以还原所有这些更改JakubNarębski的回答中有一个很好的解释,说明了您可以执行此操作的选项。哪一个最方便取决于您要还原的提交数量,以及哪种方法对您最有意义。

由于从您的问题中可以很明显地看出您已经使用git reset --hard过重置master分支的方法,因此您可能需要先使用git reset --hard ORIG_HEAD来将分支移回之前的位置。(和往常一样git reset --hard,请确保它git status是干净的,您位于正确的分支上,并且已意识到git reflog它是恢复显然丢失的提交的工具。)您还应该使用来检查ORIG_HEAD指向正确的提交的位置git show ORIG_HEAD

故障排除:

如果收到类似“ ![远程拒绝] a60f7d85-> master(预接收挂钩被拒绝) ”的消息

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


21
危险危险:此重置假定当前已检出相应的(跟踪)分支,并且没有要保留的未提交的更改。使用git update-ref代替reset --hard ; 它可以让你做同样的而不是在工作树/签出的分支
sehe

3
我知道了。它已被其他人推动和改变。所以我应该使用,revert 但是可以说我想还原过去的4次提交,所以我应该做git revert comit1; git push; git revert comit2; git push; ...还是简单地做git revert commit4; git push
nacho4d 2011年

1
@ nacho4d:您不需要在每次还原后都进行推送-JakubNarębski此答案中有一个很好的说明。您确实需要将每个提交都向后还原-只需git revert commit4创建一个新的提交,该提交只会撤消在中引入的更改commit4。但是,正如我链接到的答案所指出的那样,您可以将它们汇总为一个提交。
Mark Longair 2011年

1
@Mark我已经运行了,git reset --hard但是我已经删除了本地文件并再次从原点撤出,所以我可以这样做。git revert ...我的疑问是:我是否必须还原每个提交并一次推入(一个接一个)还是只还原第一个提交之后的提交?仅正确提交?
nacho4d 2011年

1
@sehe:很难使用,因为您需要使用完整的ref名称,因此人们很容易.git用他们本不想创建的ref来填充目录。我说错了,但是没有安全检查。您可以在git手册页中找到“管道”和“瓷器”命令的分类。
Mark Longair 2011年

123

如果您不介意丢失本地更改,请使用其他答案。如果您选择了错误的提交哈希值,该方法仍然会破坏您的遥控器。

如果您只想使远程匹配成为本地存储库中任何位置的提交,则:

  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
    

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

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

3
该图是一个非常好的技巧,我刚刚添加了-5来仅获得最后的n次提交,这是一棵巨大的树。我一直在寻找避免重置的方法。很棒
AlexanderD

@AlexanderD您还可以将别名添加到Git而不是您的shell,因此它可以在任何地方使用。Git从完整命令了解那些别名和制表符,因此您可以添加参数。git config --global alias.graph 'log --graph --all --decorate --oneline'不太混乱,您仍然可以限制它,例如:git graph -5
Walf

太棒了。我总是搞砸我的本地人。这正是我不小心将自己的演出逼到生活后所需要的:(谢谢!
Jake

1
在Windows上,输入q以退出git日志。2分钟,我永远都不会回来。
dst3p

1
@ dst3p在每个平台上,队友。寻呼机程序通常是退出程序less,这q是正常的方式。Git Bash就像一个* nix终端。
沃尔夫


13

在GitLab上,您可能必须先将分支设置为不受保护的状态。您可以在[repo]>设置>存储库>受保护的分支中执行此操作。然后,马克回答的方法起作用。

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

10

如果您想要文件的早期版本,建议使用git checkout。

git checkout <commit-hash>

这样做将使您及时返回,不会影响项目的当前状态,您可以进入主线git checkout mainline

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

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


这是一个很好的答案:它可以正常工作,很安全并且很安全;如果您搞砸了,很容易回去。
bob

8

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

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

仍然不起作用,您可能要编辑<your-remote-repo>.git/config文件的接收部分:

[receive]
  #denyNonFastforwards = true
  denyNonFastforwards = false

知道如何配置远程服务器以允许非快进推送很有帮助,因为大多数答案似乎都假设使用github或bitbucket之类的远程服务。
strongbutgood

2

如果您的分支机构不是开发部门也不是生产部门,那么最简单的方法是在本地重置为某个提交并从那里创建一个新分支。您可以使用:

git checkout 000000

(其中000000是您要转到的提交ID)在有问题的分支中,然后只需创建一个新分支:

git remote add [name_of_your_remote]

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


1

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

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

错误:无法将某些引用推送到“ https://github.com/YOURREPOSITORY/AndroidExperiments.git ”提示:由于当前分支的提示位于提示:其远程对应的后面,因此拒绝更新。在再次按下之前,集成远程更改(例如提示:'git pull ...')。**

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

git push --force origin master

  1. 因此,我希望它能起作用:)

1

Sourcetree:将远程重置为特定提交

  1. 如果您向远程发送了错误的提交(origin / feature / 1337_MyAwesomeFeature),如下图所示

前往遥控器

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

在此处输入图片说明 在此处输入图片说明

  1. 选择您的旧提交,然后选择“将当前分支重置为此提交”
  2. 选择您想要的模式(如果您不希望最后一次更改,则为硬),然后单击“确定”。

在此处输入图片说明 在此处输入图片说明

  1. 将此提交推送到新的起点/功能/ 1337_MyAwesomeFeature 在此处输入图片说明

  2. 您的本地功能分支和远程功能分支现在位于上一次(您选择的)提交中 在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.