选择修订版本

大约 6 分钟

Git 允许使用者通过几种方法在指定或者一定范围内的提交,分配提交,分组提交。

# 指明单次提交

使用简明的 SHA-1(hash 值)指明单个提交:git show [SHA-1值]

获取 SHA-1 值(hash 值):

$ git log
commit b830542ac6953c0bf1c49fa5ae00a9be239ac6ca (HEAD -> master)
Author: QAQSarah <0979@example.com>
Date:   Tue Aug 25 22:23:54 2020 +0800
    2
commit 947d9649b7a2c028050da2fa7aafef8f67cc9997
Author: QAQSarah <0979@example.com>
Date:   Tue Aug 25 22:23:33 2020 +0800
    1

如果你在 git log 后加上 --abbrev-commit 参数,输出结果里就会显示简短且唯一的值;默认使用七个字符,不过有时为了避免 SHA-1 的歧义,会增加字符数:

$ git log --abbrev-commit --pretty=oneline
b830542 (HEAD -> master) 2
947d964 1

假如这个提交的 SHA-1 的值是 974d...,则:

$ git show 947d9649b7a2c028050da2fa7aafef8f67cc9997
commit 947d9649b7a2c028050da2fa7aafef8f67cc9997
Author: QAQSarah <0979@example.com>
Date:   Tue Aug 25 22:23:33 2020 +0800
    1
diff --git a/ss.txt b/ss.txt
new file mode 100644
index 0000000..e69de29

# 分支引用

显示一个分支的最后一次提交的对象:git show [分支名]

指明一次提交最直接的方法是有一个指向它的分支引用。例如,你想要查看一个分支的最后一次提交的对象,假设 topic1 分支指向 947d... ,那么以下的命令是等价的。

$ git show 947d9649b7a2c028050da2fa7aafef8f67cc9997
$ git show topic1

如果你想知道某个分支指向哪个特定的 SHA-1,或者想看任何一个例子中被简写的 SHA-1 ,你可以使用一个叫做 rev-parse 的 Git 探测工具。

$ git rev-parse topic1
947d9649b7a2c028050da2fa7aafef8f67cc9997

# 引用日志

引用日志里的简称指明单个提交:git show HEAD@{n}

当使用 Git 工作时,Git 会在后台保存一个引用日志(reflog),引用日志记录了最近一次的 HEAD 和分支引用所指向的历史。

git reflog:查看引用日志

$ git reflog
b830542 (HEAD -> master) HEAD@{0}: commit: 2
947d964 HEAD@{1}: commit (initial): 1

每当你的 HEAD 所指向的位置发生了变化,Git 就会将这个信息存储到引用日志这个历史记录里。 通过这些数据,你可以很方便地获取之前的提交历史。 如果你想查看仓库中 HEAD 在五次前的所指向的提交,你可以使用 @{n} 来引用 reflog 中输出的提交记录

$ git show HEAD@{5}

例子如下:

# 指定次数超过提交的次数
$ git show HEAD@{2}
fatal: Log for 'HEAD' only has 2 entries.
$ git show HEAD@{1}
commit 947d9649b7a2c028050da2fa7aafef8f67cc9997
Author: QAQSarah <0979@example.com>
Date:   Tue Aug 25 22:23:33 2020 +0800
    1
diff --git a/ss.txt b/ss.txt
new file mode 100644
index 0000000..e69de29

你同样可以使用这个语法来查看某个分支在一定时间前的位置。 例如,查看你的 master 分支在昨天的时候指向了哪个提交,你可以输入:

$ git show master@{yesterday}
commit b830542ac6953c0bf1c49fa5ae00a9be239ac6ca (HEAD -> master)
Author: QAQSarah <0979@example.com>
Date:   Tue Aug 25 22:23:54 2020 +0800
    2
diff --git a/ss.txt b/ss.txt
deleted file mode 100644
index e69de29..0000000

显示昨天该分支的顶端指向了哪个提交。 这个方法只对还在你引用日志里的数据有用,所以不能用来查好几个月之前的提交。

也可以运行 git log -g 来查看类似于 git log 输出格式的引用日志信息:

$ git log -g master commit
734713bc047d87bf7eac9674765ae793478c50d3
Reflog: master@{0} (Scott Chacon <schacon@gmail.com>)
Reflog message: commit: fixed refs handling, added gc auto, updated
Author: Scott Chacon <schacon@gmail.com>
Date:   Fri Jan 2 18:32:33 2020-0800
    fixed refs handling, added gc auto, updated tests
commit d921970aadf03b3cf0e71becdaab3147ba71cdef
Reflog: master@{1} (Scott Chacon <schacon@gmail.com>)
Reflog message: merge phedders/rdocs: Merge made by recursive.
Author: Scott Chacon <schacon@gmail.com>
Date:   Thu Dec 11 15:08:43 2019-0800
    Merge commit 'phedders/rdocs' 

值得注意的是,引用日志只存在于本地仓库,一个记录你在你自己的仓库里做过什么的日志。 其他人拷贝的仓库里的引用日志不会和你的相同;而你新克隆一个仓库的时候,引用日志是空的,因为你在仓库里还没有操作。

# 祖先引用

指明某次提交的父提交:git show HEAD^git show HEAD~

如果你在引用的尾部加上一个 ^(脱字符),Git 转换其解析为该引用的上一个提交。假设你的提交历史是:

$ git log --pretty=format:'%h %s' --graph
* 3201521 test1
* b830542 2
* 947d964 1

你也可以在 ^ 后面添加一个数字 —— 例如 b830542^1 代表 “b830542 的第一父提交” 这个语法只适用于合并(merge)的提交,因为合并提交会有多个父提交。 第一父提交是你合并时所在分支,而第二父提交是你所合并的分支:

$ git show b830542^
commit 947d9649b7a2c028050da2fa7aafef8f67cc9997
Author: QAQSarah <0979@example.com>
Date:   Tue Aug 25 22:23:33 2020 +0800
    1
diff --git a/ss.txt b/ss.txt
new file mode 100644
index 0000000..e69de29

另一种指明祖先提交的方法是 ~。 同样是指向第一父提交,因此 HEAD~ 和 HEAD^ 是等价的。而区别在于你在后面加数字的时候。HEAD~2 代表 “第一父提交的第一父提交”,也就是 “祖父提交”例如,在之前的列出的提交历史中,HEAD~3 就是:

$ git show HEAD~3
commit b830542ac6953c0bf1c49fa5ae00a9be239ac6ca (test)
Author: QAQSarah <0969@example.com>
Date:   Tue Aug 25 22:23:54 2020 +0800
    2
diff --git a/ss.txt b/ss.txt
deleted file mode 100644
index e69de29..0000000

也可以写成 HEAD^^^,也是第一父提交的第一父提交的第一父提交:

$ git show HEAD^^^
commit b830542ac6953c0bf1c49fa5ae00a9be239ac6ca (test)
Author: QAQSarah <0969@example.com>
Date:   Tue Aug 25 22:23:54 2020 +0800
    2
diff --git a/ss.txt b/ss.txt
deleted file mode 100644
index e69de29..0000000

你也可以组合使用这两个语法 —— 你可以通过 HEAD~3^2 来取得之前引用的第二父提交(假设它是一个合并提交)。

# 指明范围提交

# 1. 双点

找出可从一个分支获得而不能从另一个分支获得的提交。例如,你有如下的提交历史示例范围选择的历史。

git log test..master(意思是“所有可从 master 分支中获得而不能从 test 分支中获得的提交”。)

$ git log test..master
commit ff8b135197a406132d6757e776cb66f7c547ed35 (HEAD -> master)
Author: QAQSarah <0979@example.com>
Date:   Mon Aug 31 23:39:52 2020 +0800
    test1-2
commit 7f07b6142e2064a8f77427579c6a46c6a5098fe5
Author: QAQSarah <0979@example.com>
Date:   Mon Aug 31 23:34:31 2020 +0800
    1
commit 3201521be8f8258ad85a5a0362660df0bd334a76
Author: QAQSarah <0979@example.com>
Date:   Mon Aug 31 23:00:31 2020 +0800
    test1

git log master..test(反过来所有在 test 而不在 master 中的分支)

$ git log master..test
commit 841ce6e314311f32a2738768b3bab73c9062a0e3 (HEAD -> test)
Author: QAQSarah <0979@example.com>
Date:   Mon Aug 31 23:47:56 2020 +0800
    test-v

# 2. 多点

在多个分支筛选提交。

例如查看这些提交是被包含在某些分支中的一个,但是不在你当前的分支上。在任意引用前加上 ^ 字符或者 --not,来指明你不希望提交被包含其中的分支因此下列三个命令是等价的:

git log refA..refB
git log ^refA..refB
git log refB --not refA 

多分支:

git log refA refB ^refC
git log refA refB --not refC

# 3. 三点

这个语法可以选择出被两个引用之一包含但又不被其中同时包含的提交。再看看之前双点示例中的提交历史。

看 master 或者 test 中包含的但不是两个共有的提交,你可以执行:(在两个分支中被单个分支包含但又不被同时包含)

$ git log master...test
commit 841ce6e314311f32a2738768b3bab73c9062a0e3 (HEAD -> test)
Author: QAQSarah <0979@example.com>
Date:   Mon Aug 31 23:47:56 2020 +0800
    test-v
commit ff8b135197a406132d6757e776cb66f7c547ed35 (master)
Author: QAQSarah <0979@example.com>
Date:   Mon Aug 31 23:39:52 2020 +0800
    test1-2
commit 7f07b6142e2064a8f77427579c6a46c6a5098fe5
Author: QAQSarah <0979@example.com>
Date:   Mon Aug 31 23:34:31 2020 +0800
    1
commit 3201521be8f8258ad85a5a0362660df0bd334a76
Author: QAQSarah <0979@example.com>
Date:   Mon Aug 31 23:00:31 2020 +0800
    test1
上次编辑于: 2024年5月10日 21:53