I think you have to brute-force this. It is going to be slow.
git rev-list
lists all commits in a range. git diff --shortstat
outputs the number of changed lines and files. Unfortunately, you cannot compare commits with external directories, so you either have to commit the contents of the directory once (e.g. on an orphaned/detached branch) or by checking out each commit that you want to test. I assume that having the directory available as commit will be a lot faster (YMMV).
Combine all of that and you get:
git rev-list --all \
| while read -r commit; do
echo "$(git diff --shortstat "$commit" "$needle") -- $(git log -1 --pretty="format:%h %ci" "$commit")";
done | sort -n | head -10
NB.This takes really long to run. If you know beforehand that only a limited set of commits are candidate commits, pass a range to the first rev-list
(e.g. branch-a~10..branch-a
instead of --all
to only compare the latest 10 commits on branch-a
).
needle
is a variable containing the id (hash) of your orphaned commit which you want to compare. sort -n
to perform numeric sort and head -10
to select only the 10 best candidates. You probably want to output the full list (maybe even before sorting) and write it to a file. Then you can sort and pick the best candidate without having to perform all comparisons again.