JavaBeast JavaBeast - 2 months ago 8x
Linux Question

diff two rpms? -- linux

Some unknown changes were made to my baseline (java/ C++) and installed in a new rpm. I would like a way to compare the content of this rpm with an old one to see the changes made. Is this possible?

If there is no easy way to do this, is there a way to get a content list of rpm file names within it organized by date?


If you have the previous rpm package file, you can unpack that, e.g., using unrpm into a temporary directory and use diff -r to compare the results.

Here is an example, which I made to illustrate, between two development versions of ncurses:


failed() {
    echo "? $*" >&2
    exit 1

# get the package filename as parameter, defaulting to one used for example
oldpkg=$(readlink -f "${1:-/tmp/ncurses6-6.0-20150926.x86_64.rpm}")
pkgname=$(rpm -qip "$oldpkg" 2>/dev/null | awk '/^Name .*:/ { print $3; exit 0; }')

[ -f "$oldpkg" ] || failed "no package file found: $oldpkg"
[ -n "$pkgname" ] || failed "no package name found in $oldpkg"

# The tags for this question are "linux" and "rpm", so mktemp and bash are assumed.
tempdir=$(mktemp -d "${TMPDIR:-/tmp}/pkgcompare.XXXXXX")
trap 'rm -rf "$tempdir"' EXIT ERR

# Fedora sets CDPATH, which would echo (cancel that).
unset CDPATH

mkdir -p "$tempdir"/{new-version,old-version}

cd "$tempdir/new-version" || exit
# the query returns absolute pathnames beginning with "/"
rpm -ql "$pkgname" | while :
    read path
    [ -z "$path" ] && break
    [ -d "$path" ] && mkdir -p ".$path"
    [ -f "$path" ] && mkdir -p "./${path%/*}"
    [ -f "$path" ] && cp -p "$path" ".$path"

cd "$tempdir/old-version" || exit
rpm2cpio "$oldpkg" | cpio -i -d 2>/dev/null

cd $tempdir || exit
# I would usually pipe this into diffstat, but you may want the actual diffs
diff -r -u -N old-version new-version | diffstat

and output (only the diffstat is left, other output suppressed):

 bin/ncursesw6-config           |    2 +-
 include/ncursesw6/curses.h     |    8 ++++----
 include/ncursesw6/ncurses.h    |    8 ++++----
 lib64/        |binary
 lib64/      |binary
 lib64/    |binary
 lib64/          |binary
 lib64/        |binary
 lib64/      |binary
 lib64/            |binary
 lib64/          |binary
 lib64/        |binary
 lib64/pkgconfig/formw6.pc      |    2 +-
 lib64/pkgconfig/menuw6.pc      |    2 +-
 lib64/pkgconfig/ncurses++w6.pc |    2 +-
 lib64/pkgconfig/ncursesw6.pc   |    2 +-
 lib64/pkgconfig/panelw6.pc     |    2 +-
 lib64/pkgconfig/ticw6.pc       |    2 +-
 lib64/pkgconfig/tinfow6.pc     |    2 +-
 19 files changed, 16 insertions(+), 16 deletions(-)

You could of course apply the same approach to two rpm packages; the question made it apparent that one is installed, and the other may be accessible.