关于 git 合并时使用 git megre --squash 到 master 出现冲突的问题

322 天前
 Bingchunmoli

从 master 拉出 develop 分支开发后 megre --squash 到 master 发布 下次开发 develop 时

使用 develop megre --squash 到 master 频繁出现冲突,合并提交也有很多历史内容,更新的版本居然也会冲突, 是哪里做的不对吗?

github.com/bingchunmoli/moliapi github.com/bingchunmoli/quick

1430 次点击
所在节点    git
12 条回复
BeautifulSoap
322 天前
megre --squash 就是这样的
除非你每次 megre --squash 后,再把 develop 给 rebase 或者 hard reset 到最新的 master 上
geelaw
322 天前
是 merge 不是 megre 。

在 A 上 git merge --squash B 的意思是在 A 之后建立一个 commit C ,它的 parent 是 A ,效果是 A 和 B 的 merge base 以来 B 的变化的复合。这相当于在 A 上面把 B 里面的事情重做一次再 commit ,因为 C 的 parent 没有 B (换言之,Git 认为 C 和 B 没有关系),所以继续在 B 、C 开发后再次 merge ,会导致 Git 以为 B 和 C 包含重叠的变化,于是 Git 不知道怎么办(是接受一次呢,还是接受两次呢,还是……),即冲突。

由此可见两种解决办法:一是 B 继续开发之前重新指向 C ,于是下次 merge 的时候 B 先前的变化就不是 merge 的考虑范围了;二是采用 merge commit ,让 C 记住自己来自于 A 和 B 。
zjp
322 天前
一开始为什么用 megre --squash 呢
Bingchunmoli
322 天前
@zjp 因为看晚上说 master 作为 squash 更简洁,更适合版本号管理这种,所以尝试一下
Bingchunmoli
322 天前
@geelaw 第一种就是 a 中的 c 记录 rebase 或者 merge 到 b 吧,第二种如何做
geelaw
322 天前
@Bingchunmoli #5 这个问题是很奇怪的,因为 merge commit 是常态,squash merge 是非常态。如果 git merge 不加 --squash 那么 Git 在默认设置下就会采用 merge commit 。

但这些实操并不重要,随便搜索一下就知道了。我的回复想要表达的是这个:Git 中一切信息都来自于每个 commit 里面的内容和 commit 的亲子关系,任何计算(例如 merge 如何 merge )当然只能基于这些信息。Squash merge 会导致 Git 记录的信息和人类心中的信息不一样,两种解决方案无非是告诉 Git 正确信息的方法。
yqyq1020
322 天前
你只有一个 dev 分支不适合 squash 每次拉一条 feat 分支出来开发才比较适合 squash
zjp
322 天前
megre --squash 好看的代价是要解决更多的冲突,有时甚至两边内容完全一样
而且只有一个 dev 分支用这种方式,好像很难分辨哪个 commit 的内容已经合并了吧。一个 feat 一个分支的情况合并完就删了没问题
nothingistrue
322 天前
--squash 会修改提交,你压缩合并进去的并不是原始的 develop 分支,而是临时生成的 develop' 分支。执行 megre --squash 之后,你的分支关系实际上变成了 master 、develop'、develop 三个分叉。这三个分叉,master 先接受了 develop' 分支的合并,这时候如果你在将 develop 往 master 合并,因为 develop' 跟 develop 必然是相同的修改但不同的提交,那必然冲突。

就算你解决了冲突,除了第一次外,你之后的每次 develop megre --squash master ,都是在重复合并相同的修改,master 的历史必然混乱。
nothingistrue
322 天前
git 多分支齐头并进时,请切记不要用任何修改提交的操作,例如 megre --squash ,例如 rebase 。

事实上,多分支齐头并进是一项极度高端的操作,新手请勿使用这种方式,不然要么两个分支的历史都很混乱,要么像上面那样瞎胡操作导致历史更混乱。我们常见的 git 工作流,本质上都是单一主分支的形式——出了主分支之外,其他分支都是合并完即作废的临时分支。rebase merge 还能通过再次 rebase 将已经合并的分支救活继续用,squash merge 之后的,原分支是彻底废了,除了删除没有其他出路。
anonym233
322 天前
如果想合并 dev 代码到 master 的时候整理为一个 commit ,使用 merge --squash 没有问题。但是有两个条件,在 dev 开发的时候如果要用的 master 的代码,要用 merge 而不是 rebase ;使用 merge --squash 之后,dev 分支要抛弃到,如果想继续 dev 开发,那就再最新的 master 上再重建一个 dev 分支。
Bingchunmoli
322 天前
@nothingistrue 因为觉得 --squash 是一种损失信息的方式,develop 去保存更多信息所以没有删除\⁠(゚⁠ー゚⁠\⁠),拉出 release 也是一种一样,所以单纯 merge 才是正常情况

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

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

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

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

© 2021 V2EX