金沙贵宾会官网|金沙贵宾会登录-官网

【A】金沙贵宾会官网超高的返奖率为娱乐者提供资金保障,所以金沙贵宾会登录官网更加的方便了你的娱乐,申请88元彩金,因为在当中不仅仅只有游戏。

联合代码之

日期:2019-10-05编辑作者:网络软件

项目初始情况

git最常用方法之一,合并代码,大部分时候我们都是使用merge命令。其实还有rebase命令,既然都是合并代码,两者有什么差异和共同点?
那就来深入了解一下

前言

相信大部分使用 Git 的朋友都会遇见相同的疑问,并且也从网上搜索了不少资料。那么,为什么我还要写这篇文章呢?因为我想尝试从自己的角度解释这个问题,如果能给到大家灵光一闪的感悟,便善莫大焉啦。估计点进来的朋友也对 merge 和 rebase 有了一定了解,所以我也就不浪费篇幅再去详细介绍 merge 和 rebase,让我们直入主题吧。

图片 1项目初始情况

1.相同点

虽然git合并代码有merge和rebase两种方式,但是两种合并方式的最终结果是一样的,没有任何区别。

既然整合结果没有区别,那么区别在哪了?那就是合并过程。

merge 与 rebase 的区别

fast-forward

图片 2fast-forward

快速合并,直接把指针指向前去,无冲突要解决。

2.不同点

以两个分支为例,主分支master,新分支develop,将develop分支合并到master主分支

merge

现在假设我们有一个主分支 master 及一个开发分支 deve,仓库历史就像这样:

图片 3

初始仓库历史

现在如果在 master 分支上 git merge deve:Git 会自动根据两个分支的共同祖先即 e381a81 这个 commit 和两个分支的最新提交即 8ab7cff696398a 进行一个三方合并,然后将合并中修改的内容生成一个新的 commit,即下图的 78941cb

图片 4

merge 合并图

非 fast-forward

图片 5image

保留历史记录,解决冲突

2.1. merge合并

//当前处于master分支
daideMacBook-Pro:UIFinalTest dai$ git status
On branch master
Your branch is ahead of 'github/master' by 5 commits.
  (use "git push" to publish your local commits)

//创建并切换到develop分支
nothing to commit, working tree clean
daideMacBook-Pro:UIFinalTest dai$ git checkout -b develop
Switched to a new branch 'develop'

//创建一个类,添加到develop仓库
daideMacBook-Pro:UIFinalTest dai$ git add .
daideMacBook-Pro:UIFinalTest dai$ git commit -m'Develop1'
[develop 905f008] Develop1
 Committer: dai <dai@daideMacBook-Pro.local>

//切换到master分支,并添加一个类到master仓库
daideMacBook-Pro:UIFinalTest dai$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'github/master' by 5 commits.
  (use "git push" to publish your local commits)
daideMacBook-Pro:UIFinalTest dai$ git add .
daideMacBook-Pro:UIFinalTest dai$ git commit -m'Master1'
[master 4d82b67] Master1
 Committer: dai <dai@daideMacBook-Pro.local>

//再次添加一个类到master仓库
daideMacBook-Pro:UIFinalTest dai$ git add .
daideMacBook-Pro:UIFinalTest dai$ git commit -m'Master2'
[master 3a2c545] Master2
 Committer: dai <dai@daideMacBook-Pro.local>

//最后,再回到develop分支,添加一个类到develop仓库
daideMacBook-Pro:UIFinalTest dai$ git checkout develop
Switched to branch 'develop'
daideMacBook-Pro:UIFinalTest dai$ git add .
daideMacBook-Pro:UIFinalTest dai$ git commit -m'Develop2'
[develop 78d53bf] Develop2
 Committer: dai <dai@daideMacBook-Pro.local>

因为master和develop的父分支是一样的,都是base,所以具体流程如下:
master: base <--- Master1 <--- Master2
develop: base <--- Develop1 <--- Develop2

图片 6

image.png

合并代码:

//先切换到master分支,使用git merge develop命令
daideMacBook-Pro:UIFinalTest dai$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'github/master' by 7 commits.
  (use "git push" to publish your local commits)
daideMacBook-Pro:UIFinalTest dai$ git merge develop

因为使用merge命令是按照时间戳先后顺序的,所以,得到的提交历史为:
base <--- Develop1 <--- Master1 <--- Master2 <---Develop1 <--- Merge(做了三方合并发现冲突,手工处理冲突后git add/commit增加了提交节点Merge)

图片 7

image.png

rebase

rebase 是什么情况呢?还是一个初始的仓库历史图:

图片 8

rebase初始仓库历史

如果是在 master 分支上 git rebase deve:Git 会从两个分支的共同祖先 3311ba0 开始提取 master 分支(当前所在分支)上的修改,即 85841bea016f64e53ec51,再将 master 分支指向 deve 的最新提交(目标分支)即 35b6708 处,然后将刚刚提取的修改依次应用到这个最新提交后面。操作会舍弃 master 分支上提取的 commit,同时不会像 merge 一样生成一个合并修改内容的 commit,相当于把 master 分支(当前所在分支)上的修改在 deve 分支(目标分支)上原样复制了一遍,操作完成后的版本历史就像这样:

图片 9

rebase 合并图

可以看见 master 分支从 deve 分支最新提交 35b6708 开始依次提交了自己的三个 commit(由于是提取修改后重新依次提交,故 commit 的 hash 码与上面的85841bea016f64e53ec51 不同)

设置 non fast-forward

图片 10non fast-forward

即使能快速合并,也搞出一个合并的点,保留历史记录

假设当前状况为这样

图片 11image图片 12image

此时rebase,则把rebase的历史记录插到master的头上

图片 13image

结果就是好像learn-rebase这个分支不存在一样

对比 merge 和 rebase 最终的历史记录,可以发现 merge 保持了修改内容的历史记录,但是历史记录会很复杂;而 rebase 后的历史记录简单,是在原有提交的基础上将差异内容反映进去。

图片 14merge与rebase

  1. 和同事分别开发2个分支功能时,同事时不时会提交到master分支,尽量及时rebase上游分支,这样你最终合并时可以把同事的代码带上,而不是最终解决大量冲突。

关于我:

linxinzhe,全栈工程师,目前供职于某世界500强银行的金融科技部门。

GitHub:

欢迎留言讨论,也欢迎关注我~我也会关注你的哦!

2.2 rebase合并

分支创建同上,但是在合并代码时,不需要切换到master分支

合并代码:

daideMacBook-Pro:UIFinalTest dai$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: Develop1
Applying: Develop2
  • 1:回到两个分支(master、develop)的共同祖先(base),

  • 2:提取你所在分支(develop)每次提交时产生的差异,

  • 3:把这些差异分别保存到临时文件里,

  • 4:然后从当前分支(develop)转换到你需要衍合的分支(master),

  • 5:依照顺序把分支master的差异commit放到分支feature-1中。

图片 15

合并后的 Develop2(即现在的 Develop2`)所指的快照,同上面Merge三方合并例子中的 Merge所指的快照内容一模一样了。最后整合得到的结果没有任何区别,但衍合能产生一个更为整洁的提交历史。如果视察一个衍合过的分支的历史记录,看起来更清楚: 仿佛所有修改都是先后进行的,尽管实际上它们原来是同时发生的。


rebase -i

rebase 操作加上 -i 选项可以更直观的看见被提取的 commit 信息。
仍然在 master 分支上 rebase deve 分支,不过这次要加上 -i 选项,即 git rebase -i deve,然后我们可以得到这样一个文本信息框

图片 16

rebase -i信息

  • A 区域内的信息说明了这次 rebase 操作提取了哪些 commit 记录(f9a7673edb2ba2),会连接到目标分支的哪个 commit (9c86a5c)后面。可以根据 B 区域中的命令说明修改 pick 为其他命令,对该次提取出来的 commit 做额外的操作
  • B 区域内说明了本次 rebase 操作可以选用的命令
  • 通过 :wq 保存退出后,就会按照刚刚在 A 区域内设定的命令处理 commit 并 rebase。

总结

git rebase过程相比较git merge合并整合得到的结果没有任何区别,但是通过git rebase衍合能产生一个更为整洁的提交历史。
如果观察一个衍合过的分支的历史提交记录,看起来会更清楚:仿佛所有修改都是在一根线上先后完成的,尽管实际上它们原来是同时并行发生的。

一般我们使用衍合的目的,是想要得到一个能在远程分支上干净应用的补丁,比如某个项目你不是维护者,但是想帮点忙,最好使用衍合处理。
先在自己的一个分支进行开发,当准备向主项目提交补丁的时候,根据最新的orgin/master进行一次衍合操作然后再提交,这样维护者就不需要任何整合工作。

实际为:把解决分支补丁同最新主干代码之间的冲突的责任,划转给由提交补丁的人来解决。
作为维护项目的人只需要根据你提供的仓库地址做一次快进合并,或者直接采纳你提交的补丁。

衍合的风险,请务必遵循如下准则:
一旦分支中的提交对象发布到公共仓库,就千万不要对该分支进行衍合操作。

冲突处理策略的不同

  • merge 遇见冲突后会直接停止,等待手动解决冲突并重新提交 commit 后,才能再次 merge
  • rebase 遇见冲突后会暂停当前操作,开发者可以选择手动解决冲突,然后 git rebase --continue 继续,或者 --skip 跳过(注意此操作中当前分支的修改会直接覆盖目标分支的冲突部分),亦或者 --abort 直接停止该次 rebase 操作

merge --no-ffmerge --ff-only 的区别

上面对 merge 的讲述都是基于其默认操作即 --no-ffgit merge xxx = git merge --no-ff xxx)的说明,但是 merge 还有一种常用的选项 --ff-only,那么这两种有什么区别呢?
--no-ff 是 merge 的默认操作,三方合并并提交修改;而 --ff-only 会判断当前分支可否根据目标分支快速合并,就像下面这样

图片 17

快速合并

此时 deve 分支就可与 master 分支快速合并。
在 deve 分支上 git merge --ff-only master,便得到合并完成后的版本历史图

图片 18

快速合并完成

可以发现 --ff-only 生成的历史记录和 rebase 十分相似,但是本质上 --ff-only 仍然是合并操作,但 rebase 并没有做合并,仅仅是提取修改到目标分支后面。

总结:选择 merge 还是 rebase?

  • merge 是一个合并操作,会将两个分支的修改合并在一起,默认操作的情况下会提交合并中修改的内容
  • merge 的提交历史忠实地记录了实际发生过什么,关注点在真实的提交历史上面
  • rebase 并没有进行合并操作,只是提取了当前分支的修改,将其复制在了目标分支的最新提交后面
  • rebase 的提交历史反映了项目过程中发生了什么,关注点在开发过程上面
  • merge 与 rebase 都是非常强大的分支整合命令,没有优劣之分,使用哪一个应由项目和团队的开发需求决定
  • merge 和 rebase 还有很多强大的选项,可以使用 git help <command> 查看

最后:一些注意点

  • 使用 merge 时应考虑是采用 --no-ff 默认操作,生成一个对回顾提交历史并不友好的合并记录,还是采用 --ff-only 方式
  • rebase 操作会丢弃当前分支已提交的 commit,故不要在已经 push 到远程,和其他人正在协作开发的分支上执行 rebase 操作
  • 与远程仓库同步时,使用 pull 命令默认进行了 git fetch + git merge --no-ff 两个操作,可以通过加上 --rebase 命令将 fetch 后的 merge 操作改为 rebase 操作,或者仅仅 'git fetch remoteName',然后才思考采取哪种整合策略 git merge(or rebase) origin/master
  • 开发与 commit 时注意自己此时在哪个分支上
  • 当有修改未 commit 时,不能进行 rebase 操作,此时可以考虑先用 git stash 命令暂存

参考:

  • ProGit 2nd Edition

  • Stackoverflow:Is there a difference between git rebase and git merge --ff-only

  • Git分支管理策略

本文由金沙贵宾会官网发布于网络软件,转载请注明出处:联合代码之

关键词:

一波神奇的Python语句,Python奇技淫巧

当公布python第三方package时,并不指望代码中有着的函数或然class能够被外表import,在 __init__.py 中添加 __all__ 质量,该...

详细>>

11个原生JavaScript技艺分享,JavaScript的拾二个原生

原文地址: 1、实现字符串长度截取 JavaScript的10个原生技巧分享   本文给大家分享的是个人总结的10条非常常用的原...

详细>>

MSYS2开发环境搭建,编译Windows版智能坊钱包

后天都以容器技艺,用 vagrant 恐怕 docker 布贰个 linux 的镜像,安装些linux 的工具链,比方 g++ php ngingx等等,分享给别...

详细>>

AlphaGo再次胜出,日经中文网

阿尔法狗的求学本领很强,第二盘的作战中黑狗略有失误,但黑狗是有强有力的深浅神经网络练习的,每趟对局也是...

详细>>