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

git 有什么办法能 Merge 部分文件夹保留原始 commit 信息吗

  •  
  •   Elietio · 2022-03-17 22:15:03 +08:00 · 2448 次点击
    这是一个创建于 993 天前的主题,其中的信息可能已经有所发展或是发生改变。
    现在情况是这样,有两个分支 A 、B 并行开发,A 已经上 Master 了,又基于 Master 拉了一个新分支 C ,要把 B 的内容合并过去,由于各种原因吧 B 分支比较混乱( A 的一部分实际来着于 B ),领导不让直接把 B Merge 到 C 上去(冲突太多),安排下来手动把 B 上面的改动按模块提交到 C 上去。这就比较蛋疼了,我想把指定目录提上去但是最好保留原 commit 信息。

    首先我想到了 cherry-pick ,但是我要提的模块有好几个人也改了,好几十个 commit ,我的还好都是比较小的 commit ,没有跨模块,但是别人可能有,而且和 C 还有冲突,所以这条路不太行得通。rebase 吧,又会把别人的其他模块 commit 也搞进来。又尝试先 checkout B 分支指定文件夹 commit 之后再 Merge 到 C ,但是这样 commit 信息被覆盖了。

    有什么好办法能只合并指定目录并且还保留原始 commit 吗?
    11 条回复    2022-03-18 09:35:11 +08:00
    msg7086
        1
    msg7086  
       2022-03-17 23:50:18 +08:00
    有些 Git GUI 可以做 partial cherry-pick / rebase ,也就是变更塞进来的时候可以先排除掉不要的部分然后再提交。
    rbe
        2
    rbe  
       2022-03-17 23:56:19 +08:00
    rebase 可以选择丢弃或者修改某些 commit
    a132811
        3
    a132811  
       2022-03-18 00:03:09 +08:00
    把 B 的部分目录合并到 C?

    考虑一下这样做吧

    ```
    # 基本 C 创建一个分支 mergeC
    git checkout mergeC C

    # 把 B 的指定目录,copy 到 mergeC
    git checkout B -- <path/to/(指定目录)>

    # 检查一下 diff 确认一下
    git diff

    ## 最后提交 mergeC
    git commit -am 'merge: merge 部分目录'
    git push origin mergeC:mergeC

    ```
    a132811
        4
    a132811  
       2022-03-18 00:04:32 +08:00
    @a132811 "基本 C" -> 基于 C
    Elietio
        5
    Elietio  
    OP
       2022-03-18 00:22:08 +08:00 via Android
    @a132811 这样做,强制 checkout 指定目录会直接覆盖掉,原始的 commit 好像也会没了
    Elietio
        6
    Elietio  
    OP
       2022-03-18 00:25:50 +08:00 via Android
    @msg7086 明天我再看看,主要是我要在上百个 commit 找到涉及这个目录的那几十个,而且担心别人的一些 commit 里面同时提交了这个目录和其他目录,处理起来也比较麻烦
    msg7086
        7
    msg7086  
       2022-03-18 00:30:06 +08:00
    @Elietio 涉及目录的几十个 commit ,这个一般 Git 软件不是可以按照目录筛选 commit 的吗。

    同时提交多个目录这个没办法的,只能 pick 的时候去掉。
    Elietio
        8
    Elietio  
    OP
       2022-03-18 00:39:39 +08:00 via Android
    @msg7086 我用 IDEA 内置的只试过用作者筛,回头看看能不能筛目录,多谢诸位了
    a132811
        9
    a132811  
       2022-03-18 00:52:46 +08:00
    @Elietio
    这样子呢:

    git checkout -b mergeBC B
    git merge C
    git commit -am "merge B and C"; # 现在的 mergeBC 就有全部的记录,且包含所有的目录

    git checkout -b mergePartialBC mergeBC
    git checkout C -- <B 不想合并的目录>
    git commit -am "merge partial B and C"; # 现在的 mergePartialBC 就有全部的记录,且只包含你只想合并的目录

    git checkout -b restB mergePartialBC
    git checkout B -- <B 不想合并的目录>
    git commit -am "merge rest B" ;# 现在 restB 有全部的记录,以及 B 剩余未合并的目录
    a132811
        10
    a132811  
       2022-03-18 00:59:20 +08:00
    @Elietio 另外按目录选 commit 命令行很方便的:

    git log dir1 dir2
    git log --oneline dir1 dir2
    git log --since=20.days dir1 dir2; # 20 天内的
    Rache1
        11
    Rache1  
       2022-03-18 09:35:11 +08:00
    @Elietio 直接右键目录 -> Git -> Show History 就可以看到目录的提交记录
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6015 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 02:07 · PVG 10:07 · LAX 18:07 · JFK 21:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.