相信对于很多使用git的用户来说, rebase 和 merge像两个恶梦一样, 到底应该是从哪个branch rebase/merge 到哪个branch? rebase和merge又有什么区别?

我先回答一下第一问题:
如果你想把feature branch rebase/merge到master branch. 你得从feature branch rebase onto / merge into 到 master branch.
具体做法是先checkout feature branch, 然后执行: git rebase/merge master.

然后我们讲一下rebase的使用方法, 关于merge请见我的另一篇博客https://blog.csdn.net/seamanj/article/details/104057987

好了, 下面我会把每一步的操作以及tree的结构给贴出来:

假设我们有两个branch:master 和 feature,


我们先在master提交一个commit名为master1, 树结构长这样

D:\Workspace\GIT_TEST>git log --graph --decorate --oneline --all
* 7add0d0 (HEAD -> master, origin/master) master1
* 1531f85 initial commit


然后我们需要开发另一个feature功能, 这时我们建立一个feature branch 并checkout, 在feature branch上面我们提交两个commit, feature1, feature2

D:\Workspace\GIT_TEST>git log --graph --decorate --oneline --all
* 0adde55 (HEAD -> feature, origin/feature) feature2
* 7e427bf feature1
* 7add0d0 (origin/master, master) master1
* 1531f85 initial commit


同时, 在我们开发feature的同时, 假设有人在master上面做了新的commit: master2

D:\Workspace\GIT_TEST>git log --graph --decorate --oneline --all
* 386e693 (origin/master) master2
| * 0adde55 (origin/feature, feature) feature2
| * 7e427bf feature1
|/
* 7add0d0 (HEAD -> master) master1
* 1531f85 initial commit


现在我们需要把feature branch rebase(onto)到master branch 上面去. 我们需要在master branch 上面先做pull, 把别人在master上面的修改先pull下来

D:\Workspace\GIT_TEST>git log --graph --decorate --oneline --all
* 386e693 (HEAD -> master, origin/master) master2
| * 0adde55 (origin/feature, feature) feature2
| * 7e427bf feature1
|/
* 7add0d0 master1
* 1531f85 initial commit


然后跳到feature branch, 执行git rebase master

D:\Workspace\GIT_TEST>git checkout feature
Switched to branch 'feature'
Your branch is up to date with 'origin/feature'.D:\Workspace\GIT_TEST>git rebase master
First, rewinding head to replay your work on top of it...
Applying: feature1
Applying: feature2D:\Workspace\GIT_TEST>git log --graph --decorate --oneline --all
* 848d675 (HEAD -> feature) feature2
* 3b1fa65 feature1
* 386e693 (origin/master, master) master2
| * 0adde55 (origin/feature) feature2
| * 7e427bf feature1
|/
* 7add0d0 master1
* 1531f85 initial commit


最后我们需要跳回到master branch, 执行git rebase feature, 使得master指针指向最前面

> D:\Workspace\GIT_TEST>git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.D:\Workspace\GIT_TEST>git rebase feature
First, rewinding head to replay your work on top of it...
Fast-forwarded master to feature.D:\Workspace\GIT_TEST>git log --graph --decorate --oneline --all
* 848d675 (HEAD -> master, feature) feature2
* 3b1fa65 feature1
* 386e693 (origin/master) master2
| * 0adde55 (origin/feature) feature2
| * 7e427bf feature1
|/
* 7add0d0 master1
* 1531f85 initial commit


最后我们将master branch push 到远程端

D:\Workspace\GIT_TEST>git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 431 bytes | 431.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0)
To https://gitlab.com/seamanj/git_rebase_test.git386e693..848d675  master -> masterD:\Workspace\GIT_TEST>git log --graph --decorate --oneline --all
* 848d675 (HEAD -> master, origin/master, feature) feature2
* 3b1fa65 feature1
* 386e693 master2
| * 0adde55 (origin/feature) feature2
| * 7e427bf feature1
|/
* 7add0d0 master1
* 1531f85 initial commit


okay, 现在 master branch上面完事了, 现在本地的feature 指针已经跑到master branch上面去了, 而远程的feature 指针还在原处不动. 那feature branch怎么收场呢?
具体可以参考 :https://stackoverflow.com/questions/42861353/git-pull-after-git-rebase

大概有三种结尾方式

  1. 如果现在你要pull远程的feature指针的话, 会创造一个新的merge. 然而这并没有任何意义, 也会导致大量的冲突(因为rebase已经合并过一次了)
  2. reset 本地的feature 指针 到远程的feature 指针, 这时本地的指针会指向远程的指针, 但是好像还是没有任何意义, 因为功能已经合并到master上面去了, 这时候继续在上面开发, 无论以后再次rebase或merge到master 都会造成大量的冲突(feature1, feature2会冲突)
  3. 通过 git push -f 强行push本地指针到远程指针, 这时远程指针也会跟着跳到master branch上面来, 而原来的feature branch就不复存在了.这种方法比有意义, 因为我可以随时从feature rebase 到 master顶端(先爬到顶端), 然后开发feature 3, feature 4 等等(然后生枝), 又可以继续rebase/merge到master(然后将枝移到顶端).

下面我们来试一下第3种方式

我们先跳到feature branch, 然后通过 git push 将本地push到远端

D:\Workspace\GIT_TEST>git checkout feature
Switched to branch 'feature'
Your branch and 'origin/feature' have diverged,
and have 3 and 2 different commits each, respectively.(use "git pull" to merge the remote branch into yours)D:\Workspace\GIT_TEST>git push
To https://gitlab.com/seamanj/git_rebase_test.git! [rejected]        feature -> feature (non-fast-forward)
error: failed to push some refs to 'https://gitlab.com/seamanj/git_rebase_test.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

这时会提示错误, 这是因为本地的feature指针跳到master branch上面来了. 在原来的feature branch上, 本地的feature指针落后远程2步, 而在master branch上, 本地的feature指针领先远程3步

这时我们只有通过git push -f 霸王硬上弓了

D:\Workspace\GIT_TEST>git push -f
Total 0 (delta 0), reused 0 (delta 0)
remote:
remote: To create a merge request for feature, visit:
remote:   https://gitlab.com/seamanj/git_rebase_test/-/merge_requests/new?merge_request%5Bsource_branch%5D=feature
remote:
To https://gitlab.com/seamanj/git_rebase_test.git+ 0adde55...848d675 feature -> feature (forced update)D:\Workspace\GIT_TEST>git log --graph --decorate --oneline --all
* 848d675 (HEAD -> feature, origin/master, origin/feature, master) feature2
* 3b1fa65 feature1
* 386e693 master2
* 7add0d0 master1
* 1531f85 initial commit


舒服了


然后我们继续在feature branch开发feature 3

D:\Workspace\GIT_TEST>git log --graph --decorate --oneline --all
* 466f0cc (HEAD -> feature, origin/feature) feature3
* 848d675 (origin/master, master) feature2
* 3b1fa65 feature1
* 386e693 master2
* 7add0d0 master1
* 1531f85 initial commit


与此同时, 其他人在master branch上继续开发master3

D:\Workspace\GIT_TEST>git log --graph --decorate --oneline --all
* f9bc42e (HEAD -> master, origin/master) master3
| * 466f0cc (origin/feature, feature) feature3
|/
* 848d675 feature2
* 3b1fa65 feature1
* 386e693 master2
* 7add0d0 master1
* 1531f85 initial commit


这样的分叉, 是否曾经相似, 至此, 我们可以继续选择rebase或者merge而不必担心feature1, feature2所带来的冲突了, 但是记住原来的feature branch已经不见了


参考资料:

rebase视频详解及动画过程: https://www.youtube.com/watch?v=f1wnYdLEpgI
rebase 和 merge 优缺点以及如何选择:https://dzone.com/articles/git-merge-vs-rebase

rebase in git相关推荐

  1. git rebase和git merge的用法

    http://softlab.sdut.edu.cn/blog/subaochen/2016/01/git-rebase%E5%92%8Cgit-merge%E7%9A%84%E7%94%A8%E6% ...

  2. Git rebase 和 Git merge 的区别,你知道吗?

    编辑搜图 请点击输入图片描述 Git是大多数程序必备的工具之一,Git常用那么几个命令:pull.push.status.merge.rebase.Git rebase 和 Git merge都是合并 ...

  3. git rebase和git merge使用方法详解

    看了网上很多讲git rebase和git merge的文章,这里做下总结,其中主要参考了这两位大佬的博客,后面附上链接 https://blog.csdn.net/weixin_42310154/a ...

  4. 浅谈git rebase和git checkout --ours(theirs)

    先描述下场景. A在master基础上创建了个新的branch fix_bug, 并在fix_bug上进行了1次对foo.py的修改并提交78d4c5. B在master上直接进行了1次对foo.py ...

  5. git rebase 与git merge 小结

    git merge是用来合并两个分支的. $ git merge b   将b分支合并到当前分支 同样  $ git rebase b ,也是把 b分支合并到当前分支 ---------------- ...

  6. 你在开发过程中使用Git Rebase还是Git Merge?

    1. 痛苦吗?代码历史中的迷失羔羊 我们先来看一个真实的代码提交历史图形化截图: 图片源自 https://storage.kraken.io/kk8yWPxzXVfBD3654oMN/c8b97f4 ...

  7. git rebase VS git merge? 更优雅的 git 合并方式值得拥有

    写在前面 如果你不能很好的应用 Git,那么这里为你提供一个非常棒的 Git 在线练习工具 Git Online ,你可以更直观的看到你所使用的命令会产生什么效果 另外,你在使用 Git 合并分支时只 ...

  8. git rebase 和 git merger

    & git merge 在上图中,每一个绿框均代表一个commit.除了c1,每一个commit都有一条有向边指向它在当前branch当中的上一个commit. 图中的项目,在c2之后就开了另 ...

  9. Merge和Rebase在Git中的区别

    git命令Merge和Rebase的区别 git merge 会生成一个新得合并节点,而rebase不会 比如: [plain] view plaincopyprint? D---E test / A ...

最新文章

  1. 扩增子统计绘图5火山图:差异OTU数量及变化规律
  2. 在线和本地两种方法构建 RAxML 进化树方法和解读
  3. 黑客常用的远程控制命令
  4. tomcat安装部署
  5. 数字化专业人才短缺,企业亟待组建培养体系
  6. 第一篇博客,用以规划我的编程人生
  7. [python] 安装numpy+scipy+matlotlib+scikit-learn及问题解决
  8. 软中断和硬中断的区别
  9. path弧形参数 svg_如何计算圆弧(圆弧)的SVG路径
  10. 独具匠心的好书:评《构建高性能Web站点》
  11. Mybatis3.4.x技术内幕(十七):Mybatis之动态Sql设计原本(上)
  12. SPSS PROCESS插件安装及使用【SPSS 046期】
  13. python3解密栅栏密码的正确方法
  14. 8款测试HLS m3u8视频流的免费在线播放器
  15. SWFUpload批量上传插件
  16. 《分形艺术,拿数学作画》作者:林晨 风达
  17. vue实现table课程表
  18. 解决4K屏电脑显示问题
  19. 苹果cms试看提示文字怎么改[苹果CMS技术教程]
  20. 阿里实习生转正面试记

热门文章

  1. c语言 sizeof typeof,typeof、nameof、sizeof的用法
  2. Tomcat VirtualWebappLoader 配置
  3. 用递归解决冒泡排序问题
  4. 安装和使用memcached
  5. 编程算法/面试 - K链表翻转
  6. [收藏转载]明星软件工程师的十种特质
  7. PHP仿百度实现弹窗登录效果,js仿百度登录页实现拖动窗口效果
  8. php 二维数组 根据值 找,PHP编程根据二维数组某个字段的值查找值所在的一维数组...
  9. c语言中十进制与十六进制转换_小猿圈分享-java-十进制、八进制、十六进制数互相转换...
  10. 2019电子科大计算机基础知识,电子科技大学820真题1999-2019终极版.pdf