一、分支

1.git中如何保存版本

在我们以往使用文件来进行版本控制的时候,都是将上一个版本复制一份,然后在其基础上进行修改。

但在git中,git只保存当前版本和上一个版本之间的差异,这样可以节省存储空间, 在生成版本的时候速度也会更快。

2.Master主线

如下图所示:

当只有一条主线Master时,新版本都是在上一个版本的基础上进行修改的,例如Version2在Version1的100个文件基础上,新增了20个文件,并修改了其中10个文件。

也就是说Version2只需要保存新增的20个文件,以及修改的10个文件的修改信息,当我们需要Version2的时候,git再去Version1中拿未修改的90个文件。

同理,Version3、Version4也是如此。

3.分支概念

当我们需要已某个版本作为基准,同时开发多个新功能,则可能在该基准版本处产生分支,如下图所示:

处理线上系统的紧急BUG:

例如,Version3是已上线的版本, 我们在Version3的基础上开发新功能:

Version3突然出现紧急BUG,需要修复,怎么办?我们可以在Version3的基础上新开一个分支,专门用作BUG修复,修复完后合并到主分支:

而负责新功能开发的分支,可以继续研发新功能,不受影响。等到新功能开发测试完毕后,也可以合并到主分支Master中去。

4.创建分支(开发新功能)

1)查询分支信息

git branch

可以看到,我们目前只有一个master主分支。

2)创建新的分支(开发商城功能)

git branch dev_shop

使用命令创建了一个分支,叫做dev_shop。用于开发新功能,商城。

"*"号代表我们所处的分支。

3)切换分支

使用命令:

git checkout dev_shop

可以看到,我们已经切换到了dev_shop分支,我们在这个新分支下编写代码,是不会影响到其他分支的。

通过git log查看一下版本信息:

可以看到,我们所处的版本是"修改约饭-->约",但是分支处于dev_shop。而在这个版本处存在两个分支:master和dev_shop。相当于下图所示:

如果我们在dev_shop分支上再生成一个版本,则会变成如下:

在分支中添加了商城功能后,使用git log查看版本信息:

5.创建分支(修改BUG)

 1)切换回master分支

git checkout master

2)创建新分支(修改BUG)

git branch bug

查看分支:

git branch

3)切换到BUG分支

git checkout bug

修改代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Index</title>
</head>
<body>
<ul>
<li>欧美</li>
<li>日韩</li>
<li>港台澳</li>
<li>直播</li>
<li>约</li>
</ul>
</body>
</html>

将"港台"修改为"港台澳"。并提交生成新的版本。

此时查看git log:

此时的分支结构为:

6.合并分支

将bug分支合并到master分支中。

1)切换回master分支

git checkout master

2)合并bug分支

git merge bug

查看当前的版本信息:

当前的分支结构:

7.删除分支

当Master分支将bug分支合并之后,bug分支就没用了,可以使用命令删除bug分支:

git branch -d bug

删除后,查看当前分支信息:

可以看到bug分支已经被删除。

8.继续开发dev_shop

1)从Master切换到dev_shop

git checkout dev_shop

2)继续开发dev_shop,并提交

9.将dev_shop合并到Master中

1)切换回Master分支

git checkout master

2)合并dev_shop分支

git merge dev_shop

当合并的时候,如果没有冲突(例如都是添加代码),则可以自动合并。

自动合并后会生成一个新的版本:

如果产生了冲突(例如修改了同一行代码),则自动合并失败。

当产生冲突的之后,git会将两个文件所修改的地方全部放在文件中,然后由我们人工进行处理:

我们人工修改为最终版本后,再次进行git add 、 git commit操作,重新提交即可。手工生成的版本信息,由我们自己指定。

二、分支总结

1.查看分支

git branch

2.创建分支

git branch 分支名

3.切换分支

git checkout 分支名

4.合并分支

git merge 分支名

注意,假设分支2要合并到分支1中,则需要切换到分支1中执行"git merge 分支2"。

三、简单工作流

git中默认有一个master分支,但是不建议我们直接在master分支上去做开发,master分支主要用于保存正式版本(稳定版本)。

我们开发新的功能,都应该去一个单独的分支上去做开发。例如叫dev的分支。如图所示:

从图中可以看到,我们的开发都在dev分支上做,而master分支的版本都是稳定版本。

类似于QQ的稳定版和beta版,稳定版在master分支中,beta测试版在dev分支中。

以上就是最基本的工作流。

四、github

github和git其实没有本质的联系,github只是一个类似于云盘的代码仓库。除了github,还有CSDN、码云等平台也提供类似的功能。

要使用github,需要以下几个步骤:

1)注册一个github账号

2)创建一个仓库

3)将本地代码推送到github仓库

1.注册github账号

(略)

2.创建仓库

Repository name尽量与项目名一致,方便查找。

Description用于描述项目。

Public表示开源(代码公开),Private表示只有自己能看到。

Initialice this repository with a README,自动创建一个README文件。

Add .gitignore表示创建一个不被git管理的文件夹

Add a license表示我们代码的许可证。

3.推送代码到仓库

在我们的项目文件夹中打开git bash窗口,执行命令:

git remote add origin https://github.com/leokale/dbhot.git

origin就是我们要推送的目的仓库的别名。

然后再执行push命令:

git push -u origin master

推送master分支到仓库。

此时会弹出一个用户名密码窗口,用于github验证:

输入账号密码通过验证后,可以看到推送成功:

此时,我们可以在github中看到仓库里存放着master分支的相关文件:

推送dev_shop分支的代码到仓库:

git push -u origin dev_shop

第二次推送,就无需验证github账号密码了。

此时,在github仓库中,可以看到多出了一个dev_shop分支。

4.从仓库拉代码

例如我们在另一台PC上,进入一个根目录(用于存放dbhot项目文件夹)。

在该目录打开git bash:

获取仓库的地址:

使用命令拉取代码:

git clone https://github.com/leokale/dbhot.git

可以看到该目录下出现dbhot文件夹:

进入目录使用git bash即可:

5.github总结

1)给远程仓库起别名

git remote add xxxx 远程仓库地址

2)向远程推送代码

git push -u xxxx 分支名

3)克隆全程仓库代码

git clone 远程仓库地址

当克隆代码之后,实际上帮我们执行了git remote add origin 远程仓库地址。所以我们以后推送的时候,可以使用origin就可以了。

五、局部代码推送与拉取

例如目前的版本结构如下图所示:

当我们要继续在dev_shop分支上去做开发时,发现dev_shop分支的代码不是最新的,因为master分支合并了bug分支和dev_shop分支。所有当前master分支才是最新的。

所以,我们在开发代码之前,首先在本地将master分支合并到dev_shop分支中,让dev_shop分支变为最新代码:

git checkout dev_shop
git merge master

合并后,dev_shop分支中的代码已经变为最新版,也就是和master分支一样,版本为"Merge branch 'dev_shop' "。

1.推送部分代码(在PC-A上的操作)

在dev_shop分支中开发新代码(例如新增一个a1.py文件):

touch a1.py

保存一个版本:

git add a1.py
git commit -m "在PC-A添加了一个新文件a1.py"

推送到仓库:

git push origin dev_shop

此时在仓库的dev_shop分支中可以看到:

2.拉取部分代码(在PC-B上的操作)

首先,切换到dev_shop分支:

git checkout dev_shop

然后,拉取在PC-A上提交的部分代码(a1.py文件):

git pull origin dev_shop

在a1.py中添加内容:

# a1.py文件

print("HELLO WORLD")

将新的代码推送给仓库:

git add a1.py
git commit -m "在PC-B中修改了a1.py"
git push origin dev_shop

3.pull命令分解

在git中,git pull命令实际上可以拆分为以下两个命令:

git fetch origin dev_shop
git merge origin/def_shop

git fetch的意思是将dev_shop分支从远程仓库(github)拉回本地版本库。由于拉回版本库,可能和本地的dev_shop不一致,所以名字为origin/dev_shop

git merge origin/dev_shop的意思是将原来仓库拉下来的dev_shop(origin/dev_shop)合并到工作区。

当然,merge的时候origin/dev_shop分支和本地的dev_shop可能存在冲突(例如PC-A上开发的代码忘了推送,然后在PC-B上又开发了其他代码并推送到了仓库,再在PC-A上fetch下来,就会不一样),需要我们手工解决冲突。

六、查看版本分支结构

1.graph参数

使用git log查看版本结构的时候,可以加上--graph参数:

2.简化模式

git log --graph --pretty=format:"%h %s"

%h:hash值(短)

%H:hash值(长)

%s:备注信息

%an:作者

%ae:作者email

%ad:提交时间

其他格式化字符参考:

git log --help

七、变基(rebase)

变基:git  rebase。

有以下三种使用场景。

1.合并多个提交记录

当我们反复在不同的地方开发代码时,可能会经常commit,然后push,这样会生成很多提交记录(版本)。这对于我们自己可能是由意义的,但是对于其他协同开发者是没有意义的。

例如,在某个项目中,我们一共有4条提交记录:

假设,我们想将v2~v4合并成一个提交:

git rebase -i af57743e74ce9f36a8f142e87cd10599b6a36fc4

后面的ID就是v2这个提交的ID。他会将v2~当前提交这三条提交合并成一个提交。

另一种方式:

git rebase -i HEAD~

HEAD~3是从当前提交往前数3个提交,合并成一个。

执行上述任意一个命令后,会进入以下画面:

我们关注最前面的三行(pick *****),将v3和v4的"pick"修改为"s":

表示将v3和v4合并到v2中,:wq保存,进入另外一个画面:

修改合并后的commit的描述信息:

:wq保存:

执行git log查看提交记录:

我们可以看到,合并后的commit的时间和v2的时间一致。

2.补充

在执行git rebase HEAD~3命令以后,进入的第一个画面:

我们关注的最前面三行,是分别对三个版本的处理方式:

1)pick:表示使用commit,如果3个版本都是pick,则不发生任何改变,还是v2 v3 v4。

2)reword:同pick,使用commit,但是可以修改备注信息。保存后,会进入修改备注的页面。按r指定的版本,一个一个修改备注。

3)squash:标记为s的版本,会向前合并,例如v4标记为s,则会合并到v3中,以此类推。

4)fixup:和squash很像,但不会进入修改备注的界面,也就是说丢弃标记f的版本的备注信息,并合并到前一个版本中。

5)drop:删除指定的版本。

注意:在使用rebase合并版本时,最好不要是已经push到仓库的版本,最好是合并好后再push到仓库中。

2.将分支的版本合并进master(变成master一条线)

例如,我们目前master有2个版本,分别为m1和m2。

在m1处,创建了分支dev,并且提交了版本d1。

此时的结构如下:

我们如果使用git merge命令,则会将其变为:

但是我们想将其变得更简洁,例如下图:

使用命令:

git checkout dev  # 切换到dev分支
git rebase master # 将dev作为base,相当于将master合并进dev
git checkout master # 切换回master
git merge dev # 将dev合并到master

执行上述命令后,master和dev分支的版本都是m1<----m2<----d1。如果不需要dev分支,则将其删除即可:git branch -d dev

3.合并不产生分叉

在《第五节:局部代码推送与拉取》中,我们在PC-A和PC-B上分别开发了代码,PC-A提交在本地版本库,但没有推送到远程仓库。而PC-B的推送到了远程仓库。

当我们在PC-A上pull仓库的代码时,git会帮我们自动进行合并,但可能产生冲突,然后由我们手动解决冲突。

我们知道pull命令可以拆分为:

git fetch origin dev
git merge origin/dev

但是,在这种情况下,一定会产生分叉,因为fetch回来的分支叫做 origin/dev,而本地的叫做dev。

此时,可以使用rebase来代替merge:

git fetch origin dev
git rebase origin/dev

4.rebase时解决冲突

当我们在master和dev分支中都对同一个文件的同一行进行了修改,并都提交到了版本库。我们使用rebase将他们合并成一条分支时,会报冲突错误:

此时,我们可以按照报错提示,去m3.py中查看冲突:

解决冲突:

然后执行命令,继续rebase:

git add m3.py  # 处理完冲突后,要使用add加入暂存区或使用rm命令删除
git rebase --continue # 然后继续执行rebase操作

666

[工具] Git版本管理(二)(分支)的更多相关文章

  1. [工具] Git版本管理(知识总结)

    对以下文档进行了简要总结,方面复习: [工具] Git版本管理(一)(基本操作) [工具] Git版本管理(二)(分支) [工具] Git版本管理(三)(工作流) [工具] Git版本管理(四)(贡献 ...

  2. 版本控制git之二 分支 切换分支 创建分支 合并 删除

      版本控制git之二 分支   有人把 Git 的分支模型称为它的`‘必杀技特性’',也正因为这一特性,使得 Git 从众多版本控制系统中脱颖而出. 为何 Git 的分支模型如此出众呢? Git 处 ...

  3. [工具] Git版本管理(四)(贡献开源代码、git配置、git免密、gitignore)

    一.开源项目贡献代码 1.fork项目代码 例如,我们想向tornado框架贡献代码,首先搜索tornado. 然后,将tornado的代码fork到我们的仓库中. 2.clone到本地进行开发 克隆 ...

  4. 版本控制git之二-分支

    有人把 Git 的分支模型称为它的`‘必杀技特性’',也正因为这一特性,使得 Git 从众多版本控制系统中脱颖而出. 为何 Git 的分支模型如此出众呢? Git 处理分支的方式可谓是难以置信的轻量, ...

  5. 版本管理工具Git(二)GitLab部署和配置

    安装 # 安装依赖包 sudo yum install -y curl policycoreutils-python openssh-server # 启用并启动SSHD sudo systemctl ...

  6. [工具] Git版本管理(一)(基本操作)

    一.版本控制的发展 1.用文件来做版本控制 我们在写论文.做方案等的时候,一般都会同时在文件夹中存在很多版本的文件. 例如: 这种方式很常用,在很多领域都是用这种方式来进行版本控制的. 2.本地版本控 ...

  7. [工具] Git版本管理(三)(工作流)

    一.冲突解决 Beyond Compare软件 下载BCompare软件,并安装. 删除安装目录下的BCUnrar.dll文件. 使用码: w4G-in5u3SH75RoB3VZIX8htiZgw4E ...

  8. 强大得分布式项目管理工具Git

    ---恢复内容开始--- 强大的分布式管理工具-Git(一) 前言:最近忙着写项目,在期间呢,用的是git管理,由于一个项目的管理是很重要得,所以整理了一篇关于git得博客跟大家分享一下.大家都知道, ...

  9. GIT版本管理工具教程

    目录 GIT版本管理工具教程 一 Git初始化 二 简单指令使用 基本操作 简单总结 三 Git进阶 Git三大区域 Git回滚 Git分支 Git工作流 四 Github代码管理仓库 第一步:注册G ...

随机推荐

  1. 13-2 jquery介绍

    1 什么是 jQuery jQuery 是 js 的一个库,封装了我们开发过程中常用的一些功能,方便我们调用,提高开发效率. js库是把我们常用的功能放到一个单独的文件中,我们用的时候,直接引用到页面 ...

  2. part10.3-字符驱动访问揭秘

  3. Libev源码分析07:Linux下的eventfd简介

    #include <sys/eventfd.h> int eventfd(unsigned int initval, int flags); eventfd创建一个eventfd对象,该对 ...

  4. @noi.ac - 507@ 二分图最大权匹配

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 有一天你学了一个能解决二分图最大权匹配的算法,你决定将这个算法应 ...

  5. HDU 1875 最小生成树prim算法

    #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #inc ...

  6. JS精度问题,解决方案 math.js

    JS精度问题    Vue中使用 解决方案 math.js npm install mathjs import { create, all } from 'mathjs' const config = ...

  7. Python--day47--mysql慢日志记录

  8. P1103 走迷宫三

    题目描述 大魔王抓住了爱丽丝,将她丢进了一口枯井中,并堵住了井口. 爱丽丝在井底发现了一张地图,他发现他现在身处一个迷宫当中,从地图中可以发现,迷宫是一个N*M的矩形,爱丽丝身处迷宫的左上角,唯一的出 ...

  9. H3C 最大跳数16导致网络尺度小

  10. Vue 中的过滤器的使用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...