我为我的Git工作存储库创建了一个裸存储库克隆。远程裸仓库位于网络驱动器上,我一直在推动它,所以我在不同的物理介质上备份。我现在因尝试推送到裸存储库而收到错误,因为我的本地存储库位于远程存储库之后。对远程存储库的所有修改都是从我的工作存储库中推送出来的。当没有对远程仓库进行其他更改时,我的本地仓库怎么能在遥控器后面? 这是我在尝试推送到远程仓库时遇到的错误
git -c diff.mnemonicprefix=false -c core.quotepath=false push -v --tags --set-upstream AlcatrazVehicleBW1 BitworksDevelopment:BitworksDevelopment FixSetOsDateTime:FixSetOsDateTime HeapUseBy3rdPartyLibBugFix:HeapUseBy3rdPartyLibBugFix M_Bitworks20161226CLOSED:M_Bitworks20161226CLOSED Orig_Port_to_Vx7_Review_changes_by_jdn:Orig_Port_to_Vx7_Review_changes_by_jdn ReSquashM_BitworksIntoMaster:ReSquashM_BitworksIntoMaster master:master
Pushing to //bw1/Public/Bitworks/Projects/Alcatraz/Vehicle.git
To //bw1/Public/Bitworks/Projects/Alcatraz/Vehicle.git
= [up to date] FixSetOsDateTime -> FixSetOsDateTime
= [up to date] HeapUseBy3rdPartyLibBugFix -> HeapUseBy3rdPartyLibBugFix
= [up to date] Orig_Port_to_Vx7_Review_changes_by_jdn -> Orig_Port_to_Vx7_Review_changes_by_jdn
= [up to date] master -> master
* [new branch] M_Bitworks20161226CLOSED -> M_Bitworks20161226CLOSED
* [new branch] ReSquashM_BitworksIntoMaster -> ReSquashM_BitworksIntoMaster
! [rejected] BitworksDevelopment -> BitworksDevelopment (non-fast-forward)
updating local tracking ref 'refs/remotes/AlcatrazVehicleBW1/FixSetOsDateTime'
updating local tracking ref 'refs/remotes/AlcatrazVehicleBW1/HeapUseBy3rdPartyLibBugFix'
updating local tracking ref 'refs/remotes/AlcatrazVehicleBW1/Orig_Port_to_Vx7_Review_changes_by_jdn'
updating local tracking ref 'refs/remotes/AlcatrazVehicleBW1/master'
updating local tracking ref 'refs/remotes/AlcatrazVehicleBW1/M_Bitworks20161226CLOSED'
updating local tracking ref 'refs/remotes/AlcatrazVehicleBW1/ReSquashM_BitworksIntoMaster'
error: failed to push some refs to '//bw1/Public/Bitworks/Projects/Alcatraz/Vehicle.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
拒绝 BitworksDevelopment 的分支在本地存储库中移动,指向主分支的负责人,试图丢弃旧的 BitworksDevelopment 分支,这是一个壁球合并为主人。目的是开始从当前的主人头开始新的开发。我的理解是推送将覆盖远程AlcatrazVehicleBW1裸存储库上的跟踪分支指针。似乎还有一个我不理解的Git概念。
答案 0 :(得分:1)
那么,那就是问题所在。请注意,这里最简单的方法就是删除这个分支名称。拒绝 BitworksDevelopment 的分支在本地存储库中移动,指向主分支的负责人,试图丢弃旧的BitworksDevelopment分支,该分支被压缩成母版。
...因为我的本地存储库隐藏远程存储库
来自Git的投诉,但投诉是......好吧,"错误"是错的词;也许更好的词是"推定"。
请记住,在Git中,分支名称仅指向一个特定提交。该提交是分支的"提示":
...--A--B <-- br1
\
C--D--E <-- br2
\
F <-- br3
此处,提交A
和B
位于所有三个分支上,分支名称br1
指向B
,因此{{ 1}}是B
上的提示。提交br1
到C
的提交位于两个分支上,E
是E
的提示,br2
仅在一个分支上,并且是F
。
Git允许您添加新的分支名称标签,任意跳转现有标签,以及完全删除分支名称标签。然而,有一个正常模式&#34;名称移动,以及#34;仅向前&#34;方向。即使没有添加任何新提交,我也可以将br3
向前移动到br1
到C
中的任何一个,而Git会认为这是正常的,只是这样做。我可以将F
转发到br2
。由于F
之外没有提交,我无法向前移动br3
。
但是,假设我添加了一个新的提交F
:
G
由于...--A--B----------G <-- br1
\
C--D--E <-- br2
\
F <-- br3
的父级是G
,我可以将B
向前移动到指向br1
。 G
指向G
,就像B
指向C
一样,因此将B
移至br1
或 C
没问题。
但是,一旦我做了这个动作,Git就会拒绝G
以任何方式移动 。
假设我将br1
复制到我G
末尾的新提交G'
:
F
如果我现在要求Git将...--A--B----------G <-- br1
\
C--D--E <-- br2
\
F <-- br3
\
G'
移至指向br1
,G'
会发生什么?
没有任何指向G
,我们将失去&#34;它。 Git无法找到它,如果我没有在某处(在我的reflogs或我的屏幕上)保存它的哈希值,那么我也会这样。 1 因此,请求移动从G
到br1
的{{1}}是非快进。 2
这里的基本假设是,当您推送到裸存储库时,如果您请求的分支标签更改不是&#34;快进&#34;,您可能不知道提交{{1在裸存储库上甚至存在,因为它可能是由其他人发送的,并行工作,他们只是打败了你到G
步骤。在这种情况下,您需要从裸存储库G'
到选择提交G
,然后找出如何让自己的工作追加到现有提交,而不是删除git push
。 (这通常是通过变基或合并。)
告诉Git服务器它应该移动一个分支,即使动作会丢失一些提交,你必须应用其中一个&#34; force&#34;标志。容易申请的是git fetch
或G
,它只是告诉服务器:&#34;我知道我在做什么,已经失去了一些提交。&#34;稍微长一点,更安全,是G
:你让你的Git告诉他们的Git&#34;我相信分支指向提交--force
,如果是,请指向{{ 1}}代替。&#34;
基本假设是错误的,-f
是您的提交。你知道它在那里,你打算删除它。所以,既然你的Git知道它,你可以使用--force-with-lease
来检查他们(裸回购者)G
是否仍指向同一个提交,如果是,请用你的覆盖它新的替代品。或者,如果您知道自己是唯一一个对裸存储库执行操作的人,则可以使用普通的G'
。
当然,正如脚注2所示,完全删除名称实际上更简单,因为更典型的模式是使用squash-merge。在这种情况下,由于图形看起来更像是这样:
G
通过删除分支名称而丢失的提交是您作为提交--force-with-lease
压缩合并的提交。名称BitworksDevelopment
足以保留提交--force
;你不需要两个名称。至少,还没有:当你...--A--B--C <-- master
\
... [the old BitworksDevelopment]
之后进行新的提交时,你将想要C
的另一个名字,但是你没有&#39;我想通过名称master
找到。
请注意,Git在裸存储库中的保护性仅适用于非快进分支名称更新。删除分支,丢失提交,完全没问题!但是,您必须使用C
将删除请求发送到服务器,因此不会发生这种情况。这与正常的开发推动完全不同,两个开发人员之间的竞争,都推向同一个分支,导致非快进,是正常的日常事故,值得保护
1 裸存储库通常没有reflog,并且在推送后立即运行垃圾收集,因此C
可能会很快被删除。
2 快速分支名称移动的技术定义是当前指向的提交是您提议的提交的祖先指出它。由于常规合并提交指向两个或多个提交,因此将分支名称移动到简单地将该分支与另一个分支组合的新合并提交是快进的。大多数壁球&#34;合并&#34;同样:我们在主分支上添加一个提交,表示在另一个分支上的几个提交中完成的所有工作(然后我们完全丢弃其他分支)。你的情况有所不同,就是你故意做这个而不用丢弃另一个分支;相反,您正在以非快进的方式尝试更改其他分支。