最开始分支是这样的
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 分支历史的情况下.
1
Pastsong 2023-03-21 18:31:11 +08:00
丢弃掉老的 main 分支,直接从 dev fork 出新的 main 分支
|
2
hsfzxjy 2023-03-21 18:47:43 +08:00 via Android
变基前 dev 回退到 E ?
|
5
renmu 2023-03-21 18:59:26 +08:00 via Android
那就把 revert 的 commit 再 revert 一次
|
6
kyonn OP @renmu 是指变基完成后再 revert 一遍吗? 实际因为 dev 分支开发比较久, 在变基时不一定记得有这个坑在里面...
|
7
kyuuseiryuu 2023-03-21 19:01:45 +08:00 via iPhone
回到 E ,force push ,有需要的话用 ref log 看提交记录,cherry pick Q 之后需要的 commit 。
|
8
kyuuseiryuu 2023-03-21 19:03:30 +08:00 via iPhone
@kyuuseiryuu 回不去啊,那没救了……历史记录肯定有这两个 commit 记录的,销不掉了
|
9
kyonn OP @kyuuseiryuu 实际 dev 分支存在时间比较久... 不一定记得有这么个坑在.
|
10
rrfeng 2023-03-21 19:14:52 +08:00
『但是由于 rebase 的特性, Q'被认为跟 main 上的 Q 是一样的修改, 被 rebase 自动丢弃了. 』
---- 没理解这个,这个特性叫啥?我怎么没见过? |
11
godpeo 2023-03-21 19:16:54 +08:00
别用 revert 用 reset 回到 E
|
12
kyonn OP @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 |
13
kyonn OP @godpeo 这是种解决方案, 但 dev 是公共分支, 在开发期间 reset 等价于修改公共分支的历史, 有较大的风险, 因此不太想这么做.
|
14
leonshaw 2023-03-21 19:22:07 +08:00 via Android
不明白为什么一个 commit main 上有,dev 上不能有,合并以后又要有
|
15
rrfeng 2023-03-21 19:23:37 +08:00
-i 试试交互模式能保留吗?
感觉既然 issue warning 了,应该有选项可以禁用这个特性? |
16
optional 2023-03-21 19:27:19 +08:00
再 revert 一次。。
|
17
kyonn OP @leonshaw 这个需求是比较奇怪, 原先最朴素的想法是这个问题在主线上的某个产品出现, 所以要求直接提 MR 给主线, 但是修改人提交的 MR TARGET branch 选错了, 变成了 dev 分支, 而 dev 分支上在开发其他产品, 跟这个 bug 没关系, 就直接 revert 了.
注: 这个 bug 改的不是公共代码, 而是主线上某个产品分支的代码, 而这个产品分支在 dev 上不涉及, 换句话说, dev 分支上在开发其他产品. |
19
kyonn OP @optional .... 见我后面的补充, dev 分支存在比较久... 到 rebase 的时候不一定记得有这么个坑要填....知道有这个问题了还是比较好处理的.
|
20
kyonn OP @leonshaw 对的, 但因为 Q'已经在 gitlab 上了, 所以并不能保证没人 pull 到这个 commit... 为了稳妥期间, 才选择 revert 的.
|
23
vvdsaa 2023-03-21 21:14:41 +08:00 via iPhone
从 main checkout 一个新 branch 指向 Q ;
cherrypick D 、E ; 新 branch pr 到 main |
24
weyou 2023-03-22 01:30:06 +08:00 via Android
关键点在于 dev 分支上的 Q 本就不该 revert 。既然 dev 是其他不相关的开发,不 revert 相当于提前 cp 了 main 的一些 commit ,Q 在 dev 上的存在是很正常的
|