V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
xingheng
V2EX  ›  程序员

Pull Request 允许包含 merge commit 吗

  •  
  •   xingheng · 63 天前 · 3591 次点击
    这是一个创建于 63 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在我职业生涯里这种情况很少见,不过在现在公司的工作流中居然很常见,各种奇葩的 merge ,但凡碰到我是 reviewer 应该就会毙掉了。 同事的解释基本是直接在 SourceTree 里操作拉取的,默认是 merge 操作,所以就这样了。我看了一下其实是支持 rebase 选项的,应该只是不会用而已。

    纯吐槽了,反正我不是 reviewer 。

    第 1 条附言  ·  63 天前
    我并不是完全反对 git merge ,比如在一个 feature 分支完成后准备合并发版的的时候,feature 分支 merge 到 develop 再到 master 是完全可以接受的。除此之外都是不可理喻的。
    49 条回复    2025-07-04 15:16:13 +08:00
    weixind
        1
    weixind  
       63 天前
    你觉得不合理的可以提出来,大家一起讨论如何优化。这就是你的绩效亮点之一。

    回到这个事情上来看,你的想法没错。
    ZSeptember
        2
    ZSeptember  
       63 天前
    GitHub 默认行为吧。所以绝大部分人 merge 的时候,都会包含 merge commit 。
    只要少数对这方面有想法的人,才会使用 rebase 或者 squash
    Kaiv2
        3
    Kaiv2  
       63 天前
    正常情况下不应该包含 merge commit ,我记得高版本 git 命令强制你设置
    Tink
        4
    Tink  
    PRO
       63 天前
    默认是包含的吧,新新的 merge commit 会保留原分支的提交历史
    guanzhangzhang
        5
    guanzhangzhang  
       63 天前
    有技术细节追求的是少数,好多人都是用 ide 啥 GUI 操作合并后推送,没有或者不会 git pull --rebase 和 git rebase 习惯
    peasant
        6
    peasant  
       63 天前
    我和同事说过好多次用 rebase ,但是没人愿意用
    freeman12
        7
    freeman12  
       63 天前   ❤️ 3
    特性 git merge git rebase
    是否保留分支历史 ✅ 是(有合并节点) ❌ 否(会“平铺历史”,重写 commit )
    是否修改 commit hash ❌ 否 ✅ 是,commit 会重写
    是否生成 merge commit ✅ 默认生成 ❌ 不会生成
    是否易于理解协作历史 ✅ 是(真实历史) ❌ 否(历史被改写,适合单人开发)
    是否容易冲突 🔁 重复合并可能冲突 ⚠️ 频繁 rebase 更容易遇到冲突
    应用场景 分支合并(多人协作常用) 清理分支历史(个人分支、PR 前整理)

    多人协作不是 merge 更好吗,保留了真实历史
    finab
        8
    finab  
       63 天前
    rebase 有个问题,一旦某个文件每个 commit 都有冲突,那 rebase 就需要多次解决冲突
    我现在的办法是 合并这些 commit ,然后再 rebase ,但其实我是希望保留 commit 记录的,各位彦祖有啥好办法么?
    crysislinux
        9
    crysislinux  
       63 天前 via Android
    可以 pr 合并的时候在 squash merge 吧,merge commit 经常是不好避免的,比如 review 已经开始了之后 pr 跟 main 有冲突,这时候 merge main 比 rebase main 更合适,rebase 就把 review 的历史搞乱了
    zed1018
        10
    zed1018  
       63 天前
    @finab 有的兄弟,你先合并成一个 commit 然后 rebase ,完了通过 reset --soft 退回到未提交状态,然后你自己再做一遍多个 commit
    flywanly990
        11
    flywanly990  
       63 天前
    没感觉到 rebase 在多人协作中的优点,除了 commit 看起来纯净,还有啥好处呢? merge commit 可以看到所有的操作记录,不是更好吗
    finab
        12
    finab  
       63 天前
    @zed1018
    这样这个文件会是最新状态,修改记录就已经丢失了
    encounter2017
        13
    encounter2017  
       63 天前
    pull request 里面包含 merge request 不是很正常的吗,github 上很多开源社区的做法是,在提交到主分支前,由 bot 或者人手工 rebase 成单条记录然后合并。在 pr 阶段保留 merge request 信息可以方便 review 人员查看变更历史,之前 resolve 的评论就可以往后面的 commits 看。
    一个特殊的例子,openjdk 仓库里面 pull request 合并后都是 close 状态的,主分支保持干净
    https://github.com/openjdk/jdk
    funcman
        14
    funcman  
       63 天前   ❤️ 3
    好早之前曾经在一个有一点 Google 脉络的组上班,其中 CodeReview 用的是 Gerrit 。也就是说这种提交模式( pre-commit )会导致我们一个提交会因为等待打分,导致做好多次 rebase 。rebase 的结果导致提交线直直一根很漂亮。可能会丢失实际开发信息,但是从成果角度看,丢失的信息也无所谓,丢失也是一种整理过程。

    当然如前面有人说的,这种模式一旦遇到冲突,可能要多次反复解决冲突。比较麻烦。

    至于 Merge Request 这种 post-commit ,几乎是非 Gerrit 管理的项目的实际上的唯一可靠的模式。Gerrit 需要组里有足够的熟手。而 MR 只需要一个老手加若干新手就能转起来。所以别纠结。

    术语 Merge Request 和 Pull Request 实质几乎是一样的,主要是 Gitlab 用前者,Github 用后者。所以 IDE/Tools 在生成 commit log 时,用词可能比较随意。(回想当时用 Gerrit 之前,我们的库就是托管在 Github 上,但是不使用 PR ,所有人都有权限直接往库里 push 。有的人会 rebase 一下,有的人直接来。)

    后来再也没有在有 CR 的团队里上班 🤦‍
    sepit
        15
    sepit  
       63 天前
    @flywanly990 我也是同感,感觉 merge 明显更自然一些,分锅甩锅追溯问题都更清晰
    672795574
        16
    672795574  
       63 天前
    rebase 会丢失信息, -f 操作除非我很明确知道自己在做什么 不然一般不用
    kid1412621
        17
    kid1412621  
       63 天前
    @freeman12 #7 问题就是有时候可能太过真实😀
    flywanly990
        18
    flywanly990  
       63 天前
    @sepit 对的,溯源很重要,主要是分锅的时候更方便,嘿嘿……
    另外,团队成员技术水平参差不齐,merge 可以减少的心智负担
    chimission
        19
    chimission  
       63 天前
    其实我也不太清楚,rebase 除了让 log 好看一点之外还有其他高收益的优点吗,讨论一下
    54xavier
        20
    54xavier  
       63 天前
    我讨厌 merge commit ,但是我愿意保留,比较清晰明了
    jeesk
        21
    jeesk  
       63 天前
    讨论了不知道多少次了, 还是参考 chromium 项目的方法比较稳妥。 我不觉得你的项目比 chromium 还复杂。
    kneep
        22
    kneep  
       63 天前   ❤️ 1
    取决于 merge commit 是不是反映必要的客观现实吧。如果你带进来的 merge commit 真就是因为多个人合作而产生的,或者有些 pipeline 有一些自动的处理,那就带进去。如果仅仅是因为你自己没用好工具造成的,比如改完后 git pull 一下在本地生成的 merge commit ,那是完全不应该的。

    总体来说,我认为 PR 里面带进来必要的 merge commit ,是不多见的。我以往的工作经验中,绝大部分都是因为本地的 git pull 生成的 merge commit ,这种我都会打回去。
    sparkle2015
        23
    sparkle2015  
       63 天前   ❤️ 1
    分支间有冲突时,merge 只需要解一次冲突,rebase 可能要解 n 次冲突。而且使用 rebase 不利于多人修改同一个分支 (极少情况但确实有时候会发生)。所以 rebase 只是看似美好。
    github 上用 squash merge 个人感觉是最优解。


    > https://git-scm.com/book/zh/v2/Git-%E5%88%86%E6%94%AF-%E5%8F%98%E5%9F%BA
    > 呃,奇妙的变基也并非完美无缺,要用它得遵守一条准则:
    > 如果提交存在于你的仓库之外,而别人可能基于这些提交进行开发,那么不要执行变基。
    > 如果你遵循这条金科玉律,就不会出差错。 否则,人民群众会仇恨你,你的朋友和家人也会嘲笑你,唾弃你。
    unused
        24
    unused  
       63 天前
    可以包含 merge ,但是你说的这种无意义的 merge 肯定不行
    greycell
        25
    greycell  
       63 天前
    没看懂,pr squash merge 就行了,你管人家自己 branch 上喜欢用啥呢
    unused
        26
    unused  
       63 天前   ❤️ 1
    @finab 看看 git rerere
    yunyuyuan
        27
    yunyuyuan  
       63 天前
    小需求,直接 rebase master
    大需求,如果是模块化的,一步到位的,squash 后再 rebase master 。如果不是模块化的,冲突很多的,直接 merge master ,这样也保留原始提交信息。
    RedisMasterNode
        28
    RedisMasterNode  
       63 天前
    > 我看了一下其实是支持 rebase 选项的,应该只是不会用而已。

    哈哈,rebase 操作过程中不知道有多少事情要处理,也是个纸面上好用实际用起来一大堆问题的方案。到时候会有很多人跟你争论 PR 整体大小不合适不方便 rebase->为什么要把这么多内容放一个 PR -> 为什么需求/流程/排期如何如何...

    squash 之后一个 PR 就只有一个 commit ,为什么要关心人家中间操作了什么呢?
    iyaozhen
        29
    iyaozhen  
       63 天前
    很多人推荐 rebase ,但其实操作难度比 merge 高多了,需要理解很多概念,很容易冲突,合出问题
    当然你可以说这是基本功,但实际工作中你遇到的都是“跨域报错了是前端改还是后端改都能吵半天的水平”,就释然了,爱啥啥,只要不把我的代码给合丢了就行
    wenrouxiaozhu
        30
    wenrouxiaozhu  
       63 天前
    我一般这样
    git rebase origin/master --committer-date-is-author-date
    git switch master
    git merge feat/xx --no-ff
    kakki
        31
    kakki  
       63 天前
    别一天吹 rebase 了,本来就是两种不同的对待历史的态度,没有谁更牛比的说法 ok?
    你尊重提交历史,那就 merge.
    kaedea
        32
    kaedea  
       63 天前 via Android
    当有不止一个主干的时候就别当什么 rebase 警察了。
    aragakiyuii
        33
    aragakiyuii  
       63 天前 via Android
    自己本地的 merge commit 推到远程除了污染环境还有什么用?
    WorseIsBetter
        34
    WorseIsBetter  
       63 天前   ❤️ 1
    每当遇到这种老生常谈的问题,就不得不提 fossil 了,从设计理念上就不支持 rebase 功能: https://fossil-scm.org/home/doc/trunk/www/rebaseharm.md

    不过我自己还是挺喜欢用 rebase 的,主要是在提交 review 之前 rebase -i 整理一下自己的开发分支(不过按照 fossil 的说法,这不仅是「不诚实」,还是一种「不谦虚」的行为,我认了,哈哈)

    而且在我遇到的大部分协作场景下,一个分支「在什么时候从主线分叉,中途什么时候再次同步过主线」这样的信息并不是很重要(尤其是当那个开发分支只有一个人在用的时候)。

    个人观点是,既不要一味追求「诚实」(记得以前有人写博客怼 fossil 作者:既然那么想要诚实,为什么不把你在编辑器里做过的每一个操作都分别提交上去呢),也不要盲目追求「干净」(如果某些被改写的提交历史会影响后续的问题追溯的话)。要制定好团队协作规范,分情况讨论。
    siweipancc
        35
    siweipancc  
       63 天前
    我跟同事开发的代码, 他喜欢 rebase, 容易吐槽说怎么提交的代码不见了
    Yuesh1
        36
    Yuesh1  
       63 天前
    @funcman 经历完全相同呀,我当时毕业去的第一家公司,后来出来后,后来再也没有人知道 gerrit ,也没人再做 CR ,面试的时候说 gerrit ,别人也不知道我在说什么
    Nich0la5
        37
    Nich0la5  
       63 天前   ❤️ 2
    感觉 merge vs rebase 都快成了月经贴了
    clue
        38
    clue  
       63 天前
    @flywanly990 #11 merge commit 看似你能看到所有提交细节,但实际上的改动只有 merge 的那一次,分支上的提交只是个参考引用。
    所以如果 merge 出了问题,定位都难,再碰到喜欢弄一个私人分支一直 merge main 再 merge 回去的,提交记录没法看了。

    rebase 不只是好看,分支的每个提交 rebase 到主干后都是真实有效的,唯一的缺点是对开发者要求比较高。
    Binwalker
        39
    Binwalker  
       63 天前   ❤️ 1
    @finab #8 git rerere 了解下
    htxy1985
        40
    htxy1985  
       63 天前
    理论上我是同意 22 楼的说法,要不要 merge 是看情况的,自己 merge 自己,又没有冲突,属于是自己没操作好导致的好多条 log 是可以干掉的。
    但实际操作上,我是很懒的,全 merge 也没有问题,但总会有一些自我感觉 rebase 是最优雅的人来说服我,就有点反感。
    dfkjgklfdjg
        41
    dfkjgklfdjg  
       63 天前
    我看别人会不会用 git ,或者操作的 git 的熟练度,就是看一个人对于 rebase 的理解。

    PR 要不要保留最后的 merge commit ,是看仓库作者的想法。这个在仓库里面是可以设置的。不是贡献 PR 的人该考虑的问题。

    -----

    如果是日常工作中的出现的 `Merge remote-tracking branch 'origin/master'` 或者 `Merge branch 'master' of 'http://xxxxx'` ,恕我直言:不是菜,就是懒。
    greycell
        42
    greycell  
       63 天前
    @dfkjgklfdjg 本来 repo 设置的问题,被搞成 merge 和 rebase 的矛盾我是没看懂。设成 pr 必须没有 conflict ,必须 squash merge 是不会吗。
    thulof
        43
    thulof  
       63 天前
    好多人说 rebase 模式下多 Commit 解决冲突很麻烦云云。那既然都 rebase 了,就小步 Merge Request 、频繁提交呗。
    为啥非得自己搞个大分支,和主干分叉很久之后再 rebase 主干解冲突,然后提个超大 MR ?恶心自己也恶心别人
    dfkjgklfdjg
        44
    dfkjgklfdjg  
       63 天前
    @greycell #42 ,挺多人其实不怎么会用 git ,也不会看仓库设置里面有一些什么东西,或者就是嫌麻烦。

    听到最多的就是:"我这样用着挺好的,凭什么要听你的?"。
    xingheng
        45
    xingheng  
    OP
       63 天前


    感受一下 merge history 的恐惧吧,这是我在 SourceTree 里把 Graph 列拉到最大的效果,有些还没显示出来。
    xubingok
        46
    xubingok  
       63 天前
    develop 向 master 这种的,分支之间用 merge.
    develop 或者 feture 分支内部的,多人开发用 rebase.
    weiwenhao
        47
    weiwenhao  
       62 天前
    正确的做法是什么呀?

    公司现在协作的方式是基于 master 创建 feature 分支(根据测试情况包括多次 commit ,持续几天),然后会在合并到 master 之前,会 merge master 中最新的代码到 feature 分支,处理一下冲突,然后再提交 pr 到 master 。
    suiyun39
        48
    suiyun39  
       62 天前
    我的做法是:其他分支怎么玩都无所谓,爱怎么折腾怎么折腾,但 master 必须保持线性提交(这个是有分支保护规则的)。当最终合并到 master 的时候,只允许使用 Squash Merge 把提交压缩成一条。特殊情况允许 Rebase Merge 来保留一定的提交历史(但必须提前 rebase 一次剔除掉杂音)。
    wenrouxiaozhu
        49
    wenrouxiaozhu  
       61 天前
    @suiyun39 "只允许使用 Squash Merge 把提交压缩成一条"
    rebase 后再 merge -no-ff 更好一点?这样主分支上只有线性的 merge commit+可以保留 feat 分支历史记录
    https://zhuanlan.zhihu.com/p/616897004
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3200 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 10:56 · PVG 18:56 · LAX 03:56 · JFK 06:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.