Git版本控制工具的使用

1. 前言

1.1 版本控制

什么是版本控制:是一种记录若干文件内容变化,以便将来查阅特定版本修订情况的系统。

文件补丁:是一种特定格式的文本文件,记录着对应文件修订前后的内容变化。

  1. 本地版本控制系统:使用简单的数据库来记录为文件的历次更新差异。

在这里插入图片描述

  1. 集中化的版本控制系统(Cnetralized Version Control System,CVCS)
    • 目的:让不同系统上的开发者协同工作。
    • 原理:使用一个单一的集中管理的服务器,保存所有文件的修改版本,而协同工作的人们都通过客户端连接到这台服务器,取出最新的文件或者更新文件。
    • 工具有:SVN
  • 缺点:中央服务器的单点故障。如果中央服务器的磁盘发生故障,并且没做过备份或者备份得不够及时的话,还会有丢失数据的风险。最坏的情况是彻底丢失整个项目的所有历史更改记录,被客户端提取出来的某些快照数据除外,但这样的话依然是个问题,你不能保证所有的数据都已经有人提取出来。

在这里插入图片描述

  1. 分布式版本控制系统(Distributed Version Control System, DVCS)
    • 原理:客户端不只提取最新版本的文件快照,而是把原始的代码仓库完整地镜像下来。
    • 优点:当任何一处协同工作用的服务器发生故障,都可以使用任何一个镜像出来的本地仓库恢复。
      在这里插入图片描述

1.2 Git历史

  1. 1991-2002年间:绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐事务。
  2. 2002年起:项目组开始启用分布式版本控制系统 BitKeeper 来管理和维护代码。
  3. 2005年,Git开始诞生。

1.3 Git基础要点

快照:是数据存储的某一时刻的状态记录。

  • 原理:快照锁定物理单元内容,并记录本次快照和上一次快照的所对应的物理地址(或者是上一层逻辑地址)的差异。
  • 快照仅仅记录逻辑地址和物理地址的对应关系

备份:是数据存储的某一时刻的备份。

快照和备份的区别:

  1. 备份的数据安全性更好:如果原始数据损坏,快照回滚是无法恢复出正确的数据,而备份可以。
  2. 快照的速度比备份快:生成快照的速度比备份快。
  3. 占用空间不同:备份占用双倍的存储空间,而快照所占用的存储空间则取决于快照的数量以及数据变动情况。极端情况下,快照可能会占用1%不到的存储空间,也可能占用数十倍的存储空间。(对同一份数据,同时做相同数量的快照和增量备份的话,备份还是会占用更多的空间)

1.3.1 直接快照

  1. Git只关系文件数据的整体是否发生变化,而其他版本控制系统则只关心文件内容的具体差异。这类系统(CVS、Subversion(SVN)、Perfore等等)每次记录有哪些文件作了更新,以及都更新了哪些行的具体内容。
  2. Git并不保存这些前后变化的差异数据。实际上,Git 更像是把变化的文件作快照后,记录在一个微型的文件系统中。每次提交更新时,它会纵览一遍所有文件的指纹信息并对文件作一快照,然后保存一个指向这次快照的索引。为提高性能,若文件没有变化,Git 不会再次保存,而只对上次保存的快照作一连接。

1.3.2 本地执行

​ 在 Git 中的绝大多数操作都只需要访问本地文件和资源,不用连网。但如果用 CVCS 的话,差不多所有操作都需要连接网络。因为 Git 在本地磁盘上就保存着所有有关当前项目的历史更新,所以处理起来速度飞快。

1.3.3 数据完整

​ 在保存到 Git 之前,所有数据都要进行内容的校验和(checksum)计算,并将此结果作为数据的唯一标识和索引。换句话说,不可能在你修改了文件或目录之后,Git 一无所知。这项特性作为 Git 的设计哲学,建在整体架构的最底层。所以如果文件在传输时变得不完整,或者磁盘损坏导致文件数据缺失,Git 都能立即察觉。

1.4 Git基本理论(核心)

  1. 对于任何一个文件,在Git内都只有三种状态

    • 已提交(commited):表示该文件已经被安全地保存在本地数据库中。
    • 已修改(modified):表示修改了某个文件,但还没有提交保存。
    • 已暂停(staged):表示把已修改的文件放在下次提交时要保存的清单中。
  2. 上述三种工作状态对应文件流转的三个工作区域:

    • Git的本地数据目录
    • 工作目录:从项目中取出某个版本的所有文件和目录,用以开始后续工作。
    • 暂停区域。
  3. 每个项目都有一个 git 目录,它是 Git 用来保存元数据和对象数据库的地方。每次拷贝时拷贝的即是该目录里面的数据。

Git本地有三个工作区域:工作目录、暂存区和资源库。如果加上远程的git仓库(Remote directory)就分为四个区域。
在这里插入图片描述

基本的Git工作流程:

  • 1)在工作目录中修改某些文件;
  • 2)对这些修改了的文件作快照,并保存到暂停区域;
  • 3)提交更新,将保存在暂停区域的文件快照转储到git目录中。
    在这里插入图片描述

​ 从文件所处的位置来判断状态:如果是 git 目录中保存着的特定版本文件,就属于已提交状态;如果作了修改并已放入暂存区域,就属于已暂存状态;如果自上次取出后,作了修改但还没有放到暂存区域,就是已修改状态。
在这里插入图片描述

1.5 安装及配置

1.5.1 安装

  1. 直接使用命令安装。使用如下命令在linux(CentOS)安装git。

    yum install git-core
    
  2. 从github中下载源代码安装

    • 1)删除已安装的git。yum -y remove git
    • 2)在github(https://github.com/git/git/releases)中下载最新的git版本;
    • 3)使用命令tar -zxvf xxx 解压;
    • 4)安装编译源码需要的依赖。命令如下:yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUtils-MakeMaker
    • 5)编译git源码,进入/usr/local/xxx 目录; make prefix=/usr/local/git all
    • 6)安装git 至/usr/bin/git路径 make prefix=/usr/local/git install
    • 7)配置环境变量 vim /etc/profile
    • 8)使环境变量可用 source /etc/profile
    • 9)查看Git是否安装完成 git --version

windows下各个命令的作用:

  • Git Bash:Unix与Linux风格的命令行,使用最多;
  • Git CMD:Windows风格的命令行
  • Git GUI:图形界面的Git

1.5.2 配置

  1. 用户信息

    git config --global user.name "wei lin"
    git config --global user.email "wei_lin527@163.com"
    

    每次 Git 提交时都会引用这两条信息,说明是谁提交了更新,所以会随更新内容一起被永久纳入历史记录。

  2. 文本编辑器

    git config --global core.editor emacs  #将文本编辑器设置为emacs
    

    Git 需要你输入一些额外消息的时候,会自动调用一个外部文本编辑器给你用。默认会使用操作系统指定的默认编辑器,一般可能会是 Vi 或者 Vim。

  3. 查看配置信息

    git config --list
    
  4. 查看系统配置信息

    git config --system --list
    

在这里插入图片描述

Git相关配置文件:

  • 1)D:\Git\etc\gitconfig :Git安装目录下的gitconfig --system级别;
  • 2)C:\Users\Administrator.config:只适用于当前登录用户的配置 --global级别。

这里可以直接编辑配置文件,通过命令设置后会响应到这里。

  1. 设置本机绑定SSH公钥,实现免密码登录

    • 生成公钥;

      # 生成公钥。在git bash中使用如下命令
      ssh-keygen
      

      出现的选择直接回车即可:

在这里插入图片描述

  • 在C:\Users\Administrator.ssh目录下。第一个是自己的密钥,第二个是公钥。

  • 将公钥信息public key添加倒码云账户中;

1.6 Linux常用命令

  1. cd 更改目录;
  2. cd … 回退到上一级目录,直接cd进入默认目录;
  3. pwd 显示当前所在的目录路径;
  4. ls(ll)列出当前目录中的所有文件,ll列出的内容更加详细;
  5. touch 新建一个文件,如touch index.js,就是在当前目录下创建一个node.js文件;
  6. rm 删除一个文件;
  7. mkdir 新建一个文件夹;
  8. rm -r 删除一个文件夹, rm -r src 删除src目录;
  9. mv 移动文件,mv index.html src index.html,其中src是目标文件夹;
  10. reset 重新初始化终端 / 清屏;
  11. clear 清屏;
  12. history 查看历史命令;
  13. help 帮助;
  14. exit 退出
  15. # 表示注释

2. Git基础

Git常用命令如下图所示:

  • add
  • commit:提交到本地仓库。
  • push:本地仓库提交到远程。
  • fetch/clone:从远程克隆到本地仓库。
  • pull:从远程仓库中获取一个项目到工作目录。
  • checkout
    在这里插入图片描述

2.1 获取项目的Git仓库

本地仓库搭建。有两种方法:

  • 1)在现存目录下,通过导入所有文件来创建新的Git仓库。
  • 2)从已有的Git仓库克隆出一个新的镜像仓库。
  1. 本地搭建

    • 创建新的仓库(文件夹),使用如下命令进行Git管理:

       git init
      
    • 初始化后,在当前目录下会出现一个名为 .git 的目录,所有 Git 需要的数据和资源都存放在这个目录中。不过目前,仅仅是按照既有的结构框架初始化好了里边所有的文件和目录,但我们还没有开始跟踪管理项目中的任何一个文件。
      在这里插入图片描述

  2. 克隆远程仓库

    使用如下命令克隆一个项目和它的整个代码历史(版本信息)

    git clone [url]
    
    # 例如
    git clone https://gitee.com/hms-core/hms-ecommerce-demo.git
    

在这里插入图片描述

2.2 文件操作

文件的四种状态:

版本控制就是对文件的版本控制,要对文件进行修改、提交等操作,需要知道文件处于什么状态。

在这里插入图片描述

  • 1)Untracked:未跟踪,此文件在文件夹中,但并没有加入到git库,不参与版本控制,通过git add状态变为 Staged。

    • 使用命令 git add 开始跟踪一个新文件。

      git add README  #开始跟踪README文件
      
    • 运行git status查看状态。结果显示如下。说明文件已经是暂存状态,如果此时提交,那么文件此时的版本就被留存到历史记录中。

在这里插入图片描述

  • git add 后可以接要跟踪的文件或目录的路径。

  • 如果是目录的话,就说明要递归跟踪所有该目录下的文件。

  • 2)Unmodify:文件已经入库,未修改。即版本库中的文件快照内容与文件夹中完全一致。如果该文件被修改,则变为Modified;如果使用git rm移除仓库,则变为Untracked文件。

  • 3)Modified:文件已修改,仅仅是修改,并没有进行其他操作。

    • 通过 git add可进入暂存 Staged状态;

      # git add .   	添加所有文件到暂存区
      # git add [filename]  添加具体的文件到暂存区
      
    • 使用 git checkout则丢弃修改,返回到Unmodify状态。该命令是从库中取出文件,覆盖当前修改的文件。

      # git commit -m	"message"	提交暂存区中的内容到本地仓库  -m表示提交信息message
      

    在这里插入图片描述

  • 4)Staged:暂存状态。

    • 执行git commit将修改同步到库中,这时库中的文件和本地文件又变为一致,文件为Unmodify状态。
    • 执行git reset HEAD filename取消暂存,文件状态为Modify

查看文件的状态

# 查看指定文件状态
git status [filename]

#查看所有文件状态
git status

忽略文件 git ignore (上传不会被选中)

在项目中,需要创建一个 .gitignore文件来存储那些不需要进行跟踪(不需要上传的文件),即列出要忽略的文件模式。

文件.gitignore的格式规范如下:

  • 所有空行或者以注释符号 # 开头的行都会被 Git 忽略。
  • 可以使用标准的 glob 模式匹配。glob模式是指shell所使用的简化了的正则表达式
    • *匹配 0个或多个任意字符;
    • [abc] 匹配任何一个列在方括号中的字符。该例要么匹配一个a,要么一个b,要么一个c;
    • ?表示只匹配一个任意字符;
    • [0-9]表示匹配到所有0到9 的数字。如果在方括号中使用段划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配。
  • 匹配模式最后跟反斜杠( / )说明要忽略的是目录。
  • 要忽略指定模式以外的文件或目录,可以在模式前加上惊叹号( ! )取反。
# .gitignore文件例子
*.a			# 忽略所有以 .a结尾的文件
!lib.a		# 但除 lib.a 以外
/TODO		# 仅仅忽略项目根目录下的TODO文件,不包括其他目录的TODO文件
build/		# 忽略 build/ 目录下的所有文件
doc/*.txt   # 会忽略doc/notes.txt,但不包括doc/server/arch.txt

3. Git分支

3.1 分支的概念

Git保存的是一些列的文件快照,而非是文件差异或者变化量。

​ 在Git提交时,会保存一个提交对象,它包含一个指向暂存内容快照的指针、作者和相关附属信息,以及一定数量(可能没有)指向该提交对象直接祖先的指针:第一次提交是没有直接祖先的,普通的提交有一个祖先,由两个或多个分支合并产生的提交则有多个祖先。

​ 当使用 git commit 新建一个提交对象前,Git 会先计算每一个子目录的校验和,然后在 Git 仓库中将这些目录保存为树tree对象。之后 Git 创建的提交对象,除了包含相关提交信息以外,还包含着指向这个树对象(项目根目录)的指针,如此它就可以在将来需要的时候,重现此次快照的内容。
​ 现在,Git 仓库中有五个对象:三个表示文件快照内容的 blob 对象;一个记录着目录树内容及其中各个文件对应 blob 对象索引的 tree 对象;以及一个包含指向 tree 对象(根目录)的索引和其他提交信息元数据的 commit 对象。如下图所示(表示一次提交后仓库里的数据):

在这里插入图片描述

​ 作些修改后再次提交,那么这次的提交对象会包含一个指向上次提交对象的指针(译注:即下图中的parent 对象)。两次提交后,仓库历史如下图所示:

在这里插入图片描述

Blob,Binary Large Object的缩写,代表二进制类型的大对象

3.2 Git分支中常用的命令

git branch   	# 列出所有本地分支
git branch -r 	# 列出所有远程分支
git branch [branch-name]  # 新建一个分支,但仍处于当前分支,不会自动切换到新建的分支中
git chechout -b [branch-name] # 切换分支
git merge [branch] 	# 合并指定分支到当前分支

git branch -d [branch-name]	 # 删除分支
# 删除远程分支
git push origin --delete [branch-name]
git branch -dr [remote/branch]

git chechout -b [branch-name] # 切换到分支,相当于如下两条语句:

git branch [branch-name]
git checkout [branch-name]

master主分支应该非常稳定,用来发布新的版本,一般情况下不允许在上面工作,工作一般在新建的dev分支上进行。工作完后,若需要发布,或者dev分支代码稳定后可以合并到主分支master上

git checkout master
# 该命令做了两件事情:
## 1. 将HEAD指针移动到master分支
## 2. 把工作目录中的文件换成了 master 分支所指向的快照内容。

3.3 基本的分支与合并

实际工作中的工作流程:

  1. 开发某个网站;
  2. 为实现某个新的需求,创建一个分支;
  3. 在这个分支上开展工作。

假设此时,需要对项目中某个问题进行解决,那么可以按照下面的方式处理:

  • 1)返回到原先已经发布到生产服务器上的分支。
  • 2)为此次补救建立一个新的分支。
  • 3)测试通过后,将该补救分支合并,再发布到生产服务器上。
  • 4)切换到之前实现需求的分支,继续工作。

3.3.1 基本分支

前提:在项目中已经提交过几次更新。

要求:需要修补问题追踪系统上的问题。顺带说明下,Git 并不同任何特定的问题追踪系统打交道。

步骤如下:

  1. 创建解决问题的分支issue,并切换到当前分支。

    git branch -b issue
    

    上述命令的结果如下图所示:C0表示第一次Commit。切换到issue,则HEAD指针指向issue分支。
    在这里插入图片描述

  2. 在网站上进行修改并提交。

    vim update.html   # 修改内容
    git branch -a -m 'add a new footer [issue]'	# 提交
    

    上述命令完成的结果如下图所示:

    在这里插入图片描述

  3. 提交修改后,正常转换到master分支。命令运行结果与上图一致,只是HEAD指针指向了master分支。

    【注】Git 会把工作目录的内容恢复为检出某分支时它所指向的那个 commit 的快照。它会自动添加、删除和修改文件以确保目录的内容和你上次提交时完全一样

  4. 进行紧急修补。创建一个修补分支hotfix来展开工作。

    git branch -b hotfix	# 创建并切换分支
    
    vim checkFix.html		# 修补
    git commit -a -  'fixed xxx'	# 提交修补
    

在这里插入图片描述

  1. 修改完毕之后合并到主分支。

    git checkout master	# 先切换到master分支
    git merge hootfix	# 合并修补分支
    
  2. 删除修补分支。

    git branch -d hotfix
    
  3. 回到未完成工作的issue分支继续工作。

    git checkout issue
    

在这里插入图片描述

3.3.2 基本合并

对于3.3.1中hotfix与master的合并来说,master是处于hotfix分支的直接上游,Git只需要把指针横移即可到达另一个。换句话说就是顺着一个分支走下去可以到另一个分支。如上所述的分支能够直接合并并且可以删除非主分支。

而像master分支和issue分支没有上下游关系。不能够直接合并。那么如何合并issue和master分支呢???

解决方法:

由于当前 master 分支所指向的 commit (C4)并非想要并入分支issue的直接祖先,Git 不得不进行一些处理。

  • Git 会用两个分支的末端(C4 和 C3)和它们的共同祖先(C2)进行一次简单的三方合并计算( Git 为分支合并自动识别出最佳的同源合并点)。
  • Git 没有简单地把分支指针右移,而是对三方合并的结果作一新的快照,并自动创建一个指向它的 commit(C5)。我们把这个特殊的 commit 称作合并提交(merge commit),因为它的祖先不止一个。
  • 即Git 会自动创建了一个包含了合并结果的 commit 对象
    在这里插入图片描述

**然后可以直接删除issue分支。**git branch -d issue

3.3.3 冲突的合并

当修改了两个待合并分支中的同一个文件的同一部分,Git就无法干净地把两者合并到一起。这里Git作了合并操作,但是没有提交,它会停下来等你解决冲突。这里可以使用git status查看状态。

任何包含未解决冲突的文件都会以未合并(unmerged)状态列出。Git 会在有冲突的文件里加入标准的冲突解决标记,可以通过它们来手工定位并解决这些冲突。

3.4 分支管理

  1. git branch 命令不仅能创建和删除分支,如果不加参数,则表示列出当前所有的分支

    $ git branch
    * master	# *表示当前分支。如果现在提交更新, master 分支将随着开发进度前移
    
  2. git branch -v 查看每个分支最后一次commit信息。

    $ git branch -v
    * master 6381527 [ahead 1] new file test.text
    
  3. git branch --merged:查看哪些分支已经被并入到当前分支。

  4. git branch --no-merged:查看还未进行合并发分支。如果使用git branch -d name会导致删除失败。

  5. git branch -D [branch-name] 强制删除某个分支,即使该分支尚未合并,不会报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值