如何从错误的git push -f origin master中恢复?

时间:2010-10-20 00:55:00

标签: git git-commit git-push

我刚使用--force选项向我的项目提交了错误的来源。

可以还原吗?我了解所有以前的分支都已使用-f选项覆盖,所以我可能搞砸了以前的修订版。

9 个答案:

答案 0 :(得分:44)

Git通常不会丢掉任何东西,但从中恢复可能仍然很棘手。

如果您有正确的来源,那么您可以使用--force选项将其推入遥控器。除非你告诉它,否则Git不会删除任何分支。如果您确实丢失了提交,请查看this useful guide to recovering commits。如果你知道你想要的提交的SHA-1那么你可能没问题。

最好的办法:备份所有内容,查看本地存储库中的内容。如果可能,在遥控器上执行相同操作。使用git fsck查看您是否可以恢复,最重要的是不要运行git gc

最重要的是,永远不要使用--force选项,除非你真的,真的是这个意思。

答案 1 :(得分:44)

如果你知道提交哈希,那很容易,只需重新创建你的分支。

5794458...b459f069 master -> master (forced update)

删除远程分支:

git push origin :master

然后使用以下命令重新创建分支:

git checkout 5794458
git branch master
git push origin master

答案 2 :(得分:20)

已经提到了解决方案here

# work on local master
git checkout master

# reset to the previous state of origin/master, as recorded by reflog
git reset --hard origin/master@{1}

# at this point verify that this is indeed the desired commit.
# (if necessary, use git reflog to find the right one, and
# git reset --hard to that one)

# finally, push the master branch (and only the master branch) to the server
git push -f origin master

答案 3 :(得分:6)

如果您不在强制推送来自的本地仓库中,则在原始/主要级别无法恢复。但是,如果您幸运足以使用GitHubGitHub for Enterprise,您可以查看REST API并检索丢失的提交作为补丁,例如:< / p>

  1. 列出事件并找到提交sha1长格式
  2.   

    https://api.github.com/repos/apache/logging-log4j2/events

    1. 下载丢失的提交并检索json路径中的相关补丁.files [] / patch
    2.   

      https://api.github.com/repos/apache/logging-log4j2/commits/889232e28f3863d2a17392c06c1dd8cac68485de

      1. 在本地申请并再次推送
      2.   

        git apply patch.patch&amp;&amp; git commit -m&#34;恢复提交&#34; &安培;&安培; git push origin master

答案 4 :(得分:2)

我在撤消最后一次只推送一个文件时做了同样的事情。结束后回到存储库的原始状态。我正在使用Linus的git命令,因为我在Linux上有本地副本。幸运的是,副本仍然完好无损。

我所做的只是(在疯狂地制作了更多本地回购的副本之后):

git add .
git status

(它说origin / master提前68次提交,很好......那些是我删除的所有提交)

git remote set-url origin <GIT_SSH_URL>
git push

在我强行推动之前,一切都恢复了原样。 要记住的最重要的事情是永远不要做一个git checkout。你强行推后。但最佳做法是禁用推送选项。我再也不会用它了。学到了我的教训!

答案 5 :(得分:2)

如果先前的推送不是来自本地仓库,则恢复丢失的提交甚至找出丢失的提交的另一种方法是查看CI机器。

如果您有一项工作,应该在每次提交(或一系列连续的提交)之后测试master分支,则可以查看它最近一次测试的内容。那就是您需要还原的提交。

CI机甚至可以保留该存储库的本地克隆,您可以从该克隆中执行此恢复。

来源:可能是Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation (Addison-Wesley Signature Series (Fowler))

答案 6 :(得分:1)

对于像我一样处境非常糟糕的人(例如,如果您在运行bad object时遇到git reset --hard错误)

我写了a script called treesaver,作为最后的选择,它从GitHub API中提取了所有文件。使用方法如下:

  1. 克隆treesaver脚本并cd
  2. 通过访问查找要还原的树的SHA字符串 https://api.github.com/repos/<your_username_or_org>/<repo>/events
  3. 在与您的推送事件对应的payload属性中,找到您要还原为的commit,然后单击其url
  4. commit.tree下,复制tree的{​​{1}}。
  5. 运行url

例如,对于我来说,我会运行:

python3 main.py <tree_url> <path_to_save_to>

当然,欢迎PR。

答案 7 :(得分:0)

在这里您可以阅读决策https://evilmartians.com/chronicles/git-push---force-and-how-to-deal-with-it

第二个人帮助了我。 这些命令我做错了

1) (some-branch) git pull -> correct command was git pull origin some-branch

2) (some-branch) git push -f origin some-branch

执行这些命令后,我丢失了三个提交。为了恢复它们,我查看了错误执行“ git pull”的终端,并在其中看到了

60223bf ... 0b258eb some-branch->起源/ some-branch

第二个哈希0b258eb正是我需要的。所以,我拿了这个哈希并产生命令

git push --force origin 0b258eb:some-branch

答案 8 :(得分:0)

是的,您可以在post_install do |installer| project_path = 'Y.xcodeproj' project = Xcodeproj::Project.open(project_path) project.targets.each do |target| build_phase = target.build_phases.find { |bp| bp.display_name == '[CP] Copy Pods Resources' } assets_path = '${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Assets.car' if build_phase.present? && build_phase.output_paths.include?(assets_path) == true build_phase.output_paths.delete(assets_path) end end project.save(project_path) end 之后恢复提交

  

文档中的文本

     

修剪条目早于指定时间。如果不是这个选项   指定,到期时间取自配置设置   gc.reflogExpire,默认为90天。 --expire =全部   修剪条目,无论其年龄如何; --expire =从不关闭   修剪可访问条目(但请参阅--expire-unreachable)。

因此您可以这样做:

1- git push -f your_branch

enter image description here

2-您选择要用git reflog恢复的Head_Number

enter image description here

3-您可以在git reset –hard HEAD@{HEAD-NUMBER}上看到此标题上的所有提交

4-最后,您应强制按下git cherry -v branch_name

OR

1-从您的GIT客户端(界面)获取SHA的数量

git push -f branch_name

2-力推

git reset --hard commit_SHA

希望这会有所帮助