有可能告诉Github我的分支被合并到上游主人吗?

max*_*max 15 git github git-workflow

我使用我的本地分支feature为github仓库创建一个PR(我没有写入权限).后来我决定将其最后一次提交分成独立的PR,所以我将feature一个提交移回:

git checkout feature
git branch feature2
git reset --hard @~
git push -f
Run Code Online (Sandbox Code Playgroud)

第一个PR合并到上游,所以现在我要创建第二个PR:

git checkout master
git pull upstream master
git push origin
git checkout feature2
git rebase master
Run Code Online (Sandbox Code Playgroud)

不幸的是,事实证明git缺乏feature合并的信息master.因此,它没有意识到最近的共同基础feature2并且master非常接近:它只是feature.相反,它rebase一直回到共同基础,feature并且master好像它们从未合并过一样.结果,git rebase master变得不必要地混乱.

为什么Github失去通过上游PR feature合并的信息master?有没有办法提供Github这些信息?

最后,我不得不诉诸:

git checkout master
git checkout -b feature2_new
git cherry-pick feature2
Run Code Online (Sandbox Code Playgroud)

幸运的是,我只需要处理一次提交.甚至与单个提交,我认为这与真正的基础(如果混帐知道这件事),合并会优于cherry-pick因为git将能够使用它的历史知识来自动解决更多的矛盾.

请注意,如果我要合并featuremaster本地而不是执行github PR,则不会丢失任何信息.当然,那么我master不会与上游回购同步,所以这将毫无意义.

jth*_*ill 7

要回答问题,

有可能告诉Github我的分支被合并到上游主人吗?[...]为什么Github失去了通过上游公关将功能合并为主人的信息?

是的,记录合并当然是可能的.那是平常的.

有人选择告诉git(和github)不记录这个,所以效果出现在上游主分支上,没有他们来自哪里.

您所看到的是有人选择将主线历史与您提供的历史分开的结果.为什么他们选择这样做,你必须从他们身上找到答案.这是一种常见且广泛使用的选择,因为任何数量的人都会非常乐意发表意见.线性化历史看起来不错但涉及权衡,无论是哪种方式都有缺点,不同的人和不同的情况会以自己的方式倾斜平衡.

无论如何,在获取结果之后,你现在得到了一个未记录的合并,这是好的,干净的和花花公子,只要你永远不会尝试合并仍然基于未记录的父级的后续工作.

该怎么办?

您选择的选项,也可以更灵活地(它处理多次提交feature1..feature2历史)完全拼写为

git rebase --onto master feature1 feature2
Run Code Online (Sandbox Code Playgroud)

通常是最干净的:上游放弃了你的feature1历史,所以你放弃它,在你现有的内容上重新设置你的feature2.

如果由于某种原因你真的不想放弃你自己的存储库中的feature1历史记录 - 也许你不仅仅是基于旧的feature1技巧的feature2而且变基会开始变得单调乏味 - 你也可以添加合并的本地记录.

echo $(git rev-parse origin/master origin/master~ feature1) >>.git/info/grafts
Run Code Online (Sandbox Code Playgroud)

这告诉本地git当前的origin/master commit既有父记录的第一次父提交,也有本地feature1提交.由于上游已经放弃了feature1提交但你没有,所以git的所有机器现在都可以在这里和上游正常工作.

不同的项目对拉动请求历史应该基于什么有不同的规则,有些希望基于一些最新的提示,其他人希望一切基于维护基础标记,其他人希望基于引入错误的提交错误修正(我认为这应该是更常见的).有些人并不在乎,因为每个人都非常熟悉代码库,因此根据需要使用rebase仍然是最简单的.

但这里的重要部分是推销前的反弹是你最后的机会,以确保你所推动的是完全正确的.这是一个很好的习惯,在这个工作流程中漂亮地工作.


max*_*max 6

Github现在支持3种技术来合并拉取请求:

  • 合并:创建合并提交(无快进)+从PR分支获取所有原始提交
  • 壁球和合并:创建一个提交
  • Rebase和merge:创建与PR分支一样多的提交,但它们被重新命名为master

只有常规合并才能保留我的本地提交是PR合并为master的一部分的知识.如果使用它,我不会遇到我在问题中描述的问题.

另外两种技术失去了这些知识 - 我没有办法追溯地创建它(不修改上游主机).这是为更简单的历史付出的代价.

直观地说,为了git知道上游主提交U有关我的本地提交L,需要有从一个箭头指向UL.

从概念上讲,有两种方法可以实现这一目标.

首先,U可以有两个父项:一个连接到它L,另一个连接到上游的所有先前提交master.这正是Github 合并技术所做的.

其次,如果已经指向上游的所有先前提交,则U可以L作为其唯一父级.Github可以通过允许快进合并技术来支持这一点,但它选择不这样做.Lmaster

如果Github PR与squash和mergerebase和merge合并,则在上游master上创建的所有提交只有一个父级; 他们和我的本地提交之间没有箭头.

编辑:

我现在也相信,我所询问的历史遗失首先并不是什么大不了的事.IIUC,我遇到的冲突git cherry-pick实际上与git rebaseif 通过常规合并提交master连接的冲突相同feature2.如果我将超过1次提交分成独立的PR,那么cherry-pick 也可以轻松处理.