如何排除pull请求不必要的提交?

问题描述 投票:1回答:4

我面对使用Git分支问题。我发PR合并开发分支到主分支,但它包含不必要的提交。我想从公关删除这些。

  1. 我创建了从主分支发展分支,并且我加入D1,D2提交。最后,我合并的开发分支使用“南瓜和合并”的主人。
  2. 我创建了从开发分支一个特性分支,我加入F1,F2承诺。
  3. 与此同时,另一个人加入M4提交到主分支。
  4. 我发了拉请求功能分支合并到主。然而,这个PR包括D1,D2,F1,F2和承诺。

我不得不创建从主关注的分支。这是我的错误:(


 ───M1───M2───M3───S────M4 (master)
    └────D1───D2───┘ (develop)
              └────F1───F2 (feature)

我怎么只包括F1和F2承诺除了D1和D2?

git github
4个回答
0
投票

Rene's answer是正确的,但所有这些略显花哨的(采用箱字符集 - )图是有点过了,开始用自己的:

───M1───M2───M3───S────M4 (master)
   └────D1───D2───┘ (develop)
             └────F1───F2 (feature)

原因是这样的:

...我合并的开发分支使用“南瓜和合并”的主人。

在clicky图形用户界面的命令行上的“南瓜和合并”按钮,或git merge --squash,使得一个新的承诺,是不是合并。代替:

...--M1--M2--M3--S--M4   <-- master
      \         /
       D1-----D2   <-- develop

你实际得到的是:

...--M1--M2--M3--S--M4   <-- master
       \
        D1--D2   <-- develop

S和任何Ds之间没有祖先/后代关系,也没有任何MM1和任何Ds之间。这正是出游好以后的Git操作。如果你做一个实际的使用合并平原git merge,或git merge --no-ff,或非熟透的GitHub clicky按钮,然后S(因此M4以及)将D1D2的后裔。

但是,这不是我们所拥有的。所以,当我们看featuremaster,我们看到:

...--M1--M2--M3--S--M4   <-- master
       \
        D1--D2--F1--F2   <-- feature

我们看到,feature有四个提交其尖端到达提交(包括端提交自身)不是来自master,即D1-D2-F1-F1到达。不管是不是有一些名字指向D2,这四个提交是四个是在feature是不是也master。 (提交M1是两个分支机构,是一切的离开了。)

我想,想到了一个很好的办法就是“南瓜合并”具有杀死刚合并分支的副作用。提交D1D2现在,实际上,“死”的,必须考虑至少轻微放射性。作为Ahmad Khundaqji said,他们往往会在年底无害。但是,他们可以让你的提交历史看起来很丑陋,在为什么这个会两次,一次是作为两个独立的提交,后来成为一个更大的吗?如果feature实际上,合并,而不是squash-“合并” - 和在最坏的情况,他们可以在以后会引起冲突,由于一些变化的承诺是S的后裔。

由于合并后的分支现在是“死的”,它应该被删除。也就是说,你应该运行git branch -D develop。但在此之前,请务必提交D1D2是不包含在任何其他部门,这当然,你的情况,他们是自己。如果它们包含在其他部门,则必须按照变种不再有这两个提交重建这些分支。

请注意,“重订和合并”(在GitHub上,实际上这三个组合成一个内部下拉一个按钮,另一clicky按钮,但是这仅仅是表达三种不同按键的方式),还具有杀死分支的副作用,因为底垫真正意义的老提交复制到新的,然后停止支持新副本的使用旧的提交。

我谨提请后git rebase --onto master develop feature图这种方式,保持“死” develop中的图片:

                       F1'-F2'  <-- feature
                      /
...--M1--M2--M3--S--M4   <-- master
       \
        D1--D2   <-- develop
              \
               F1--F2   [abandoned]

这使得它更清晰的是F1F2下其独特的提交哈希标识依然存在。他们只是不再容易找到,因为没有名字,我们可以用它来找到them.1从名字feature开始,我们先找到补发F2',我们是用的,而不是F2,然后F1',我们应该使用地方F1,那么M4,然后S,等等,倒退到过去。 Git命令状git log不会发现我们已经闪亮新的,从F2'而不是从M1下降取代了旧沉闷的提交。

(而且,现在它是安全的删除develop,只要没有其他分支还包括D1。需要注意的是,包括D2自动包括D1所以这就是我们要在这里提到的唯一一个。)

在长篇git rebase --onto master develop feature命令,我们有三个有趣的论点(加上选项当然关键字--onto)。从年底开始和向后工作,因为Git是wont做,我们有:

  • feature作为一个额外的参数,它the git rebase documentation调用[<branch>]:告诉git rebasegit checkout feature启动。如果你这样做你自己,你可以在最后一个参数离开了。这真的只是传递给git checkout,2所以它应该永远是一个分支名称。
  • develop作为git rebase文档所说[<upstream>]:告诉git rebase其承诺不会复制。如果忽略此参数,Git使用任何被配置为目标(或电流)分支的上游。这个名字是通过git rev-parse通过,因此它几乎可以为任何:生哈希ID,标签名,git describe输出,分支机构的名称,如HEAD~2相对操作,等等。
  • --onto master作为git rebase文档所说<newbase>:告诉git rebase放在哪里提交复印件,并最终引导它在哪里重新点的分支,一旦复制完成。如果你离开了这一点,它默认为<upstream>,像<upstream>它是通过git rev-parse通过。

所以这个命令行git rebase命令的意思是:

检查出feature后,复制所有提交从分支的末端到达,排除也可到达从呈交由develop确定任何承诺,也不包括任何其他提交你,git rebase,觉得有必要omit.3做副本正确的拓扑排序的顺序,以便早期,依赖较少的提交首先复制,后来,更多的依赖提交稍后复制。将每个副本使得第一拷贝自带提交后立即提交由master标识。当你复制的最后一次提交,猛拉分支名feature周围,使其指向最后复制的提交,或者如果没有提交被复制,直接将提交由master标识。

当Git的完成这样做,你最终提交看起来我们吸引他们的方式。 (你也分支feature,除非Git的人有固定的我认为在一个小错误git rebase,好像如果你告诉衍合做git checkout feature开始,但你,比如说,master,它应该离开你关于到底master,而不是feature。当然,如果底垫必须停止与冲突,它将停止在“分离的头”模式,但是当你git rebase --continuegit rebase --abort继续或终止操作,它最终应该把你回来你在哪里,即使这不是feature。)


1还有是通过它可以发现,原来F2F1,存储在Git的reflogs名字。任何引用名的引用日志,包括那些分支名称,包含日志,其中承诺确定了分支名,通过哈希值来标识,因为一些特定的时间戳的。每次更新一个引用,通过git update-ref refs/heads/feature例如做,一直在引用日志的前值,并与时新价值刚刚写入的时间戳(和引用日志消息,作为对正在发生的事情)增加了新的价值。

运行git reflog feature看到了refs/heads/feature的引用日志条目。没有为HEAD本身的附加引用日志。运行git refloggit reflog HEAD看到一个。需要注意的是旧的条目最终到期;更多关于这一点,看看git reflog expire子命令和the git reflog documentation

需要注意的是git reflog show,这是你使用的子命令在这里,真的只是运行git log -g,所以你可以在这里改用git log -ggit reflog

删除任何分支删除其引用日志,但在HEAD引用日志条目保持。有计划,来保存从删除分支reflogs在将来的某个Git版本中能够“不删除”的一个分支服务,但这些计划还没有茸毛而散尚未,并有实现的一些问题。

2AT一点字面上这里的词是从字面上正确的,因为git rebase是一个很大的shell脚本。但现在git rebase许多地方是用C写的git checkout命令也用C写的,当你建立Git,那么建立一个分享一些后端实现代码的二进制文件。如果git rebase是调用相同的后端代码否则,单独git checkout二进制的C代码,是从字面上叫git checkout,或者是现在比喻?哪些词字面这里的正确的语义?如果字面只需要匹配的前端和后端,或匹配后端?

3The承诺是git rebase忽略自身有:

  • 合并提交。这是根本不可能复制。在某些模式下,git rebase将根据需要重新进行合并。这些模式是旧--preserve-merges和新奇的,改进的--rebase-merges;两者都是棘手,我不会试图在这里描述它们。
  • 犯用相同的补丁ID对称差的另一侧。也就是说,虽然关于发现提交的清单,<upstream>..HEAD复制的底垫文档会谈,它实际上使用<upstream>...HEAD找到两套提交的对称差:从HEAD那些可到达,但不是从上游的说法,而那些到达距离上游参数而不是从HEAD

最后这部分采用git rev-list --left-right命令的区分哪个“方”这样的提交来自能力:可复制的提交是从HEAD右可达但不能从<upstream>。然而,在这个对称差的左侧的是那些“过去的分界点”,但到达从<upstream>。在这种特殊情况下,这些提交都会被S本身M4。所以Git的计算补丁ID为这两个提交,使用git patch-id。它还计算补丁ID对每个考生的复制,在这种情况下F1F2。如果任一复制候选人的修补程序ID匹配的任何的另一半,Git的结论,他们必须已樱桃采摘到<upstream>,应该在复制过程中被省略。

这个结论通常是正确的,但在某些情况下,它可能是错的!它总是以测试的任何Git的自动化操作的结果是一个好主意。出了问题的方法是,例如,如果一个人本身承诺修复线路上的杂散},并且对上游系列独占一行的另一杂散}。这两个修补程序是在不同的源极线,并且可以具有不同的缩进为好,但以git patch-id,它们是相同的变化,作为补丁ID通过去除行号和一些白空间的构成。


2
投票

因为你做了南瓜,你的第一个PR合并,Git不会知道,D1和D2已经包含在主分支。

您需要将特性分支rebase --onto到(最新)提交主分支:

git checkout feature
git rebase develop --onto master

其结果将是这样的:

───M1───M2───M3───S────────────M4 (master)
    └────D1───D2──┘ (develop)   └────F1───F2 (feature)

现在,您可以push --force的特性分支,并更新你的PR。或关闭旧PR,并创建一个新的与当前的特性分支。

BTW:从你的分支名称我假设你使用的是一种GitFlow分支模式。在这种模式下,你不应该合并develop分支与壁球合并主,因为你总是有已经合并提交这个问题。


0
投票

只要D1,D2的变化已经被合并到主会有通过新的拉动请求重新发送它们在没有问题的(D1,D2不会考虑改变)

但是,你在你的情况需要衍合与M1开发分公司提交,这样你的PR与一切更新,GIT检测F1和F2,因为只有新的东西。

  • 要么

最简单的方法,就是从主创建一个PR开发,并将其合并在拔出后更新。


0
投票

问PR的作者(在你的仓库或分支目标)来创建最新的主的另一个分支

作者必须采摘樱桃的提交要求,如果需要做南瓜和承诺

作者将一个新的PR

© www.soinside.com 2019 - 2024. All rights reserved.