Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Git的顺序号及其应用

引言

Git中每条Commit都会有一个 commit id,它是一个 sha1 hashsha1 hash 是commit的唯一标识。

SVN中的每条Commit则一般会带有一个顺序号。可以比较直观地看到commit序号的顺序增长。

那么Git中是否有类似SVN中顺序号的概念呢?答案是有的。而且在有些场合中,它还会发挥作用。

Git的顺序号

顺序号的定义

要获取顺序号,首先要明确顺序号的含义。

一般来说,有如下两种常用的定义:

  • 从给定的 git revision 开始,递归寻找 parent revision。所有能找到的 revision数量+1即为当前revision的顺序号。
  • 从给定的git revision开始,递归寻找parent revision,但是在有多个parent时(Merge)只取第一个parent。所有能找到的revision数量+1即为当前revision的顺序号。

两种方式的主要区别是在遇到Merge时,是否处理所有链路。

顺序号的获取

新版的 git 中,提供了 rev-list命令,可以列出所有的parent revision。通过参数,还可以控制对Merge的处理方式。

因此要获取顺序号,只需要 git rev-list --count HEADgit rev-list HEAD|wc -l即可。

在遇到Merge请求时,默认采用方式一,即递归查找所有的parent revision。rev-list中也提供了--first-parent选项,可以使用方式二,即只取第一个parent的方式。

顺序号的应用

知道了顺序号之后,能用来做什么呢?

一个典型的应用场景,是在持续集成环境中,使用顺序号发布决定版本号,提供一种易读的版本自增方案。

举例来说,对npm仓库中的软件包,如果希望每次 git push时都自动发布版本,则有如下选择:

  1. 每次版本发布时,自动修改package.json中的版本号。如将 2.1.0 自动改成 2.1.1。
  2. 每次版本发布时,不修改package.json中的版本号,通过给它加后缀来使其唯一。如2.1.0-234,或 2.1.0-sha1。这里的234是指顺序码。

第一种方式不太可取,因为它会自动添加很多个Commit,对持续集成是比较大的干扰。

第二种方式中,添加后缀的时候,可选择顺序号或sha1,或者同时添加。顺序号相对会比较容易理解,且能够方便地通过版本号看出版本间的时间先后关系,所以优先使用顺序号。

这种方式在多分支环境中不能保证唯一性,所以一般会通过加 preid (一般是分支名)来保证唯一性。另外在发布到 npm 仓库时,也可以使用 --dist-tag 的方式,使每个分支的 dist-tag相互独立,不互相干扰。

顺序号和sha1之间的关联

顺序号和sha1之间的关联是 1:N。

  • 通过给定的sha1,可以得到固定的顺序号
  • 通过给定的顺序号,无法得到确切的sha1

这也是为什么上方中提到,涉及到多分支时,通过顺序号无法保证版本号的唯一性。

示意图如下:

➜  git init
Initialized empty Git repository in /private/tmp/git/.git/
➜  touch README.md && git add . && git commit -m 'init' 
[master (root-commit) 220ec4b] init
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README.md
➜  git rev-list --count HEAD   
1
➜  git checkout -b develop && touch 1.txt && git add . && git commit -m '1.txt'
Switched to a new branch 'develop'
[develop 014af28] 1.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 1.txt
➜  git rev-list --count HEAD   
2
➜  git checkout master && touch 2.txt && git add . && git commit -m '2.txt'
➜  git rev-list --count HEAD   
2
➜  git merge develop
➜  git rev-list --count HEAD   
4

最初的 init 顺序号是1,切出新分支或在原分支中做修改,之后顺序号都是2。而在两个分支合并后,顺序号就变成了4。

因此,顺序号是不唯一的,在上面的示例中,出现了两个顺序号为2的revision。

以上就是对Git顺序号的简单介绍,希望对您有所帮助。

@banyudu

This comment has been minimized.

Copy link
Owner Author

@banyudu banyudu commented Feb 29, 2020

git_order

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.