git分享

git

git介绍与基本原理

git介绍

概述

   git的全称为Global Information Tracker,是由Linux创始人林纳斯-托瓦兹发明的一种分布式版本工具,最开始用以管理Linux系统版本的控制,现已被很多企业广泛用以小型、中型、大型项目的版本控制。其主要作用是备份、回溯、共享软件项目,有着速度快、完全分布式、允许成千上万个并行开发的分支、有能力高效管理类似 Linux 内核一样的超大规模项目等特点。

git分布式管理

   在git分布式版本控制系统中,客户端并不只提取最新版本的文件快照,而是把原始的代码仓库完整地镜像下来。这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。这类系统都可以指定和若干不同的远端代码仓库进行交互。因此,你就可以在同一个项目中,分别和不同工作小组的人相互协作。你可以根据需要设定不同的协作流程。其工作方式如下图:

在这里插入图片描述

git与svn

在这里插入图片描述

   从上图可以看到,版本控制工具从集中式发展到分布式,花了将近20年的时间,现如今市面上使用较多的是svn以及git这两种工具,他们各自的优缺点,可以查看svn与git的比较

git原理

.git重要目录以及文件介绍

   当你在一个新目录或已有目录内执行git init时,Git会创建一个.git目录,其结构大致如下:

drwxr-xr-x   2 mi mi  4096 2月   2 11:38 branches
-rw-rw-r--   1 mi mi    25 4月  16 20:44 COMMIT_EDITMSG
-rw-r--r--   1 mi mi   314 2月  17 11:53 config
-rw-r--r--   1 mi mi    73 2月   2 11:38 description
-rw-r--r--   1 mi mi    99 4月   2 20:05 FETCH_HEAD
-rw-rw-r--   1 mi mi   541 2月  20 20:57 gitk.cache
-rw-rw-r--   1 mi mi    23 3月  24 14:16 HEAD
drwxr-xr-x   2 mi mi  4096 2月   2 11:38 hooks
-rw-rw-r--   1 mi mi 17954 4月  16 20:44 index
drwxr-xr-x   2 mi mi  4096 2月   2 11:38 info
drwxr-xr-x   3 mi mi  4096 2月   2 11:38 logs
drwxr-xr-x 240 mi mi  4096 4月  16 20:44 objects
-rw-rw-r--   1 mi mi    41 4月   7 16:05 ORIG_HEAD
-rw-r--r--   1 mi mi   179 2月   2 11:38 packed-refs
drwxr-xr-x   5 mi mi  4096 4月   7 16:05 refs

   其中最重要的几个结构介绍如下:

  1. config文件:包含项目特有的配置选项;
  2. info目录: 保存了一份不希望在.gitignore文件中管理的忽略模式的全局可执行文件;
  3. hooks目录:保存了客户端与服务器端钩子脚本;
  4. HEAD文件:指向当前git分支;
  5. object目录:存储所有数据内容;
  6. refs目录:存储指向数据分支的提交对象的指针;
  7. index文件:保存了暂存区域信息,快照索引。
git工作区域

在这里插入图片描述

   从上图可以清楚的看到,本地使用git时,有3个工作区域:工作目录、暂存区、本地仓库。

  • 工作目录:指从本地仓库取出某版本的所有目录与文件;
  • 暂存区:讲修改的文件添加索引(快照)后的状态,index文件
  • 本地仓库:存有完整代码的集合,用以管理版本

   从而我们可以总结出,基本的git工作流程如下:

  1. 在工作目录中修改某些文件;
  2. 对修改后的文件进行快照,然后保存到暂存区域;
  3. 提交更新,将保存在暂存区域的文件快照永久转储到git目录中。

   除了本地这3个状态,其实还有一个叫远程分支,即远程代码仓库,一般存储着该项目最完整的代码,再进行本地开发前,一般要同步远程代码仓库中的代码,以保证代码的同步。

git快照

   传统的VCS关心的是文件内容的具体差异,而git关系的是文件数据整体是否发生了变化,传统的VCS工作方式如下图,其每个版本中记录着各个文件的具体差异:

在这里插入图片描述

   git则并不保存这些前后变化的差异数据,git更像是把变化的文件作快照后,记录在一个微型的文件系统中。每次提交更新时,它会纵览一遍所有文件的指纹信息并对文件作一快照,然后保存一个指向这次快照的索引。为提高性能,若文件没有变化,git不会再次保存,而只对上次保存的快照作一链接。其工作方式如下图:

在这里插入图片描述

   正是git这种工作方式,使其颠覆了传统VCS的套路,越来越被推崇。

git完整性

在这里插入图片描述

   如上图所示,git使用SHA-1算法计算数据的校验和,通过对文件的内容或目录的结构计算出一个SHA-1哈希值,作为指纹字符串。该字串由40个十六进制字符(0-9及a-f)组成,看起来就像是:

760ca66a1546160113df602a5b1edda24b0bb98a

   在保存到git之前,所有数据都要进行内容的校验和(checksum)计算,并将此结果作为数据的唯一标识和索引。因此如果文件在传输时变得不完整,或者磁盘损坏导致文件数据缺失,git都能立即察觉, 从而保证了git数据的完整性以及安全性。

git对象

   git是一套内容寻址文件系统,这种说法的意思是,git从核心上来看不过是简单地存储键值对(key-value)。它允许插入任意类型的内容,并会返回一个键值,通过该键值可以在任何时候再取出该内容。git所有内容以tree、blob对象以及commit存储,其中tree对象对应于Linux中的目录,blob对象则大致对应于inodes或文件内容,commit为一个修改的快照。下图是一个简单的git项目存储结构图:

在这里插入图片描述

   存储git对象的目录就在objects,当git添加一个对象后,可以在objects目录下看到一个文件。这便是git存储数据内容的方式──为每份内容生成一个文件,取得该内容与头信息的SHA-1校验和,创建以该校验和前两个字符为名称的子目录,并以(校验和)剩下38个字符为文件命名(保存至子目录下)。

   进入项目的目录,在终端输入以下指令,即可看到git存储的所有对象。

$ find .git/objects -type f

.git/objects/76/5a5cf64fe3b1a8d3dc1cabf2045a134cdde824
.git/objects/76/0ca66a1546160113df602a5b1edda24b0bb98a
.git/objects/76/1d169fefbe8577272be4a3bf569b48139f62e0
.git/objects/76/2e0211d471f9ffc57b2c8da4d2abc18479eb25
.git/objects/d6/1307ccaa342049d8ba9c7a5e6545edb4a5f622
.git/objects/d6/e8ece936713f55af69eca275459ce6fbd19084
.git/objects/d6/48fcee7a49f0c1676de9eea6eebb575308ae72
.git/objects/68/d5ed6705ca88879118b594256df63f0d5ad68f
.git/objects/21/f9817189ab6b807e78a1b6cd19baf0497c11e9
...

   使用以下指令,可以看到对象所存储的类型:

git cat-file -t 765a5cf64fe3b1a8d3dc1cabf2045a134cdde824
blob
git cat-file -t 761d169fefbe8577272be4a3bf569b48139f62e0
tree
git cat-file -t 760ca66a1546160113df602a5b1edda24b0bb98a
commit

   使用以下指令,可以看到对象所存储的内容:

$ git cat-file -p 760ca66a1546160113df602a5b1edda24b0bb98a
tree cd04844da69b1b5f1bc893b188fcb3bdf07b3917
parent 292dc4eb120cab96eb8eea1fd5c8b6c9834db46e
author KidSea <594643219@qq.com> 1553173451 +0800
committer KidSea <594643219@qq.com> 1553408224 +0800

add basemodelfragment
git cat-file -p 761d169fefbe8577272be4a3bf569b48139f62e0
040000 tree c5d48785dc0218b16f1563609069b442ea8ce922	musicplayer
git cat-file -p c5d48785dc0218b16f1563609069b442ea8ce922
100644 blob e8bfcf05a48f9655a9dcdf51a57e82f6d9717681	MusicApplication.java
040000 tree ac16eb60b1610fe52fda6492a926a16c37b9c78c	base
040000 tree 8a751b9740e53f5ef82092bdbf0b1ee8c66de841	ui
040000 tree ce61d25e48e3bc41cc626d74ed44f1ff0ee62f0c	utils
040000 tree d6d6195a28d88033043e0a6e8dbde91002e65796	widget

   从tree输出的结果,也可以验证,前面所说的,其代表项目的目录结构。

git基本使用

   git的使用网上有很多,这里不在赘述,推荐一本git的基本教程《Pro Git》,之前写过一篇git教程也可以参考下。

git工作流

   推荐一篇好文章深入理解学习Git工作流

repo介绍

   repo是谷歌基于python开发的一个管理git仓库的自动化脚本,它的出现不是为了代替git而是为了更好的管理git,关于其原理以及实现,这里推荐一篇以前同事写的一篇文章repo介绍

   对于应用开发或者系统开发时,当一个项目达到一定程度,不免会创建很多Project或者Module,这时候就可以使用repo来管理项目,能够提升一定的工作效率。

automerge介绍

   AutoMerge概念的提出是基于Android系统多分支,多渠道的情境下,这种时候,产商们往往会维护很多代码分支,而很多代码是通用的,实现自动的代码流,能够减轻日常开发的工作量,提升工作效率,减少维护成本。

   这里不在赘述其介绍,推荐一篇以前同事写的文章一种Android多分支的自动合并方案

   这个技术可能应用层面使用的概率较少,但是项目达到一定规模后可能也可以尝试使用该技术。

git开发工具介绍

   由于笔者习惯使用Linux系统以及Android Studio(简称AS)进行开发,所以下面将对推荐Linux以及AS中好用的git管理工具。

Linux

tig

   tig是Linux系统下用以方便查看git commit信息的工具。

安装:sudo apt-get install tig

使用方式:
打开terminal,进入项目根目录(.git所在的根目录),输入tig
键盘上下选择键可以选择commit信息
长按Enter键可以浏览commit详细信息
按q退出

   以下为tig的使用展示。

在这里插入图片描述

gitk

   gitk是git提供的一个gui工具,可以很清晰地查看搜索提交历史及git相关操作。

安装:sudo apt-get install gitk

使用方式:
打开terminal,进入项目根目录(.git所在的根目录),输入gitk

   以下为gitk的使用展示。

在这里插入图片描述

   通过右键我们可以执行一些简单的操作,包括基于当前提交创建tag,创建分支,reset到当前提交、revert当前提交、对比两个commit差异等,如下图。

在这里插入图片描述

   一般在开发过程中,可以结合这两个工作使用,简单的查看commit信息可以使用tig,要进行一些复杂操作或者搜索可以使用gitk。

Android Studio

Version Control

   Version Control是AS自带的类似gitk一样的版本管理工具,其功能非常强大,这里只是简单的介绍其基本使用。

使用方式:
点击View菜单,选择Tool Windows中的Version Control,此时AS底下菜单栏会出现Version Control菜单,点击即可使用

   使用效果如下:

  1. Log页面

在这里插入图片描述

   在Log页面选中一条修改记录后,右侧会显示出对应修改过的文件,双击文件可打开该次提交修改了什么内容,如下。

在这里插入图片描述

  1. Local Change页面

在这里插入图片描述

   其他的就不再介绍了,读者可以自己体验下,这里再介绍下使用Version Control解决代码冲突的使用。

   当有本地提交与外部提交冲突时,点击Version Control中的Local Changes可以看到如下界面:

在这里插入图片描述

   点击自己解决冲突时,会出现如下页面:

在这里插入图片描述

   根据代码情况,修复好冲突后,Version Control会自动将文件加入暂存区,需要自己提交commit即可。Version Control可以极大程度减少冲突带来的不适感,能够大大提升解冲突的效率,推荐读者使用。

Annotate

   Annotate用一句话来总结就是,能让你简单直接明了的看到每一行代码是由什么人在什么时候因为什么修改的,而且还能很方便的知道当时修改了哪些文件,而哪些文件已经不存在了。

使用方式:
打开文件, 左侧空白处右键,打开Annotate,选择一个commit双击查看

   效果如下:

在这里插入图片描述
   左侧可以看到包括commit id,作者,日期,commit message和changeId等信息。双击后会弹出新的窗口,这个窗口里显示出了本次提交修改了那些文件,双击一个文件则显示本次这个文件修改了那些内容。

注:你在不同的log上点击Annotate的话,得到的是不同的结果,即每次显示的是那个版本的文件的信息,以及那个文件包括的内容的各行修改历史。

Local History

   Local History是AS中内置的一个版本管理工具,能记录12h内操作的文件,方便我们追溯一些丢失的代码。

使用方式:
1. 右键自己的项目,点击Local History下的Show History
2. 选择具体文件,右键点击Local History下的Show History

   使用展示如下:

在这里插入图片描述

   有了这样的工具,就可以避免在进行一些git操作或者是文件操作时把辛苦写好的代码误删除的风险。

参考文献

svn与git的比较

pro git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值