第六章:提交

1】提交(commit)是用来记录版本库的变更的。(一一对应关系)

2】提交时,Git会记录索引的快照并把快照放进对象库中。

3】提交是将变更引入版本库的唯一方法。

一、原子变更集

  1】每一个Git提交都代表一个相对于之前状态的单个原子变更集。

  2】对于一个提交中所有做过的变动,相当于一个原子。要么全部应用,要么全部拒绝。

  3】在底层模型,原子性是有意义的。一张提交快照代表所有文件和目录的变更。

       它代表一棵树的状态,而两张提交快照之间的变更集就代表一个完整的树到树的转换。

二、识别提交

  1】在Git中,可以通过显式或隐式的引用指代每一个提交。

  2】唯一的40位十六进制SHA1提交ID是显式引用。

  3】始终指向最新提交的HEAD则是隐式引用。

  

1、绝对提交名

  1】散列标识符(散列ID)就是绝对名,它只能代表唯一确定的一个提交。

  2】散列ID是全局唯一的,而且是对任意版本库都是唯一的。

  3】标签名不是全局唯一,但标签名会明确指向一个唯一的提交。

2、引用和引用符号

  1】引用是一个SHA1散列值,指向Git对象库中的对象。

  2】一个引用通常指向提交对象。(引用可以指向任何Git对象)

  3】符号引用:间接的指向Git对象。(它仍然只是一个引用)

  4】本地特性分支名称、 远程跟踪分支名称和标签名都是引用。

  5】每一个符号引用都有一个以 ref/ 开始的明确全称,并且都分层存储在版本库的  .git/refs/目录中。

  6】.git/refs/ 目录有三种不同的命名空间代表不同的引用。

  

   7】如果 一个分支和一个标签使用相同的名字,Git会应用消除二义性的启发式算法,。

    根据git  rev-parse手册上的列表选取第一个匹配项。

  8】Git自动维护几个用于特定目的的特殊符号引用。(这些引用可以在使用提交的任何地方使用)

  

   9】Git中有一个特殊符号集来指代引用名。冒号 ":"可以用来指向一个产生合并冲突的文件的替代版本。

3、相对提交名

  1】Git的另一种(确定相对于另一个引用的提交)的机制,分支的头。

  2】同一代提交中,^符号选择不同的父提交。

  

   3】波浪线 ~ 用于返回父提交之前并选择上一代提交。

  

   4】master~10^2~2^2复杂的名字。

    

  5、git  rev-parse + 提交名。把任何形式的提交名(标签、相对、简写绝对或者绝对名)都能转化为提交ID。

  

   6】git  show-branch 。查看提交的相对名和提交日志消息。

三、提交历史记录

1、查看旧提交

  1】显示提交历史记录的主要命令是 git  log。(更多的选项、参数、选择器、格式化器等)

  2】git  log = git  log  HEAD,输出可从HEAD找到的历史记录中的提交日志。

  3】注意: 回溯历史记录的时候,Git依附于提交图,而不是时间。

  4】git  log  提交名,从指定的提交进行回溯。(对于查看某个分支的历史记录很有用)

  5】无需查看版本库所有历史记录。我们要限制历史记录: since...until指定提交范围。

     (没有since,有until)

  

   6】--pretty选项: 调整提交的信息数量。(有  oneline、short、full三种)

  7】--abbrev-commit:只是请求缩写散列ID。

  8】-p 选项: 输出提交引进的补丁或变更。(查看某个提交修改的内容)   

  

   9】-n 选项,指定查看的提交日志的数量。

  

   10】--stat选项,查看提交中变更的文件以及每个变更文件的改动行数。(可以与上图对应)

  

  

   11】git  show  命令,查看对象库对象的命令。也可以用来查看提交或某个对象。

 

2、提交图

  1】图1、一幅完整但稍稍简化的提交图。

  

  2】图2、极大地简化蓝图:每一个提交都引入一个树对象来表示整个版本库。

  

  3】Git通过DAG(有向无环图)实现版本库的提交历史记录。

  (提交图中,每一个节点代表一个单独的提交,所有边都从子节点指向父节点,形成祖先关系)

  4】图3、标记提交图。将每一个提交做一个标记。

  

  5】gitk命令,可以画出版本库的DAG。

  6】理解DAG: (a)一般提交只有一个父提交、 (b)只有初始提交没有父提交、 (c)合并提交有多个父提交、

                         (d)多个子提交的提交是出现分支的地方。

  7】git  merge-base命令,可以查看分支的起点。

3、提交范围

  1】很多Git命令都允许指定提交范围。(提交范围: 一系列提交的简写)

  2】双句点(..)形式就表示一个范围。(开始..结束)【结束可达,开始不可达】

  3】不可达原因: git:log  X..Y == git  log  ^XY。

    "要从Y提交可到达的所有提交, 但是不要任包括X提交及其之前的提交"。

  4】图4: 不可达。    ( M~12..M10 )

  

   5】图5、范围是两个分支,topic..master表示在master分支而不再topic分支的提交。

  

   6】图6、三个句点(...):对称差。 A...B: A和B之间的对称差。(A...B ==  B...A)

    也就是A或B可达但又不是A和B同时可达的提交集合。

  

  

四、查看提交

1、使用git  bisect 命令

  1】git  bisect, 基于任意搜索条件查找特定的错误提交。

  2】前提条件: 要知道一个"好"状态版本和一个"坏"状态版本,以便搜索可以界定范围。

  3】采取的是二分查找模式。(尽量让"好" 和 "坏" 离得近一些)

  4】第一步: git  bisect  start  表示开始进行查找。

     第二步: git  bisect  bad  指定提交   表示已知的"坏"状态版本。

        第三步: git  bisect  good  指定提交    表示已经的"好"状态版本。

     第四步: 会定位到两个提交的中间提交。 用 git  bisect  bad 或者 git  bisect  good标记该提交。

     第五步:  会定位到新的  good 和  bad的中间。再次指定好坏(递归下去,可以得到错误提交)

   

  5】git  bisect  log 命令,查看  good 和 bad对应提交ID的问答日志。

   

   6】git  bisect  replay   日志文件。可以重新开始:

  

   7】git  bisect  visualize --pretty=oneline,可视化的检查提交范围内的内容。

  

   8】git  bisect  reset,退出bisect  debug的状态。(注意: 问答的过程中。HEAD会发生改变

2、使用git  blame

  1】git  blame, 也有助于识别特定提交。某个文件, 每一行最后修改的作者,修改的提交ID。

  

3、使用Pickaxe

  1】git  blame命令,查看文件的状态,git  log  -Sstring,会根据string沿着文件差异历史搜索。

  2】通过搜索修订版本间的实际差异,可以找到执行改变的提交。

  

  

   3】带有-S选项的  git  log 命令称为pickaxe。

原文地址:https://www.cnblogs.com/changdasheng/p/13258618.html