当git历史记录不同但更改相同时,如何发送pull请求?
这是我的起点和起点当git历史记录不同但更改相同时,如何发送pull请求?,git,github,Git,Github,这是我的起点和起点 上游:--A--B--C--D-- origin:--A--B--C--D--E--F 我向上游提出了拉动请求,并开始进一步工作 origin:--A--B--C--D--E--F--G--H-- 现在,存储库所有者压缩了我的提交,现在我的上游看起来 上游:--A--B--C--D--EF-- 我想再次发出一个请求,但是我怎么做呢,因为git认为提交E、F和EF是不同的?这件事已经发生在我身上很多次了,我总是把我的git历史弄得一团糟。有人能告诉我正确的方法吗?我已经试过做一
上游:--A--B--C--D--
origin:--A--B--C--D--E--F
我向上游提出了拉动请求,并开始进一步工作
origin:--A--B--C--D--E--F--G--H--
现在,存储库所有者压缩了我的提交,现在我的上游看起来
上游:--A--B--C--D--EF--
我想再次发出一个请求,但是我怎么做呢,因为git认为提交E、F和EF是不同的?这件事已经发生在我身上很多次了,我总是把我的git历史弄得一团糟。有人能告诉我正确的方法吗?我已经试过做一些重基,壁球和其他的事情,但是这些都不起作用。也许我做这些事情的方式是错误的。我甚至想不出一个合适的题目来回答我的问题。TL;博士
您将需要在上使用git-rebase--on。正确使用它有点棘手,特别是因为你需要强迫自己使用叉子
长的
我想再次发出一个请求,但是我怎么做呢,因为git认为提交E、F和EF是不同的
他们是不同的
记住,提交的“真实名称”是它的原始散列ID。1 E的散列ID不同于F和EF的散列ID;这三个都是独立的、唯一的提交。EF是挤压E和F的结果并不重要(好吧,这对你很重要;问题是它对Git没有任何好处,所以Git在这里不能/不会帮助你)
我们需要了解Git是分布式的,Git实现这种分发的方式是分发提交的副本,由它们的哈希ID标识。每个提交本身主要是一个独立的快照,但每个提交都记录其父提交的哈希ID。名称,无论是分支名称(如master
或develope
)还是远程跟踪名称(如origin/master
或upstream/master
),都是用于记住一个特定提交的Git设备。一次提交会记住另一次提交、上一次(父级)提交以及父级记住其父级,依此类推。因此,当我们查看笔记本电脑上的任何一个特定存储库时,我们可以绘制提交图:
A <--B <--C ... <--H <--master
在一个Git存储库中,让另一个空Git调用它并从中接收,空Git将获得A-B-C-D
序列和名称master
。如果接收的Git正在执行Git提取
,则接收方将其主机
重命名为origin/master
或upstream/master
,具体取决于我们是执行Git提取origin
还是Git提取upstream
。如果上游
和起点
都有这个A-B-C-D
序列,并且都通过名称主
来识别它们的D
,并且我们从两者中提取,我们最终得到:
A--B--C--D <-- origin/master, upstream/master
A--B--C--D--EF--GH <-- master [on upstream at GitHub]
然后创建我们的E
:
A--B--C--D <-- origin/master, upstream/master
\
E <-- master (HEAD)
然后,我们的Git建议origin的Git将自己的master
更改为指向commitF
。Origin的Git很容易遵守,因此它现在有:
A--B--C--D--E--F <-- master [on origin]
现在,您可以在GitHub上导航clicky按钮并使用“发出拉取请求”选项。这样做的目的是将提交E
和F
传递到您在笔记本电脑上调用的Gitupstream
,设置一个隐藏的名称,以便上游存储库具有以下功能:
A--B--C--D <-- master [on upstream at GitHub]
\
E--F <-- refs/pull/123/head [on upstream]
A--B--C--D--EF <-- upstream/master
\
E--F <-- master (HEAD), origin/master
(一旦pull请求关闭并停止足够长的时间,特殊的refs/pull/123/head
名称可能会消失,两个提交E-F
会被垃圾回收。这些细节都由GitHub决定。)
此时,如果您将笔记本电脑存储库连接到您调用的GitHub存储库上游
,您将得到他们拥有的任何您没有的提交,这就是提交EF
。因此,现在您的存储库具有以下功能:
A--B--C--D <-- master [on upstream at GitHub]
\
E--F <-- refs/pull/123/head [on upstream]
A--B--C--D--EF <-- upstream/master
\
E--F <-- master (HEAD), origin/master
如果您创建或已经创建了H
,则以此类推。这就是你现在所处的情况
您不想做的是尝试将所有这些内容交付到您调用的Git存储库上游
。您不能更改提交G
和H
,但可以将它们复制到新提交。让我们称它们为G'
和H'
,因为它们非常像G
和H
。G
和G'
之间的主要区别在于G'
将EF
作为其父级,H'
将G'
作为其父级:
A--B--C--D--EF <-- upstream/master
\
E--F <-- origin/master
\
G <-- master (HEAD)
G'-H' <-- ???
/
A--B--C--D--EF <-- upstream/master
\
E--F <-- origin/master
\
G--H <-- ???
这就告诉它,要移动的名称是master
,复制的目标是由other name
标识的提交,要复制的提交是那些可以从master
访问的提交(以Git通常的方式,从顶端开始向后操作),但不能从other name
访问任何提交(从这个尖端开始,然后向后工作)。但在这一点上,你有:
A--B--C--D--EF <-- upstream/master
\
E--F <-- origin/master
\
G--H <-- master
这告诉我们的Git:选择提交G和H;将它们复制到上游/master
之后的新提交;然后使我们的名称master
指向上次复制的提交。结果是:
G--H <-- master (HEAD)
/
A--B--C--D--EF <-- upstream/master
\
E--F <-- origin/master
\
G--H [abandoned]
这会传递复制的提交,然后命令他们的Git,而不是礼貌地请求将其名称master
移动到commitH'
,就像我们自己的master
一样。假设他们服从命令,2他们会将存储库更改为:
A--B--C--D--EF--G'-H' <-- master [on origin at GitHub]
在这之后,我们将不得不放弃我们的G
和H
,取而代之的是他们的组合GH
,就像我们不得不处理我们的E
和F
取而代之的是他们的组合EF
这里涉及的负责人,或者,为什么他们的过程有点不友好
任何重基或挤压操作都涉及将一些提交复制到一些新提交。新提交具有新的、不同的哈希ID
任何
A--B--C--D--EF <-- upstream/master
\
E--F <-- origin/master
\
G--H <-- master
git checkout master
git rebase --onto upstream/master origin/master
G--H <-- master (HEAD)
/
A--B--C--D--EF <-- upstream/master
\
E--F <-- origin/master
\
G--H [abandoned]
git push --force origin master
A--B--C--D--EF--G'-H' <-- master [on origin at GitHub]
A--B--C--D--EF--GH <-- master [on upstream at GitHub]