背景
前面已经记录了git从克隆/创建仓库–>提交至远程仓库的过程!该篇文章会记录如何查看提交历史、重写提交历史
查看提交历史
- 查看当前分支最后提交的n条提交记录
    $ git log -n [HEAD/BRANCH_NAME]
- 查看文件/目录提价历史
```sh
    查看指定文件的提交历史$ git log file1 file2 …. 
查看指定目录的提交历史
$ git log path1/ path2/ …
3. 查看分支提交历史
```sh
# 查看master分支和fast分支的提交历史
$ git log master fast [ ... branchName-n]
# 查看branch1与branch2的差集提交记录
$ git log branchName1 --not branchName2
【重要】以git log master fast为例,该命令读取记录顺序如下:

【重要】以git log master --not fast为例,该命令读取记录范围如下:

对比
2. 查看文件/目录提价历史和3. 查看分支提交历史很容易发现:查看分支提交历史和查看指定文件提价历史的用法是相同的!试想:如果分支名与文件名相同,当前分支中有一个名为name1的文件,同时还存在一个名为name1的分支,那么
git log name1到底是查看name1分支还是当前分支name1文件的提交历史呢?【如果有相同的目录可以不用考虑这个原因,是因为目录会带上/】
- 事实上:当分支名与文件名相同时,系统会提示错误,可通过
--选项来指定给定的参数是分支名还是文件名:git log [options] branchName -- fileName- 同时也建议:文件名应该放到参数的最后位置,通常在前面加上
--并用空格隔开表示是查看文件提交历史. PS:git log -- file1 file2 ...
- 查看指定提交点间提交历史
    - 查看提交点a 和提交点b的提交合集$ git log a b
 
- 查看提交点a 
- 查看提交点a 到提交点b的提交历史【不包含a】$ git log a..b
- 查看提交点a 到提交点b的提交历史【包含a】$ git log a^..b
写在最后的话:
Git是一套”内容寻址 (content-addressable) “文件系统,其一切都是引用关于有界区间的知识点:
- 闭区间:[a,b]
- Git中闭区间表示为(使用空格分隔或
...):a b 或 a…b- 左开右闭区间:(a,b]
- Git中左开右闭区间表示为:a..b
- 开区间:(a,b)【其等同于左开右闭区间(a,b-1]】
- Git中左开右闭区间表示为:a..b^
- 右开左闭区间:[a,b)【其等同于左开右闭区间(a-1,b-1]】
- Git中左开右闭区间表示为:a^..b^
这一块(⊙o⊙)…还没想好这个地方如何简单清晰的表达出来
git log`几个重要的选项
- 关于提交记录类型
    - 只查看非merge提交记录: –no-merges
- 只查看merge提交记录: –merges
 
- 关于提交用户
    - 只查看某个用户提交记录: –author=’xxx’
 
- 关于提交记录
    - 查看提交记录中包含xxx的提交: –grep=xxx
 
- 关于美化
    - 使用--pretty=格式化打印记录
 
- 使用
| -选项- | -说明- | 
|---|---|
| online | 简短显示信息,显示在同一行 | 
| short | 显示简略信息 | 
| format: | 自定义格式化信息 | 
format选项如下
| -选项- | -说明- | 
|---|---|
| %H | 提交对象(commit)的完整哈希字串 | 
| %h | 提交对象的简短哈希字串 | 
| %T | 树对象(tree)的完整哈希字串 | 
| %t | 树对象的简短哈希字串 | 
| %P | 父对象(parent)的完整哈希字串 | 
| %p | 父对象的简短哈希字串 | 
| %an | 作者(author)的名字 | 
| %ae | 作者的电子邮件地址 | 
| %ad | 作者修订日期(可以用 -date= 选项定制格式) | 
| %ar | 作者修订日期,按多久以前的方式显示 | 
| %cn | 提交者(committer)的名字 | 
| %ce | 提交者的电子邮件地址 | 
| %cd | 提交日期 | 
| %cr | 提交日期,按多久以前的方式显示 | 
| %s | 提交说明 | 
重写提交历史
重写提交历史意味着你可以:修改你以往的提交记录、删除或对提交记录进行重新排序,这对于保持分支提交记录的简洁有效有很大的作用!
重写提交历史的铁则:只针对你本地的提价记录或个人分支上的提交的记录进行重写,否则会造成很严重的后果!
原则上重写历史只能是针对本地的提交记录,因为不管你如何的更改本地提交记录,并不会对该远程分支上的其他用户造成影响;但是如果你100%确定该分支只有你自己用,那么该远程分支和你本地是没有区别的,只是你在这种情况下进行了提交历史重写后,需要执行极其不建议的
git push -f进行强行覆盖远程提交历史记录!
重写最后一次提交信息
$ git commit --am -m "new message"

批量重写提交历史
曾在10.Git操作-分支合并一文中的“变基”合并中提到过rebase的作用:将当前分支以补丁的方式在指定分支上重演合并!
如果在这个演合的过程中,我们能够控制这些演合后的节点的顺序、是否保留该节点、是否继续沿用该节点提交信息,那么我们就可以达到批量重写历史的目的了!
以下是git rebase中-i选项的解释,似乎恰好符合我们的目的:
# -i, --interactive  让用户编辑可提交的rebase列表
-i, --interactive  let the user edit the list of commits to rebase
用法如下:
$ git rebase -i commitId-A commitId-B(默认为HEAD) 
- <remote/branch> / 都是一个特殊的commitID 
- 两个操作范围的提交节点是左开右闭区间–(commitId-A commitId-B]【包含commitId-B但是不含commitId-A】
假设当前分支如下:

我们需要将fast分支上的提交重写为3个提交点,合并到master分支上,并进行提交!
- 将fast分支上的提交重写为3个提交点

选项说明
- q直接使用该提交节点
- e编辑使用该提交节点
- s压缩合并使用提交节点
- 将重写后的fast分支合并到master分支上
    - 使用:git merge branch– 会产生一个额外节点
- 使用:git rebase master然后git merge branch– 采用变基合并,提交简洁,但分支信息不明确
- 采用:git cherry-pick commit多次采摘提交点进行提交 – 既保留了原有分支信息,又将其集成到了当前分支,但该种方式可以通过提交时间分清提交节点到底来源于哪个分支,但是麻烦
 
- 使用:
资料参考

 
 
        
         
       
                
 
                 
                
