diff --git a/schhist/README b/schhist/README new file mode 100644 index 0000000..f30d56e --- /dev/null +++ b/schhist/README @@ -0,0 +1,46 @@ +gitwhoareyounow +--------------- + +gitwhoareyounow is used to find a single identity for files that have been +renamed in the history of a project. + +E.g., if a file foo.c is created in revision 1 (assuming successive revisions +numbered 1, 2, etc.) and renamed to bar.c in revision 2, gitwhoareyounow +would then return the name bar.c for this file in any revision we consider. + +gitwhoareyounow has to be given a repository in which the historical commit +has been checked out, and the name the file had in that commit. + +Example: + +$ git init +$ date >foo.c +# git add foo.c +# git commit -m "foo.c, rev 1" +$ git mv foo.c bar.c +$ git commit -m "foo.c renamed to bar.c, rev 2" +$ git checkout HEAD~1 +$ ls +foo.c +$ gitwhoareyounow . foo.c +bar.c + + +Multiple files may use the same identity +- - - - - - - - - - - - - - - - - - - - + +E.g., if a file foo.c is created in revision 1, deleted in revision 3, and +then a new file named foo.c is created in revision 4, gitwhoareyounow would +call both of them foo.c + + +Multiple files sharing the same identity can conflict +- - - - - - - - - - - - - - - - - - - - - - - - - - - + +E.g., taking the first example with foo.c renamed to bar.c in revision 3, if +a file bar.c existed in revision 1 but was deleted in revision 2, +gitwhoareyounow running on revision 1 would identify both the foo.c and the +bar.c as bar.c + +gitwhoareyounow does not try to resolve such conflicts. This is already +complex enough as it is :-) diff --git a/schhist/gitwhoareyounow b/schhist/gitwhoareyounow new file mode 100755 index 0000000..50f130f --- /dev/null +++ b/schhist/gitwhoareyounow @@ -0,0 +1,49 @@ +#!/bin/sh +# +# gitwhoareyounow - Trace the future of a file in git across renames +# +# Written 2010 by Werner Almesberger +# Copyright 2010 Werner Almesberger +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# + + +usage() +{ + cat <&1 +usage: $0 repo-dir path + + The file to trace must be at repo-dir/path + The repo must be on a branch in the past of the current master. +EOF + exit 1 +} + + +if [ -z "$2" -o ! -z "$3" ]; then + usage +fi + +if [ ! -d "$1" -o ! -d "$1/.git" ]; then + echo "no git repository at $1" 1>&2 + exit 1 +fi +if [ ! -f "$1/$2" ]; then + echo "cannot find $2" 2>&1 + exit 1 +fi + +cd "$1" || exit +prev=`git rev-parse @{0}` +name=$2 +for n in `git rev-list --reverse ..master`; do + new=`git diff-tree --name-status -r -M $prev $n | + awk -F '\t' '$1~/^R/ && $2=="'"$name"'" { print $3 }'` + [ -z "$new" ] || name=$new + prev=$n +done +echo "$name"