Git 看这一篇就够了

今天简单讲下 Git 的实现原理,知其因此然才能知其然;而且梳理了平常最经常使用的 12 个命令,分为三大类分享给你。php

本文的结构以下:git

  1. 做者和开发起因程序员

  2. Git 的数据模型github

  3. 经常使用命令数据库

  4. 资源推荐vim

 

做者和开发起因安全

Talk is cheap. Show me the code.服务器

这句话就出自 Linux 和 Git 的做者
Linus Torvalds数据结构

本来 Linux 内核的版本控制系统是用的 BitKeeper,然而 2005 年,BitMover 公司再也不让 Linux 开发团队无偿使用了。。分布式

Linus 一听,不给用了?老子本身写!

因而,大佬十天以内完成了 Git 的第一个版本。

因此 Git 是一个免费的、开源的版本控制系统。

版本控制系统

版本控制其实每一个人都用过,那些年修改过的简历:

小齐简历 2012 版
小齐简历 2013 版
小齐简历 2014 版
小齐简历 2015 版
小齐简历 2016 版
小齐简历 2017 版
小齐简历 2018 版
小齐简历 2019 版
...

还有那些年打死都再也不改的毕业论文:

毕业论文最终版
毕业论文最最终版
毕业论文最最最终版
毕业论文最最最最终版
毕业论文最终不改版
毕业论文最终真不改版
毕业论文最终真真不改版
毕业论文最终打死不改版
毕业论文最终打死不改版 2
...

没错,这就是本地版本控制系统。

很明显,好处是简单,可是只能一我的在这改,没法和他人完成合做。那么如下两种主流的版本控制系统应运而生。

1. 集中化版本控制系统

Centralized Version Control Systems (CVCS)

好比:CVS, Subversion, Perforce, etc.

这种版本控制系统有一个单一的集中管理的服务器,保存全部文件的最新版本,你们能够经过链接到这台服务器上来获取或者提交文件。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

这种模式相对本地版本控制系统是有所改进的,可是缺点也很明显,若是服务器宕机,那么轻则耽误工做、重则数据丢失。因而分布式版本控制系统应运而生。

2. 分布式版本控制系统

Distributed Version Control Systems (DVCS)

好比:Git, Mercurial, Bazaar, etc.

分布式的版本控制系统会把代码仓库完整地镜像下来,这样任何一个服务器发生故障,均可以用其余的仓库来修复。

更进一步,这种模式能够更方便的和不一样公司的人进行同一项目的开发,由于两个远程代码仓库能够交互,这在以前的集中式系统中是没法作到的。

那么什么叫“把代码仓库完整地镜像下来”呢?

CVCS 每一个版本存放的是当前版本与前一个版本的差别,所以也被称做基于差别的版本控制 (delta-based);

Git 存储的是全部文件的一个快照 (snapshot),若是有的文件没有修改,那就只保留一个 reference 指向以前存储的文件。

不是很好理解?那接着看吧~

 

Git 的数据模型

1. 什么是快照 (snapshot) 呢?

首先咱们来学两个 Git 中的术语:

  • blob, 就是单个的文件;

  • tree, 就是一个文件夹。

快照则是被追踪的最顶层的树。

好比个人“公众号”文件夹的这么一个结构:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

那么一个快照就是追踪的“公众号”这颗树。

2. 本地库的数据模型

Git 记录了每一个快照的 parent,也就是当前这个文件夹的上一个版本。

那么快照的迭代更新的过程就能够表示为一个有向无环图,是否是很熟悉?咱们在「拓扑」那篇文章里讲过,忘了的小伙伴快去公众号内回复「拓扑」获取拓扑的入门文章吧~

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

每一个快照其实都对应了一次 commit,咱们用代码来表示一下:

class commit {
  array<commit> parents
  String author
  String message
  Tree snapshot
}

这就是 Git 的数据模型。

blob, tree, snapshot 其实都同样,它们在 Git 中都是对象,均可以被引用或者被搜索,会基于它们的 SHA-1 hash 进行寻址。

git cat-file -t: 查看每一个 SHA-1 的类型;
git cat-file -p: 查看每一个对象的内容和简单的数据结构。

可是经过这个哈希值来搜索也太不方便了,毕竟这是一串 40 位的十六进制字符,就是第二部分 git log 里输出的那个编码

所以,Git 还给了一个引用 reference

好比,咱们常见的 HEAD 就是一个特殊的引用。

本地库就是由 对象引用 构成的,或者叫 Repositories.

在硬盘上,Git 只存储 对象引用,全部的 Git 命令都对应提交一个快照。

那有哪些经常使用命令呢?

 

经常使用命令

本章分三大部分介绍平常经常使用命令:

  • 本地操做

  • 和远程库的交互

  • 团队协做 - 分支

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

本地操做

在学习经常使用命令以前,你首先须要知道的 Git 的「三个分区」和对应的文件的「三种状态」:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

  • 工做区:就是你本地实际写代码的地方,不管你是用 vim 直接改也好,仍是在 IDE 里写,都无所谓。

    • 对应的文件状态是:modified,已修改,但还没保存到数据库中。

  • 暂存区:就是临时存放的地方。

    • 对应的文件状态是:staged,Git 已经对该文件作了标记,下次提交知道要包含它。

  • 本地库:存放本地历史版本信息。

    • 对应的文件状态是:committed,文件已经安全的保存在本地数据库中。

1. $ git add

工做区改完了代码,就用 git add 提交到暂存区。

这里若是文件改动的比较多,但又不是每一个都须要提交,我会设置 git ignore file,就表示这些文件不要提交,好比在 build project 的时候会自动生成的那些文件等等。

2. $ git commit -m "comment"

从暂存区提交到本地库,就须要用 commit。

通常后面都会跟个 -m 加句 comment,简单说下改动的内容或者缘由,咱们公司你们默认也会把 Jira连接附上,这样就知道这个改动对应哪一个任务。

那若是想再改,再从新 git add 便可,可是 commit 这句须要改为

$ git commit --amend

这样就仍是一条 git log 信息。

3. $ git log

git log 能够查看到提交过的信息,从近到远显示每次 commit 的 comment 还有做者、日期等信息,好比大概长这个样子:

commit 5abcd17dggs9s0a7a91nfsagd8ay76875afs7d6
Author: Xiaoqi<xiaoqi@163.com>
Date: xxx xxx xxx
改了 Test 文件

commit 后面的这个编号,是每次历史记录的一个索引。好比若是须要对版本进行前进或者后退的时候,就须要用到它。

这样打印的 log 太多,更简洁的打印方式是:

$ git log --oneline

就一行打印出来了。

或者:

$ git reflog

更经常使用一些。

4. $ git reset

那咱们刚刚说过,若是须要前进或退回到某个版本,就用

$ git reset --hard <编号>

这样就直接跳到了这个编号对应的那个版本。

那么这个 hard 是什么意思呢?

这里有 3 个参数:hard, soft, mixed,咱们一一来讲一下。

回到咱们最重要的这张图上来:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

咱们刚刚说的前进或后退到某一版本,是对本地库进行的操做。

那有个问题:
本地库的代码跳到那个版本以后,工做区和暂存区的代码就和本地库的不一样步了呀!

那这些参数就是用来控制这些是否同步的。

$ git reset --hard xxx

三个区都同步,都跳到这个 xxx 的版本上。

$ git reset --soft xxx

前面两个区不一样步,就只有本地库跳到这个版本。

$ git reset --mixed xxx

暂存区同步,工做区不动。

因此呢,用的多的就是 hard.

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

远程交互

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

和远程库的交互主要是,也就是写入和读取。

5. $ git push

小齐写完了代码,要提交到公司的代码库里,这个过程要用 git push.

固然了,这么用会被打的。。毕竟还要 cr 呢。

5. $ git clone

新来的实习生首先要 clone 整个项目到本地来,而后才能增删改查。

固然了实际工做中也没人这么用。。由于每家公司都会有本身包装的工具。不过若是是作 Github 上的开源项目,就用得上了。

6. $ git pull

小齐提交了新的代码以后,领导要审查呀,因此用 git pull 把最新的代码拉取下来瞅瞅。

实际上呢,

git pull = fetch + merge

7. $ git fetch

git fetch 这个操做是将远程库的数据下载到本地库,可是工做区中的文件没有更新。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

而要谈 get merge,咱们还须要先讲下分支

mergegit pull 默认的选项,合并其实还有另一种方法:rebase,中文叫作变基

8. $ git rebase

rebase 的做用更多的是来整合分叉的历史,能够将某个分支上的全部修改都移到另外一分支上,就像是变了基底。

分支与合并

首先咱们来看几个关于分支的基本操做:

9. 查看分支:

$ git branch

相似于ls,可以列出当前全部分支。

git branch -v 可以显示更多信息。

10. 建立分支:

$ git branch <branchName>

11. 切换分支:

$ git checkout <branchName>

有了分支以后必然会有合并:

12. 合并分支:

$ git merge <branchName>

而合并时就可能会有冲突,何时会有冲突呢?:

在同一个文件的同一个位置修改时。

由于 Git 会努力的把大家改动不一样的地方合并在一块儿,但若是实在是在同一个地方改的,那它也没办法了,只能留给程序员去手动处理了。

固然了,每一个命令延伸下去还有无限多个,本文不可能涵盖所有,因此在此重磅推荐齐姐精心挑选的三大学习资源,你们能够自行享用~

 

学习资源

git help

其实我我的使用最多的是git help

真心方便又好用啊!

好比 git help pull:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

先介绍了有哪些参数,而后 description 详细解释了它的工做原理,下面还有图解,有木有太香!!

不过这种方式更像是 cheatsheet,当你已经知道了这个命令、只是忘了它的用法的时候去查。

若是你想系统的学习,那么下面 ???? 的更适合你。

Pro Git

这本书是强烈推荐了!!

Pro Git 这本书不只讲了 Git 的基础用法、高级用法,以及最后还深刻讲解了 Git 的原理,很是细致全面。

书的电子版也能在网站上直接下载。

英文版:

  • https://git-scm.com/book/en/v2

中文版:

  • https://git-scm.com/book/zh/v2

玩游戏

Practice makes perfect!

推荐一个宝藏资源:玩游戏来练 Git

项目:https://github.com/pcottle/learnGitBranching

网址:https://learngitbranching.js.org/

我熟悉不少工具都是经过小游戏来练习的,好比 vim 的操做,仍是蛮推荐这种方式的。就不剧透啦,你们本身去探索吧~

有道无术,术可成;有术无道,止于术

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

相关文章
相关标签/搜索