求助 git 自动 merge 丢代码

257 天前
 freesun165

今天遇到个 git 合并丢代码的场景。 featB->featA->master featA 基于 master 开发,featB 基于 featA 开发。featA 合入 master 后,我直接在 featB 分支上 git merge master ,出了问题。 具体如下 featA 对于 file1 加了 line70 ,featB 对 file1 删了 line70 ,在 featB 上 merge master 后,git 自动 merge 的结果是 line70 依然还在

5130 次点击
所在节点    git
45 条回复
kivmi
257 天前
太危险了,master -> branch , 相当于你对同一行的修改无效啊,各种冲突吧?可以从 master 同时 fork 几个分支?一个为开发分支,一个为上线分支?当需要上线时,合并到上线分支,然后合并到 master ,一直保持上线分支跟 master 保持一致,实现快速上线。貌似 git flow hotfix 也可以做到。
zthxxx
257 天前
老生常谈话题之「不要把 master/dev 合到自己的分支」,开发时也始终应该像 GitHub / GitLab 那样的「把自己分支合到 master/dev (主干分支)」
leonshaw
257 天前
@freesun165 #15 这样 base 应该是切出去时的 commit ,不然就是后面这个 commit 被重写掉了,最好画个图看看。
BeautifulSoap
257 天前
我实际在本地测试了一下

最终结果是 master 合并入 feature b 后的确没报冲突,但被 feature b 删除的 line 也没再次出现

可能 lz 实际给个最小可复现例子比较好
nightwitch
257 天前
git 只允许 fast-forward 就不容易出现这个问题。
三路合并一定要小心,否则很容易出现冲掉别人的代码 / 别人的代码把自己的冲掉 / 两边的代码合并到了一起导致逻辑不对了。
FrankAdler
257 天前
我也遇到过,目前没有头绪,我是 master 拉出来的分支,修改后合并到 dev 分支,cicd 到测试 k8s ,出现过几次代码没有提示冲突,但是丢了几行。
jqtmviyu
257 天前
![]( )

我也是没有复现,main 合并到 B 没有冲突, 此时 B 比 A 和 main 领先一次提交,合并没有变化,删除的行也不会回来。
jqtmviyu
257 天前
@jqtmviyu #27 我是设置了

```~/.gitconfig

[merge]
ff = false
[pull]
rebase = true
```
acorpe
257 天前
@jqtmviyu 好早啊
networm
257 天前
@freesun165 #14 使用 Fork 的 Leaning Branch 功能进行同步,只需要一键就可以自动同步。

另外推荐看下:
Git 精干分支 - 狂飙
https://networm.me/2022/09/11/git-lean-branching/

合并分支只会通过合并提交引入最终的修改,而不是合并分支中的原始提交。
因为合并提交也是提交,但是大家潜意识都不会关注合并提交的改动,因此可能会在冲突解决中引入大量的错误的修改。
如果一个东西容易引起错误,那么建议减少这个东西的使用,使用 Lean Branching 方案就可以。
在与主干同步的时候,相当于检出到主干新建分支,将原有分支上的东西 cherry-pick 到新分支,因此需要逐个解决冲突。
这个方案的核心是只在最后时合并提交,同时由于主干与功能分支的起点之间没有提交,合并提交引入的修改全部都是功能分支的改动。由于前面已经处理了冲突,这里逻辑上就不需要处理冲突,从根本上去除了冲突的处理。
chenluo0429
257 天前
我猜 featA 合并到 master 时,经过了 sqlash 之类的操作,导致 master 上 featA 的修改与 featB 所基于的 featA 并不是同一笔提交,而是修改内容相同的两笔不同提交
feelapi
257 天前
merge, rebase 两种思路是冲突的。不建议混合使用。
merge ,master->A->B ,不能跨越这个流程,B 回到 master ,也要顺序回去。merge 之前,要先从 parent 更新,例如 B 回到 master:
1. merge A->B
2. Merge B->A
3. merge master->A
4. merge A->master
wgbx
257 天前
Git 不是万能药,要遵守 git flow
freesun165
257 天前
@rbaloatiw 发了,大佬可以看下
freesun165
257 天前
@jqtmviyu 就是( main ) git merge A 时加上 squash 就可以复现了,因为当时是 gitlab 上勾选了 squash commit 的选项
freesun165
257 天前
@chenluo0429 是的
ryougifujino
257 天前
不用 squash 就不会有这个问题,squash 等于把历史线改了。还有功能基于功能分支进行切换是典型的“穷人的模块化架构”,一般采用 feature flags 类似的技术比较好。建议看一下 Martin Fowler 的这篇版本控制流的文章: https://v2ex.com/t/1072486
zhuisui
257 天前
你要想充分利用 git merge 的自动冲突解决能力,就不要做 squash 、fixup 、amend 、cherry-pick 这类会修改 commit 的操作,你必须在 merge 时原样保留各路 branch 。
你只要记住,如果你要 merge branch ,一定要保留 branch 原来的样子。因为 git 就是利用 branch 和 merge commit 来决定冲突解决结果的。
proxychains
257 天前
rebase 的好
p1gd0g
256 天前
之前遇到几次丢代码,几个主流的 git 软件都看不到哪一次提交丢了,只有 tortoisegit 可以。
但我们没有用 squash ,我也没搞清楚同事到底是怎么操作的。

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

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

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

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

© 2021 V2EX