Git重置 – 硬和远程存储库

我有一个仓库,它有一些不好的提交(在这个例子中,D,E和F)。

ABCDEF主机和原点/主机

我已经用git reset --hard专门修改了本地仓库。 我在复位前拿了一个分支,所以现在我有一个回购看起来像:

 ABC master \ DEF old_master ABCDEF origin/master 

现在我需要那些不好的提交的一些部分,所以我樱桃select了我需要的一些位,并做了一些新的提交,所以现在我有以下本地:

 ABCGH master \ DEF old_master 

现在我想把这种情况推到远程回购。 然而,当我试图做一个git push Git礼貌地给我刷:

 $ git push origin +master:master --force Total 0 (delta 0), reused 0 (delta 0) error: denying non-fast forward refs/heads/master (you should pull first) To git@git.example.com:myrepo.git ! [remote rejected] master -> master (non-fast forward) error: failed to push some refs to 'git@git.example.com:myrepo.git' 

我如何获得远程回购采取当地回购的当前状态?

如果强制推送不起作用(“ git push --force origin ”或“ git push --force origin master ”应该足够了),这可能意味着远程服务器拒绝通过接收进行非快速推送。 denyNonFastForwardsconfigurationvariables(请参阅gitconfiguration手册页的描述),或通过更新/预接收挂钩。

使用旧的Git,你可以通过删除“ git push origin :master ”(见分支名称前面的':'),然后重新创build分支的“ git push origin master ”来解决这个限制。

如果你不能改变这个,那么唯一的解决办法就是不用重写历史logging来创build一个在DEF中恢复更改的提交

 ABCDEF  -  [(DEF)^  -  1]主

 ABCDEF原点/主

为了补充Jakub的回答,如果你有权访问ssh中的远程git服务器,你可以进入git远程目录并设置:

 user@remote$ git config receive.denyNonFastforwards false 

然后回到本地仓库,再次尝试使用--force

 user@local$ git push origin +master:master --force 

最后,将服务器的设置恢复到原来的保护状态:

 user@remote$ git config receive.denyNonFastforwards true 

而不是修复你的“主”分支,通过重新命名分支来交换它与“所需的主”更容易。 请参阅https://stackoverflow.com/a/2862606/2321594 。 这样你甚至不会留下任何多个恢复日志的痕迹。

整个Git重置业务看起来很复杂。

所以我做了一些事情,让我的src文件夹处于我有几个提交前的状态

 # reset the local state git reset <somecommit> --hard # copy the relevant part eg src (exclude is only needed if you specify .) tar cvfz /tmp/current.tgz --exclude .git src # get the current state of git git pull # remove what you don't like anymore rm -rf src # restore from the tar file tar xvfz /tmp/current.tgz # commit everything back to git git commit -a # now you can properly push git push 

这样,src中的事务状态就保存在一个tar文件中,git被迫接受这个状态,而不用太多的调用,src目录被replace为之前的几个提交的状态。