首页 > 其他分享 >git merge vs git rebase

git merge vs git rebase

时间:2024-06-03 16:33:09浏览次数:14  
标签:git rebase feature merge master 分支

 

 

git rebase命令经常被认为是Git巫术,初学者应该远离它,但它实际上可以让开发团队在使用时更加轻松。在本文中,我们将git rebase与相关git merge命令进行比较。


概念


首先要理解的是git rebase和git merge解决了同样的问题。这两个命令都旨在将更改从一个分支集成到另一个分支 - 它们只是以不同的方式进行。
试想一下当你开始在专用分支中开发新功能时另一个团队成员以新提交更新master分支会发生什么。这会出现分叉历史记录,对于使用Git作为协作工具的任何人来说都应该很熟悉。



现在,我们来说说当master新提交与你正在开发的功能相关。要将新提交合并到你的feature分支中,你有两个选择:merge或rebase。


Merge


最简单的是将master分支合并到feature分支中:
git checkout feature
git merge master
或者,你可以简化为一行:
git merge master feature
这会在feature分支中创建一个新的“merge commit”,它将两个分支的历史联系在一起,为你生成如下所示的分支结构:



合并很好,因为它是一种非破坏性的操作。现有分支结构不会以任何方式更改。这避免了rebase的所有潜在缺陷(下面讨论)。
另一方面,这也意味着每次上游更改时feature都需要合并,且有无关的合并提交。如果master改动非常频繁,这可能会严重污染你分支的历史记录。尽管可以使用高级git log选项减轻此问题的影响,但它可能使其他开发人员难以理解项目的历史更改记录。


Rebase


作为merge的替代方法,你可以使用以下命令将feature分支rebase到master分支上:
git checkout feature
git rebase master
这会将整个feature分支移动到master分支的顶端,从而有效地整合了所有master的新提交。但是,rebase不是使用merge commit,而是通过为原始分支中的每个提交创建全新的提交来重写项目历史记录。



rebase的主要好处是可以获得更清晰的项目历史记录。首先,它消除了不必要的git merge产生的merge commit。其次,正如在上图中所看到的,rebase也会产生完美线性的项目历史记录 - 你可以从feature分支顶端一直跟随到项目的开始而没有任何的分叉。这使得它比命令git log,git bisect和gitk更容易导航项目。
但是,对这个原始的提交历史记录有两个权衡:安全性和可追溯性。如果你不遵循rebase的黄金法则,重写项目历史记录可能会对你的协作工作流程造成灾难性后果。其次rebase会丢失merge commit提供的上下文 - 你无法看到上游更改何时合并到功能中。


Interactive Rebase


Interactive rebase使你有机会在将提交移动到新分支时更改提交。这比自动rebase更强大,因为它提供了对分支提交历史的完全控制。通常,这用于在合并特征分支到master分支之前清理杂乱的历史记录。
要开始基于交互式会话,请将i选项传递给git rebase命令:
git checkout feature
git rebase -i master
这将打开一个文本编辑器,列出即将移动的所有提交:
pick 33d5b7a Message for commit #1
pick 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3
列表准确给出了执行rebase后分支的概况。通过更改pick命令和(或)重新排序,可以使分支的历史记录成为你想要的内容。例如,如果第二次提交修复了第一次提交中的一个小问题,你可以使用以下fixup命令将它们压缩为单个提交:
pick 33d5b7a Message for commit #1
fixup 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3
保存并关闭文件时,Git将根据你的指令执行rebase,从而产生如下所示的项目历史记录:



消除这种无意义的提交使你的历史记录更可读。这是git merge无法做到的事情。


rebase的黄金法则


一旦你理解了什么是rebase,最重要的是了解什么时候不使用它。git rebase的黄金法则是永远不要在公共分支使用它。
例如,想想如果你把master分支rebase到你的feature分支会发生什么:



rebase将master所有提交移动到feature顶端。问题是这只发生在你的仓库中。所有其他开发人员仍在使用原始版本master。由于rebase导致全新的提交,Git会认为你的master分支的历史与其他人的历史不同。
同步两个master分支的唯一方法是将它们合并在一起,从而产生额外的合并提交和两组包含相同更改的提交(原始提交和来自rebase分支的更改)。这将是一个非常令人困惑的情况。
因此,在你运行git rebase之前,总是问自己,“还有其他人在用这个分支吗?”如果答案是肯定的,那就把你的手从键盘上移开,考虑使用非破坏性的方式进行(例如,git revert命令)。否则,你可以随心所欲地重写历史记录。


强制推


如果你尝试将rebase过的master分支推到远程仓库,Git将阻止你这样做,因为它与远程master分支冲突。但是,你可以通过传递--force标志来强制推送,如下所示:
#这个命令要非常小心!
git push --force
这将覆盖远程master分支以匹配rebase过的分支,并使团队的其他成员感到困惑。因此,只有在确切知道自己在做什么时才能非常小心地使用此命令。
工作流
rebase可以根据你团队的需要尽多地或少量地整合到你现有的Git工作流程中。在本节中,我们将了解rebase在功能开发的各个阶段的好处。
任何工作流程git rebase的第一步是为每个功能创建专用分支。这为你提供了必要的分支结构,以安全地利用rebase:



本地清理


将rebase加入工作流程的最佳方法之一是清理本地正在进行的功能。通过定期执行交互式rebase,你可以确保功能中的每个提交都具有针对性和意义。这使你可以写代码而无需担心将其分解为隔离多个的提交 - 你可以在事后修复它。
调用git rebase时,有两个基(base)选项:feature的父分支(例如master),或feature中的历史提交。我们在Interactive Rebasing部分看到了第一个选项的示例。当你只需要修复最后几次提交时,后一种选择很好。例如,以下命令仅针对最后3次提交的交互式rebase。
git checkout feature
git rebase -i HEAD~3
通过指定HEAD~3为新的基,你实际上并没有移动分支 - 你只是交互式地重写其后的3个提交。请注意,这不会将上游更改合并到feature分支中。



如果要使用此方法重写整个功能,git merge-base命令可用于查找feature分支的原始基。以下内容返回原始基础的提交ID,然后你可以将其传递给git rebase:
git merge-base feature master
交互式rebase的使用是引入git rebase工作流的好方法,因为它只影响本地分支。其他开发人员唯一能看到的就是你的成品,这应该是一个简洁易懂的分支历史记录。
但同样,这仅适用于私有功能分支。如果你通过相同的分支与其他开发人员协作,则该分支是公共的,并且你能重写其历史记录。


将上游更改合并到feature中


在概念部分中,我们了解了feature分支如何使用git merge或git rebase合并master上游更改。merge是一个安全的选择,可以保留仓库的整个历史记录,而rebase则通过将feature分支移动到master顶端来创建线性历史记录。
这种使用git rebase类似于本地清理(并且可以同时执行),但在此过程中它包含了那些master上游提交。
请记住,rebase到远程分支而不是master。当与另一个开发人员协作使用相同的功能并且你需要将他们的更改合并到你的仓库时,就会发生这种情况。
例如,如果你和另一个名为John的开发人员新增了对feature分支的提交,从John的仓库中获取远程分支后,你的仓库可能如下所示:



你可以用从master集成上游更改相同的方法来解决这个分叉问题:要么用john/feature合并本地feature,或rebase本地feature到john/feature。



请注意,此rebase不违反黄金法则,因为只有你的本地feature提交被移动 - 之前的所有内容都不会受到影响。这就像是“将我的更改添加到John已经完成的工作。”在大多数情况下,这比通过merge与远程分支同步更直观。
默认情况下,git pull命令执行合并,但你可以通过向其传递--rebase选项来强制它与远程分支rebase集成。


集成已验证的feature


在你的团队通过某feature后,你可以选择将该feature rebase到master分支的顶端,然后git merge再将该功能集成到主代码库中。
这是将上游更改合并到功能分支中的类似情况,但由于你不允许在master分支中重写提交,因此你必须最终使用git merge该功能进行集成。但是,通过在合并之前执行rebase,你可以确保合并产生完美的线性历史记录。这也使你有机会压缩在拉取请求期间添加的任何后续提交。



如果你不熟悉git rebase,可以随时在临时分支中执行rebase。这样,如果你不小心弄乱了feature的历史记录,可以查看原始分支,然后重试。例如:
git checkout feature
git checkout -b temporary-branch
git rebase -i master
#[清理历史]
git checkout master
git merge temporary-branch


总结


这就是你需要知道的关于rebase你的分支。如果你更喜欢提交的干净,消除不必要合并的线性历史记录,那么你在继承另一分支的更改时应该使用git rebase 而不是git merge。
另一方面,如果你想保留项目的完整历史记录并避免重写公共提交的风险,你可以仍然使用git merge。这两种选择都是完全可以的,但至少可以选择利用git rebase有它的好处。

 

https://zhuanlan.zhihu.com/p/57872388

 

标签:git,rebase,feature,merge,master,分支
From: https://www.cnblogs.com/erichi101/p/18229163

相关文章

  • git-更换本地远程仓库地址
    命令不删除远程仓库修改#查看远端地址gitremote-v#查看远端仓库名gitremote#重新设置远程仓库gitremoteset-urloriginhttps://gitee.com/xx/xx.git(新地址).git配置config文件修改修改.git隐藏文件夹下的config文件内容,将[remote"origin"]下的url修......
  • git 命令报错:Another git process seems to be running in this repository, e.g. an
    执行git命令时,报错:Anothergitprocessseemstoberunninginthisrepository,e.g.aneditoropenedby'gitcommit'.Pleasemakesureallprocessesareterminatedthentryagain.Ifitstillfails,agitprocessmayhavecrashedinthisrepository......
  • 常用 Git 命令清单
    目录一、新建代码库 二、配置三、代码提交和同步代码第1步:工作区与仓库保持一致第2步:文件增删改,变为已修改状态第3步:gitadd,变为已暂存状态第4步:gitcommit,变为已提交状态第5步:gitpush,变为已推送状态四、代码撤销和撤销同步已修改,但未暂存已暂存,未提......
  • 【Git 版本管理】合并 + 变更,看懂Git
    看懂Git合并操作分离HEAD分离HEAD测试相对引用(^||~)操作符^相对引用^测试操作符~相对引用~测试撤销变更GitResetGitRevert撤销变更测试整理提交记录GitCherry-pick测试交互式rebase交互式rebase测试合并操作关键字:commit、branch、merge、......
  • 各位用到git的,请注意CVE-2024-32002安全漏洞
    解释几个缩写名词CVE:CVE是CommonVulnerabilitiesandExposures的缩写,指的是通用漏洞与暴露(CommonVulnerabilitiesandExposures),它是一个用于标识和跟踪计算机系统中的安全漏洞的标准化命名方案,每个CVE条目都包含一个唯一标识符(CVEID),以及漏洞的描述、评分、影响......
  • Git基本语法
    官网及下载地址        Git官网:GitGit基本语法1.Git初始化配置git--version #Git版本gitupdate-git-for-windows #升级版本gitconfig--system[--unset]user.name用户名#设置/删除用户签名(全局)gitconfig--system[--unset]......
  • 推荐一个Github上收集了大量的C#/.NET/.NET Core项目宝库组织
    项目宝库介绍为.NET开发者提供一个寻找优秀C#/.NET/.NETCore项目和框架的入口,通过了解和对比更多的项目和框架来选择最适合我们自己学习、工作开发的一套项目或者框架。优秀的项目不应该被埋没,欢迎大家一起加入这个组织共同完善、发展.NET社区!这些都是非常优秀的项目和框架,排......
  • 一份代码推送2个git仓库并根据不同分支推送不同仓库(Gitee为例)
    需求说明在开源项目中怎么保证Pro版本或者收费版本的代码私有?解决方案1,在码云上新建一个公开仓库,和一个私有仓库 2,代码先从公开仓库克隆下来 3,新建Pro分支 4,在.git=>config设置master分支同时上传到公开和私有2个仓库,并设置Pro分支只上传到私有仓库 如......
  • git分布式版本控制系统(六)
    目前世界上最先进的分布式版本控制系统官方网址:https://git-scm.com学习目标:1了解git前世今生2掌握git基础概念、基础操作3各种git问题处理4互联网常用gitflow(工作流程规范)5git代码提交规范6git分支管理及命名规范代码提交规范Commitmessage我......
  • Git
    Git概述 Git代码托管服务 Git常用命令 在IDEA中使用Git 一、git版本2.20.164-bit Git是一个分布式版本控制工具,通常用来对软件开发过程中的源代码文件进行管理。通过Git仓库来存储和管理这些文件,Git仓库分为两种:本地仓库:......