Git 是一个分布式版本控制系统,本文对其基本的一些内容进行了简单整理,具体参考 Pro Git前三章。

1. 基本工作原理:

分布式

和SVN等集中化的版本控制系统不同,客户端存储了代码仓库的完整镜像。由于有完整镜像,所以大部分操作都是本地执行,在需要时才和服务端通信

记录快照,非差异

Git 更像是把数据看作是对小型文件系统的一组快照。每次你提交更新,或在 Git 中保存项目状态时,它主要对当时的全部文件制作一个快照并保存这个快照的索引。为了高效,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。Git 对待数据更像是一个快照流。
(表面上看是存储了每个文件每个修改版本的快照,但是出于容量的考虑,Git底层会有压缩操作,将文件快照改成存储差异。)

使用Hash值索引文件

存储所有数据(管理文件,Git内部使用对象等)都根据文件内容计算一个40个十六进制字符组成的Hash值,使用该Hash值索引文件,而不是使用文件名。

工作区域划分

  • Git仓库(.git):保存项目元数据和对象数据库
  • 工作目录:对项目的某个版本独立提取出来的内容
  • 暂存区域:一个文件,保存了下次将提交的文件列表信息,一般在 Git 仓库目录中,也被称作“索引”

文件状态

分两大类状态,已跟踪和未跟踪,已跟踪中可以细分三个状态。文件状态的流转相当于就是操作步骤。

  • 已跟踪(Tracked):被纳入了版本控制的文件,在上一次快照中有它们的记录
    • 未修改or已提交(Committed, Unmodified):已保存到本地数据库
    • 已修改(Modified):修改了文件,但是还未保存到数据库
    • 已暂存(Staged):对已修改文件做了标记,包含在下次提交的快照中
  • 未跟踪(Untracked):既不存在于上次快照的记录中,也没有放入暂存区

2. 分支基础

Git对象基础

为了实现Git的版本管理,以及记录不同时刻的文件快照,Git有三类基本对象:

  • blob 对象((binary large object),二进制大对象):文件快照
  • tree 对象:记录着目录结构和 blob 对象索引
  • commit 对象(提交时生成):包含指向暂存区内容快照指针,提交信息,父对象指针。

初次提交时对象之间的关系:

多次提交之后对象关系:

分支简介

分支原理

Git 的分支,其实本质上仅仅是指向提交对象的可变指针。创建分支只是创建了一个可以移动的新的指针,所以Git创建分支的成本非常低。

HEAD 指针用来指向当前所在的本地分支(将 HEAD 想象为当前分支的别名,checkout是修改了HEAD指针指向的分支)。
在分支上进行提交,其对应的分支指针会前移到最新的提交对象。

远程分支
本地仓库和远程仓库的关系:

远程引用是对远程仓库的引用(指针),包括分支、标签等等。对于远程仓库中的分支,本地都会存一个远程跟踪分支,它们是你不能移动的本地引用,当你做任何网络通信操作时,它们会自动移动。

克隆远程仓库之后本地仓库和远程仓库的关系:

远程仓库如果有提交,本地仓库没有进行拉取的话,本地仓库记录的远程仓库指针是不会移动。

连接远程仓库拉去更新后:

跟踪分支

从一个远程跟踪分支检出一个本地分支会自动创建一个叫做 “跟踪分支”(有时候也叫做 “上游分支”)。跟踪分支是与远程分支有直接关系的本地分支。如果在一个跟踪分支上输入git pull,Git能自动地识别去哪个服务器上抓取、合并到哪个分支

分支合并
  • 快进合并(Fast-forward):顺着一个分支可以达到另外一个分支,则合并只是简单将指针向前推进。

  • 三方合并:将两个分支的最新快照和两者最近的公共祖先进行三方合并。

分支变基

rebase(变基)是将提交到某一分支上的所有修改都移至另一分支上(不会合并成一个修改),类似重新播放一样。实质是丢弃一些现有的提交,然后相应地新建一些内容一样但实际上不同的提交。变基使得提交历史更加整洁。但是切记不要对在你的仓库外有副本的分支执行变基

  • step 1:对experiment分支进行变基
1
2
$ git checkout experiment
$ git rebase master

  • step 1:master快速合并
1
2
$ git checkout master
$ git merge master

3. 基本命令

  • 配置Git:git config
  • 初始化仓库:git init
  • 把不在暂存区和未提交的文件放入暂存区:git add fileName
  • 暂存区文件提交到仓库:git commit -m ‘message’
  • 克隆仓库:git clone [url]
  • 文件状态简览:git status
  • 提交文件:git commit
  • 查看日志:git log
  • 远程仓库相关操作(查看或编辑关联):git remote
  • 从远程仓库中抓取与拉取(只抓取,不merge):git fetch [remote-name]
  • 合并分支:git merge branchName
  • 拉去并合并:git pull = git fetch + git merge
  • 推送到远程仓库:git push [remote-name] [branch- name]
  • 打标签:git tag
  • 创建分支:git branch branchName
  • 查询日志:git log
  • 分支切换:git checkout branchName
  • 分支管理:git branch (创建、删除、展示branch)
  • 远程分支管理:git remote (添加、删除、展示远程仓库)