背景
前面已经记录了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
多次采摘提交点进行提交 – 既保留了原有分支信息,又将其集成到了当前分支,但该种方式可以通过提交时间分清提交节点到底来源于哪个分支,但是麻烦
- 使用:
资料参考