git变基

我们已经使用过git的合并(merge)功能,与之功能类似的是rebase(变基)。

开始前请记住:不要对在你的仓库外有副本的分支进行变基。

变基的实质是丢弃一些现有的提交,并且新建一些内容一样但实际上不同的提交。所以如果你的分支上的内容已经被共享,进行变基之后就会有一部分现有提交被丢弃,这会给其他用户带来麻烦与困惑。

合并是将两个分支的最新快照以及共同祖先进行三方合并,并且生成一个新的快照。比如下图是将C7、C6和C4进行三方合并。

合并是三方合并

还有另外一种方法,就是变基。变基将提取C5和C6中的补丁和修改,并且将其在C7上重新作用一次,然后生成一个新的提交。

变基会生成内容一样但实际不同的提交

如上图所示,在testing分支进行变基操作到master后,git会进行如下操作:

  • 找到testing分支和master分支的共同祖先,即C4。
  • 收集共同祖先C4到目前提交C6的所有修改和补丁,放到临时文件中。
  • 将目前的分支testing指向目标基底master
  • testing上依次应用临时文件中所有的修改和补丁。本例中为将C5和C6的修改和补丁依次应用。
  • 生成一个新的提交,即C8。

三方合并和变基生成的新提交C8内容是一致的,不同的是提交历史:三方合并能够清楚地看到合并的历史,而变基只有一条串联的历史。

如果你要向他人维护的项目贡献代码,就可以将自己的修改都变基到master上,推送之后,维护者只需要进行快进操作。

现在让我们实践一下。

我们创建一条分支testing,并且在该分支上进行两次提交。

然后回到master分支,进行一次提交。

再次切换到testing分支。

提交历史大致如下:

* c36bdf6 (master) i see you there| * c5a1cc4 (HEAD -> testing) i see you here
| * 86a451c water water everywhere|/  
* af05578 (origin/master) We all love git.

如果现在从testing变基到master,那么86a451cc5a1cc4中所做的修改会依次重演到master。如果遇到冲突,那么会依次需要人工解决冲突。为了避免多次修改冲突,我们将86a451cc5a1cc4合并为一次提交:

$ git reset --soft af05578
$ git commit -m "i see water here"[testing cf6dc96] i see water here 1 file changed, 4 insertions(+)
$ git log --oneline --decorate --graph --all
* cf6dc96 (HEAD -> testing) i see water here| * c36bdf6 (master) i see you there
|/  
* af05578 (origin/master) We all love git.

现在执行变基到master的操作:

$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: i see water here
Using index info to reconstruct a base tree...
M   README.md
Falling back to patching base and 3-way merge...
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
error: Failed to merge in the changes.
Patch failed at 0001 i see water here
The copy of the patch that failed is found in: .git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

在执行变基操作时,git提示我们README.md有冲突,解决冲突后使用git rebase --continue继续执行变基操作。现在请解决冲突,将文件添加到暂存区后表示该文件冲突解决完成。解决后继续执行变基操作:

$ git rebase --continue Applying: i see water here

git告诉我们更改已经被应用到master分支。提交历史如下:

* c148ffd (HEAD -> testing) i see water here
* c36bdf6 (master) i see you there
* af05578 (origin/master) We all love git.

可以看到,git帮我们生成了一个新的提交,并且testing指向该提交。提价历史变成了一条串联的线。

最后,将master快进到testing即可:

$ git checkout master 
Switched to branch 'master'Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
$ git merge testing 
Updating c36bdf6..c148ffd
Fast-forward
 README.md | 4 ++++
 1 file changed, 4 insertions(+)

原文发布于微信公众号 - mwangblog(mwangblog)

原文发表时间:2018-01-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏vue学习

33、vuex初探(一)

看完以后应该是有点懵逼的,所以这就是这篇文章存在的意义了:就是让你不那么懵逼;总归理论与实践相结合才能真正弄明白一个东西,所以我们简单实践一下。

17960
来自专栏性能与架构

linux w命令查看系统负载

w命令和uptime命令相似,都可以查看系统的负载状况,但w的结果信息更丰富一些,还可以查看登录用户的状态 命令信息 $ w ? 第一行的信息和uptime的结...

450110
来自专栏Django中文社区

分类与归档

侧边栏已经正确地显示了最新文章列表、归档、分类等信息。现在来完善归档和分类功能,当用户点击归档下的某个日期或者分类下的某个分类时,跳转到文章列表页面,显示该日期...

37590
来自专栏Golang语言社区

编写一个go gRPC的服务

前置条件: 获取 gRPC-go 源码 $ go get google.golang.org/grpc 简单例子的源码位置: $ cd $GOPATH/src/...

61870
来自专栏Ryan Miao

Linux 学习笔记

Linux学习笔记 请切换web视图查看,表格比较大,方法:视图》》web板式视图 博客园不能粘贴图片吗  http://wenku.baidu.com/vie...

73790
来自专栏用户2442861的专栏

深入剖析Socket实现

http://blog.csdn.net/zapldy/article/details/5813984

14720
来自专栏Java编程技术

深入浅出一致性Hash原理

在解决分布式系统中负载均衡的问题时候可以使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载...

11010
来自专栏漏斗社区

漏洞|74cms 3.6 前台SQL注入+Python脚本小练习

最近有个74cms v4.2.3任意文件下载的漏洞,本来想试着和74cms 3.6 前台SQL注入漏洞结合下然后取出QS_pwdhash的值进行MD5碰撞,可...

565100
来自专栏大内老A

如何通过VPC在本机搭建局域网

前几天在家里测试一个基于WS-AT的分布式应用,但是连接公司网络的VPN出现了问题,不得不采用VPC在本机搭建一个局域网。虽然以前也做过这样的尝试,可能是很久没...

33570
来自专栏Python、Flask、Django

python中用requests获取API参数

26060

扫码关注云+社区

领取腾讯云代金券