- 在实际的项目开发阶段,往往会出现许多的历史版本,那么对于传统的开发版本管理,可以使用文件复制的时候完成,但是这样的操作毕竟对于整个的项目维护不方便,所以在Git中提出了一个分支的概念,而且每一个分支都可以成为单独的可以运行的项目存在
分支的创建与合并
- 在git里面肯定个会存在有大量的分支,但是所有的分支都会存在一个master分支,在git中规定,所有的最重要使用的代码都应该保存在Master分之上,既然所有的最终代码都要保存在Master上,则如果要进行代码的修改操作,那么就可以使用一系列的子分支方式完成
-
通过分支管理可以保证项目可以正常执行 ,但是又可以进行正常发布.
-
查看当前仓库中的可用分支
git branch
- 在git交互中,对于当前正在使用的分支,往往会使用"*"表示
- 创建一个新的dev分支(开发分支)
- 所有的分支创建都是在当前分支创建的
git branch dev
- 查看当前所有分支
git branch
- 现在依然在使用master分支
- 切换分支
- 如果要保证代码的开发,master分支坚决不能够直接使用,所以需要切换分支
git checkout dev
- 此时如果在dev分之上对代码的所有操作都不会影响到master分支.
- 在dev分支上创建一个Dept.java文件
echo "public class Dept{ private Integer deptno;private String dname;}" >> Dept.java
这个时候所编写的代码虽然是在dev上保存,但是现在的代码还未提交,要将代码提交到dev分支点上
git add .
git commit -m "new Dept file"
-
通过分析可以发现,此时的dev分之上的代码要对于master分之上的操作,而且在dev分之上都有一个提交点(实际上每一个提交点都表示代码完成).
-
切换为master分支
git checkout master
- 最终所需要在master分之上合并dev分支
- 在合并分支前,一定要切换到你所需要的分之上,
git merge dev
- 所谓的"Fast-forward合并的处理模式指的就是直接对分支改变他的指向.
- 在实际的开发过程之中,如果要进行项目的开发那么往往是一个长期的过程,那么就要将分支保存到远程仓库之中.
- 如果原本的远程仓库已经被删除了,那么建立了新的仓库,则需要重新建立链接
git remote set-url origin 新仓库地址
- 将代码提交到仓库中
git push -u origin master
- 上传成功之后,github主页中的仓库内容
- 将dev分支上传到远程仓库之中
git push -u origin dev
- 上传成功之后github上的分支内容
- dev分支既然只是作为开发使用,并且现在也已经跟master分支合并了,那么就可以进行删除了
git branch -d dev
- 删除远程仓库中的dev分支
-
- 虽然在本地上删除了dev分支,但在远程仓库中依然保存着dev分支,可以直接在页面中选择dev分支,然后删除
- 也可以使用命令行方式删除
git push origin --delete dev
- 还可以直接通过推送一个空的分支,来删除分支
git push oragin :dev
冲突解决
- 有了分支方便程序进行代码管理,但也可能出现在不同的分支上,对同一个文件进行修改,这样就会产生冲突.
- 创建并且切换到dev分支
git checkout -b dev
- 在dev分支上创建一个新的文件(Admin.java文件),同时修改一个已有的文件"Hello.java"
4. 在dev上将所修改的内容进行提交,提交到git仓库之中
git add *
git commit -a -m "注释内容"
5. 切换回master分之上,同时也针对于Hello.java文件进行修改,随后也进行提交
git checkout master
- 修改的Hello.java文件内容
- 提交代码
git add .
git commit -a -m "Change in master"
- 在master分之上合并dev分支
git merge dev
-
由于已经在Hello.java文件中出现了冲突,所以系统会在hello.java文件中标记出冲突位置
-
查看Hello.java文件中的内容
- 开发者必须手工修改冲突文件,而后进行提交处理
git add .
git commit -m "注释内容"
2. 一旦产生冲突之后,需要有一个转的分支的开发者进行手工处理,而后进行提交
3. 随后dev分支已没有任何作用,可以将其进行删除处理
git branch -d dev
分支合并模式
-
在之前实现的分支合并处理操作,是采用的模式为"Fast-forward"模式,此案用的是直接改变Head指向,达到快速合并处理,但是这种合并的缺点在于,合并时没有提交点,这也就意味着,无法使用提交点进行代码恢复.
-
以图像化的方式观察所有的合并记录
git log --graph --pretty=oneline
-
使用 git gui工具打开,选择"浏览所有的历史分支"
-
鼠标右键,选择 git gui here
-
选择 Visualize All Branch History
- 历史分支图
- 为了更好的发现问题,再次执行分支操作
git checkout -b dev #创建dev分支,并使用dev分支
echo "edit" >> Hello.java #追加内容到Hello.java文件中
git add . #将所有修改内容添加到暂存区
git commit -m "Test FF More" #提交所有暂存区内容到dev提交点
- 查看当前的提交日志
git log --graph --pretty=oneline
- 发现此时在dev分之上产生了一个提交点,随后切换到Master分之上进行合并处理
git checkout master
git merge dev
-
此时进行了分支合并,但是发现没有产生提交点,所以这种默认的合并模式,在实际开发中不会被采用.
-
此时的提交日志
使用HO-FF提交模式
- 使用"NO-FF"模式处理
- 删除dev分支,在重新创建一个dev分支
git branch -d dev
git checkout -b dev
- 使用"No-FF"模式合并dev分支
git merge --no-ff -m "User No-ff" dev
- 查看合并记录
git log --graph --pretty=oneline
-
现在会清楚的记录每一个分支的合并和处理情况,这样才方便代码的维护.
-
在master分之上始终保持着"最终"的可用版本,他作为项目的发布,不允许出错
-
如果要进行项目的开发,需要在master分之上建立"dev"分支,而后如果需要进行具体的代码编写则应该在dev分之上继续划分出子分支
-
所有的代码一定要在dev分之上县合并,在dev分之上合并的代码一定是可用的代码,随后使用–no-ff模式进行合并.
-
对于不使用的分支一定要及时删除处理
bug分支
- 如果当你正在编写的个人上出现了错误,而如此时主分支上的代码也出现了问题,而在不将错误代码提交到个人分之上的情况下,去切换出一个bug分支,修改代码
- git考虑到了这种情况,所以提供有工作区的暂存模式
- 创建并且切换到dev分支
git checkout -b dev
- 假设现在dev分之上进行一系列代码修改
- 中间考虑到现在要解决的bug问题,所以需要将此时的工作区暂存处理
git stash
- 由于需要修改bug,并且保证master分支可用,所以将当前的分支切换回master分支之中
git checkout master
- 创建并切换到bug分之上
git checkout -b bug
- 在bug分之上进行代码的修改同时将修改后的bug分支于master分支合并
修改 Emp.java类
git add .
git commit -m "edit bug"
git checkout master
git merge --no-ff -m "bug Reparied" bug
git branch -d bug
- 此时实现了bug的修正,随后还要进行之前的代码继续编写,首先查看所有的挂起的工作区
git stash list
- 已经知道有挂起的工作区,那么需要恢复处理,恢复有两种操作
- 分布进行:
- 恢复暂时挂起的工作区:git stash apply
- 清楚暂时挂起的工作区:git stash drop
2. 一步完成:
- 从暂挂区恢复进行清楚:git stash pop
- 随后切换到dev分之上,继续完成未完成的处理
feature分支
-
在很多的项目开发之中经常会出现这样一种情况:要求增加某些功能,但是编写一半时,突然这个需求不需要了.
-
观察可能会出现的问题
-
创建feateure分支
git checkout -b -fearture
- 修改该分支的代码,并使用git commit提交到版本库
- 若此时该功能不需要了,就需要删除该分支,所以该分支不需要进行合并,于是切换为master分支,但是会发现无法删除此分支
git checkout master
git branch -d feature
- 以上的系统提示我们说:fearture分支还没有进行合并,如果非要进行删除,可以使用"git branch -D fearture"指令完成强制删除
git branch -D fearture
补丁
- 在实际的项目开发之中,往往每一个项目都会非常的庞大,那么这些代码要想使用,一定要发布到服务器端,这样就会造成一个问题,假设你的整体项目大小有30w个文件,但是现在只有其中一个或者项目的几个文件进行了改变.那么按照之前的做法,那么所有的代码都需要进行重复提交操作
- 所以在这样的情况下,git也充分考虑到了此类问题的出现,所以提出了补丁的概念,相当于你现在修改了某一个文件,为了让服务器端文件于此文件进行同步,就将两个文件不同的部分做一个差别化的标记, 这样的文件称之为补丁文件.
- 创建并切换到dev分之上
git checkout -b dev
- 在dev分之上修改了Hello.java文件
- 这个时候千万不要将整个Hello.java文件进行提交,可以将不同的部分做出标记.
git diff Hello.java
- 这个时候"diff"命令可以明确的的标记出代码修改位置
- 在dev分之上提交所做的所修改的操作
git add
git commit -m "注释内容"
- 现在代码很明显dev分之上的内容是最新的,而master分支上不是最新的,所以需要将master中的内容和dev内容进行比较,并将比较的结果保存在一个补丁文件之中
- 在dev分之上,于master分支进行比较处理
git diff master > patch
- 产生的补丁文件内容
- 切换回到master分之上,应用此补丁文件
git checkout master
git apply patch
- 这个时候虽然实现了补丁文件的创建操作,但是这种文件存在有局限性,这种文件适合于小范围的开发,并要求开发人员沟通方便情况下.
- 如果是在跨地理位置或者沟通不方便,那就非常麻烦.
- 所以在生成补丁的时候强烈建议要生成带有特别格式的补丁文件(format-patch)
- 创建并且切换到pat分支之上
git checkout -b pat
- 在pat分之上进行代码的部分修改,并且将其进行提交:
git add .
git commit -m ""
- 生成格式化补丁
git format-patch -M master
- 随后将自动生成一个以Email风格的补丁文件
- 这个补丁文件一定要发给指定的开发者,随后开发者如果觉得可行则可以应用该文件
git am 0001-edit-pat.patch
多人协作开发
- 所谓的git的多人协作开发指的就是直接利用已有的git服务器(github),但是在多人开发状态下,必须有一个维护原则,master分支不允许做任何修改,所有的修改都要在dev分之上进行.
- 分支名称尽可能一样
- 为观察问题,首先建立一个新的dev分支
- 创建并切换到dev分之中:
git checkout -b dev
- 在dev上对代码进行一些修改,随后上传到服务器端
git add *
git commit -m "edit in dev 2019年1月26日 15:39:07"
- 将两个分支一起提交给远程的github上
git push origin master
git push origin dev
- 观察github上有没有分支信息
- 现在如果要想查看远程仓库可以使用:git remote命令完成
- 如果要查看详细的远程仓库信息可以使用"git remote -v
git remote -v
- 现在对于远程仓库已经明确的给出了抓取以及内容的仓库信息
- 第二开发者:打开新的一个命令窗口,表示第二个开发者,要进行仓库克隆
- 切换为d盘,在d盘中进行内容的克隆处理:
d:
git clone https://github.com/Xiemaoshu/xmsFirstGithub.git
- 克隆完成之后,会在d盘下发现有xmsFirstGithub的文件夹,这个文件夹就是远程仓库的名称,但是在这个仓库中发现只能够克隆master分支内容,因为一直强调的master分支才是可以被用户去使用的,但是现在仓库存在有dev分支,所以现在如果要想取得这个分支,则可以进行抓取
- 第二开发者:将远程仓库中的dev分支抓取到本地的yootk分支
- 目的:让第二个开发者的本地的其他分支名字与远程不同而产生错误
git checkout -b yootk origin/dev
-
也就是说此时本地的yootk的分支于远程仓库中的dev分支是有关系的.
-
如果在以后要想继续抓取远程仓库中的指定分支的内容,则可以使用如下操作
# 如果你的远程分支于本地分支的名称是相同的,那么就不需要第一个指令了
git branch --set-upstream-to=origin/dev yootk
git pull
- 现在已经有了两个开发者了,那么这两个开发者就有可能进行同一个代码的开发操作
- 假设第一个开发者修改了Admin.java文件
- 第一个开发者将代码提交给远程的dev分支
git add .
git commot -m ""
git push origin dev
- 第二个开发者:在自己的项目之中也修改了Admin.java文件:
- 第二个开发者:将代码也进行远程仓库的代码推送
git add .
git commit -m ""
git push origin yootk
- 这个时候进行了推送,但此时显示的结果是:推送了一个新的分支"yootk"
- 现在最主要的问题实际上并不在分支的名称上,而关键的问题是:此时yootk这个分支应该和远程仓库中的dev分支有关系,下面首先对分支做一个抓取
git pull
- 这个时候发现由于远程仓库中分支的关系存在在,所以即使本地使用了yootk的分支,实际上最终也将加载远程dev分之上的内容,同时由于此文件已经被第一个开发者所修改了,所以会产生冲突
- 第二个开发者:打开冲突文件
- 第二个开发者:需要自己手工来解决这些问题的出现,随后对分支进行提交
git add .
git commit -m
git push origin yootk
- 此时冲突已经解决,但是发现现在提交的分支还是yootk这个新的分支.
- 当分支不一样的时候就会出现一个新的问题了,现在第二个开发者将他自己的代码提交了yootk分支,但是对于第一个开发者而言,如果要想抓取到这个分支那么就非常麻烦了
- 第一个开发者
git pull
- 因为两个分支不一样,所以当第一个开发者如果要想抓取内容的时候就必须于远程仓库的指定分支产生关系.
- 将本地的dev分支指向远程仓库的yootk分支
git branch --set-upstream-to=origin/yootk dev
- 这就表示现在第一个开发者要进行抓取操作的时候本地的dev分支要通过远程的"yootk"分支名字取得内容
- 而设置完成后再次使用git pull命令抓取
git pull
-
通过以上的演示可以发现,如果在git操作过程之中分支名称不一样,则对于代码维护实在非常不方便,所以建议以后的分支名称还是采用相同的名称比较合适.
-
第二个开发者:删除远程yootk分支:
git push origin --delete yootk
- 这里要我输入用户名和密码
- 第二个开发者:建立并切换到dev分支,这样就和远程仓库的分支名称一样
git checkout master # 切换到master分支
git branch -D yootk # 删除本地yootk分支
git checkout -b dev origin/dev # 创建并切换到dev分支,该分支来自于远程仓库中的dev分支
- 如果要相对代码进行修改处理了,则继续进行推送于抓取操作
git pull #抓取远程仓库分支内容
- 在使用git 进行开发过程之中,强烈建议是:分支名称尽可能一样