Git概述
引言
- 在担任开发过程中,需要进行版本管理,以利于开发进度的控制。
- 在多人开发过程中,不仅需要版本管理,还需要进行多人协同控制。
版本管理:比如我现象想做一个博客项目,我们创建了一个项目,里面有许多包、类、配置文件,称之为Version1.0吧;做好之后呢,突然又想加一个聊天功能,此时就在前面的基础上又创建新的包、类、配置文件等;可是突然你发现这个聊天功能开始设计的很不好,或者这个功能不想要了,你要退回到Version1.0版本。怎么办呢?删除新增的包、类、配置文件,但其实这是基本不可能的,或者说非常繁琐。
正常情况下,你在做好Version1.0后会复制一份放在磁盘的一个位置,称之为Version1.0_copy吧;然后接着做聊天功能,后来想推到重来时,就把原来的Version1.0_copy复制过来就好了。
但是你想啊,你不可能自己手动复制,而且还有很多的冗余,因此就要一个工具来进行版本控制,那就是Git。
介绍
Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。
Git是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。
Git环境搭建
Git安装
下载git:https://git-scm.com/downloads
安装过程:除了安装位置外,其它一直下一步即可
其它等后续补充一下////////////////???????????????????
Git应用
架构
- 版本库:工作区中有一个隐藏目录.git,这个目录不属于工作区。而是git的版本库,是git管理的所有内容;
- 暂存区:版本库中包含一个临时区域,保存下一步要提交的文件。
- 分支:版本库中包含若干分支,提交的文件存储在分支中。
工作区其实就是编写项目(代码)的区域;暂存区是临时存储编写后代码的区域;master分支是管理暂存区提交的代码的。
后续还会对这几个概念进行深入掌握。
仓库
对应的就是一个目录,这个目录中的所有文件被git管理起来。
以后会讲一个项目的根目录,作为仓库。
仓库中的每个文件的改动都由git跟踪。
新建仓库
选择一个目录,执行指令:git init
具体流程:打开D:IDEAworkspace 2_java_advancestudy_git(当然这个文件夹是我自己建的),在地址栏输入cmd并回车,打开命令行窗口,输入git init命令,新建仓库成功。此时该目录下会有一个.git文件夹,这里面存放的是暂存区和master分支。这个由Git管理,我们不用管。
工作区
执行git init的目录即为工作区,如上例:D:IDEAworkspace 2_java_advancestudy_git目录即为工作区【不包含.git目录】,简言之。该目录下除.git目录,其它区域称为工作区。
所有文件,都首先在工作区新建,然后可以存入仓库(版本库),进行版本控制。
暂存区
暂存区也在.git目录中,工作区的文件进入仓库时,要先进入暂存区。
分支
版本控制,简单说,就是记录文件的诸多版本,分支就是这些版本的最终记录位置。
基本操作
查看仓库状态
执行git status可以看到工作区中文件的状态
在目录中新建两个文件,并输入cmd打开命令行窗口在,执行git status命令。
On branch master:表示在master分支上;
No commits yet:表示暂时还未提交东西到分支;
Untracked files:表示未跟踪文件,有两个,是说这两个文件还未提交到暂存区或分支。
暂存文件
执行git add .将工作区中的所有文件全部存入暂存区
此时仍是No commits yet,说明还未提交东西到分支,因为上一步是存到了暂存区。
Changes to be committed:是说可以commit到分支;
下面两个文件颜色已经变化,且前面是new file,说明这两个文件是新文件。
提交文件
执行git commit -m "这里写提交的描述信息",作用是将暂存区的文件存入分支,形成一个版本。
这里是将两个文件从暂存区存放到分支中,其中m是message的缩写,代表着每次提交到分支时写的版本描述信息。因为提交到分支中就代表一个版本,而我们会提交几十个版本,因此要有描述信息,否则就不知道这个版本的变动是什么。
远程仓库
前面讲的仓库,其实是本地仓库。
当多人协同开发时,每人都在自己的本地仓库维护版本。
但很重要的一点是,多人之间需要共享代码、合并代码,此时就需要一个远程仓库。
远程仓库工作模式
远程仓库选型
- 有很多远程仓库可以选择,比如github,码云,这里需要说一下,其实这里准确地讲不应该说是远程仓库,而是远程仓库的服务器,或者说git服务器,我们可以在上面构建远程仓库。这两种可以注册自己测试使用,但如果是商业项目,需要更多支持需要付费。
- 公司内部也可以有自己构建的远程仓库。
- 本节以码云为例进行讲解。
基本操作
每个开发人员,在面对远程仓库时,会面临的一些基本操作。
注册git服务器账号
在码云注册账号,并登录。
进入公司后,很可能会使用公司自己搭建的git服务器,则账号向领导索要即可。
这是在码云上注册好的界面。
新建远程仓库
刚刚已经说过了,其实github和码云不算是远程仓库,而是个服务器,我们需要在其上构建自己的远程仓库。
这里仅需要输入仓库名称,其它默认,点击创建即可。仓库介绍为非必填项,公司项目仓库肯定是选择私有。
本地关联远程仓库
现在本地仓库是本地仓库,远程仓库是远程仓库,两者之间还没有关联,因此我们需要把两者关联到一起。
下面选用仓库的https协议的地址(网站上复制),讲此地址关联到本地git中。
推送文件到远程仓库
将本地仓库中已经commit的内容push到远程仓库,以共享自己的代码。
git status:先查看一下本地仓库中工作区的内容是否上传到分支中,结果是nothing to commit,working tree clean;
git remote add “https/ssh仓库地址”,作用是关联远程仓库;
git remote -v:查看远程仓库地址;
git push origin master:将本地master分支,上传到远程master分支;
弹窗:需要输入码云账号和密码,第二次可能就不需要输入了,会有记录;
master->master:本地master->远程master
再次刷新后,发现现在的仓库里面已经具有内容了。
这里再将一个小tips,假设现在在本地新建一个文件,并以此提交到暂存区、本地分支和远程仓库,然后再次刷新页面。
这里把两次本地提交的信息都列举出来了,相当于本地的所有信息在远程仓库全部保存了一份。
克隆远程仓库
如果仓库已经由别人创建完毕,我们需要其中的内容,则可以通过git clone "https地址"将其复制到本地。
我们一般进项目组的时候,仓库肯定已经建好了,第一件事就是把别人的项目clone下来。
现在我们在本地新建一个空白的,保存clone下来的项目的目录test_gitclone,进入该目录,在地址栏输入cmd进入dos命令行窗口。
代码共享
现在我们可以完成三件事:
- 在本地仓库中完成:工作区->暂存区->本地分支;
- 本地仓库上传到远程仓库;
- 远程仓库clone到本地仓库。
下面就是要开发了,当你开发了一个模块,同时开发了一个模块,之间如何协同呢?即如何协同开发呢?
现在我们本地由了两个仓库,假设这是两个程序员的本地仓库,以此来完成协同开发。
现在者两个程序员的项目进度是一致且是最新的(如果有一个不一致,就从远程clone最新的),假设上面的仓库是程序员A,下面的是我们自己。现在程序员A在ghi.txt中修改了文件,再新加一个文件(其实就是修改,怎么修改无所谓);第二步通过git add .将工作区中的所有修改添加到暂存区;第三步通过git commit -m "modify files"指令将暂存区中的所有信息保存到本地分支中。
现在程序员A本地仓库的操作已经完成,他要将自己开发的全新版本上传到远程仓库,通过git push origin master命令。
此时由于程序员A已经完成了新增功能,我们需要从远端再次把代码拉去过来(注意这次和clone的区别),命令是git pull origin master;
注意:这里colne和pull去区别,虽然两个都是从远程仓库拉取,但是clone是第一次使用,本地什么都没有的情况下拉取。
命令汇总
git remote add 表示名(origin) 远程地址 | 本地关联远程仓库 |
git push 标识名 master | 将本地仓库内容上传到远程仓库 |
git pull 标识名 master | 从远程仓库下载内容到本地仓库 |
git clone 远程地址 | 将远程仓库复制到本地,并自动形成一个本地仓库 |
这里需要说明一下:如果说我们现在又在另外一个远程仓库服务器,如github或者是gitlab上面clone了一个项目,现在从远程clone下来一个项目,需要设置git remote add 标识名(origin) 远程地址吗?不需要设置origin即可用该标识名进行push和pull操作,即该标识名是默认的。
但是如果你自己创建了一个远程仓库,和本地仓库,你开始很顶是把本地仓库的内容push到远程仓库,这之前要用git remote add 标识名(origin) 远程地址,对该远程仓库起别名,才能用别名进行push和pull。对此,抛出一个问题,如果没有起别别名,是否可以直接用仓库地址进行push和pull?
Git分支
分支简介
分支,是一个个版本最终存储的位置。
分支,就是一条时间线,每次git commit形成一个个版本,一个个版本依次存储在分支的一个个提交点上。
分支基操
现在我们做如下操作,新建一个文件夹(存放项目);用命令git init初始化仓库;里面创建a.txt文件;git add .将工作区中的内容提交到暂存区;git commit -m "add a.txt"将暂存区内容提交到本地分支,其实此时就会在master分支上创建一个节点,所有commit的内容都在这一条分支上;此时再修改文件,在a.txt中添加hello world!!;再次依次添加到暂存区和提交到本地分支,此时就又在master分支上创建了第二个节点,此时分支上的指针指向第二个节点;再新增b.txt和c.txt文件,并依次添加和新增。
查看分支
- 查看当前仓库的分支 git branch
- 仓库默认只有master分支
- 执行git commit时,默认是在master分支上保存版本
创建分支
- 在商业项目开发过程中,我们不会轻易的在master分支上做操作。
- 我们会新建一个开发用的分支,在此分支上做版本的记录。当代码确实没有问题时,才会将开发分支上成熟的代码版本添加到master分支上。
- 保证开发过程中,可以及时记录版本,又保证master分支上每个提交点都是稳健版本。
切换分支
- 默认情况下,当前使用的分支是master分支
- 可以切换到dev分支,则后续的git commit便会在dev分支上新建版本(提交点)
此时讲一个小tips:此时分支是dev,我们在工作区新建d.txt文件,并添加、提交到分支上。
现在用git checkout master分支,则工作区中的d.txt文件会自动消失;如果再切换到dev分支,d.txt文件会自动回来。
新建分支细节
新建分支后,新分支里面是空的吗?如果不是,里面默认有哪些内容?分支中包含了哪次提交??
新分支初始内容
每个分支都有一个指针,新建一个分支,首先是新建一个指针。
而且新分支的指针会和当前分支指向同一个提交点。
新分支包含的提交点就是从第一个提交点到分支指针指向的提交点。
多分支走向
在master分支和新分支,分别进行git add和git commit
分支情况如下图:
新建分支并不是新建了一条时间线,而仅仅只是新建了一个指针,指向当前分支锁指向的节点位置。因此新分支创建出来后,会和当前分支拥有完全相同的内容。
其实新建分支和当前分支拥有相同的起点,但是后面差异就会越来越大了。
新建分支和当前分支内容完全一样,意义何在??假设当前项目稳定版本在master分支上的某节点处,称为version3.0,现在要开发4.0版本,我们一定不要在master分支上直接开发,而是在此新建一个dev分支,然后进行开发,如果开发失败,就重新开发,不影响master分支,如果开发成功,则合并到master分支。
分支提交日志
用git log和git log --oneline分别查看分支的提交日志,进而看到分支中提交点的详细情况。
注意:这里还有分支提交的作者,这是前面我们设置过的,Author: YCKJ3911 <gaojuntao@cloudwalk.com>
分支合并
快速合并
三方合并
合并冲突
冲突演示
冲突解决