V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
git
Pro Git
Atlassian Git Tutorial
Pro Git 简体中文翻译
GitX
unco020511
V2EX  ›  git

关于 git 和 git workflow 的几个疑点请教下大家

  •  
  •   unco020511 · 2021-04-16 14:39:31 +08:00 · 3591 次点击
    这是一个创建于 1077 天前的主题,其中的信息可能已经有所发展或是发生改变。

    迫于目前团队 git 使用不是很规范,故有几个疑问想请教下

    1. merge 和 rebase 有什么区别,实际使用中更推荐使用哪一个,为什么

    2. 实际使用中应该使用哪种 workflow,好像 github/gitlab/git folw 这几种有不小的差异

    3. github 的 pull request 其实就是 git 自带的 merge 或者 rebase 吗,为啥叫 pull request,这个好难理解

      • 延伸出问题 6
    4. commit 的颗粒度如何把握,每个 commit 都应该保证代码能编译和 run 吗?还是只需要保证每一个 pr 能正常编译和 run 就行

    5. 功能分支合并后应该立马删除吗,还是应该定期删除,又或者永久保留

    6. 实际 git 工作流中,pull request 这个流程是必须的吗,直接 git 自带的 merge 不行吗

    7. 最后,有没有推荐的 git 和 git workfow 相关的文档,最好是中文的,可视化的更佳

    先谢谢大家了

    第 1 条附言  ·  2021-04-16 17:28:51 +08:00
    谢谢大家,基本都明白了
    31 条回复    2021-04-17 14:25:48 +08:00
    jinx930621
        1
    jinx930621  
       2021-04-16 14:48:08 +08:00   ❤️ 4
    先扔一个可视化 git 教程的链接在这 https://learngitbranching.js.org/?locale=zh_CN
    我们现在在用的是 gitlab,gitlab 上就直接叫 merge request
    xlui
        2
    xlui  
       2021-04-16 14:51:36 +08:00
    1. 推荐 merge,rebase 会改写 commit 历史,导致所有合作者都需要处理冲突。
    3. GitHub 的 PR 有多种形式,可以直接 merge,也可以把 PR 中所有的 commit 都 squash 为一个 commit 。
    4. 个人习惯一个功能点一个 commit 。
    5. 个人习惯合并后删除,因为合并后分支跟 master 已经没区别了。
    6. PR 是必须的,master 分支禁止直接 push 。因为 master 要保证始终是稳定的。同时 PR 也会要求其他人去 review 你写的代码,对代码质量做一定的保障(虽然实际上大多数人不会去细看)。
    zdt3476
        3
    zdt3476  
       2021-04-16 14:54:17 +08:00
    仅供参考
    首先是大致分为 release 线、dev 线、feature 线
    1. feature 开发过程中,需要用到 dev 合入的其他线的代码,推荐 rebase 到当前的 feature 。当前 feature 要合入 dev 的时候用 merge
    2. 这个没研究过
    3. 我们项目用的 gitlab,然后是 merge request,和 github 的 pull request 应该没啥区别
    4. commit 按我的习惯是,保证能编译能 run,然后粒度尽量细一点,这个需要自己把握
    5. 功能分支我都是 git branch 觉得显示太多了,就回去删
    6. 我们反正 feature 合入 dev 都是 merge request
    floyda
        4
    floyda  
       2021-04-16 14:57:39 +08:00
    ## 1. merge 和 rebase 有什么区别,实际使用中更推荐使用哪一个,为什么

    > 推荐使用 merge, 虽然容易冲突, 但是安全; rebase 虽然让分支树好看, 但是在断开与 Parent 的连接, 这个很危险

    ## 2. 实际使用中应该使用哪种 workflow,好像 github/gitlab/git folw 这几种有不小的差异

    > 根据团队人数, 合作方式, 自己选择. 没有最好的, 只有最合适的.

    ## 3. github 的 pull request 其实就是 git 自带的 merge 或者 rebase 吗,为啥叫 pull request,这个好难理解

    > 2 个不同的仓库, 请求你从我的仓库, pull 某些 commit

    ## 4. commit 的颗粒度如何把握,每个 commit 都应该保证代码能编译和 run 吗?还是只需要保证每一个 pr 能正常编译和 run 就行

    > 建议使用 feature 分支, commit 的颗粒度无所谓, 包括提交信息都可以随意. finish feature 的是时候保证通过测试即可.

    ## 5. 功能分支合并后应该立马删除吗,还是应该定期删除,又或者永久保留

    > 使用`git flow`, 会自动帮你处理.

    ## 6. 实际 git 工作流中,pull request 这个流程是必须的吗,直接 git 自带的 merge 不行吗

    > 看团队的负责人是否想去做这个工作了.

    ## 7. 最后,有没有推荐的 git 和 git workfow 相关的文档,最好是中文的,可视化的更佳

    > 推荐使用 `Sublime Merge`, 欢迎进群(不知道能不能放群号)
    floyda
        5
    floyda  
       2021-04-16 15:01:06 +08:00
    1. 推荐使用 merge, 虽然容易冲突, 但是安全; rebase 虽然让分支树好看, 但是在断开与 Parent 的连接, 这个很危险
    2. 根据团队人数, 合作方式, 自己选择. 没有最好的, 只有最合适的.
    3. 2 个不同的仓库, 请求你从我的仓库, pull 某些 commit
    4. 建议使用 feature 分支, commit 的颗粒度无所谓, 包括提交信息都可以随意. finish feature 的是时候保证通过测试即可.
    5. 使用`git flow`, 会自动帮你处理.
    6. 看团队的负责人是否想去做这个工作了.
    7. 推荐使用 `Sublime Merge`, 欢迎进群(不知道能不能放群号)

    恢复居然不支持 Markdown
    Rwing
        6
    Rwing  
       2021-04-16 15:05:25 +08:00   ❤️ 4
    我针对 1 发表一下个人意见,其他的都和大家差不多。
    merge 和 rebase 要分情况使用:
    如果是从一个分支合并到另一个分支,要表达强烈的“合并”的意图,那么 merge 。
    如果仅仅是从远端拉代码,要同步到当前的进度,并不是真的想“合并”,用 rebase 。
    unco020511
        7
    unco020511  
    OP
       2021-04-16 15:10:27 +08:00
    @floyda 感谢解答

    pull request 应该叫 push request 或者 merge request 是不是更直观一些呢,就好像我发现了你的一些 bug 并帮你修复了,我想向你的仓库(或者分支)push 一些最新的 bugfix 代码
    unco020511
        8
    unco020511  
    OP
       2021-04-16 15:11:29 +08:00
    @jinx930621 谢谢,宝藏网站,不过这个网站我之前就学习过
    unco020511
        9
    unco020511  
    OP
       2021-04-16 15:13:49 +08:00
    @xlui 一般 pr 这个动作是 feature 分支合并到 dev 吧,dev 合并到 master 是专人维护
    unco020511
        10
    unco020511  
    OP
       2021-04-16 15:15:51 +08:00
    @Rwing 明白了,你和三楼说的一样
    SingeeKing
        11
    SingeeKing  
       2021-04-16 15:16:04 +08:00
    commit 可以随便 commit,pr 之前把共性的 rebase 掉
    floyda
        12
    floyda  
       2021-04-16 15:31:24 +08:00
    @unco020511

    Q: 432333235
    欢迎讨论 Sublime Merge 的使用
    xlui
        13
    xlui  
       2021-04-16 15:52:56 +08:00
    @unco020511 #9 经验之谈,实际执行的时候都是直接从 feature 往 master 合,并没有专人维护 dev 分支。

    当然开源项目按这个流程没问题。
    yeqizhang
        14
    yeqizhang  
       2021-04-16 16:14:59 +08:00 via Android
    @Rwing 赞同啊,我就同步一下代码,不用 pull rebase 搞的时间轴很难看的
    yeqizhang
        15
    yeqizhang  
       2021-04-16 16:17:31 +08:00 via Android
    @unco020511 他跟三楼说的不一样,他说的分支之间合并都用 merge,同步远程仓库代码 rebase
    otakustay
        16
    otakustay  
       2021-04-16 16:27:52 +08:00
    PR 为什么叫 pull request:我请求( request )代码的负责人来拉( pull )我的代码到主干
    ryougifujino
        17
    ryougifujino  
       2021-04-16 16:37:04 +08:00
    抽几条回答一下

    1. 首先如果是一个私人分支的话,你要同步 master 的代码,这时候用 rebase 其实是最好的,因为不像 merge 可能会产生一个 merge commit,可以一定程度上保持提交历史的简洁。
    如果是你的分支(假如 feature 分支)开发完毕了,想合入主分支,这时候用 merge 比较好,因为可以保留你的分支痕迹(--no-ff )。但是有很多著名的开源项目合入主分支时也是用的 rebase (比如 angular ),这样主分支就是一条直线,很简洁。

    3. 说到 pull request,直译过来就是拉取请求,这个怎么理解呢,就要说起在 GitHub 上的协助方式。在 GitHub 上有一个开源项目,它可能会收到来自其他人成千上万的贡献,如果大家都提交到一个 repo 的话,就可能会很混乱。所以非 member 的开发者是对主仓库没有提交权限的。这时候怎么做贡献呢?就要 fork 一份主仓库,这个 fork 的仓库是完全属于你的,你可以随意提交。当你想把你的提交贡献给主仓库时,就可以发起一个 pr (拉取请求,即“主仓库 member 拉取你代码的请求”)。然后主仓库的 member 拉取了你的代码 review 后决定要不要并入主干。所以 pr 机制就保证了,既可以保持主仓库的整洁,又可以方便的接受别人的贡献。
    msg7086
        18
    msg7086  
       2021-04-16 16:46:34 +08:00   ❤️ 1
    1. Merge 会产生一个 Merge 节点,而 Rebase 会改变历史。实际使用中,该 Merge 的时候用 Merge,该 Rebase 的时候用 Rebase 。就我个人意见,一味 Merge 和一味 Rebase 都是错误的行为。
    2. 几种 Workflow 其实都大同小异,本质上是一样的,在自己的小世界里随意玩耍,折腾完了再拿出去给别人看。然后还有一个 Release branch 。
    3. Pull request 或者 Merge request 是拿来 code review 的过程。PR 是开源软件中用的,因为人与人之间互为不信任,所以每个人在自己的 Repo 里工作,跨 Repo 合并的过程就是请别人从你这里 Pull 。MR 一般是企业开发用得多,因为人与人之间互信,所以大家都在同一个 Repo 里工作,Repo 内合并就是 MR 了。本质上原理相同。
    4. Commit 的粒度随意,只要发 PR/MR 之前把分支整理干净就可以了。
    5. 合并时删除。
    6. 如果没有人 Code review,那当然自己 Merge 就行了。有 Code review 就先提 PR/MR,等 approval 和 CI,然后再合并。
    msg7086
        19
    msg7086  
       2021-04-16 16:49:01 +08:00
    关于 Merge 和 Rebase 的使用时机,原则上:
    从主干更新代码到分支,用 Rebase,把分支 Rebase 到主干 HEAD 上;
    从分支更新代码到主干,用 Merge,先按上一条 Rebase 后,再把分支 Merge 回主干。Merge 时可以附上这个分支所实现的功能,或者修复的 Bug 编号,或者完成的 Jira 编号等等。
    unco020511
        20
    unco020511  
    OP
       2021-04-16 16:54:15 +08:00
    @ryougifujino 谢谢,说的很详细,基于此我的理解:其实 pr 已经脱离标准的 git 流程了,属于团队外协作,因为 pr 是仓库(repo)与仓库之间的合并.那么实际公司团队开发中,应该不存在 fork 这个操作吧,都是基于同一个 repo 的不同分支的,那当我们从 feature 合并到 dev 的时候,也会涉及 pull request 吗,这个 pr 和 repo 之间的 pr 又有什么区别呢
    unco020511
        21
    unco020511  
    OP
       2021-04-16 16:59:06 +08:00
    @msg7086 谢谢,关于 pr 的回答感觉你这个是最好的,我之前一直会混淆 pr(repo 间协作)和 mr(repo 内协作),这样区分就很清晰了,开源项目与企业项目的协作方式是不同的,不能一概而论
    unco020511
        22
    unco020511  
    OP
       2021-04-16 17:12:30 +08:00
    @msg7086 18# 但我去看了 github 和 gitlab 的文档,在 github 中,branch 间发起合并也叫 pull request,在 gitlab 中,repo 间发起合并也叫 merge request,看来只是名字不一样.只不过 github 多用于开源项目协作,gitlab 多用于私有部署,所以命名会不太一样?
    ryougifujino
        23
    ryougifujino  
       2021-04-16 17:15:50 +08:00
    @unco020511 #20 首先你可以参考下这个链接,对 pr 有详细解释 https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests

    pr 和 mr 其实是完全一样的,它们可以发生在不同的 repo,也可以发生在同一个 repo 。
    在同一个 repo 时,需要指定 pr 的源分支和目标分支(必须是不同的分支)。
    在不同的 repo 时可以分支的对应可以任意。比如我们要像一个开源项目提 pr 时,除了默认的 origin 指向我们 fork 的仓库,还需要一个 upstream (上游)指向主仓库。这时候我提一个 pr,就可以这样对应分支:origin/master (源)——>upstream/master (目标)。
    msg7086
        24
    msg7086  
       2021-04-16 17:18:41 +08:00
    @unco020511 功能本质上是一样的,就是叫法不同,因为起源不同。
    确实就是如你所说,GitHub 是社交网站性质更多,而 GitLab 是企业用更多,所以风格不太一样。
    ryougifujino
        25
    ryougifujino  
       2021-04-16 17:21:15 +08:00
    @unco020511 #20 说 pr 脱离了 git 流程其实不太准确,因为所谓的“git 流程”其实指的就是 git 工作流。git 工作流有很多种,涉及到 pr 的叫 GitHub flow,涉及到 mr 的是 GitLab flow,它们都是 git 工作流的一种。在实际公司的开发者,也可能会 fork,也可能没有,这主要是由公司使用哪种 git flow 决定的。
    unco020511
        26
    unco020511  
    OP
       2021-04-16 17:22:16 +08:00
    @ryougifujino
    @msg7086 现在我完全弄明白了,谢谢
    miyuki
        27
    miyuki  
       2021-04-16 17:24:43 +08:00 via iPhone
    其实是 request 对方去 pull 你的代码🐶
    LuckyLight
        28
    LuckyLight  
       2021-04-16 17:41:29 +08:00
    1. 本地分支拉取当前分支最新代码,使用 rebase
    本地分支拉取主干分支最新代码,使用 rebase
    本地分支合并到主干分支,使用 merge
    4. 细粒度 commit,防止多人开发时冲突太多
    5. 一般合并到主干分支上线打 tag 之后,可以立即删除
    icylogic
        29
    icylogic  
       2021-04-17 12:14:33 +08:00   ❤️ 2
    两个 rebase 适用场景:
    你的 private branch 在准备提交 pr 前,用 rebase -i 整理好,为 merge 提供一个干净清晰的历史。
    你在 local branch 上工作,然后主分支有了更新,你需要这些更新或者有了冲突需要解决,你可以选择 rebase 到最新主分支上。

    rebase 会改变历史,而 git repo 里需要遵守的是“不要修改公开历史”,rebase 就是给非公开历史准备的工具。

    可以看看 Linus on git rebase and merge:
    https://www.mail-archive.com/[email protected]/msg39091.html
    icylogic
        30
    icylogic  
       2021-04-17 12:16:25 +08:00
    People can (and probably should) rebase their _private_ trees (their own
    work). That's a _cleanup_. But never other peoples code. That's a "destroy
    history"
    wisetc
        31
    wisetc  
       2021-04-17 14:25:48 +08:00 via iPhone
    没有推之前放肆 rebase,推了之后 rebase 会和远程冲突,而冲突其实就是 commit 历史不一致,而远程往往是公用的,至少是两个端,两个以上就容易冲突。用 merge 以示尊重,不要随便变更他人的分支。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3320 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 13:36 · PVG 21:36 · LAX 06:36 · JFK 09:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.