Blame view

tools/tardiff 1.42 KB
Georg Hopp authored
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
#!/bin/bash

##
# Create an unified diff over two tar archives.
#
# Author: Georg Hopp <ghopp@bigpoint.net>
# Date: Tue Apr 17 17:19:56 CEST 2012
# Version: 1.0.0
#

##
# This one is not POSIX conform. POSIX does not define
# process substitution via <() or >(). The alternative
# I tries is using fifos but doing this with seems to
# be a synchonization nightmare.
#

function tardiff() {
	local SED="/bin/sed"
	local SORT="/usr/bin/sort"
	local TAR="/bin/tar"
	local DIFF="/usr/bin/diff"
	local XARGS="/usr/bin/xargs"
	local BASH="/bin/bash"

	if [ 2 -ne $# ]
	then
		echo "tardiff tar1 tar2"
		return 1
	fi

	local TAR1=$1
	local TAR2=$2

	local FILES1="${TAR} tfa \"${TAR1}\""
	local FILES2="${TAR} tfa \"${TAR2}\""

	##
	# get the union of all files in both tar's
	# Exclude directories.
	#
	local FILES="${SORT} -u <(${FILES1}) <(${FILES2}) | ${SED} '/\/$/d'"

	##
	# create a diff over all files and change the /dev/fd/ entries
	# with the current filename.
	# The resulting diff can be used as a patch on the extracted
	# first tar to get the content of the extracted second tar.
	#
	eval ${FILES} | ${XARGS} -I %file ${BASH} -c "
		FILE=\"%file\"
		ESC_FILE=\"\${FILE//\//\/}\"
		${DIFF} -Nau \
		<(${TAR} xfOa \"${TAR1}\" \"%file\" 2>/dev/null) \
		<(${TAR} xfOa \"${TAR2}\" \"%file\" 2>/dev/null) | \
		${SED} 's/\/dev\/fd\/[0-9]\+/'\${ESC_FILE}'/'"
}

test "X$(basename -- "$0")" = "Xtardiff" && tardiff "$@"

# vim: set ft=sh ts=4 sw=4: