V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
echooo0
V2EX  ›  程序员

git rebase 命令主要啥作用

  •  1
     
  •   echooo0 · 2022-10-21 15:09:01 +08:00 · 4302 次点击
    这是一个创建于 768 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有 2 个分支,分别是 dev 和 master ,各有线下和线上的配置文件,

    以前一般用的都是 check out 到 master 分支后,把 dev 改动的部分 merge 进来,

    刚刚不小心在 dev 分支误点了 Rebase dev onto master , 会有啥问题吗?

    27 条回复    2023-08-28 19:21:18 +08:00
    sampdoria
        1
    sampdoria  
       2022-10-21 15:12:57 +08:00
    ysc3839
        2
    ysc3839  
       2022-10-21 15:13:15 +08:00   ❤️ 3
    一般是在分支 A 某个 commit fork 出了分支 B 进行开发,同时分支 A 又有新提交,用 rebase 可以把分支 B 的那些提交“叠”到分支 A 最新的提交上面
    f5a599
        3
    f5a599  
       2022-10-21 15:13:58 +08:00
    让别人能 ff-only ,很安心
    gtexpanse
        4
    gtexpanse  
       2022-10-21 15:15:51 +08:00
    我是用来保持分支线整洁,代码 review 或者追溯历史 commit 的时候清晰明了
    ysc3839
        5
    ysc3839  
       2022-10-21 15:18:12 +08:00
    还有一个很好用的功能是 interactive rebase ,可以很方便地修改某一个分支,或者执行 squash 操作
    optional
        6
    optional  
       2022-10-21 15:21:13 +08:00 via iPhone
    可以保持主干清爽,单人单功能开发的时候非常清晰。
    但是功能分支也是协作开发的时候,冲突会比较麻烦,反而不好追溯历史。
    wangxiaoaer
        7
    wangxiaoaer  
       2022-10-21 15:27:22 +08:00
    有个项目基于开源项目定制,是从 master 切换到某个 tag ,然后拉出来一个 dev 分支做自己的开发。同时还要定期同步上游的最新更新,目前就是当上游有新 tag 发布时,切换到 master ,pull ,就拉下来,然后回到 dev 分支 rebase 最新 tag 。
    ampedee
        8
    ampedee  
       2022-10-21 15:27:23 +08:00 via iPhone   ❤️ 2
    核心作用是重写提交历史,之前写过一篇讲解原理的博客: https://waynerv.com/posts/git-rebase-intro/
    javlib
        9
    javlib  
       2022-10-21 15:33:26 +08:00
    只有 2 个分支,恐怕不能用 rebase ,容易搞出问题。

    举一个 rebase 实用的场景:如果每个 feature / bug 都是用一个分支,而且只有一个开发人员在这条分支开发,开发完成后,准备往 mater/dev 合并,如果之前做了多次 commits ,会显得很凌乱,这时候可以用 rebase ,把多个 commits 合并成 1 个。
    grit136907108
        10
    grit136907108  
       2022-10-21 15:34:27 +08:00
    我主要用来合并本地提交记录
    echooo0
        11
    echooo0  
    OP
       2022-10-21 15:34:51 +08:00
    @ysc3839 #2 这样的话,A 就不会按照提交时间顺序排列,而是 "叠" 的顺序排列对吧
    ysc3839
        12
    ysc3839  
       2022-10-21 15:36:33 +08:00
    @echooo0 是的,不过 B 分支的 commit 最初的提交时间是会保留的,可能会出现 A 分支中 commit 晚提交在下面,B 分支中 commit 早提交在上面
    andyJado
        13
    andyJado  
       2022-10-21 16:19:27 +08:00
    其实就是重复执行 cherrypick
    cnoder
        14
    cnoder  
       2022-10-21 16:23:02 +08:00
    简单说 直接 merge 是菱形线,rebase 是一条线。一条线方便看写
    lessMonologue
        15
    lessMonologue  
       2022-10-21 16:32:24 +08:00
    主要是其中无 merge 时,多次提交合并成一个提交,保持 commit 清晰
    f6x
        16
    f6x  
       2022-10-21 16:32:53 +08:00   ❤️ 4
    你的树好难看啊
    你的提交把我的树弄丑了
    你每次合并为什么总是这么慢
    你这堆中间版本压缩一下
    曾经有一个拼写错误被我 commit 了, 没 push 的话还有补救机会么?
    liquid207
        17
    liquid207  
       2022-10-21 17:35:04 +08:00   ❤️ 1
    git rebase: 修改分支的起点

    git rebase -i: 合并 commit, 修改 commit, 调整 commit 的顺序
    unco020511
        18
    unco020511  
       2022-10-21 17:43:08 +08:00
    你可以理解为在你原来的 commit 改写并生成新的 commit,然后提交
    dqzcwxb
        19
    dqzcwxb  
       2022-10-21 18:02:37 +08:00
    变基😏
    libook
        20
    libook  
       2022-10-21 18:16:46 +08:00
    rebase 可以把一个分支上的提交复制出来并挨个重新提交到另一个分支上,也就是说虽然修改内容一样,但提交的 commit id 会不同,新提交的时间也会变成 rebase 的时间。
    merge 就是把一个分支上的提交原样合并到另一个分支上去,同时创建一个合并提交来记录这个合并操作。
    我个人建议不要滥用 rebase 。版本控制系统的价值在于回溯代码修改版本,merge 能记录更多有用的信息,特别是在多人合作的时候,但 rebase 不行,你可以在自己的分支对自己的提交进行 rebase ,但是最好不要跨多人的工作使用 rebase 。
    crab
        21
    crab  
       2022-10-21 19:23:48 +08:00   ❤️ 2
    pengtdyd
        22
    pengtdyd  
       2022-10-21 20:20:32 +08:00
    rebase 这个还不明显吗,--help 看一下不就行了吗,有这时间发帖,一个命令早就知道了。
    ClericPy
        23
    ClericPy  
       2022-10-21 21:18:46 +08:00
    拉 PR 时候其中一种方式, 还有俩是 merge 和啥来着

    反正挨骂几次分支不小心整出圈儿来就记住要 rebase 了... 一根儿的分支树确实好看很多

    git flow 还是 Github flow 是不是提到过相关规范
    icylogic
        24
    icylogic  
       2022-10-22 01:58:20 +08:00   ❤️ 1
    rebase 是一个整理历史的工具,在*私人分支*里使用 rebase 去整理历史(不管是直接 rebase onto ,rebase -i ,还是 pull —rebase )是非常合理而且甚至在多人合作中是应该被鼓励的。

    因为这代表你最后能给别人贡献一个干净的、非常易于理解、以后也很方便追溯的 patch series/pr ,这代表了你想告诉别人(包括一个月后的你自己),我的每一个 commit 都是有意义、可以被 checkout 出来构建和测试、甚至是做 bisect 的阶段性工作成果,而不是草稿纸上的来回涂鸦,所谓的 graph 好看其实是最次要的

    而且这没有听上去那么麻烦,大部分切分合理的快速小分支应该是直接 squash 成一个 commit 的,它就是这次全部的改动,删掉了你在某些地方反复调整的过程(几乎没有人包括你自己需要回顾这个过程),这也是一些团队会直接不管三七二十一把 pr 全都 squash merge 掉的情况(你去看主流的 git 服务器都会提供这个选项);只有一些确实比较大的改动需要花点时间去认真整理一下。

    但是 rebase 正常情况下只应该用于整理私人分支,而不能用于修改公开历史,公开历史包括别人的分支,以及你已经发布出去让别人 checkout 过的分支,这会严重影响协作。

    https://www.mail-archive.com/[email protected]/msg39091.html
    Linus on git rebase and merge (2009)
    zhengzhongzhao
        25
    zhengzhongzhao  
       2022-10-22 12:18:39 +08:00
    @f5a599 啥功能 咋就安心了
    charlie21
        26
    charlie21  
       2022-10-23 11:02:27 +08:00
    @icylogic
    "你最后能给别人贡献一个干净的、非常易于理解、以后也很方便追溯的 patch series/pr "
    对于这一目的,两个办法做到:

    在 pr 提交方的做法是 rebase 出一个 commit 历史(方便 pr 被并入方 执行 "Create a merge commit" 拿到被遴选出的几个 commit 历史)

    在 pr 被并入方的做法是 Squash and merge (拿到一个 commit 历史,即: 故意将 pr 提交方的若干 commit 都压缩为一个 commit )。这是 “兜底” 考虑的

    // 以上两个选择一个就可以了,在 pr 被并入方的做法是更 “兜底” 的
    sparky
        27
    sparky  
       2023-08-28 19:21:18 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4976 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 09:51 · PVG 17:51 · LAX 01:51 · JFK 04:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.