Git基础
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分支进行变基
|
|
- step 1: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 (添加、删除、展示远程仓库)