#!/bin/sh # situation: work tree is unknown rev # arguments: git rev-list arguments # we now identify the one revision with least differences usage() { echo "Usage: $0 [--cached] git-rev-list args..." echo echo "Example: $0 --all" echo "Compares current work tree to all revisions, and identifies the" echo "closest match." echo echo "Example: $0 --cached v1.0..HEAD" echo "Compares current index to all revisions between v1.0 and HEAD," echo "and identifies the closest match." } case "$1" in --cached) use_worktree=false shift ;; --help|-h) usage exit 0 ;; *) use_worktree=true ;; esac if [ $# = 0 ]; then usage >&2 exit 1 fi diffopts="-M -C" if $use_worktree; then echo >&2 "Saving index..." oldindex=`git write-tree` # set up resetting trap 'echo >&2 "Restoring index..."; git reset "$oldindex" .' EXIT trap 'exit 1' INT TERM echo >&2 "Creating index..." git add -A fi echo >&2 "Listing candidates..." allrevs=`git rev-list "$@"` echo >&2 "Evaluating candidates..." bestrev= bestrevscore= for rev in $allrevs; do score=`git diff $diffopts --cached "$rev" | wc -l` if [ -z "$bestrevscore" ] || [ "$score" -lt "$bestrevscore" ]; then echo >&2 "Improved to $rev (score: $score)" bestrev=$rev bestrevscore=$score if [ $score -eq 0 ]; then break fi fi done echo >&2 "Done." if [ -z "$bestrevscore" ]; then exit 1 fi echo "$bestrev" git diff $diffopts --cached "$bestrev" >&2