那些年前端接触的Git知识大全

一、Git诞生的历史

  • Git的定义

    • Git是当下最早进的开源分布式版本控制系统,能够高效便捷地管理大大小小的项目版本
    • 所谓的分布式,按个人理解就是主要专一于字,分开,分离,把某些事物分开布置在各个角落上,分布式版本控制系统不把相应的版本项目集中在一个电脑/服务器/中央服务器上,而是每一个人的电脑都保存着一个完整的版本项目。
    • 所谓的版本控制系统,通俗地说就是对一个或若干个文件的内容改动状况按照特定的版本号进行保存,以便未来浏览者快速清晰了解文件的改动信息(内容变化信息,内容改动时间,做者等)
  • Git的缔造者(father)javascript

    • 名称:Linus Torvalds 林纳斯 托瓦兹 芬兰人 现受聘于开放源代码开发实验(OSDL:Open Source Development Labs, Inc)
    • 他的自传《乐者为王》just for fun 都说通常吊炸天的大牛之牛,脾气都有些古怪,哈哈

    图片加载失败

  • Git的诞生史

    • 1991年,Linus建立可谓统治服务器的操做系统-Linux系统,因为它的快速发展Linux的代码管理成为一个大难题
    • 2002年之前,Linus其实都是经过手工方式合并世界各地开发者提交的源代码
    • 2002年,名为BitMover的这家公司出于人道主义精神免费提供BitKeeper商业版的版本控制系统的使用权
    • 2005年,但因为Linux秀儿众多,开发Samba的Andrew试图Crack BitKeeper的协议,被BitMover公司发现了,因而BitMover公司怒了,要收回Linux社区的无偿使用权
    • 不让用便本身搞一个,Linus便花费10天的时间用C语言开发了Git,日后时间,Linux的源码都是用Git管理。
    • 2008年GitHub网站上线,为开源的项目免费提供Git存储。

二、Git的版本控制系统

  • 本地版本控制系统

    • 第一代版本控制系统被称为本地版本控制系统。经过加锁将并发执行转换成顺序执行。 一次只能有一我的处理文件。具体流程以下:首先,应该把文件放在一个服务器上,方便使用者上传或下载文件;其次,任何人想对文件修改时,须要先把这个文件加锁,经过checkout指令,使得其余人没法修改;最后,当修改完成以后,须要释放锁,经过checkin指令,造成一个新的版本,存放到服务器端。第一代版本控制系统主要有 RCSRevision Control System )、SCCS。html

    • 硬盘上(本地,local computer)保存补丁集(文件修订先后的变化),经过全部的补丁,能够计算出各个版本的文件内容,大多都是采用某种简单的数据库来记录文件的历次更新差别。前端

      图片没法加载
  • 集中式版本控制系统

    • 第二代版本控制系统被称为集中式版本控制系统(Centralized Version Control Systems,CVCS),其对同步修改更加宽容,但有一个明显的限制,用户必须在容许提交以前将当前修订合并到他们的工做中。不便之处就是要联网,若中央服务器发生单机故障,宕机了,那么在这宕机期间谁都没法提交更新,也就没法协同工做,还有中央服务器丢失数据的可能等。java

    • 由下图可看到,在集中式版本控制系统中,若是服务器嗝屁了,那么全部的开发者就只能干瞪眼了!由于,SVN 对于项目的管理是依赖于服务器中的中心仓库的!咱们的更改必需要提交到服务器中的中心仓库。第二代版本控制系统主要有 CVSSubversion、SourceSafe、Team Foundation Server、SVK。git

      图片加载失败
  • 分布式版本控制系统

    • 第三代版本控制系统被称为分布式式版本控制系统(Distributed Version Control Systems,DVCS),其容许合并和提交分开。在每一个使用者电脑上就有一个完整的数据仓库,没有网络依然可使用。程序员

    • 由下图可看到,分布式版本控制系统也能够有个服务器端的仓库,用来同步各开发者的私有仓库。在分布式版本控制系统中,每一个参与者的本地也会有一个完整的仓库。及时服务器端崩溃,咱们仍然可使用 Git(仅在本地仓库管理咱们的代码),在网络具有时,再和服务器进行同步便可!第三代版本控制系统主要有 Bazaar、Git、Mercurial、BitKeeper、Monotone。github

    图片没法加载

思考:web

  1. 怎么理解分布式与集中式?(廖雪峰老师给出的理解)
    • 集中式:版本库是集中存放在中央服务器的,而干活的时候,用的都是本身的电脑,因此要先从中央服务器取得最新的版本,而后开始干活,干完活了,再把本身的活推送给中央服务器。中央服务器就比如是一个图书馆,你要改一本书,必须先从图书馆借出来,而后回到家本身改,改完了,再放回图书馆。
    • 分布式:分布式版本控制系统根本没有“中央服务器”,每一个人的电脑上都是一个完整的版本库,这样,你工做的时候,就不须要联网了,由于版本库就在你本身的电脑上。
  • SVN与GIT的特性对比:

    特性 SVN GIT
    架构模式 集中式 分布式
    安全性 较差,按期备份 高,开发者本地电脑就是一个完整的版本库
    适用性 文档管理, 代码管理,
    易用性 简单上手,对新手友好 上手困难,学习成本高但效率搞
    灵活性 较低,易发生单点故障,拉取分支 高,单机本地操做,多个备份,本地新建分支
    权限管理 拥有严格的权限管理 尚无严格权限管理,有帐号角色划分

三、Git与Github、Gitlab

  • GitHub

    • GitHub是什么?
      • 百度百科上的定义是:面向开源以及私有软件项目的代码托管平台,只支持git 做为惟一的版本库格式进行托管,故名GitHub。
      • GitHub是一个代码托管云服务网站,帮助开发者存储和管理其项目源代码,且可以追踪、记录并控制用户对其代码的修改。甚至能够把它看成存储代码等的网盘,用来存储任何东西。
    • Github与Git的关系?
      • GitHub不等同于Git,两者彻底是不一样物,不能搞混,相似地,捋一捋java与javascript、周杰与周杰伦的关系,或许你能从中领悟到一些真谛。
      • Git只是一个命令行工具,一个分布式版本控制系统。正是它在背后管理和跟踪你的代码历史版本,比如一个时光机,让你在代码出错时不至于手忙脚乱,能快速回退以前的历史版本。
      • GitHub是一个代码托管网站,背后使用Git做为版本管理工具(而非svn)。主要服务是将你的项目代码托管到云服务器上,而非存储在本身本地硬盘上。
    • GitHub能作什么?
      • 托管代码,管理项目的历史版本
      • 查找查看开源项目的介绍及源码等
      • 使用GitHub Pages更能,可以搭建属于本身的我的博客
      • 分享技术心得、项目等,在线交流,提高本身的影响力
  • Gitlab

    • Gitlab是什么?
      • GitLab 是一个用于仓库管理系统的开源项目,使用Git做为代码管理工具,并在此基础上搭建起来的web服务(在线代码仓库管理软件)。
    • Gitlab与GitHub的区别?查看对比
      • GitHub上存放的项目是面向世界开源的,若想存放私人仓库,得交钱,交钱使你的项目变得更隐私
      • GitHub是在线代码仓库,全世界只有GitHub一家,你们把代码存储在人家的服务器上
      • GitLab比较私密,用于企业、学校或者我的的代码托管库
      • Gitlab至关于小型的GitHub,你能够在本地搭建一个属于你本身的相似GitHub仓库,让小伙伴把代码存储在上面,这样代码只有大家几我的能看见,可是你要存在GitHub上,全世界都能看见
    • Gitlab能为咱们作什么?
      • Git仓库管理、代码审查、问题跟踪、动态订阅、wiki等功能,GitHUb能作的Gitlab也能作(99%)。
  • 国内代码托管平台

四、Git的工做原理

咱们使用Git来记录每一次文件内容的变动,版本的更新,清晰地比较出不一样版本的内容差别;可使用Git在项目的历史版本自如地进行切换;还可使用Git从当前项目的更改中撤销一些操做,能够新建分支,合并分支甚相当联远程服务器仓库等,这一切的背后都是怎么实现的?了解Git的思想以及基本原理这些操做也就略知一二了。算法

  • Git的分区

    • workspace: 工做区 直接编辑的地方,开发者可见具体的项目,能够直接操做项目文件
    • index(stage): 暂存区 数据暂存的地方
    • repository: 本地仓库 存放已提交的数据
    • remote: 远程仓库 在远程服务器上存放本地仓库的数据

图片没法加载

  • .git文件夹

    • .git下的文件夹数据库

      • hooks 文件夹则存放项目的客户端或服务端钩子脚本
      • info 文件夹下的exclude文件包含项目全局忽略匹配模式,与.gitignore文件互补
        • exculd 文件
      • logs 保存全部更新的引用记录
        • refs
        • HEAD # 最后一次的提交信息
      • objects 文件夹存储着Git数据库的全部内容,存储全部Git的对象
        • info 记录对象存储的附加信息
        • pack 以压缩形式(.pack)存储许多对象的文件,附带索引文件(.idx)以容许它们被随机访问
      • refs 文件夹存储着全部分支指向各自提交对象的指针;本地分支,远端分支,标签等
        • heads 记录commit分支的树根
          • master 标识了本地项目中的master分支指向的当前commit的哈希值
        • remotes 记录从远程仓库copy来的commit分支的树根(只读)
          • origin
            • HEAD
            • master 标识了远端项目中的master分支指向的当前commit的哈希值。
        • tags 记录任何对象名称(不必定是提交对象或指向提交对象的标签对象)
    • .git下的文件

      • HEAD 文件指向当前分支, 包含了一个分支的引用,经过这个文件Git能够获得下一次commit的parent,能够理解为指针

      • index 文件存储着暂存区的内容信息

      • config 文件包含项目的配置信息

      • description 存储着仓库的描述信息,主要给gitweb等git托管系统使用

      • packed-refs 打包标头和标签以便高效的存储库访问

      • FETCH_HEAD 是一个版本连接,指向着目前已经从远程仓库取下来的分支的末端版本

      • ORIG_HEAD 记录的是在进行危险(drastic)操做(如合并merge,回退reset等)时,此操做以前HEAD所指向的位置,便于咱们在发生毁灭性失误时进行回退

      • COMMIT_EDITMSG 保存最新的commit message,Git系统不会用到这个文件,只是给用户一个参考

        images loading rror

  • Git数据库

    • Git本质上是一个内容寻址文件系统(就是根据文件内容的hash码来定位文件。 这就意味着一样内容的文件,在这个文件系统中会指向同一个位置,不会重复存储。)Git 的核心部分是一个简单的键值对数据库,能够向该数据库插入任意类型的内容,它会返回一个键值,经过该键值能够在任意时刻再次检索(retrieve)该内容

    • Git 保存的不是文件的变化或者差别,而是一系列不一样时刻的文件快照。在进行提交操做时,Git 会保存一个提交对象(commit object)。该提交对象会包含一个指向暂存内容快照的指针。 但不只仅是这样,该提交对象还包含了做者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针。

    • git经过一种安全散列算法1(SHA-1)能够获得任意文件的SHA-1哈希值(40位的字符),也就是commit ID,而后经过文件哈希值存取数据,存取的数据都位于objects目录,SHA-1哈希值的前两个字符做为子目录名称,后 38 个字符则做为子目录内文件的名称

    • Git的数据存储原理

      • Git对象
        • 数据对象(blob object) 存储的是一个文件的具体内容
        • 树对象(tree object) 存储的文件的目录,一大坨指针,指向子级tree,或者blob
        • 提交对象(commit object) 存储做者信息,提交者信息,注释,指向一个 big tree 的指针
        • 标签对象(tag object)它包含一个标签建立者信息、一个日期、一段注释信息,以及一个指针。
      • Git的底层命令、高层命令
        • Git经常使用命令共有30多个,可运行git help查看;但Git总共有130多个命令,能够经过git help -a查看,这些命令能够分为高层命令和底层命令,底层命令被设计成unix风格,不经常使用

          图片没法加载

          • 往Git数据库存入数据
          • 往Git数据库取出数据
          • 首次提交 testA.txt文件
          • 第二次提交,修改了test.txt文件内容
          • 第三次提交,增长一个新文件 testB.txt ,一个新目录 lib ,lib 里增长一个文件 testC.txt
          • 第四次提交,新建一个分支 branchB,而且在新分支中作了一次 commit
          • 第五次提交, 合并一分支
      • Git的引用(reference或refs)

        浏览完整的提交历史,但为了能遍历那段历史从而找到全部相关对象,须要记住最后提交的SHA-1值。咱们须要一个文件来保存 SHA-1 值,并给文件起一个简单的名字,而后用这个名字指针来替代原始的 SHA-1 值。文件被称为“引用(references,或缩写为 refs)”,使用git branch (branchname) 这样的命令时,Git 实际上会运行 update-ref 命令,取得当前所在分支最新提交对应的 SHA-1 值,并将其加入你想要建立的任何新引用中。

        • HEAD引用
          • 分支和标签都是指向提交对象的指针,全部的本地分支都存储在 git/refs/heads 目录下,每个分支对应一个文件
          • Git 分支的本质:一个指向某一系列提交之首的指针或引用
        • 远程引用
          • 若是你添加了一个远程版本库并对其执行过推送操做,Git 会记录下最近一次推送操做时每个分支所对应的值,并保存在 refs/remotes 目录下
        • 标签引用

    Git的对象模型

5. Gitflow工做流

  • Gitflow工做流约定使用的分支简介

    • master分支为项目的核心分支,也是最终对外发布的分支,惟一且稳定。仅提供可读,不可在该分支上直接修改代

    • develop分支是项目的开发主干分支,惟一。仅提供可读,不可在该分支上直接修改代码。新功能的开发需从该分支拉取新的分支展开。develop分支应该包含项目完整的所有历史记录。

    • featrue分支项是目的需求开发分支,可多个,从develop分支或其余featrue分支拉取。程序员的多人分工协做即经过featrue来实现,是代码具体实现的一线程序员接触最多的分支。需求开发完成后,要合并回develop分支。

    • release分支为预发布分支,一般被叫作测试分支,主要用于开发阶段的测试及bug修复。当feature分支开发完毕后会合并回develop分支,而后再从develop分支拉取release分支提测。测试并修复后的release分支要合并回develop分支以及master分支,并打上合适的tag标记(包含必要的releaseNote)。

    • hotfix分支为紧急线上修复分支,即当对外发布的master分支出现重大bug,影响线上使用时,从master分支拉取hotfix分支进行紧急修复。修复后的hotfix分支要合并回master分支和develop分支。

      图片没法加载

  • GitFlow工做流程

图片没法加载
首先,完成中央仓库的初始化,将新项目搭建起框架后的工程代码或要转gitflow的项目代码上传至git中央仓库。项目负责人克隆中央仓库到本地造成master分支,并拉取develop分支(步骤①)推送至服务器。通常的实际场景,开发团队中只有项目负责人有权限操做master分支,拉取develop分支,并将develop分支的代码合并到master分支中。

而后,开发团队中的其余人克隆中央仓库的develop分支到本地,造成全体成员统一的惟一的develop分支轨迹。以后,按照需求及成员各自的分工,各个成员能够从develop分支拉取出各自的featrue分支(步骤②)进行独立的开发;若涉及到多人合做开发同一分支,拉取的分支要及时推送至服务器,便于各成员共享。

当各成员完成各自的功能开发后,需将完成后的代码提交到featrue分支,而后合并到develop分支(步骤③)。代码合并后,featrue分支能够再也不保留。

功能累积足够且稳定或到达约定的提测周期时,项目负责人应当从develop分支拉取出release分支(步骤④),打包提交相应的版本给测试人员进行部署测试,测试中提交的bug所有在该release分支完成修改。

测试结束并完成bug修复后,release分支应该合并回develop分支和master分支(步骤⑤),代码合并后,release分支能够再也不保留。合并后的master分支,应由项目负责人及时推送到中央仓库(步骤⑥)。同时全体成员要及时同步本身develop分支。

有上线需求时,直接从master分支打包提交应用版本进行部署。当线上版本出现重大bug,项目负责人需从master分支拉取hotfix分支(步骤⑦),进行线上的紧急修复。

最后,修复后的hotfix分支要合并回develop分支和master分支(步骤⑧)。并推送到中央仓库(步骤⑨)。

六、Git经常使用命令

  • 配置Git-SSH

    • 配置Git的user name以及Git要关联的邮箱email

      git config --global user.name 'your name'
      git config --global user.email 'your email'

    • 生成密钥
      $ ssh-keygen -t rsa -C "your email"
      复制代码
    • 按三个回车,跳过设置密码,通常咱们使用Git不须要设置密码,最终生成id_rsaid_rsa.pub这两个文件,(若以前就已经生成过这个两个文件,就直接overwrite进行覆盖)
    • 登陆Github或者Gitlab,添加ssh

      打开在windows(c盘)/用户/xxx/.ssh文件夹下的id_rsa.pub文件,复制里面的内容;粘贴在GitHub或Gitlab的setting的ssh key

    images loading error

  • 简单命令

    图片没法加载

  • 高级命令

    • HEAD

      • 老是指向当前分支最新的一次提交commit
      • git diff HEAD 显示工做区与当前最新commit之间的差别
    • commit

      • git commit --amend -m [message] 修改上一次提交
    • branch

      • git branch --track remote-branch 新建一个分支,与指定的远程分支创建追踪关系
      • git branch --set-upstream-to=origin/[remote branch] 将remote设置为当前分支的上游分支
    • merge 合并指定分支

      • git merge branch 合并其余分支到当前分支

        图片加载失败

    • rebase 衍合指定分支

      图片没法加载
    • reset 重置

    • revert 撤销,回滚到指定的特定版本

    • cherry-pick 选择合并某次提交的commit到当前分支

    • reflog 查看HEAD的全部移动轨迹

思考:

git merge 与 git rebase 的区别是?

  • rebase会合并该分支与其余分支的commit history,可能会获得一个新的commit history
  • rebase获得更简洁的项目历史,去掉了merge commi,若是合并出现代码问题不容易定位,由于re-write了commit history
  • merge会建立新的commit,包括每一个分支的commit 详情
  • 每次merge会自动产生一个merge commit,特别是commit比较频繁时,看到分支很杂乱。
  • 想要获得一个干净的,没有merge commit的线性commit历史记录,选择git rebase
  • 想要获得一个完整的commit历史记录,且想避重写commit历史记录的风险,选择git merge

git reset 与 git rebase的区别?

  • git revert会生成一个新的提交来撤销某次提交,这次提交以前的commit都会被保留,也就是说对于项目的版本历史来讲是往前走的。
  • git reset 则是回到某次提交,相似于穿越时空。

附前端全站书籍PDF文档下载连接:juejin.im/post/5d7216… (要书籍资源的请在下面留言,网盘收集了先后端时髦的书籍电子版)

images loading error
相关文章
相关标签/搜索