我在git存储库上创建了一个独立的master分支。在那段时间里,我在我的分支上做了几十次提交,并且做了一百件提交以便掌握。现在我想将我的分支合并回主人。在第一次将master合并到我的分支之后,git说我的分支是在master之前提交了2200次,这肯定是错误的。存储库中总共有大约3000次提交。
什么可能导致这样的事情发生?
答案 0 :(得分:1)
很难确定无法访问实际的提交和存储库,但如果您的上游 - 控制您git clone
您自己的存储库的存储库的人员,就会发生这种情况 - 已经做了大量的历史改写。
问题的核心在于“前方”和“后方”并不意味着人们最初想要的是什么,因为人们喜欢将历史视为线性的:事情X发生了,然后事情Y发生了之后,事情Z.Git的历史是不线性:事情X发生了,而事情Y也发生了。事情Z将X和Y捆绑在一起:
...--X--Y--Z <-- present-day
错了,并且:
...--X
\
Z <-- present-day
/
...--Y
是对的。 X和Y都没有相互“先行”或“落后”,即使两者都明显“落后”Z.
(不要把这个特别的比喻太过分了:它只是作为一个例子。从Z开始并向后工作,Git可能先向你显示Y,然后是X,当Git一次向你显示一个提交时 - 但是并不意味着X和Y之间有一些强烈的排序。你可能会看到Z然后是X然后是Y,就像那样容易。)
考虑到上述情况,假设您克隆了一个包含一些提交字符串的存储库:
...--F--G--H <-- master
因为您的克隆复制了实际的提交,所以您在自己的(单独的)存储库中获得完全相同的提交:
...--F--G--H <-- master, origin/master
origin/master
是你的Git对他们的Git master
的记忆:他们的Git master
指向提交H
。
您现在可以在自己的存储库中,在您调用feature
的自己的分支上进行自己的提交:
...--F--G--H <-- master, origin/master
\
I--J <-- feature (HEAD)
同时,出于某种原因,控制您克隆的存储库的人决定他们讨厌提交G
和H
,并且他们会使用改进的提交G'
和{{1}来替换它们}。您现在运行H'
以使用他们的新提交更新您的存储库,为您提供:
git fetch origin
您的分支现在四个提交“{1}}之前提交,还有两个提交”隐藏“ G'-H' <-- origin/master
/
...--F--G--H <-- master
\
I--J <-- feature
。你领先的四个是origin/master
,origin/master
,G
和H
- 就你的Git而言,你必须自己写,因为I
从J
返回origin/master
返回H'
,跳过G'
和F
。
(你“落后”的两个当然是G
和H
。)
在这个特定的例子中,你最多只能提前两个。如果他们使用G'
或者BFG或其他类似的操作进行了大量的复制和替换操作,那么你将会在他们扔掉的那些之前提交数百或数千个提交,这就是你现在的Git认为是你自己的工作。正如Git所说,你可以解决这个问题"recovering from an upstream rebase"。