如何撤消“git push --mirror”?

时间:2012-02-07 21:43:12

标签: git github

在git / github项目中,我正在分支机构工作。推动后,它说:

git push
To git@github.com:...
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@github.com:...'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.

我试图解决这个问题,在Googleing上我提出了这个问题:

git push --mirror

我发出以下命令,现在好像我从服务器上删除了很多分支。

Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:...
 - [deleted]         develop
 + 797beee...bafbc50 master -> master (forced update)
 - [deleted]         milestone
 - [deleted]         robot
 - [deleted]         strategy
 * [new branch]      origin/HEAD -> origin/HEAD
 * [new branch]      origin/develop -> origin/develop
 * [new branch]      origin/master -> origin/master
 * [new branch]      origin/milestone -> origin/milestone
 * [new branch]      origin/robot -> origin/robot
 * [new branch]      origin/robot_simulator -> origin/robot_simulator
 * [new branch]      origin/strategy -> origin/strategy
 * [new branch]      origin/vision -> origin/vision

你能告诉我发生了什么吗?如何撤消我所做的更改?(如果我删除了这些分支)

2 个答案:

答案 0 :(得分:12)

您推送到默认推送目标git@github.com。这意味着,git@github.com是您的源代码库中的遥控器。

这意味着,在推送后,从服务器删除的引用仍然在本地远程。 不要更新遥控器(!)。

通过执行

验证
git branch -a

推送一侧(本地)。

它可能会显示从远程服务器删除的引用。

[待续]

您可以执行以下操作:

for-each-ref refs/remotes/origin | while read sha type name
do 
    git branch "rescue_$(basename "$name")" "$sha"
done

在本地恢复分支。它们的名称前缀为rescue_,仅作为预防措施(如果您的引用名称有趣或相互矛盾)。

origin替换为您的远程名称


测试脚本

如果你想在受控环境中测试程序,这里的方法是浓​​缩到最小步骤(在空目录中执行,例如/ tmp / work)

git init A; (cd A; touch test; git add test; git commit -m initial; git branch test1; git branch test2; git branch test3)
git clone A B
(cd B; git push --mirror origin; git branch -a)
cd A
git for-each-ref refs/remotes/origin | while read sha type name; do git branch "rescue_$(basename "$name")" "$sha"; done
git branch -a

注意在这个版本中,我是如何进入A - 这将是你的github回购。你可以git clone --mirror git@github.com:... local_rescue来获得合适的本地版本。

我建议您在尝试之前尝试使用该程序。在此过程中备份您的存储库永远不会受到伤害。

答案 1 :(得分:3)

你遇到这样的情况:

- x - A - B - C (origin/master)
   \
    D - E - F (master)

你想做两件事之一,这两件事都在Git建议你阅读的文档中描述:

  • 拉,然后推,给你这个:

    - x - A - B - C
       \           \
        D - E - F - M (master, origin/master)
    
  • 强制推送(git push --force),为您提供:

    - x - D - E - F (master, origin/master)
    

相反,使用git push --mirror基本上相当于强制推送所有内容,使远程存储库成为本地存储库的镜像。这意味着,正如它所报告的那样,删除遥控器上不在存储库中的所有内容。

编辑:sehe的答案描述了如何恢复。如果运行git remote update,这将删除它用于从中恢复的远程分支,那么以下内容可能很有用。否则,你们都已经确定了。

你最好的办法是找到从远程存储库克隆过的其他人(或者如果你很幸运,你做了一个单独的克隆),告诉他们不要拉/获取/远程更新< / strong>,并按照该回购协议的说明进行操作。

如果做不到这一点,恢复将会非常棘手。如果您最近与任何远程分支机构进行了交互,那么HEAD的reflog中可能会有痕迹:

git reflog show

否则,如果删除的引用引用了作为任何剩余分支的祖先的提交,则可以快速重新创建它们。如果他们引用不是剩余分支的祖先的东西,你可以找到悬空提交:

git fsck

并且可能弄清楚哪些分支指向它们。