本章目标
1.git简述
2.基本操作
3.分支管理
4.远程操作
5.标签管理
6.多人协作
7.分支模型
1.git简述
git是一款现在最主流的分布式的版本控制器,所谓的版本控制就是这个文件的发展的各个历史都可以被查询到,我们可以把它理解成能够看到各个版本的改动的管理系统
git只能保存文件,网页,程序代码的改动,但是对于图片,二进制文件的我们只能够看到他的文件大小的改动,但具体改了什么内容,我们无从得知,只能够具体进行查看
2.基本操作
一般来说git在你的Linux的系统下默认是装好的,如果没有可以根据不同发行版具体获得它的安装指令,在这里我们给出Ubuntu和centos的shell命令
#Ubuntu
sudo apt-get install git -y
#centos
sudo yum install git -y
你可以通过
git --version
这个命令查看你的版本,如果能够正确显示就代表你的git 成功安装
2.1创建本地仓库
本地仓库是用来进行版本控制的目录,一般来说我们进行本地的版本控制需要创建一个仓库
我们可以通过创建一个文件夹然后通过
git init
我们通过ls -a查看隐藏文件能够创建出一个.git的隐藏目录就代表我们成功进行了仓库创建
这个目录是用来跟踪管理本地仓库的,我们一般来说,并不会直接对它进行修改.
我们可以看一下这个文件目录里面的东西,在这篇文章中,我们会细致介绍里面的东西
2.2认识工作区,暂存区,版本库
在这张图里面三个我们本地,我们一般把它们分为两个地方,工作区,和版本库
1.我们一般会在有.git目录同级的地方进行文件的创建与修改,这里我们一般管它叫做工作区
2.而剩下的stage,我们一般管他叫做暂存区
3.在创建仓库的时候我们,git会为我们自动创建一个master分支,通过通过一个head指针指向这个master分支的最新一次提交
4.当我们进行 git add 操作的时候会将工作区的文件提交到stage当中,暂存区的目录索引会被更新.
5.当我们进行git commit 操作的时候,才会将暂存区的内容正式写入到当前仓库的版本库中.
6.当我们仅仅是将文件复制粘贴到仓库中,就仅仅只是在工作区中增加文件,而不是在仓库中增加文件,想在仓库中增加文件就必须通过git add 和git commit 操作进行.
2,3添加文件
我们可以通过
git add [文件1] [文件2] ...
git add 可以跟不同的多个文件通过空格隔开即可
也可以通过
git add .
的方式进行添加.该方式是将当前工作区的所有文件添加到版本库中的暂存区
当我们添加完文件之后便可以通过
git commit -m "提交信息"
的方式将暂存区的文件正式写入到当前版本库中当前正在工作的分支中
在这里我们的版本库只有master分支,就是写入到这里
我们也可以通过
git status
这个指令查看当前暂存区的工作状态
在当前暂存区中因为文件都已经被提交到了master分支上,我们也就看到他说我们当前的暂存区是干净的
git log
我们可以通过git log 这个指令查看当前仓库的提交记录
我们也可以增加 --pretty=oneline的选项来减少信息
在这里我们可以看到在我们的提交的信息前面,有一大串用16进制表示的数字,这是git的版本号,它是通过内置的hash函数进行生成的,我们可以把它理解成在我们学习c++时候lambda表达式底层原理使用一个通过Unicode命名的仿函数的方式,它们是类似,都是为了保证它是唯一独特的
在我们提交完文件之后我们再次查看.git目录
他与我们第一次看到的样子是不同的
在这里我们index就是我们的暂存区
当我们进行add 操作之后文件会被暂时放到这里面
HEAD就是我们指向master分支的指针
而默认的master分支就是
我们可以看到一串数字,这个就是最新的commit id
这个可以分为两个部分来看
前面两个数字和后面的一串数字
前面两个是文件夹名
后面是文件名
我们呢可以在objects这个目录下找到这个文件
objects就是版本库中的对象库,里面创建各个版本库中各个分支的对象以及内容
当通过git add 提交之后,新创建的文件或被修改的文件就会在这个文件夹中被保存
一般来说我们是不能够直接去这个目录下去查看的,该文件是被安全哈希进行加密的
但是git给我们提供了
git cat-file -p
这个指令去查看其中的内容
在这里我们可以看到就是我们最新一次的提交
我们可以通过同样的方法可以看到,这里面放着我们的提交,创建的文件以及里面的内容
2.4修改文件
当文件被修改了我们需要重新进行add操作进行提交
我们可以通过前面说过git status操作来去查看当前缓存区的状态
也可以通过
git diff [file1]
来查看工作区与暂存区文件的不同
也可以通过git diff HEAD --文件名的方式查看当前工作区与版本库之间的不同.
2.5版本回退
版本回退的功能一般来说我们会应用于我们之前的任务出现了问题当下需要重新提交,
git 给我们提供了
git reset
这个命令来让我们进行版本回退
并给我们提供了三个选项
–sort 只会回退版本库中的版本,工作区和暂存区的内容不会发生改变
–mixed 会回退版本库中和暂存区的内容到指令版本,工作区的内容不会发生改变
–hard 会回退版本库中,暂存区,工作区的内容到指定版本
在这里我们假设我们在version2的版本发生了bug,我们要回退到version1的版本
我们可以通过
git reset --选项 指定版本的commit id
来进行回退
如果我们又后悔了,也可以通过找到之前版本的commit id 来进行恢复
如果我们找不到commit id 可以通过
git reflog
这个指令来进行查看
在这里前面的一段数字就是commit id 的一部分
我们也可以根据这个短版本来进行恢复
有关于为什么git的版本回退时如此的迅速它时修改的HEAD指针的指向
2.6撤销修改
情况一:当前只有工作区有代码,但是没有add
我们可以通过
git checkout -- filename
的方式来进行i修改
也可以通过我们前面的 给git diff 指令来查看区别来进行手动修改.
在这里就不过多演示
情况2:add了,但没有commit
我们可以通过git reset 来恢复版本库和暂存区的内容到指定版本,HEAD表示当前版本
HEAD^表示上一个版本
HEAD^^表示上两个版本
以此类推
然后再接着用给git checkout – filename
来进行我们情况一的修改
也可以通过当前git reset --hard来进行修改,直接回退到当前版本
情况3:add了也commit了
我们可以通过
git reset --hard HEAD^来全部回退到上一个版本
2.7删除文件
我们要删除一个我们已经commit 操作的文件可以如下操作
可以自己手动删除
然后重新提交,如果出现如下警告可以带上 -A参数来添加删除操作到暂存区
你的git 版本应该时1.x的版本
也可以使用
git rm
来进行删除,这个操作相当于删除加上add 再这之后你只需要提交一次即可
3.分支管理
分支的出现,能够让我们进行多人协作开发,在最开始我们说过在最开始我们说过git会在我们初始化的时候给我们提供一条默认的master分支,我们可以围绕这个master分支来进行管理,创建出新的分支分别进行开发,互相不干扰
3.1创建分支
我们可以通过
git branch
的指令进行分支的查看
在这里*表示HEAD指针指向的分支,也就是我们当前正在工作的分支
也可以通过这个指令+名字的方式来进行分支创建
git branch dev
我们可以看到在这里多出了一条分支
3.2分支切换
我们可以通过
git checkout 分支名
的方式来进行分支切换
在这里我们在dev分支进行提交的时候,我们再次切换到master分支的时候发现
二者仓库的格式完全不同
因为dev比master多一次提交二者因此不同
3.3分支合并
为了在master分支上能够看到dev分支的东西我们需要在master分支上来进行合并dev分支的东西
fast-forword表示快进模式
后面我们会提及这个东西的
我们就相当于将master的分支进行更新了
3.4删除分支
dev分支再我们进行与master分支进行合并之后,它就没有存在的意义了
我们可以删除它,删除操作不能在被删除的分支中进行
3.5合并冲突
想象一下这个情况,我们基于master分支的时候,创建出一个新分支,master分支和这个新分支都同时对一个文件进行操作.在这种情况下,我们我们进行合并就一定会出现内容冲突,在git中,它会让我们自己解决,再重新提交
我们模拟下这个环境,我们也可以通过git checkout -b 分支名
的方式来进行创建新的分支
,当我们进行合并的时候
它会主动的提示我们进行修改
在等号上面的就是我们当前工作路径上的内容,等号下面的就是我们合并路径上的内容
在这里面我们保留最后合并路径上的内容,再重新提交
3.6分支模式
一般来说,我们我们进行提交和合并的时候,一般是用fast_forword的方式来进行合并的
但是这种模式有一个弊端.
我们在进行合并的时候,并不知道我们的提交的分支信息,它们被混在了一起
就像这样.
在git中是支持我们使用no-ff的选项来解除fast_forword
我们模拟下这个环境
3.7分支合并策略
一般来说跑在master分支上的内容,我们把它认为是稳定版本,当我们进行合并的时候
一般来说是在dev我们自己拉出来的分支上进行合并,然后再去master分支上进行合并
3.8bug分支
在这里我们假设一种情况,在当前dev分支中,但是我们突然发现了bug,这个时候我们要解决这个bug,一般我们会在当前的master的分支中再拉出来一条分支来进行解决.
我们一般dev分支去解决因为这个分支是负责开发任务的,在下面我们模仿一下下面的
环境
当我们发先bug的时候我们可以使用
git stash这个操作来存储当前工作区的内容假设我们当前最后一行少了一个1,让程序报错
我们切会master分支
基于这次提交,我们创建一个fix_bug的分支来进行修复bug
重复我们的合并分支
我们再回到当前的dev分支用
git stash pop
命令将之前的工作内容放出来
这里的操作也可以用git stash apply
来进行恢复,但是这种办法,只会将工作区的内容恢复,并不会将stash中的内容删除,如果想要删除仍需git stash drop
这个命令来进行删除
在我们将master完整的无bug分支放出来前,我们需要先将当前dev分支中与master分支进行合并,因为master分支相当于多一次提交.
我们将修改完的东西保存,提交之后再次回到master分支进行合并
此时的dev和fix_bug分支全部都已经无用了.我们可以删除.
3.9删除临时分支
在许多情况下我们可能会有需求变更导致当前分支直接在没有合并到master之前就被砍掉了,但是在git中没有合并到主分支的其他分支在合并前是不允许我们删除的,但是可以强制删除可以通过
git branch -D
4.远程操作
4.1新建远程仓库
远程仓库的平台可以选择GitHub但是国内的情况,可能很难登入,除非魔法,在这里我们以国内的gitee作为平替
在我们创建远程仓库的时候,我们,我们可以设置一些选项,开源和不开源的区别,在前面的Linux操作里面我们已经提过在这里不做过多的解释.
接着初始化仓库在这里我们可以选择仓库的主要语言.关于.gitignore这个文件我们后面会进行介绍.
设置模板这个选项,readme文件就是这个仓库的使用说明书
这个issue就是我们其他并不是仓库成员的人想要对仓库的内容找出bug可以提起issue
让仓库的管理员去解决.
pull request这个文件,是其他分支如果想向master分支进行合并可以提起的这个,让管理员进行操作.在前面我们说过master分支上跑的都是我们稳定版本的代码与程序
4.1克隆远程仓库
关于克隆仓库我们一般会选择https或者是ssh这两种协议.
当我们使用https协议的时候是没有任何需求的,我们可以直接进行克隆操作.
ssh协议使用的是公钥加密和公钥登入机制.
使用此协议需要我们将公钥放在git上进行保存由git进行管理.
下面我们分别进行演示
使用https协议我们只要使用git clone
的指令加上我们git仓库的远程地址即可.
如果我们要使用ssh协议去进行登入的话,我们需要检查我们主目录里有没有.ssh的目录
像我们这种没有的需要主动创建ssh key
ssh-keygen -t rsa -C "自己的邮箱"
在这里我们只需要一路回车即可
在这里有两个文件,前一个是私钥,我们需要自己保存,后一个是公钥,我们要将它复制到git上去
打开我们的id_rsa.pub将里面的东西复制到git上面
在gitee个人设置里面可以找到添加公钥的选项.名称可以随意.
当我们将公钥配置好了即可按照仓库给的指令进行clone仓库
我们可以通过
git remote -v
的指令来查看当前仓库的权限
可以看到在当前仓库我们有拉取文件和推送文件的权限
4.2推送到远端仓库
在进行远端仓库的推送的时候,我们要先检查,我们本地的config有没有设置user.email和user.name两个配置项,如果之前没有可以通过
git config user.name ""
git config user.email ""
如果希望本地所有仓库都使用一个提交邮箱和用户可以带上--global
选项
我们创建一个文件,然后先提交到本地仓库,最后再向远端进行推送.
可以使用git push这个指令
git push 远端仓库名 本地分支名:远端分支名
如果本地分支名和远端分支名相同,则可以省略:后面的内容只写本地分支名
我们可以看到我们本地成功推送了
4.3拉取远端仓库
我们在这里模拟下本地仓库并不是最新的情况.
我们可以用git pull 从远端进行一个拉取
这个指令的格式如下
git pull 远端仓库名 远端分支名:本地分支名
同样的如果本地分支和远端分支名是一样的我们可以省略
4.4.gitignore文件
有些时候,我们要向远端仓库,进行提交的时候,难免会提交一些工程文件,但是我们并不需要.gitignore这个文件就会忽略以特定后缀为结尾的文件.
如果我们想在这=某个文件不使用这套规则,可以使用
!加文件名来规避
同时也使用git check-ignore 文件名
的方式来进行查看是因为什么原因,本地文件被什么忽视了
4.5给git指令配置别名
git config --global alias.st status
alias.别名 指令名.
给git指令配置别名的方式是与我们Linux的操作类似的.
在这里不过多赘述
–global的选项同样是全局配置
5.标签管理
5.1创建和推送标签
在我们之前的生活中绝对碰过什么v0.9,版本,v1.0版本
标签是对某一次具体提交的标识
我们可以通过
git tag +标签名
的方式进行打标签
这种形式打的标签是基于当前分支的最新提交的
我们创建一个新的文件并且打上标签
我们也可以在后面跟上commit id 来对某一次具体的提交进行打标签
我们也可以通过git show+标签名
的方式来查看具体信息
我们可以用git push origin <tagname>
的指令向远端推送标签
但是在这个里我们创建两个标签,用git push origin --tags
的指令来进行推送
这个指令是推送本地所有的标签
查看我们的远端,已经成功推送了
5.2删除标签
我们通过git tag -d 标签名的方式来进行删除
在本地删除之后,我们可以用git push 远程仓库名:标签名
因为我们要删除的远端的标签
刷新下远端仓库,我们已经成功删除了
6.多人协作
git的出现让我们的多人开发成为了可能
在这里我们模拟两种常见多人开发场景
6.1情况1
在多人开发中,我们可以用Linux和window两个主机来分别模拟两个用户
一般来说,我们是不能够再master分支上直接进行开发的,我们再远端先创建一个dev分支
我们可以用 git branch -r
查看远端分支
接着再本地创建dev分支,并与远端的仓库的dev分支建立连接
建立连接的方式很简单,我们至于要再这个git checkout -b 分支名这个指令后面跟上远端仓库名/远端分支名
即可
我们再这个文件下更新一个文件并提交
在这里我们就是已经成功推送了
在Linux的用户这里我们的并没有远端dev分支,我们需要git pull 拉取一下
接着我们再创建本地分支,这个时候我们不进行与远端的连接
因为我们没有进行一个本地分支与远端分支的一个连接,我们是拉不下来东西的
git branch --set-upstream-to=origin/<branch> dev
我们通过它给的连接与本地分支建立连接
出现这个是因为我们本地的提交与远端提交出现冲突,我们需要拉去一下远端的东西
远端拉取出现问题,解决冲突,重新提交
重新add commit 之后成功提交.
在这之后我们我们需要将我们开发的内容合并到master分支当中
在这里我们选择用命令行的方式,情况2我将在gitee采用pull request的方式进行提交
6.2情况2
两个用户在不同的主机上进行开发,创建两个不同的分支
我们在window下新创建分支然后创建一个新的文件并提交.
最后本地提交这个分支
我们可以看到当我们把本地分支提交到远端的时候,他就自动在远端创建分支并且建立连接了.
在这是window这个程序员噶了,我们Linux要继续接受它的工作
我们可以提起pull request来进行合并
合并成功了!!!
7.分支模型
分支模型有很多种,具体要看公司的安排
详情可以转到这篇博客
https://blog.csdn.net/howeres/article/details/124927771