概括

rebase翻译过来为“变基”,可以理解为改变基础,它可以用于分支合并和修改提交记录。

合并分支的区别

我们知道merge操作也可以用于分支合并,但是其和rebase操作有着明显的不同。假定有一个分支foo在B提交处检出了分支bar,接着两个分支各自前进出现了分叉,现在要将bar分支合并回foo分支。

A--B--C----E  foo
\
----D bar

首先使用merge操作,在foo分支下执行git merge bar命令,git就会在当前分支(即foo分支)下生成一个新的commit节点,从而实现分支的合并。

A--B--C----E---F foo
\ /
----D----
bar

而reabse操作合并分支的过程与之明显不同,我们在foo分支下执行git rebase bar命令。

现在来看看rebase操作的合并过程,它先是会暂存当前分支上从分叉开始之后commit节点,然后回退到分叉开始的节点。

stage: C, E

A--B  foo
\
----D bar

接着bar分支上的所有commit被移动到foo分支上,最后再合并之前暂存的节点。

A--B--D--C'--E' foo
\
----D bar

可以看到rebase操作合并之后的提交记录是一条线,而不像merge操作一样变成棱形,因此rebase操作合并分支会让提交记录看起来更加简洁。

工作流程

接下来基于rebase操作设计一个简单的分支协同开发流程,流程分为检出分支前和分支上提交后两个部分。

检出之前先在dev分支上pull以获取分支上最新提交,这样可以减少后续提交时的冲突,当然该步骤不是必须的。

接着便可以检出分支来进行开发,下面是该流程的命令示例。

[origin/dev => dev => ${new_branch}]

(dev)$ git pull
(dev)$ git checkout -b ${new_branch}

开发完成并在本地分支上提交后,就可以进行分支的合并了,首先还是先pull拉取dev分支上的最新提交。

接着分为两种情况,一种是没有其他人提交显示“Already up to date.”,这时候就直接切换到dev分支,然后执行rebase操作合并分支,最后提交到远程。

还有一种当然是有人提交过了,这时候就要先执行rebase操作将dev分支合并到当前开发的分支,接着可能就会出现冲突,需要手动修改冲突后执行git add ${conflict_file}git rebase --continue完成冲突修改。

冲突修改之后的操作和前面是一样的这里不再叙述,详细请参考下面的命令示例。

[${new_branch} => dev => origin/dev]

(${new_branch})$ git pull origin dev:dev
=========IF NOT UP TO DATE=========
(${new_branch})$ git rebase dev
(${new_branch})$ <fix the conflict>
===================================
($(new_branch))$ git checkout dev
(dev)$ git rebase ${new_branch}
(dev)$ git push

修改提交记录

rebase操作除了合并分支,还可以用于提交记录的修改。

当然一般不推荐在多人协同开发的分支上修改提交记录,一来是修改记录时的误操作可能会导致提交数据丢失。

二来是使用rebase修改提交记录后,需要使用--force选项强制推送到远程,假设刚好有其他人提交了代码而你没有及时更新,就会导致其他人的代码被你覆盖掉。

rebase操作修改提交记录其实也很简单,先是执行命令git rebase -i <START> [END],选项-i指的是使用交互式操作方式,后面两个参数是操作的范围。

这里<START>指的是开始的提交记录,而[END]则是结束的提交记录,如果结束的提交记录省略则默认为HEAD。注意这里范围是前面为开区间后面为闭区间,用区间表示为(START, END]。提交记录既可以用哈希值表示,也可以用头指针的偏移值表示,例如HEAD~1表示头指针指向的上一个提交。

上面命令执行完之后,就会出现如下格式的文本,同commit一样都是使用编辑器打开,修改完成后保存即可。

pick acaa54 Add `demo.md`
pick baed03 Add one line

每一行代表一个提交记录,第一个字段是对提交记录的操作命令,第二个字段是提交记录的哈希值,最后则是提交记录的注释。

下面是完整的操作命令和其作用,默认为pick命令即表示使用该提交记录且不做更改。

# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.

总结

虽然rebase操作功能强大,但掌握其正确使用才是重中之重。还有使用rebase还是merge合并分支仍有争议,两种方式各有利弊,这需要团队内部进行权衡选择。

Git Rebase操作的更多相关文章

  1. git rebase 操作撤销

    git rebase可以更改提交历史,在不影响别人的情况下,能够重整git树. 但如果git rebase操作失误,却在push后才发现,怎么撤销rebase操作呢? 使用git reflog + g ...

  2. 解决git rebase操作后推送远端分支不成功的问题

    转:解决git rebase操作后推送远端分支不成功的问题 前段时间在工作中同事在rebase时遇到一个问题来问我,今天突然想起来觉得有必要记录一下. 在我们日常工作中,经常使用git座位代码管理工具 ...

  3. git的学习笔记(一):git本地操作

    1.Git介绍 Git是一个开源的分布式版本控制软件,用以有效.高速的处理从很小到非常大的项目版本管理. Git 最初是由Linus Torvalds设计开发的,用于管理Linux内核开发. Git ...

  4. Git rebase命令实战

    一.前言 一句话,git rebase 可以帮助项目中的提交历史干净整洁!!! 二.避免合并出现分叉现象 git merge操作 1.新建一个 develop 分支   2.在develop分支上新建 ...

  5. 你真的懂git rebase吗?

    前段时间由于某种原因,开始接手开发公司前端Vue搭建的项目 该前端项目采用的是基于git rebase的形式去合并代码,而我之前使用git一直都是采用merge的形式合并分支代码,对于rebase一概 ...

  6. 【转】git rebase详解

    git合并代码方式主要有两种方式,分别为:1.merge处理,这是大家比较能理解的方式.2.rebase处理,中文此处翻译为衍合过程. git rebase操作讲解例子: cd /usr/local/ ...

  7. git merge 与 git rebase的区别?

    一,git merge 与 git rebase的区别 1,git merge 例如: master分支合并dev分支,git将两个分支dev和master上的所有commit , 按照提交时间的先后 ...

  8. git pull、git fetch、git merge、git rebase的区别

    一.git pull与git fetch区别 1.两者的区别       两者都是更新远程仓库代码到本地. git fetch相当于是从远程获取最新版本到本地,不会自动merge. 只是将远程仓库最新 ...

  9. [置顶] 【Git入门之十】Rebase操作

    原创作品,转载请标明:http://blog.csdn.net/jackystudio/article/details/12309627 Rebase,衍合?变基?唉,我也不知道要怎么翻译合适...变 ...

随机推荐

  1. 开发并发布npm包,支持TypeScript提示,rollup构建打包

    前言: 工作了几年,想把一些不好找现成的库的常用方法整理一下,发布成npm包,方便使用.也学习一下开发发布流程. 主要用到的工具:npm. 开发库:babel.typescript.rollup.es ...

  2. 劳动节快乐!手写个核心价值观编码工具 - Python实现

    前言 今天是五一劳动节,祝各位无产阶级劳动者节日快乐! 然后来整活分享一些有趣的东西~ 这个小工具是我大学时做着玩的,对于各位接班人来说,12个词的核心价值观这东西,大家都非常熟悉了,这工具可以实现将 ...

  3. 老生常谈系列之Aop--Spring Aop源码解析(二)

    老生常谈系列之Aop--Spring Aop源码解析(二) 前言 上一篇文章老生常谈系列之Aop--Spring Aop源码解析(一)已经介绍完Spring Aop获取advice切面增强方法的逻辑, ...

  4. this-4

    ES6函数里的this指的是定义这个函数时外层代码的this,可以理解为:1.ES6箭头函数没有自己的this:2.ES6箭头函数的this是外层代码(定义时,非执行时,也就是词法作用域)this的引 ...

  5. 使用C#跨PC 远程调用程序并显示UI界面

    在项目中有一个需求是需要在局域网内跨PC远程调用一个程序,并且要求有界面显示,调查了一些资料,能实现远程调用的.Net技术大概有PsExec.WMI.Schedule Task. 这三种方式都做了一个 ...

  6. Linux嵌套目录权限的比较探究

    在/tmp目录下新建一个嵌套目录,名字分别为test_0.test_1.test_2.在test_2目录下新建普通文件,名为tryme.设置test_0和test_2的权限为777,设置test_1的 ...

  7. 【Java8新特性】Lambda表达式

    一.Lambda 表达式 是什么? Lambda读音:拉姆达. Lambda是一个匿名函数,匿名函数就是一个没有名字的函数. Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中). ...

  8. Go微服务框架go-kratos实战01:quickstart 快速开始

    先来感受下用 kratos 快速创建项目 一.环境准备 1.1 安装依赖软件 protoc protoc-gen-go 建议开启 GO111MODULE 1.2 安装 kratos cli go in ...

  9. PostMan 快快走开, ApiFox 来了, ApiFox 强大的Api调用工具

    简介 为什么要用ApiFox呢, 一般现在程序员开发测试, 一般都是PostMan, PostWoman等Api调用工具, 我之前也是一直在用, 但是今天我发现了一款相比于Postman更加好用的工具 ...

  10. 【原创】项目一GoldenEye

    实战流程 1,通过nmap查找本段IP中存活的机器 ┌──(root㉿whoami)-[/home/whoami/Desktop] └─# nmap -sP 192.168.186.0/24 排查网关 ...