nebulali 2020-05-27
*DevOps一次词的来自于Development和Operations的组合,突出重视软件开发人员和运维人员的沟通合作,通过自动化流程来使得软件构建、测试、发布更加快捷、频繁和可靠。 **是一种方法,一种过程,一种理念:狭义上指共同协作,广义上指所有软件生命周期内所有参与的角色
提高产品质量 自动化测试 持续集成 代码质量管理工具 程序员鼓励师
设计架构规划-代码的存储-构建-测试、预生产、部署、监控
vcs `version control system` 1) 版本控制系统是一种记录一个或若干个文件内容变化,以便将来查阅特定版本内容情况的系统 2) 记录文件的所有历史变化 3) 随时可恢复到任何一个历史状态 4)多人协作开发
在软件开发过程,每天都会产生新的代码,代码合并的过程中可能会出现如下问题:
代码被覆盖或丢失 代码写的不理想希望还原之前的版本 希望知道与之前版本的差别 是谁修改了代码以及为什么修改 发版时希望分成不同的版本(测试版、发行版等)
因此,我们希望有一种机制,能够帮助我们:
可以随时回滚到之前的版本 协同开发时不会覆盖别人的代码 留下修改记录,以便随时查看 发版时可以方便的管理不同的版本
SVN是Subversion的简称,是一个开源的集中式版本控制系统,只有一个中央数据仓库,如果中央数据仓库挂了或者不可访问,所有的使用者无法使用SVN,无法进行提交或备份文件,相较于RCS、CVS,它采用了分支管理系统,它的设计目标就是取代CVS。
说得简单一点SVN就是用于多个人共同开发同一个项目,共用资源的目的。
Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。
github是基于git的在线web页面代码托管平台,可以选择付费服务 gitlab可以认为是一个开源的github,两者没有直接关系
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 哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
[:~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) [:~]# uname -r 3.10.0-862.el7.x86_64
在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,配置方法见下文。
在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
如果想要使用git进行版本管理,我们首先要做的就是,设置自己的"用户名"和"用户邮箱",这些信息是必须的,特别是在多人协作时,这些信息也是非常必要的,所以,在完成安装操作以后,我们首先要做的就是设置自己的"用户名"和"用户邮箱",这些信息只需要设置一次,就可以一直正常的使用git,除非你有需要修改这些信息。
我们可以使用如下两条命令,设置用户名和邮箱
注:我的系统是win10,你可以打开"Git Bash",然后执行下列命令,也可以使用win10自带的终端(比如power shell)执行如下命令,在Linux、Unix或Mac中,打开系统自带的终端输入如下命令即可。
$ git config --global user.name "nsthink" # 配置git使用用户 $ git config --global user.email "" # 配置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"选项最常用。
1)初始化工作目录
#说明: 我们需要使用git进行版本管理时,要接触的第一个概念就是"仓库",你可以把"仓库"理解成一个目录,只有这个目录中的文件才能被git管理,换句话说就是,如果你想要对某个文件进行版本管理,你就需要把这个文件放入到一个带有git功能的目录中,这个带有git功能的目录就是所谓的git仓库,git仓库的英文为"git repository",后文中所提到"仓库"、"版本库"、"repository"、"repo"其实都是一种东西,我们会不加区分的使用这些名词,它们都表示"仓库",当你把一个文件加入到某个git仓库以后,你对这个文件的所有操作都可以被git记录,从而实现版本管理的目的。 所以,为了使用git进行版本管理,我们首先要做的,就是创建一个git repository。 我们可以直接创建一个空的git仓库,也可以将一个已经存在目录转化成git仓库,我们先来看看怎样创建一个全新的、空的git仓库(操作系统为centos7)。
mkdir git_data #创建目录 [:~/git_data]# cd git_data [:~/git_data]# git init # 初始化 [:~/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的时候,这个文件还没有
[:~/git_data]# git status # On branch master [:~/git_data]# git add a b c [:~/git_data]# git add a #将a文件添加到暂存区 [:~/git_data]# git status #查看当前仓库的状态 # On branch master # # Initial commit # # Changes to be committed: # (use "git rm --cached <file>..." to unstage) #使用此选项撤出暂存区 # # new file: a [:~/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 [:~/git_data]# git add . #使用git add .或者*添加目录中所有改动过的文件到暂存区 ##此时还未被版本控制系统管理起来,还未添加到本地仓库
1.先从暂存区撤回到工作区,然后直接删除文件 [:~/git_data]# git rm --cached c [:~/git_data]# rm -f c 2.直接从工作区域和暂存区域一同删除文件命令 [:~/git_data]# git rm -f b
# git commit -m [:~/git_data]# git commit -m "commit a" #提交到本地仓库 [master (root-commit) 63d575c] commit a #生成一个哈希值 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 a [:~/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提交即可
git diff #默认比对工作目录和暂存区有什么不同 git diff --cached 比对暂存区域和本地仓库有什么不同 [:~/git_data]# echo index >a [:~/git_data]# cat a index [:~/git_data]# git diff diff --git a/a b/a index e69de29..9015a7a 100644 --- a/a +++ b/a @@ -0,0 +1 @@ +index [:~/git_data]# git add a [:~/git_data]# git diff [:~/git_data]# git diff --cached diff --git a/a b/a index e69de29..9015a7a 100644 --- a/a +++ b/a @@ -0,0 +1 @@ +index [:~/git_data]# git commit -m "add index" [master fc54d42] add index 1 file changed, 1 insertion(+) [:~/git_data]# git diff [:~/git_data]# git diff --cached
说明:
如果某个文件已经被仓库管理,如果再更改此文件,直接需要以下一条命令即可:
git commit -am "add newfiile" # git commit #相当于虚拟机的镜像,任何操作都被做了一次快照,可以恢复到任意一个位置
git log #查看历史的git commit快照操作 git log --oneline # 单行显示历史信息 git log --oneline --decorate # 显示当前的指针指向哪里 git log -p # 显示具体内容的变化 git log -1 # 显示最近的一条commit内容 git reflog # 查看所有的历史操作 git log --oneline --decorate # 查看当前指针的指向(当前的指针指向哪里说明在那个版本上)
git reset --hard 824u329 # 回滚数据到某一个提交 [:~/git_data]# git log --oneline fc54d42 add index 63d575c commit a [:~/git_data]# git reset --hard 63d575c HEAD is now at 63d575c commit a
分支即是平行空间,假设你在为某个手机系统研发拍照功能,代码已经完成了80%,但如果将这不完整的代码直接提交到git仓库中,又有可能影响到其他人的工作,此时我们便可以在该软件的项目智商创建一个名叫"拍照功能"的分支,这种分支只会属于你自己,而其他人看不到,等代码编写完成后再与原来的项目主分支合并下即可,这样即能保证代码不丢失,又不影响其他人的工作
一般在实际的项目开发中,我们要尽量保证master分支是非常稳定的,仅用于发布新版本,平时不要随便直接修改里面的数据文件,而工作的时候则可以新建不同的工作分支,等到工作完成后在合并到master分支上面,所以团队的合作分支看起来会像上面图那样。 [:~/git_data]# git log --oneline --decorate 63d575c (HEAD, master) commit a #查看分支指向 [:~/git_data]# git branch testing #创建一个测试分支 [:~/git_data]# git branch #查看分支 * master testing [:~/git_data]# git checkout testing #切换到testing分支,对应的HEAD指针也指向了testing Switched to branch ‘testing‘ [:~/git_data]# git branch master * testing # *号在哪里就说明当前在哪个分支上 #也可以直接创建testing分支并切换到testing分支上 git checkout -b testing [:~/git_data]# git branch -d testing #删除testing分支
思路:
1,首先在master上创建aaa,bbb,ccc文件,然后再创建testing分支,此时切换到master主干上会发现aaa,bbb,ccc文件均被复制过来了,即会从主干复制一份完整的代码到分支上 2,切换到master上创建master-eee文件,再切换到testing分支上,创建test-ddd文件,此时会发现master与testing分支的文件相互独立 3,然后通过merge完成代码的合并
实现步骤:
[:~/git_data]# touch aaa bbb ccc [:~/git_data]# git add aaa bbb ccc [:~/git_data]# git commit -m "add aaa bbb ccc " # 创建testing分支 [:~/git_data]# git checkout -b testing #创建并切换到testing分支 [:~/git_data]# touch test-ddd #创建test-ddd文件 [:~/git_data]# git add . #添加到暂存区 [:~/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 [:~/git_data]# git branch master * testing [:~/git_data]# git log --oneline --decorate #查看指针 b0d3133 (HEAD, testing) add newfile test-ddd 88e8975 (master) add aaa bbb ccc 63d575c commit a [:~/git_data]# git checkout master #切换到master主干 Switched to branch ‘master‘ [:~/git_data]# git branch * master testing [:~/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 [:~/git_data]# git log --oneline --decorate #master的指针还是指向最近的一次操作 88e8975 (HEAD, master) add aaa bbb ccc 63d575c commit a #同理在master主干上创建master-eee文件 [:~/git_data]# touch master-eee [:~/git_data]# git add . [:~/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 [:~/git_data]# git log --oneline --decorate 0fc1d63 (HEAD, master) add newfile master-eee 88e8975 add aaa bbb ccc 63d575c commit a #代码合并 [:~/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 [:~/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 [:~/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就变成老的代码了,没用了,如果想要开发新的功能可以将原分支删除,重新创建一个分支即可 [:~/git_data]# git branch -d testing Deleted branch testing (was b0d3133).
[:~/git_data]# git branch * master testing # master主干的aaa文件 [:~/git_data]# cat aaa [:~/git_data]# echo master >> aaa [:~/git_data]# cat aaa master [:~/git_data]# git commit -am "modifide aaa master" [master 53322f7] modifide aaa master 1 file changed, 1 insertion(+) [:~/git_data]# git status # On branch master nothing to commit, working directory clean #testing分支上的aaa文件 [:~/git_data]# git checkout testing Switched to branch ‘testing‘ [:~/git_data]# cat aaa [:~/git_data]# echo testing >> aaa [:~/git_data]# git commit -am "modified add testing" [testing 33e4aa4] modified add testing 1 file changed, 1 insertion(+) [:~/git_data]# cat aaa testing #合并 [:~/git_data]# git checkout master Switched to branch ‘master‘ [:~/git_data]# git merge testing Auto-merging aaa CONFLICT (content): Merge conflict in aaa Automatic merge failed; fix conflicts and then commit the result. #有冲突 [:~/git_data]# cat aaa <<<<<<< HEAD master ======= testing >>>>>>> testing [:~/git_data]# vim aaa #编辑aaa文件,删除多余的符号,保留我们想要的内容 master testing [:~/git_data]# git commit -am "merge testing" [master 227b961] merge testing [:~/git_data]# git status # On branch master nothing to commit, working directory clean