分布式版本控制系统Git------分支管理与合并(merge与rebase)

零、需要使用到的命令:

git branch                      
           查看当前分支。

git branch <name>              
     创建一个名为<name>的分支。

git checkout <name>             
  切换到名字为<name>的分支。

git checkout -b <nama>          
  创建一个名为<name>的分支并且切换到此分支(等于git branch <name>命令 + git checkout <name>命令)。

git merge <name>                
    把一个名为<name>的分支合并到当前分支。

git branch -d <name>            
   删除一个名为dev的分支。

git merge   <分支名>              
  把<分支名>合并到当前分支

git rebase   <分支名>             
  把<分支名>合并到当前分支(与merge不同)

git fetch<主机名> <分支名>       将版本库中的内容取回本地

git
pull <远程主机名> <远程分支名>:<本地分支名>                        将版本库中的内容取回本地并和<本地分支名>合并(merge合并方式)。

git pull --rebase<远程主机名> <远程分支名>:<本地分支名>         将版本库中的内容取回本地并和<本地分支 
名>合并(rebase合并方式)。

git stash                                        备份当前工作区的内容至git栈,再从最近的一次commit提交覆盖到当前工 
作区。

git stash list                                 显示当前git栈所有的备份

git stash pop                                从git栈中恢复一次内容至工作区,默认是恢复最近的一次

git stash clear                               清空git栈。

一、简单介绍一下分支的基本操作。

先看看分支创建  ->  切换  ->  提交  ->  合并  ->  删除的基本套路吧。

使用上面的几个命令可以实现最基础的分支操作。

1.创建分支 git branch name

2.查看当前所有分支 git branch

当前有两个分支,分别是master和gzl

3.切换分支 git checkout name

git提示当前已经切换到分支gzl

4.在分支上修改文件或者添加一个新的文件,在分支上进行一个commit。

5.回到master分支 git checkout master

这个时候的打开master分支的test.txt文件看看

发现test.txt文件回到了没有更改的之前的内容。这是因为我们修改是在gzl分支的,而不是master分支。可以将分支看成一个个平行空间,你在其中修改并不会影响到其他分支的内容。

6.合并gzl分支的内容到master分支 git merge gzl

这里采用的Fast-forward合并方式,即快速合并。也就是说,只是把master指向了gzl分支。

7.删除gzl分支  git branch -d gzl

再用git branch 命令查看,发现只剩下了master分支了。

Fast forward模式:如果顺着一个分支走下去可以达到另外一个分支的话,那么git合并的时候,就只要简单的把master指针往后移。因为这种单线的操作不需要合并不同的分支,所以不会产生分歧,所以称为Fast forward模式。

普通模式:在一个commit节点发生分支,有两个不同的分支,如果想要合并这两个分支,这个时候不能室友Fast forward模式。往往需要手动修改产生冲突的文件,然后在进行一次commit。

二、合并分支的两种方式

前面使用的是git的merge合并方式,分支还有一种合并方式叫做rebase衍合。

rebase衍合与merge合并最终的结果其实是一样的,但是执行的过程却是不相同的。

merge方式(合并):

看看官方文档里面的示例图,master分支合并experiment分支,将会产生一个新的C5快照,而且只要你不删除experiment分支它就会一直存在。C5分支就像C4和C3两根绳子连在一起样子,这样C5既有了C4的内容,也有了C3的内容

rebase方式(衍合):

rebase流程

(以下图是已经rebase之后的结果图):

1.首先切换到C4所在的experiment分支。

2.从C4开始向前找,直到找到和master分支最近的一个相同commit快照,C4和C4之前的所有commit快照生成patch文件。

3.强制转化到master分支,从C2开始,将上面生成的patch文件,从C2开始往下一个一个打上patch文件。

4.最后生成新的C4‘commit快照,它之前所在的分支experiment也随着它的改变指向了master的上游。最后可以使用Fast forward方式让master分支和experiment保持一致。

注意: rabase在第三步之中会发生冲突。

在这种情况,Git会停止rebase并会让你去解决 冲突;在解决完冲突后,用"git-add"命令去更新这些内容的索引(index),
然后,你无需执行 git-commit,只要执行:

git rebase --continue

这样git会继续应用(apply)余下的补丁。

在任何时候,你可以用--abort参数来终止rebase的行动,并且"mywork" 分支会回到rebase开始前的状态。

git rebase --abort

rebase的优势和劣势

可以看到当使用rebase方式的时候,产生了C4‘快照,这个快照和merge方式得到的快照是一样的。可是不一样的地方还有有的。

1.experiment分支从独立的分支,到和master分支相同的上游去了。

2.C4快照消失了。

乍一看没什么,可是仔细想想,如果你在C4修改了一次重要的操作,可是使用rebase方式合并之后,你的C4却丢失,那么会造成不可忽略的影响。

通过查看文档,rebase方式有优势也有劣势:

优势:

采用rebase方式合并的快照,在主分支上看起来就像是一条平行线一样整洁干净,让人一目了然,这样管理人员就不需要花费时间去整理分                          
                                                                   分支了。

劣势:

就像上张图那样,采用rebase方式合并之后,以前的分支的快照都会消失。引用文档的概括的一句话------

Do not rebase commits that exist outside your repository.

为什么会这样,文档上的例子很生动,我大概翻译一下:

如果你rebase一个文件,放弃了目前的修改,然后创建了一个新的看起来相同可是内容却不同的
快照一 。如果你将这个快照放到网上或者其他地方,别人pull下了它,然后按照这个为基准进行工作。这个时候你又重写了它并且使用了git rebase方法把它上传到了网上称为  快照二,你的同事将会被这个新的快照搞得头昏眼花。因为他们是基于你第一次快照来进行开发的,可是你使用rebase命令之后,你的快照一将会消失,那么你同事做的事情就会白费。

那么如果你面临这样的情况,改怎么办呢?别担心,还是有机会挽回损失的。

如果你面临这样的困难,那么你所面临的第一个挑战就是分辨出哪些是你写的,哪些是你同事写的。

原来commit 对象除了SHA-1计算校验之外,Git还基于你引进的补丁计算了一种校验码,叫做“patch-id”。

如果你从你同事那里拉下重改的代码是基于最新的一次提交,Git也能也能够成功的解决而且申请它回到一个新的分支上。

使用git rebase teamone/master命令。

1.找到唯一工作在分支上的commit快照。

2.找到没有合并的commit快照。

3.找到没有被改写的commit快照加入目标分支。

4.应用这些commit快照在master分支和teamone分支。

但是它只工作在旧commit快照C4和新快照C4’有着差不多的补丁,否则衍合就不能够分辨C4‘是C4的复制快照。这样的话就会添加一个新的C4 ‘‘的补丁文件(这将会导致衍合失败,而且这样的话会导致一些不可预料的变化)。

你也可以用git pull --rebase命令来代替平常的git pull命令。

最后附上git文档里面的最后一段,关于什么时候使用rebase和merge

三、git pull 和 git pull --rebase

先说说git pull命令。

git push是把本地文件上传至远程库的命令。那么自然而然就有把远程库的文件拉下来放到本地工作区的命令,这个命令就是git fetch命令。git
fetch所做的只是把远程库的文件获取到本地。

git pull = git fetch + git merge。

如果后面加上--rebase参数。git pull --rebase命令

表示把你的本地当前分支里的每个提交(commit)取消掉,并且把它们临时 保存为补丁(patch)(这些补丁放到".git/rebase"目录中),然后把本地当前分支更新
为最新的"origin"分支,最后把保存的这些补丁应用到本地当前分支上。

其实git pull --rebase = git fetch  + git rebase。

浏览了一些博客,发现大多数博主都有个提醒的地方:尽量少使用git pull或者git
pull --rebase命令,多使用git fetch命令 + git pull命令或者git fetch命令 + git rebase命令。因为逐步执行可以保证文件的安全性。直接git pull会隐藏一些细节,或许这些细节就是你所需要的。

而到底是使用git pull还是使用git pull --rebase,其实也就是面临是选择git merge还是git rebase合并一样的情景。git merge可以保存所有的commit记录方便之后的使用,而git
rebase是为了有一条清晰明朗的主线,避免无谓的commit。存在即为合理,两种不同的方式各有优点,就看实际情况到底如何使用了。

四、无大脑的简单问题测试

问题一:git merge 分支的时候,合并冲突。

情景再现:在分支修改了某个文件之后,回到master分支想要将两个分支合并。因为某个文件内容不一样,出现了

git告诉你合并失败因为有一个未合并的文件。这个时候应该在工作区打开文件,手动修改,在使用add,commit命令,最后使用git
merge命令最后才能成功的合并。

盗取廖雪峰老师的图来解释一下应该会更清楚点:

1.你修改了两个不同分支相同的文件,这个文件在不同分支内容是不同的,不能使用快速合并了。

2.这个时候你手动修改了这个文件,使用git merge命令发现出现下面的提示。

解决方法:手动修改未合并的文件,再次add,commit。合并之后相当于多了一次提交。改变图如下:

结论:如果merge的时候使用的是Fast forward模式,git只是将mater的分支移到另外一个分支上。如果没有使用Fast
forward模式(普通模式),Git会产生一个新的commit。Fast forward模式合并之后是没有分支记录的,普通模式是用分支记录的。

问题二:git pull的时候合并冲突

你工作做到一半,突然有个bug要放下手上的活儿去解决bug。可是直接pull会丢失你这几天的辛辛苦苦工作。下面几个步骤搞定。

1.git add *        把所有值钱工作的文件放入暂存区。

2.git  stash        将文件放入git栈备份

3.git pull origin 将远程库代码拉下来(避免冲突了)

4.git stash pop  将git栈的备份文件拿出来

5.git merge        合并文件

以上是我的一些总结,如果有什么错误的地方欢迎大家指正!

时间: 2024-10-01 00:31:38

分布式版本控制系统Git------分支管理与合并(merge与rebase)的相关文章

[.net 面向对象程序设计进阶] (26) 团队开发利器(五)分布式版本控制系统Git——图形化Git客户端工具TortoiseGit

[.net 面向对象程序设计进阶] (26) 团队开发利器(五)分布式版本控制系统Git——图形化Git客户端工具TortoiseGit 读前必备: 接上篇: 分布式版本控制系统Git——使用GitStack+TortoiseGit 图形界面搭建Git环境 http://www.cnblogs.com/yubinfeng/p/5182271.html 本篇导读: 上篇介绍了一款Windows环境下的Git服务器工具GitStack ,搭建了最简单的Windows下的Git服务器,需要再次提醒的是

[.net 面向对象程序设计进阶] (25) 团队开发利器(四)分布式版本控制系统Git——使用GitStack+TortoiseGit 图形界面搭建Git环境【转】

转自:http://www.cnblogs.com/yubinfeng/p/5182271.html 前面介绍了两款代码管理工具VSS和SVN,这两种管理工具在很长一段时间曾为我们的代码管理提供了便利,本篇介绍一款思维方式完全不同(也可以说不合常理)的版本控制系统——Git.可以说Git目前非常火,这与设计者剑指偏锋的设计思想有很大关系.Git采用发散的思维管理代码,最大的特点就是分布式,他可以让来自不同地区的开发者共同完成一个作品,让每个开发者都可以发挥个性,同时又可以由发起者(即项目管理者)

分布式版本控制系统GIT的使用

一.什么是Git Git是一个分布式版本控制系统,Git 和其他版本控制系统的主要差别在于,Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异(如CVS.Subversion等).而Git并不保存这些前后变化的差异数据.Git更像是把变化的文件作快照后记录在一个微型的文件系统中.每次提交更新时,它会纵览一遍所有文件的指纹信息并对文件作一快照,然后保存一个指向这次快照的索引.若文件没有变化,Git不会再次保存,而只对上传保存的快照做一次连接,即若文件未变化则指向上

分布式版本控制系统---Git&amp;GitHub

 GIT的起源 Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常大的项目版本管理.Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件. Torvalds 开始着手开发 Git 是为了作为一种过渡方案来替代 BitKeeper,后者之前一直是 Linux 内核开发人员在全球使用的主要源代码工具.开放源码社区中的有些人觉得 BitKeeper 的许可证并不适合开放源码社区的工作,因此 Torvalds 决定着手研究许可

分布式版本控制系统 Git 教程

目录   简介  原理  安装  配置  命令  小结  资料 简介 Git 是什么? Git 是一个开源的分布式版本控制系统. 什么是版本控制? 版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统. 什么是分布式版本控制系统? 介绍分布式版本控制系统前,有必要先了解一下传统的集中式版本控制系统. 集中化的版本控制系统,诸如 CVS,Subversion 等,都有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文

分布式版本控制系统Git——使用GitStack+TortoiseGit 图形界面搭建Git环境

本篇导读: 可以说Git目前非常火,这与设计者剑指偏锋的设计思想有很大关系.Git采用发散的思维管理代码,最大的特点就是分布式,他可以让来自不同地区的开发者共同完成一个作品,让每个开发者都可以发挥个性,同时又可以由发起者(即项目管理者)统一发布新版本.各个地区的开发者,还可以离线开发,这样版本管理系统之所以火,也和当今社会万众创新的氛围分不开.通过Git你可以尽情的发挥想象力,开源的春天已经到来,让我们启航吧!  1. Git简介 名称:Git (Git的读音为/g?t/,开源.免费.分布式的版

分布式版本控制系统--Git使用

前言 花了点时间,学习Git版本管理工具,以前用过SVN比较之后,确实Git比SVN好用,更强大.简单总结了一些Git使用命令,如果想弄明白Git请猛击底下推荐学习网站. 使用总结 创建版本库: 初始化一个Git 仓库,使用git int 命令 添加文件到Git仓库,分两步: 第一步,使用命令git add ,注意,可反复多次使用,添加多个文件: 第二步,使用命令git commit,完成. 查看内容 要随时掌握工作区的状态,使用git status命令. 如果git status告诉你有文件被

分布式版本控制系统Git(二):github

前言 但凡是喜欢研究技术,或者听大牛们说起过的,都应该至少是听过github这个东西.具体就不介绍了,不了解的可以去了解了解,最主要的功能当然是代码托管啦,上面有各种各样的大牛写的项目.另外这一章不仅仅是说明如果跟github关联操作,因为github是远程版本库,实际上在公司中,也只是先给你一个远程版本库的地址给你,你自己去克隆,然后开发,所以下面操作,可以跟公司远程版本库操作一致. 连接github 1. 当然是注册github账号了 https://github.com 2. 创建SSH密

分布式版本控制系统Git的安装与使用

业来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2103 远程仓库地址是:https://github.com/BinGuo666/git 1.下载安装配置用户名和邮箱. 2. 创建工作目录并通过git init命令把这个目录变成Git可以管理的仓库. ls -a 命令可以发现工作目录下多了一个.git的隐藏目录,该目录是Git用于跟踪管理版本库的,别手动修改.git里的文件,免得破坏了Git仓库. 3. 在工作目录下准备文