5

I found the following changelogs, but all of them list change / new features in terms of date rather than version number:

For instance, I was trying to find out in what GNU sed version the -z / --null-data option was introduced, and while the above tells me 2012-02-05, I cannot tell what version number that maps to.

2 Answers 2

4

For a list, see the end of this answer.

above tells me 2012-02-05, I cannot tell what version number that maps to

For simply mapping dates to version numbers you can check the download section on GNU sed's homepage. There you have a list of the form

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     
[...]

Note that the list is sorted alphabetically, so 4.2 comes after 4.2.1. You can correctly sort it by copy-pasting it into sort -V.

Assuming that every change lands in the next version, the change from 2012-02-05 would be released in version 4.2.2.

determine which feature was introduced in what version?

In general, this is very tricky. Even though ChangeLog-2014 and git log together pretty much cover the whole lifespan of GNU sed, not every change is mentioned. The next step would be to parse the documentation (manpages and usage() function) of the old versions, but those are incomplete too sometimes.

Example 1: -E first appeared in version 4.2 on 2004-08-22, but was neither mentioned in the logs nor in the official documentation. The option was first mentioned in in a git commit from 2013-10-16 (more than 9 years later!) saying "Document "-E" option to use EREs".

In other cases, the changelog might be very misleading.

Example 2: In Changelog-2014 the first reference to -r seems to be an entry from 2000-12-08 noting "sed/sed.c(main): Implemented the `r' and `R' options". This sounds pretty definite: Clearly -r cannot have been available before that, right?! No, it was already in version 3.0.1 from 1998.
No idea what's up with that changelog entry, but version 3.0.1 is clearly from 1998 (the source files have that modification date and their copyright comments list 1998 as the last year, also the changelog mentions the release of 3.0.1 in 1998) and clearly supports -r (I compiled that version and ran ./sed -r 's/a(b)c/\1/' <<< abc which printed b as expected, and abc when leaving out the -r option).

Therefore, it seems like the best way to find out when a feature was introduced, is to inspect the source code of all versions. This may seem daunting at first, but at least for command line options this is pretty straightforward: Search for the main() function and look where argv is used.

Note that git://git.sv.gnu.org/sed is incomplete too. The oldest commit is from 2004 (check git log --reverse) and the oldest tag v4.1.5 tags a version from 2006 (check git log --simplify-by-decoration --format="%ai %d"). So, to inspect the older versions you have to download them from the earlier mentioned website.
Even there some things are lost to time. The versions 4.0.0 to 4.0.5 are "not available because their authenticity is being confirmed". But I guess this isn't important since 4.0.0 is less than one year apart from 4.0.6.

Luckily, the option parsing of GNU sed was so stable that I could hack something together to automatically generate a list of changes:

The script (compressed into one line to safe space in this answer) ...

#! /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

... generated the following list:

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

From there we can see that -z first appeared in version 4.2.2 which was released on 2012-12-22.

Note that -R/--regexp-perl from version 4.0.6 to 4.5 required #define REG_PERL before compiling, so the the packaged versions in Debian, Ubuntu, and so on never supported this option.

1
  • My pleasure, @Socowi; the previously accepted answer was definitely helpful too, but yours paints a more complete picture and even includes an automated way to get the information.
    – mklement0
    Aug 25, 2021 at 12:37
4

Since you have the git history, and the GNU sed developers added git tags for versions, the version you're looking for is 4.2.2, whose tag was added 4 years ago (4.2.1's tag was added 8 years ago, so clearly before 2012). The log for 4.2.2 includes the commit adding -z. Also, if you cloned the source, you can look up which tags included that commit:

git tag --contains <commit>
1
  • Great, thanks. Just to list all steps (correct me if there's a better approach): to find the relevant commit, search the output of git log for the relevant mention of the feature (e.g., --null-data), then look up the tags as described.
    – mklement0
    Jul 11, 2017 at 8:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .