求助 git 自动 merge 丢代码

5 天前
 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 依然还在

3125 次点击
所在节点    git
45 条回复
xiaozhu5
5 天前
git reflog 和 git fsck 两个结合看一下应该找到丢失信息
gesse
5 天前
featA 添加了 line70 ,并合并进了 master ,你在 featA 上 fork 出 featB ,featB 上删除了 line70 后,又把 master 合并进 featB ,这不就是在 featB 上添加了 line70 吗? 一点毛病没有。
mark2025
5 天前
为什么要在 featB 上面执行 featB 分支上 git merge master ? 这就是混乱的根源
1. 要么是在 featB 分支上 `git merge featA`
2. 要么是在 featB 分支上 `git rebase master`
netabare
5 天前
所以不要把 master 合入分支,分支上面只用 rebase 。
GeruzoniAnsasu
5 天前
https://v2ex.com/t/843165#r_11508345


> (!!) 其实我本来想简单解释一下为什么三路合并会出问题,但在我搜索看了近一个小时文章后,我选择放弃解释:
https://www.waynerv.com/posts/git-merge-intro/
https://git-repo.info/zh_cn/2020/03/something-about-git-merge/
https://actake.github.io/2021/03/21/git%E5%BF%85%E7%9F%A5%E5%BF%85%E4%BC%9A-%E5%88%86%E6%94%AF%E5%90%88%E5%B9%B6%E9%82%A3%E4%BA%9B%E4%BA%8B/

> (!!) 因为这已经是我至少第 4 次搜索这个问题然后仍然没有完全搞懂了
mark2025
5 天前
@GeruzoniAnsasu 三路合并就是人多嘴杂,你不仔细查看变动就无法确定最终合并结果是否符合预期。所以基于 rebase 的线性合并在团队开发中是最高效的( gitlab 可以设定强制线性合并)
mark2025
5 天前
@mark2025 并且线性合并的另外一个好处是 revert 时工作量低不容易出错。
sagaxu
5 天前
git merge 除非是 fast forward ,在处理多个分支修改同一文件时,不一定符合你的预期。

所以这种情况用 rebase 甚至是 reset --soft ,然后手动处理变更会更好。
GeruzoniAnsasu
5 天前
@mark2025 人多嘴杂是其次,问题在用好 merge 要制定的规范(比如不允许 pull-merge ,自己的分支不能 merge 别人分支后再 merge 到 main……等等,它一点也不直观。

你搞不清楚需要哪些规范才能保证不发生 A merge B 然后 B merge A 导致代码没了这种问题
mark2025
5 天前
@GeruzoniAnsasu 这是我所有 git 项目钩子自动执行的:

git config --global i18n.commitencoding utf-8
git config --local core.autocrlf input
git config --local core.eol lf

if [ -z "$CI" ]; then
git config --local core.filemode false
git config --local core.hooksPath ./.githooks
git config --local core.ignorecase false
git config --local core.precomposeUnicode true
git config --local fetch.prune true
git config --local pull.rebase true
git config --local push.autoSetupRemote true
git config --local push.followTags true
git config --local rebase.autoStash true
git config --local remote.origin.prune true
git config --local remote.origin.tagopt --tags
git config --local remote.pushdefault origin
git config --local rerere.enabled true
fi;
leonshaw
5 天前
base 没有 line70 ,那严格来说 B 并没有基于 A 开发
leonshaw
5 天前
B merge master 没有问题,但是不能 merge 没有进 master 的 A
LeeEnzo
5 天前
强制 rebase 和 squash 开发
freesun165
5 天前
@netabare 话虽如此,但我这个业务场景经常一个分支测一个月以上,一百多个提交,每次 master 更新,我挨个 rebase 下,成本太高了
freesun165
5 天前
@leonshaw 我是直接在 featA 上切出去 featB
freesun165
5 天前
@mark2025 俺这规范就是上线前 featB 需要合并 master 推到远端,远端 master 再合并 featB ,然后就出现了这么不符合知觉的事
riceball
5 天前
还是 Git 操作要有规范,这个彼此合并,左右互搏,啧啧,建议使用 Git flow 规范,有 git 插件支持: https://danielkummer.github.io/git-flow-cheatsheet/index.zh_CN.html
rbaloatiw
5 天前
按你的描述感觉不太可能, 你有最小可复现样例吗, 可以发出来看看
coolcoffee
5 天前
git 的分支操作应该是像一颗树一样,开叉但是不会互相交叉。 如果平行的节点需要互相同步,那么应该一方往上推到相同的节点,另外一方再去拉,这样就遇到相同修改就必定会产生冲突。
BeautifulSoap
5 天前
唔嗯?这情况你确定真没冲突吗?

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

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

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

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

© 2021 V2EX