开源项目二开如何让 git 不分叉。

2020-12-20 20:07:42 +08:00
 tlerbao

某个项目来自于开源项目的二次开发

项目本身有两个 remote

origin : 该项目我自己的私有 remote

upstream : 依赖的开源项目本身的 remote

项目有两个分支 master 和 dev,dev 用来开发,master 分支只合并 dev 上线分支。

现在是大部分时候我和 upstream 开源项目作者可能同时进行开发,如果我本地没有任何 commit 还好,一旦我本地有若干 commit (甚至已经合并到 master 并且已经 push 了)之后,我此时从 upstream 开源项目 pull 最新代码下来合并后,git log 就会分叉,并且会产生多余的一条 commit:Merge branch 'master' of https://xxx into dev 。

请问有办法避免分叉和产生这个多余的 commit 吗? rebase 似乎不行,求大神指教 另外这是我的强迫症作祟,如果能避免,避免分叉真的好吗,还是我无病呻吟 应该改掉这个强迫症,继续让他保持分叉。

4839 次点击
所在节点    git
30 条回复
msg7086
2020-12-20 20:15:03 +08:00
你用 merge pull 当然会产生 merge 。用 rebase 就行了。
tlerbao
2020-12-20 20:16:31 +08:00
@msg7086 具体一点小哥,我似乎用 git pull --rebase 也不行
ysc3839
2020-12-20 20:17:47 +08:00
@tlerbao git rebase upstream/master
saberlong
2020-12-20 20:21:18 +08:00
简述书上有个"如何使用 Git Rebase",我觉得不错
nightwitch
2020-12-20 20:23:45 +08:00
https://learngitbranching.js.org/?locale=zh_CN

建议把这个里面和 rebase 有关的章节都练习一下,自能解惑
msg7086
2020-12-20 20:26:23 +08:00
首先,我相信你是在做类似 mod 一样的工作。
这样的话,你所有的修改,应该都是在 upstream 上追加,对不对。
那么假设有 upstream 版本 v1,然后你在上面加了一堆 commit 做成了 v1mod 。
看上去是这样:
v1
 ↳ v1mod

现在 upstream 更新到了 v2
v1 → ...... → v2
 ↳ v1mod

那这里就很简单啊,你签出 v2,然后把 v1mod 上所有的提交搬过去不就得了。
v1 → ...... → v2
 ↳ 旧 v1mod  ↳ 搬走的 v1mod


最后应该是类似这样的结构:
https://vip1.loli.net/2020/12/20/R9Juo3MjUqgidTy.png

你不如先看看你的下游分支是不是结构干净整洁。不整洁的分支历史是很难处理的。
msg7086
2020-12-20 20:28:09 +08:00
shawndev
2020-12-20 20:32:23 +08:00
不如换一个思路,将原始项目作为 submodule,你的所有修改导出为 patch 文件。
hantsy
2020-12-20 20:42:04 +08:00
我是日常使用方式:

上游的项目 Fork 到你账号。

git clone github.com/your/project

git remote add origin your project url
git remote add upstream upstream project url

同步:(我的本地 Master 只作同步,相当只读方式)
git checkout master
git pull upstream master
git push origin master

feat 开发:
git checkout master // make sure you are branching from master.
git checkout -b feat1
git commit -am "feat: my feat"

gh pr create // use Github CLI to push to my origin/feat and create PR base on upstream/master

// 可能再次 Commit
git commit -am "commit"

//合并上面的没 Push 的 Commit
git commit --amend -am "commit "

//可能 push 了, 再次 Commit
git push -u
git commit -am "another commit"

//想合并一些 Comment,重整一下 Commit log 。
git rebase -i Head~3

//上游 Master 太多更新了,想同步一下。
// 先按上面的 同步 说明,切换到本地 Master,上游 Master 更新到本地 Master,Push 到 origin/master, 切换回 feat1
git rebase -i master

//最后你的 Pr 合并到上游
//可以是 Rebase (没冲突),也可能是 Merge (+Squash )
gh pr list
gh pr merge 55
liuxey
2020-12-20 20:54:58 +08:00
核心就是 变基( rebase ) ,好好研究一下吧,rebase 的使用姿势很多
tlerbao
2020-12-20 21:15:27 +08:00
@msg7086
@ysc3839
@saberlong
@nightwitch
@msg7086
@hantsy
@liuxey

我看了下简书那个如何使用 rebase 有点收获,我现在是 在 dev 分支这样操作
首先 git pull --rebase upstream master,没冲突最好,有冲突合并,或者还未 commit 的冲突先存储
成功 pull 后然后 rebase 到 master
git rebase master
然后
git checkout master && git merge dev
然后 push master

这样似乎我的时间线清楚了也没有分叉,但是在 git log 的时候,上游的 log 好像还是出了一个小叉这是正常的把,入下图

https://talent-miaoqiang.oss-cn-hongkong.aliyuncs.com/markdown/20201220/D1UA54.png
YouLMAO
2020-12-20 22:26:19 +08:00
好好用 git,不要提一些不合理要求,rebase 不建议在生产的仓库使用,个人玩耍就随便
cnnblike
2020-12-20 22:33:58 +08:00
@YouLMAO 没明白,我们工作的主 repo 有大概几百个 commit,历史两年多,rebase 用得好好的,另一个历史更长
saberlong
2020-12-20 22:44:42 +08:00
@tlerbao
确实会存在。rebase 方案这个地方确实不完美。只要分支开发提交到上游就会有。确认没问题后,删除这个分支也不影响。但是一般会保留用于追溯。由于基变导致 commit log 编号不同,需要靠 commit 说明来对比。虽然有瑕疵对比 merge 方案,我更喜欢 rebase 。
saberlong
2020-12-20 22:47:05 +08:00
@tlerbao 另外多个分支并行开发时。rebase 方案操作步骤会更多,我会使用本地临时分支
YouLMAO
2020-12-20 22:47:43 +08:00
@cnnblike 为了追求 Git 的线好看,在团队合作中使用 rebase 说轻点是舍本逐末,说重了是对团队不负责任。个人玩耍项目无所谓。非 Apache 项目不管你。
saberlong
2020-12-20 22:58:23 +08:00
@tlerbao 另外要说明的是,团队使用 rebase 方案,需要培训和约束的。否则请用 merge 方案。
msg7086
2020-12-20 23:33:15 +08:00
@YouLMAO 菜不是弃用一个优秀功能的理由。
Git 线好看怎么就是舍本逐末了。版本管理系统里,「版本管理」自然就包括对历史的把控。一个清晰的历史记录可以方便地追溯代码的变更,也方便把某个或者某组提交拿出来做 revert 或者 cherry pick 。
因为某些开发人员水平太菜,导致该 rebase 的地方滥用 merge,最后版本管理记录变成一大坨犬牙交错的屎山,这才叫舍本逐末,这才叫不负责任。
不懂可以去学,可以让同事教,没人会怪你的。

怎么不说因为有些人写不好 C++所以大家都去改用 VB6 呢。

当然,还有一种可能,你们团队太大了,不可避免地遇到坑队友而且没人愿意培训。
这种情况下最好的方法既不是 rebase 也不是 merge,而是 squash 。
我们团队现在就是推荐用 squash,虽然主线上一坨坨的 squash 谁都不知道里面到底有哪些东西,但是老板开心就好了呗,反正出问题也轮不到我背锅,我一点儿也不想操心。
msg7086
2020-12-20 23:38:04 +08:00
@tlerbao #11 你这个看上去不太对。
rebase 完以后应该是一条直线,像是:
e723 → 1219 → 你的项目的 4 次提交

你看我 7 楼贴的图,upstream (mainline) 到 mod (sb-master) 之间应该是一条线。
ooee2016
2020-12-21 00:28:45 +08:00

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

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

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

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

© 2021 V2EX