Git拒绝推送(在远程对手后面)

时间:2015-05-20 15:08:59

标签: git github

关于这个问题有很多问题,但它们似乎都指的是有远程变化的时候。对我来说情况并非如此。

$ git push repo master
...
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart.

$ git fetch repo master
$ git diff repo/master
<single commit I've done locally>

是的,git pull将允许我推动,但因为每次出现问题时我都需要或多或少地做。

修改

根据Rup的评论,我检查了它在gitk --all中的样子,看起来我的遥控器正在转移。所以,这很奇怪。

Image from gitk --all

检查我是否在本地提交:

$ git branch -r --contains 48673b311730fdfcf71b0e5776f6180c5173df42
  origin/master
$ git branch --contains 48673b311730fdfcf71b0e5776f6180c5173df42

所以,显然我有一个远程提交,只有我可以访问的回购,我不在本地。我只使用一台计算机,除了这台计算机和我之外,其他地方都没有提交。我很困惑。

编辑2: 所以,按照Javabrett的回答,我冒险进入了reflogs。

d022f6d HEAD@{144}: pull bt master:
41a6f50 HEAD@{145}: pull bt master: checkout 41a6f50f7e3e96723f0d1c222205645d78a504db
48673b3 HEAD@{146}: commit: Added commented out urls to .env
14948e3 HEAD@{147}: rebase finished: returning to refs/heads/master
14948e3 HEAD@{148}: pull bt master: checkout 14948e3c4dd014bb5af7293fdee6772a9e605b6f

其中bt是共享仓库。我最好的猜测,我已经推到了我的私人仓库,但是从共享仓库中撤下我的bt / master,原来的提交&#34;消失了#34;。再次推送到私人会引发拒绝,因为历史不会同步。那是对的吗?

2 个答案:

答案 0 :(得分:1)

也许你可以尝试使用rebase选项。

git pull --rebase origin master

比:

git push

答案 1 :(得分:1)

gitk视图有点小,所以这里有一些猜测,并且不包含提交哈希或当前本地HEAD或提交“从主布局中删除广告” - 它是一个提交评论“添加注释掉的网址到.env”或完全不同的东西?无论哪种方式,它都没有提交哈希48673b3

您的--contains测试很有帮助。您还应该运行git refloggrep或搜索48673b3。这可能会显示您的本地HEAD何时指向48673b3,以及在此之后或之后发生的事情。

最有可能的是,通过直接命令或某种工具,您已经重新定位或压缩或修改了本地仓库中remotes/origin/master的提交。或者您可以重置日期/时间或作者。 Git现在认为这是一个独立的开发线 - 你应该永远不要贬低或压制你已经推到某个地方的提交,如果发生了这种情况,那就再来了。

您的git reflog可能会显示例如:

20fa43d HEAD@{0}: commit (amend): Added commented out urls to .env
48673b3 HEAD@{1}: commit: Added commented out urls to .env
e039c6c HEAD@{2}: commit: Updated backend variables to new test server.

如果是这样,(修正)会告诉你出了什么问题 - 在那种情况下你会重写本地历史记录,你就不能再快速推进这个分支了。如果是这种情况,您可以使用rebase修复它(可能首先在临时分支上执行此操作):

git rebase --onto origin/master origin/master

根据您本地历史记录中的更改,您可能会遇到合并冲突,以解决本地修订后的提交问题。之后,您将重新编写任何本地提交,以便他们同意远程历史记录,您应该能够执行快速推送。

问题编辑2回答更新:

关于另一方面的信息,上游远程,refase和reflog,相当清楚发生了什么。

您在48673b3中推送到origin/master的相同更改也包含在另一个提交中,无论是单独还是与其他更改混合,由您或其他人制作并推送到upstream/masterbt/master为你)。当您从上游git pull编辑时,Git将创建一个合并提交。虽然它没有显示在reflog中,但你之前在HEAD@{148} / HEAD@{147}拉了然后重新定位,所以假设你在HEAD@{144}之后的某个时间再次这样做是合理的,返回线性历史记录,删除合并提交。您在没有git rebase的情况下运行了--keep-empty,并且在48673b3上重播了bt/master时,没有任何事情可做,因此提交被丢弃,这是rebase的默认行为

origin/master现在已经偏离了您的本地仓库,在最年轻的共同父级之前提交48673b3,可能是14948e3。 Git不会允许你推(没有-f强制) - 即使树哈希值可能相同,提交历史也有分歧。

关于工作流程的一些建议:

1)如果您更喜欢使用rebasing和线性历史记录进行合并提交(足够公平),那么请始终坚持下去。运行git fetch ...git rebase ...,永远不要运行git pull(获取并合并)或git merge,或者如果必须,请使用--ff=only运行它们,当你在本地没有任何新的提交时运行。考虑设置config pull.ff=onlymerge.ff=only以强制执行此操作,以防您在命令行中忘记它们。有了这个,除非你明确说明,否则你永远不会进入上游的非线性状态,你将始终被提醒git rebase bt/master

这实际上不会解决您的问题,但最好避免混合合并/变基策略。如果您的策略是重组并且您不小心创建了合并,请重置为最新的本地提交,然后重试。

2)如果您使用并推送到两个远程回购,其中一个更改(上游),并且您正在变基础,迟早您将遇到此问题并需要确定您的本地现在是“最新的” “并强制推送到您的私人origin/master。重新分配已经被推到遥控器的分支总是最终会崩溃 - 重新定位(或挤压或修改)是重写历史的方式,所以历史总是会分歧。如果您只是将origin/master用作代码的“只写”远程备份,请习惯运行push -f来覆盖它(当然您需要知道这是正确的,否则您将丢失提交),或者更好的是,只需push origin HEAD:`date -u +%Y%m%d%H%M%S``即可为您提供以后可以丢弃的非冲突引用。如果您使用origin来处理更复杂的事情,那么您需要了解在重新定位到上游时会遇到的问题。