第一章 Devops介绍
1.1 Devops是什么
*DevOps一次词的来自于Development和Operations的组合,突出重视软件开发人员和运维人员的沟通合作,通过自动化流程来使得软件构建、测试、发布更加快捷、频繁和可靠。
**是一种方法,一种过程,一种理念:狭义上指共同协作,广义上指所有软件生命周期内所有参与的角色
1.1 Devops能干嘛
提高产品质量
自动化测试
持续集成
代码质量管理工具
程序员鼓励师
1.1 Devops如何实现
设计架构规划-代码的存储-构建-测试、预生产、部署、监控
第二章 版本控制系统
2.1 版本控制系统简介
vcs `version control system`
1) 版本控制系统是一种记录一个或若干个文件内容变化,以便将来查阅特定版本内容情况的系统
2) 记录文件的所有历史变化
3) 随时可恢复到任何一个历史状态
4)多人协作开发
2.2 为什么需要版本控制系统
在软件开发过程,每天都会产生新的代码,代码合并的过程中可能会出现如下问题:
代码被覆盖或丢失
代码写的不理想希望还原之前的版本
希望知道与之前版本的差别
是谁修改了代码以及为什么修改
发版时希望分成不同的版本(测试版、发行版等)
因此,我们希望有一种机制,能够帮助我们:
可以随时回滚到之前的版本
协同开发时不会覆盖别人的代码
留下修改记录,以便随时查看
发版时可以方便的管理不同的版本
2.3 SVN
SVN是Subversion的简称,是一个开源的集中式版本控制系统,只有一个*数据仓库,如果*数据仓库挂了或者不可访问,所有的使用者无法使用SVN,无法进行提交或备份文件,相较于RCS、CVS,它采用了分支管理系统,它的设计目标就是取代CVS。
说得简单一点SVN就是用于多个人共同开发同一个项目,共用资源的目的。
2.4 Git
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。
github是基于git的在线web页面代码托管平台,可以选择付费服务
gitlab可以认为是一个开源的github,两者没有直接关系
2.5 SVN与Git的区别
1)SVN与Git的最主要的区别(核心区别)
SVN是集中式版本控制系统,版本库是集中放在*服务器的,而干活的时候,用的都是自己的电脑,所以首先要从*服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到*服务器。集中式版本控制系统是必须联网才能工作,如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网速慢的话,就纳闷了。
Git不仅仅是分布式版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。那么它就没有*服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
2)Git 把内容按元数据方式存储,而 SVN 是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似 .svn、.cvs 等的文件夹里。
3)Git 分支和 SVN 的分支不同:分支在 SVN 中一点都不特别,其实它就是版本库中的另外一个目录。
4)Git 没有一个全局的版本号,而 SVN 有:目前为止这是跟 SVN 相比 Git 缺少的最大的一个特征。
5)Git 的内容完整性要优于 SVN:Git 的内容存储使用的是 SHA-1 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
第三章 SVN
第四章 Git
4.1 系统环境准备
[root@git:~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
[root@git:~]# uname -r
3.10.0-862.el7.x86_64
4.2 Git安装部署
4.2.1 在windows中安装git
在windows上和mac上安装git都很方便,我们可以从官方网站上下载安装包,按照默认配置快速安装(一直下一步),访问git官网,即可下载git,git的官方网址如下:
https://git-scm.com/downloads
1)在windows中安装git的过程中,如果你没有修改默认的设置,当安装完成后,安装程序会自动为你安装两种客户端,一种是图形化的客户端,一种是命令行的客户端.
2)图形化的客户端被称之为"Git GUI",命令行的客户端被称之为"Git Bash",在系统的"开始"菜单中可以找到"Git GUI"和"Git Bash",同时,默认情况下,当你安装完成git后,你的右键菜单中会多出两个选项,"Git GUI Here"和"Git Bash Here",通过这两项,你可以在任何目录中打开"Git GUI"和"Git Bash","Git GUI"和"Git Bash"都是客户端程序,我们可以通过这两种程序中的任意一种来操作git,从而达到版本控制的目的,这两种工具在不同的使用场景下各有优势,命令行的优势在于比较通用,而且当你需要编写一些版本控制的自动化脚本时,无可避免的需要使用git命令,使用图形化的好处就是比较直观,所以,我们有可能会交替的使用这两种工具,但是主要以命令行的使用模式为主,因为只要理解了相关概念和git命令后,
再去使用任何一种图形化工具,都是非常简单的。
3)除了gitk(默认安装的图形化客户端就包含了gitk),比较出名的git图形化工具还有SourceTree、TortoiseGit、GitHubDesktop、GitKraken、GitUp等,当你熟悉了git命令以后,再去操作这些图形化工具都会变得游刃有余。
安装工作完成后,还需要一些初始化的设置,才能开始使用git,配置方法见下文。
4.2.2 在centos中安装git
在linux中,有可能已经自动安装了git,也有可能没有,当服务器中的某些脚本需要使用git命令时,我们就需要确保服务器上已经安装了git,一般使用1.x版本即可,此处以centos7为例,演示怎样安装git的2.X版本。
即使你的centos7中默认安装了git,git的版本应该也是1.X,因为默认的yum源中,git的版本就是1.X,到目前为止,这个版本应该算是比较老的版本了,所以,如果你的centos7上没有安装git,而你又需要安装git,可以直接安装git的2.X版本。
你可以通过编译源码的方式安装git的最新版,也可以通过yum源的方式安装git的2.X版本,此处演示yum源方式的安装与配置,此时,我的centos7上还没有任何版本的git,安装配置过程如下:
首先,我已经在我的centos7中安装了base源和epel源,因为之后的安装包需要依赖这两个源,base源和epel源的配置分别如下
# cat /etc/yum.repos.d/aliBase.repo
[aliBase]
name=aliBase
baseurl=https://mirrors.aliyun.com/centos/$releasever/os/$basearch/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/centos/$releasever/os/$basearch/RPM-GPG-KEY-CentOS-$releasever
# cat /etc/yum.repos.d/aliEpel.repo
[aliEpel]
name=aliEpel
baseurl=https://mirrors.aliyun.com/epel/$releasever\Server/$basearch/
enabled=1
gpgcheck=0
上述基础配置工作完成后,我们需要下载一个安装包,这个安装包会自动为我们配置git2.X需要的yum源,你可以从官网推荐的网址中下载,我选择的是针对centos7的安装包,执行如下命令下载并安装
# wget https://repo.ius.io/ius-release-el7.rpm
# yum install ius-release-el7.rpm
上述包安装完成后,会自动为我们配置ius仓库,我们可以通过ius仓库安装git2.X版本,命令如下:
# yum install -y git2u
完成上述操作,即可在终端中使用git命令了。
上述过程并没有安装默认的图形化客户端,因为大部分linux服务器都不会开启图形化,如果你需要,可以执行如下命令安装gitk(gitk是windows中和mac中默认安装的图形化客户端工具)
# yum install git2u-gitk
4.2.3 配置用户和邮箱
如果想要使用git进行版本管理,我们首先要做的就是,设置自己的"用户名"和"用户邮箱",这些信息是必须的,特别是在多人协作时,这些信息也是非常必要的,所以,在完成安装操作以后,我们首先要做的就是设置自己的"用户名"和"用户邮箱",这些信息只需要设置一次,就可以一直正常的使用git,除非你有需要修改这些信息。
我们可以使用如下两条命令,设置用户名和邮箱
注:我的系统是win10,你可以打开"Git Bash",然后执行下列命令,也可以使用win10自带的终端(比如power shell)执行如下命令,在Linux、Unix或Mac中,打开系统自带的终端输入如下命令即可。
$ git config --global user.name "nsthink"
# 配置git使用用户
$ git config --global user.email "ns@nsthink.net"
# 配置git使用邮箱
$ git config --global color.ui true
# 语法高亮
将上述命令中的用户名和邮箱修改成你自己的用户名和邮箱即可,上述命令不言自明,看字面意思就能理解,git config命令是用来对git进行配置操作的一条命令,user.name和user.email分别用来设定用户名和邮箱,至于"--global"选项是什么意思,如下:
从字面上看,"--global"的意思是"全局的",也就是说,如果我们在设置用户名和用户邮箱的时候,使用了这个选项,那么,当前系统用户(windows系统用户)创建的所有Git仓库都会使用这个用户名和邮箱,除了"--global"选项,还有"--local"选项和"--system"选项,没错,聪明如你一定想到了,我们可以通过这三个选项控制设置作用域的范围,这三个选项的作用域如下:
git config --system:使对应配置针对系统内所有的用户有效
git config --global:使对应配置针对当前系统用户的所有仓库生效
git config --local:使对应配置只针对当前仓库有效
local选项设置的优先级最高。
如果想要查看对应作用域的设置,可以使用如下命令:
git config --system --list
git config --global --list
git config --local --list
说明:我们在设置用户名和邮箱时,通常会使用"--global"选项,因为这样我们只需要设置一次,当前用户的所有仓库都会使用这些用户名和邮箱信息,即使是当前用户新创建的仓库,也会使用同样的配置,如果使用"--system"选项,可能会影响到系统中的其他系统用户,如果使用"--local"选项,当信息不需要变化时,每次创建新仓库时又都需要重复的为新仓库设置一次,所以,当设置用户名和邮箱时,"--global"选项最常用。
4.2.3 初始化
1)初始化工作目录
#说明:
我们需要使用git进行版本管理时,要接触的第一个概念就是"仓库",你可以把"仓库"理解成一个目录,只有这个目录中的文件才能被git管理,换句话说就是,如果你想要对某个文件进行版本管理,你就需要把这个文件放入到一个带有git功能的目录中,这个带有git功能的目录就是所谓的git仓库,git仓库的英文为"git repository",后文中所提到"仓库"、"版本库"、"repository"、"repo"其实都是一种东西,我们会不加区分的使用这些名词,它们都表示"仓库",当你把一个文件加入到某个git仓库以后,你对这个文件的所有操作都可以被git记录,从而实现版本管理的目的。
所以,为了使用git进行版本管理,我们首先要做的,就是创建一个git repository。
我们可以直接创建一个空的git仓库,也可以将一个已经存在目录转化成git仓库,我们先来看看怎样创建一个全新的、空的git仓库(操作系统为centos7)。
mkdir git_data #创建目录
[root@git:~/git_data]# cd git_data
[root@git:~/git_data]# git init # 初始化
[root@git:~/git_data]# tree ./.git
./.git
├── branches
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
git status #查看工作区状态
隐藏文件介绍:
branches # 分支目录
config # 定义项目特有的配置选项
descripttion # 仅供git web程序使用
HEAD # 显示当前的分支
hooks # 包含git钩子文件
info # 包含一个全局排除文件(exclude文件)
objects # 存放所有数据内容,有info和pack两个子文件夹
refs # 存放指向数据(分支)的提交对象的指针
index # 保存暂存区信息,在执行git init的时候,这个文件还没有
4.3 Git常规使用
4.3.1 创建数据-提交数据
4.3.2 git四种状态
4.3.3 git基础命令
4.3.3.1 添加文件
[root@git:~/git_data]# git status
# On branch master
[root@git:~/git_data]# git add a b c
[root@git:~/git_data]# git add a #将a文件添加到暂存区
[root@git:~/git_data]# git status #查看当前仓库的状态
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage) #使用此选项撤出暂存区
#
# new file: a
[root@git:~/git_data]# tree ./.git
./.git
├── branches
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── index #新生成一个index目录
├── info
│ └── exclude
├── objects
│ ├── e6
│ │ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
10 directories, 15 files
[root@git:~/git_data]# git add . #使用git add .或者*添加目录中所有改动过的文件到暂存区
##此时还未被版本控制系统管理起来,还未添加到本地仓库
4.3.3.2 删除文件
1.先从暂存区撤回到工作区,然后直接删除文件
[root@git:~/git_data]# git rm --cached c
[root@git:~/git_data]# rm -f c
2.直接从工作区域和暂存区域一同删除文件命令
[root@git:~/git_data]# git rm -f b
4.3.3.3 提交到本地仓库
# git commit -m
[root@git:~/git_data]# git commit -m "commit a" #提交到本地仓库
[master (root-commit) 63d575c] commit a #生成一个哈希值
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 a
[root@git:~/git_data]# git status
# On branch master
nothing to commit, working directory clean
小结:如何真正意义上通过版本控制系统管理文件
1.工作目录必须有个代码文件
2.通过git add file 添加到暂存区域
3.通过git commit -m "你自己输入的信息" 添加到本地仓库
#### 4.3.3.4 修改文件名称
```bash
git mv old-filename new-filename
直接更改文件名称,更改完直接commit提交即可
4.3.3.5 git文件的比对
git diff #默认比对工作目录和暂存区有什么不同
git diff --cached 比对暂存区域和本地仓库有什么不同
[root@git:~/git_data]# echo index >a
[root@git:~/git_data]# cat a
index
[root@git:~/git_data]# git diff
diff --git a/a b/a
index e69de29..9015a7a 100644
--- a/a
+++ b/a
@@ -0,0 +1 @@
+index
[root@git:~/git_data]# git add a
[root@git:~/git_data]# git diff
[root@git:~/git_data]# git diff --cached
diff --git a/a b/a
index e69de29..9015a7a 100644
--- a/a
+++ b/a
@@ -0,0 +1 @@
+index
[root@git:~/git_data]# git commit -m "add index"
[master fc54d42] add index
1 file changed, 1 insertion(+)
[root@git:~/git_data]# git diff
[root@git:~/git_data]# git diff --cached
说明:
如果某个文件已经被仓库管理,如果再更改此文件,直接需要以下一条命令即可:
git commit -am "add newfiile"
# git commit #相当于虚拟机的镜像,任何操作都被做了一次快照,可以恢复到任意一个位置
4.3.3.6 查看历史提交信息
git log #查看历史的git commit快照操作
git log --oneline # 单行显示历史信息
git log --oneline --decorate # 显示当前的指针指向哪里
git log -p # 显示具体内容的变化
git log -1 # 显示最近的一条commit内容
git reflog # 查看所有的历史操作
git log --oneline --decorate # 查看当前指针的指向(当前的指针指向哪里说明在那个版本上)
4.3.3.6 恢复历史数据
git reset --hard 824u329 # 回滚数据到某一个提交
[root@git:~/git_data]# git log --oneline
fc54d42 add index
63d575c commit a
[root@git:~/git_data]# git reset --hard 63d575c
HEAD is now at 63d575c commit a
4.4 Git分支
4.41 创建及删除分支
分支即是平行空间,假设你在为某个手机系统研发拍照功能,代码已经完成了80%,但如果将这不完整的代码直接提交到git仓库中,又有可能影响到其他人的工作,此时我们便可以在该软件的项目智商创建一个名叫"拍照功能"的分支,这种分支只会属于你自己,而其他人看不到,等代码编写完成后再与原来的项目主分支合并下即可,这样即能保证代码不丢失,又不影响其他人的工作
一般在实际的项目开发中,我们要尽量保证master分支是非常稳定的,仅用于发布新版本,平时不要随便直接修改里面的数据文件,而工作的时候则可以新建不同的工作分支,等到工作完成后在合并到master分支上面,所以团队的合作分支看起来会像上面图那样。
[root@git:~/git_data]# git log --oneline --decorate
63d575c (HEAD, master) commit a #查看分支指向
[root@git:~/git_data]# git branch testing #创建一个测试分支
[root@git:~/git_data]# git branch #查看分支
* master
testing
[root@git:~/git_data]# git checkout testing #切换到testing分支,对应的HEAD指针也指向了testing
Switched to branch 'testing'
[root@git:~/git_data]# git branch
master
* testing # *号在哪里就说明当前在哪个分支上
#也可以直接创建testing分支并切换到testing分支上
git checkout -b testing
[root@git:~/git_data]# git branch -d testing #删除testing分支
4.42 代码合并
思路:
1,首先在master上创建aaa,bbb,ccc文件,然后再创建testing分支,此时切换到master主干上会发现aaa,bbb,ccc文件均被复制过来了,即会从主干复制一份完整的代码到分支上
2,切换到master上创建master-eee文件,再切换到testing分支上,创建test-ddd文件,此时会发现master与testing分支的文件相互独立
3,然后通过merge完成代码的合并
实现步骤:
[root@git:~/git_data]# touch aaa bbb ccc
[root@git:~/git_data]# git add aaa bbb ccc
[root@git:~/git_data]# git commit -m "add aaa bbb ccc "
# 创建testing分支
[root@git:~/git_data]# git checkout -b testing #创建并切换到testing分支
[root@git:~/git_data]# touch test-ddd #创建test-ddd文件
[root@git:~/git_data]# git add . #添加到暂存区
[root@git:~/git_data]# git commit -m "add newfile test-ddd" #提交到本地仓库
[testing b0d3133] add newfile test-ddd
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test-ddd
[root@git:~/git_data]# git branch
master
* testing
[root@git:~/git_data]# git log --oneline --decorate #查看指针
b0d3133 (HEAD, testing) add newfile test-ddd
88e8975 (master) add aaa bbb ccc
63d575c commit a
[root@git:~/git_data]# git checkout master #切换到master主干
Switched to branch 'master'
[root@git:~/git_data]# git branch
* master
testing
[root@git:~/git_data]# ll #发现并没有test-ddd文件
total 0
-rw-r--r-- 1 root root 0 May 26 20:21 a
-rw-r--r-- 1 root root 0 May 26 22:19 aaa
-rw-r--r-- 1 root root 0 May 26 22:19 bbb
-rw-r--r-- 1 root root 0 May 26 22:19 ccc
[root@git:~/git_data]# git log --oneline --decorate #master的指针还是指向最近的一次操作
88e8975 (HEAD, master) add aaa bbb ccc
63d575c commit a
#同理在master主干上创建master-eee文件
[root@git:~/git_data]# touch master-eee
[root@git:~/git_data]# git add .
[root@git:~/git_data]# git commit -m "add newfile master-eee"
[master 0fc1d63] add newfile master-eee
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 master-eee
[root@git:~/git_data]# git log --oneline --decorate
0fc1d63 (HEAD, master) add newfile master-eee
88e8975 add aaa bbb ccc
63d575c commit a
#代码合并
[root@git:~/git_data]# git merge testing
Merge made by the 'recursive' strategy.
test-ddd | 0
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test-ddd
[root@git:~/git_data]# ll
total 0
-rw-r--r-- 1 root root 0 May 26 20:21 a
-rw-r--r-- 1 root root 0 May 26 22:19 aaa
-rw-r--r-- 1 root root 0 May 26 22:19 bbb
-rw-r--r-- 1 root root 0 May 26 22:19 ccc
-rw-r--r-- 1 root root 0 May 26 23:07 master-eee
-rw-r--r-- 1 root root 0 May 26 23:12 test-ddd
[root@git:~/git_data]# gitlog --oneline --decorate"
2f17cc5 (HEAD, master) Merge branch 'testing'
0fc1d63 add newfile master-eee
b0d3133 add newfile test-ddd
88e8975 add aaa bbb ccc
63d575c commit a
#说明:合并完之后,testing就变成老的代码了,没用了,如果想要开发新的功能可以将原分支删除,重新创建一个分支即可
[root@git:~/git_data]# git branch -d testing
Deleted branch testing (was b0d3133).
4.43 代码冲突合并
[root@git:~/git_data]# git branch
* master
testing
# master主干的aaa文件
[root@git:~/git_data]# cat aaa
[root@git:~/git_data]# echo master >> aaa
[root@git:~/git_data]# cat aaa
master
[root@git:~/git_data]# git commit -am "modifide aaa master"
[master 53322f7] modifide aaa master
1 file changed, 1 insertion(+)
[root@git:~/git_data]# git status
# On branch master
nothing to commit, working directory clean
#testing分支上的aaa文件
[root@git:~/git_data]# git checkout testing
Switched to branch 'testing'
[root@git:~/git_data]# cat aaa
[root@git:~/git_data]# echo testing >> aaa
[root@git:~/git_data]# git commit -am "modified add testing"
[testing 33e4aa4] modified add testing
1 file changed, 1 insertion(+)
[root@git:~/git_data]# cat aaa
testing
#合并
[root@git:~/git_data]# git checkout master
Switched to branch 'master'
[root@git:~/git_data]# git merge testing
Auto-merging aaa
CONFLICT (content): Merge conflict in aaa
Automatic merge failed; fix conflicts and then commit the result. #有冲突
[root@git:~/git_data]# cat aaa
<<<<<<< HEAD
master
=======
testing
>>>>>>> testing
[root@git:~/git_data]# vim aaa #编辑aaa文件,删除多余的符号,保留我们想要的内容
master
testing
[root@git:~/git_data]# git commit -am "merge testing"
[master 227b961] merge testing
[root@git:~/git_data]# git status
# On branch master
nothing to commit, working directory clean