[git]git 的一个变基问题.

2023-03-21 18:26:08 +08:00
 kyonn

最开始分支是这样的

A-B-C(main)
    |
    |-D-E(dev)

然后发现个 bug,需要合入 main 分支(对应图中的 Q), 但是开发人员误合入了 dev 分支(对应途中的 Q'), 由于 dev 也是公共分支, 不能复写历史, 只能 revert(对应图中的 Q''), 然后最终历史变为下图. 其中 Q 和 Q'是相同的修改, Q''是 Q'的 revert.

A-B-C-Q(main)
    |
    |-D-E-Q'-Q''(dev)

假设这时开发完成了, 我要把 dev 合回 main. 选择把 dev 变基到最新的 main, 但是由于 rebase 的特性, Q'被认为跟 main 上的 Q 是一样的修改, 被 rebase 自动丢弃了. 最终变为下图. 其中 Q'''跟 Q''是等价的,是针对 Q 或者 Q'的 revert, 这样反而导致主线上的修改 Q 被 dev 回退了, 不符合最终目标.

A-B-C-Q(main)-D'-E'-Q'''

有一种解决方案是变基前先将 dev 压缩为一条 commit, 缺点是丢失了历史. 不知道 V 友们是否有更好的解决方法? 在保留 dev 分支历史的情况下.

1279 次点击
所在节点    问与答
24 条回复
Pastsong
2023-03-21 18:31:11 +08:00
丢弃掉老的 main 分支,直接从 dev fork 出新的 main 分支
hsfzxjy
2023-03-21 18:47:43 +08:00
变基前 dev 回退到 E ?
kyonn
2023-03-21 18:55:38 +08:00
@hsfzxjy 实际 dev 开发时间比较久, 不一定会记得有这种 revert.
kyonn
2023-03-21 18:56:00 +08:00
@Pastsong 那 main 分支上的 Q 修改就丢了, 因为 dev 上没改这个.
renmu
2023-03-21 18:59:26 +08:00
那就把 revert 的 commit 再 revert 一次
kyonn
2023-03-21 19:01:16 +08:00
@renmu 是指变基完成后再 revert 一遍吗? 实际因为 dev 分支开发比较久, 在变基时不一定记得有这个坑在里面...
kyuuseiryuu
2023-03-21 19:01:45 +08:00
回到 E ,force push ,有需要的话用 ref log 看提交记录,cherry pick Q 之后需要的 commit 。
kyuuseiryuu
2023-03-21 19:03:30 +08:00
@kyuuseiryuu 回不去啊,那没救了……历史记录肯定有这两个 commit 记录的,销不掉了
kyonn
2023-03-21 19:04:26 +08:00
@kyuuseiryuu 实际 dev 分支存在时间比较久... 不一定记得有这么个坑在.
rrfeng
2023-03-21 19:14:52 +08:00
『但是由于 rebase 的特性, Q'被认为跟 main 上的 Q 是一样的修改, 被 rebase 自动丢弃了. 』
----
没理解这个,这个特性叫啥?我怎么没见过?
godpeo
2023-03-21 19:16:54 +08:00
别用 revert 用 reset 回到 E
kyonn
2023-03-21 19:18:21 +08:00
@rrfeng
> If the upstream branch already contains a change you have made (e.g., because you mailed a patch which was applied upstream), then that commit will be skipped and warnings will be issued (if the merge backend is used). For example, running git rebase master on the following history (in which A' and A introduce the same set of changes, but have different committer information):

https://git-scm.com/docs/git-rebase
kyonn
2023-03-21 19:19:59 +08:00
@godpeo 这是种解决方案, 但 dev 是公共分支, 在开发期间 reset 等价于修改公共分支的历史, 有较大的风险, 因此不太想这么做.
leonshaw
2023-03-21 19:22:07 +08:00
不明白为什么一个 commit main 上有,dev 上不能有,合并以后又要有
rrfeng
2023-03-21 19:23:37 +08:00
-i 试试交互模式能保留吗?
感觉既然 issue warning 了,应该有选项可以禁用这个特性?
optional
2023-03-21 19:27:19 +08:00
再 revert 一次。。
kyonn
2023-03-21 19:28:31 +08:00
@leonshaw 这个需求是比较奇怪, 原先最朴素的想法是这个问题在主线上的某个产品出现, 所以要求直接提 MR 给主线, 但是修改人提交的 MR TARGET branch 选错了, 变成了 dev 分支, 而 dev 分支上在开发其他产品, 跟这个 bug 没关系, 就直接 revert 了.
注: 这个 bug 改的不是公共代码, 而是主线上某个产品分支的代码, 而这个产品分支在 dev 上不涉及, 换句话说, dev 分支上在开发其他产品.
leonshaw
2023-03-21 19:28:44 +08:00
@kyonn #13 其他人 pull 到 Q' 之前 force push 是安全的。
kyonn
2023-03-21 19:29:47 +08:00
@optional .... 见我后面的补充, dev 分支存在比较久... 到 rebase 的时候不一定记得有这么个坑要填....知道有这个问题了还是比较好处理的.
kyonn
2023-03-21 19:30:39 +08:00
@leonshaw 对的, 但因为 Q'已经在 gitlab 上了, 所以并不能保证没人 pull 到这个 commit... 为了稳妥期间, 才选择 revert 的.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/925933

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX