Skip to content

Instantly share code, notes, and snippets.

@srbs
Created October 7, 2012 07:16
Show Gist options
  • Save srbs/3847393 to your computer and use it in GitHub Desktop.
Save srbs/3847393 to your computer and use it in GitHub Desktop.
diff any file using opendiff (svn, git, mercurial, fossil)
# function for .bash-profile or .bashrc
# od <file> [<file2>]
# diff's the given file using opendiff based on the file's vcs
# supports svn, git, mercurial, fossil, & CVS
# can specify any path, checks are done where the file is
# when file2 is specified, fall back to default opendiff behavior
od()
{
# check params
[ $# -eq 0 ] && echo "No files to compare!" >&2 && return 1
[ $# -ge 1 ] && [ ! -e "$1" ] && echo "File does not exist: $1" >&2 && return 1
[ $# -ge 2 ] && [ ! -e "$2" ] && echo "File does not exist: $2" >&2 && return 1
if [ $# -ne 1 ]; then
`exec opendiff "$@"`
return 0
fi
dir="$(dirname "$1")"
file="$(basename "$1")"
# svn check
if [ -d "$dir/.svn" ] || [ 0 -eq `svn info "$dir" >/dev/null 2>&1; echo $?` ]; then
# svn 1.6 & before
if [ -d "$dir/.svn/text-base" ]; then
# src: http://tlzprgmr.wordpress.com/2009/09/19/opendiffsvn-command-line-shortcut/
opendiff "$dir/.svn/text-base/$file.svn-base" "$1"
return 0
# svn 1.7 & after
else
`
cd "$dir"
# src: http://stackoverflow.com/questions/1242364/how-can-i-find-the-root-folder-of-a-given-subversion-working-copy#comment15044736_1242548
root_dir="$(svn info|grep "^Working Copy Root Path")"
root_dir="/${root_dir#*/}"
# should I validate existence of either "$root_dir/.svn/pristine" or "$root_dir/.svn/wc.db" ??
rel_path="$(pwd)/$file"
rel_path="${rel_path#$root_dir}"
rel_path="${rel_path#*/}"
svnbase_file="$(sqlite3 "$root_dir/.svn/wc.db" "select substr(checksum, 7, 2)||'/'||substr(checksum, 7) from nodes where local_relpath = '${rel_path//\'/''}';")"
opendiff "$root_dir/.svn/pristine/${svnbase_file}.svn-base" "$file"
`
return 0
fi
fi
# git check
if [ -d "$dir/.git" ] || [ 0 -eq `cd "$dir"; git rev-parse --git-dir >/dev/null 2>&1; echo $?` ]; then
`
cd "$dir"
git difftool -t opendiff --no-prompt "$file"
`
return 0
fi
# mercurial check
if [ -d "$dir/.hg" ] || [ 0 -eq `cd "$dir"; hg -q stat >/dev/null 2>&1; echo $?` ]; then
`
cd "$dir"
# write original file to temp file
temp="$(mktemp ".$file.XXXXXX")"
hg cat -o "$temp" "$file"
# diff file
opendiff "$temp" "$file"
# remove temp file
rm -f "$temp"
`
return 0
fi
# fossil check
if [ 0 -eq `cd "$dir"; fossil info >/dev/null 2>/dev/null; echo $?` ]; then
`
cd "$dir"
# preserve current settings
original="$(fossil settings diff-command|grep local|awk '{print $3}')"
# diff file
fossil settings diff-command opendiff
fossil diff "$file"
# revert setting
if [ 0 -eq ${#original} ]; then
fossil unset diff-command
else
fossil settings diff-command "$original"
fi
`
return 0
fi
# CVS check
if [ -d "$dir/CVS" ]; then
`
cd "$dir"
# write original file to temp file
temp="$(mktemp ".$file.XXXXXX")"
# src: http://hints.macworld.com/article.php?story=20040316115029198
cvs update -p "$file" > "$temp" 2>/dev/null
# diff file
opendiff "$temp" "$file"
# remove temp file
rm -f "$temp"
`
return 0
fi
# otherwise, throw error
echo "Unknown vcs" >&2
return 1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment