GNU Sed 版本历史记录(变更日志)——如何确定哪个版本引入了哪个功能?

GNU Sed 版本历史记录(变更日志)——如何确定哪个版本引入了哪个功能?

我找到了以下变更日志,但它们都列出了以下方面的变更/新功能日期而不是版本号

例如,我试图找出在哪个 GNUsed版本中引入了-z/--null-data选项,虽然上面告诉我 2012-02-05,但我无法判断映射到哪个版本号。

答案1

有关列表,请参阅此答案的末尾。

上面告诉我 2012-02-05,我不知道映射到什么版本号

为了简单地将日期映射到版本号,您可以检查下载部分GNU sed 的主页。那里有一个表格列表

Index of /gnu/sed
Name                   Last modified      Size
[...] 
sed-4.2.1.tar.gz       2009-06-27 18:22   1.1M   
sed-4.2.1.tar.gz.sig   2009-06-27 18:22   72 
sed-4.2.2.tar.gz       2012-12-22 11:01   1.3M   
sed-4.2.2.tar.gz.sig   2012-12-22 11:01   72     
[...]

请注意,该列表是按字母顺序排序的,因此 4.2 出现了4.2.1.您可以通过将其复制粘贴到 中来正确排序sort -V

假设每个更改都会在下一个版本中发布,则 2012-02-05 以来的更改将在版本 4.2.2 中发布。

确定哪个版本引入了哪些功能?

一般来说,这是非常棘手的。虽然ChangeLog-2014一起git log几乎涵盖了 GNU sed 的整个生命周期,但并未提及所有更改。下一步是解析usage()旧版本的文档(手册页和函数),但有时这些文档也不完整。

示例1: -E首次出现于2004年8月22日的4.2版本中,但日志和官方文档中均未提及。该选项首次在 git 中提到2013-10-16 提交(9年多后!)说“使用 ERE 的文档“-E”选项”

在其他情况下,变更日志可能非常具有误导性。

示例2:Changelog-2014第一个参考似乎-r是 2000-12-08 的条目“sed/sed.c(main):实现了‘r’和‘R’选项”。这听起来很明确:显然-r在此之前不可能可用,对吧?!不,它已经是 1998 年的 3.0.1 版本了。
不知道那个变更日志条目是怎么回事,但 3.0.1 版本显然是 1998 年的(源文件有修改日期及其版权评论列表,1998 年是去年,变更日志还提到了 1998 年 3.0.1 的发布)并明确支持-r(我编译了该版本并运行,其按预期./sed -r 's/a(b)c/\1/' <<< abc打印,并且在省略该选项时)。babc-r

因此,看起来像最好的办法找出某个功能何时推出,就是检查所有版本的源码。乍一看这可能令人望而生畏,但至少对于命令行选项来说,这非常简单:搜索main()函数并查看argv使用位置。

请注意,这git://git.sv.gnu.org/sed也是不完整的。最旧的提交来自 2004 年(检查git log --reverse),最旧的标签v4.1.5标记 2006 年的版本(检查git log --simplify-by-decoration --format="%ai %d")。因此,要检查旧版本,您必须从前面提到的下载它们网站
即使那里有些东西也随着时间而丢失了。版本 4.0.0 到 4.0.5 是“不可用,因为其真实性正在确认”。但我想这并不重要,因为 4.0.0 与 4.0.6 相隔不到一年。

幸运的是,GNU sed 的选项解析非常稳定,我可以将一些东西组合在一起以自动生成更改列表:

脚本(在这个答案中压缩成一行以确保安全)...

#! /bin/bash
old=; curl -s "https://ftp.gnu.org/gnu/sed/" | sed -nE 's/.* href="sed-([0-9.]*)(\.tar\.[^."]*)".*([0-9]{4}-..-..).*/\1 \3 sed-\1\2/p' | sort -u -k1,1V | while read version date file; do printf '%-6s %s\n' "$version" "$date"; curl -sO -C- "https://ftp.gnu.org/gnu/sed/$file"; new=$(tar -xaf "$file" -O --wildcards '*/sed.c' | sed -En -e '/"[^" ]*e:[^" ]*"/{s/.*"([^" ]*e:[^" ]*)".*/\1/;s/://g;s/./\n-&/gp}' -e '/longopts\[]/,/};/s/[^"]*"([^"]*)".*/--\1/p' | sort -u); comm -3 <(printf %s "$old") <(printf %s "$new") | awk '{if (/^-/) r=r" "$1; else a=a" "$1} END {if (a!="") print "  new:" a; if (r!="") print "  removed:" r}'; old=$new; done

...生成以下列表:

1.18   1993-06-01
  new:  -e --expression -f --file -h --help
        -n --quiet --silent -V --version
2.05   1994-05-13
3.01   1998-07-23
  new: -r --rxtest
3.02   1998-08-02
4.0.6  2003-03-18
  new: -i --in-place -l --line-length
       -R --regexp-extended --regexp-perl
       -s --separate -u --unbuffered
  removed: --rxtest
4.0.7  2003-04-11
4.0.8  2003-10-21
4.0.9  2004-01-10
4.1    2004-06-15
  new: --posix
  removed: -h
4.1.1  2004-07-06
4.1.2  2004-08-22
4.1.3  2005-01-19
4.1.4  2005-01-28
4.1.5  2006-02-03
4.2    2009-04-30
  new: -b --binary -E --follow-symlinks
4.2.1  2009-06-27
4.2.2  2012-12-22
  new: --null-data -z --zero-terminated
4.3    2017-01-04
  new: --sandbox
4.4    2017-02-03
4.5    2018-03-31
4.6    2018-12-20
  new: --debug
  removed: -R --regexp-perl
4.7    2018-12-21
4.8    2020-01-14

从那里我们可以看到它-z首次出现在2012年12月22日发布的4.2.2版本中。

需要注意的是,从4.0.6到4.5版本需要在编译前-R加上/ ,所以Debian、Ubuntu等打包版本从来不支持该选项。--regexp-perl#define REG_PERL

答案2

由于您有 git 历史记录,并且 GNU sed 开发人员为版本添加了 git 标签,因此您要查找的版本是 4.2.2,其标签是 4 年前添加的(4.2.1的标签是8年前添加的,在 2012 年之前就很清楚了)。这4.2.2 的日志包括提交添加-z.另外,如果您克隆了源,您可以查找该提交包含哪些标签

git tag --contains <commit>

相关内容