From 419be355e2c200f940e02aba1a5f503974399bec Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Mon, 25 Mar 2019 13:50:16 +0100 Subject: pkgs.profpatsch: add git-commit-index tools A set of utilities to generate and query a git commit index, which is a database that knows which revs (that is: commits) are in which git repository. That way we can query for the project that contains a commit and show them, e.g. with xdg-open. --- pkgs/profpatsch/git-commit-index/lib.sh | 102 ++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 pkgs/profpatsch/git-commit-index/lib.sh (limited to 'pkgs/profpatsch/git-commit-index/lib.sh') diff --git a/pkgs/profpatsch/git-commit-index/lib.sh b/pkgs/profpatsch/git-commit-index/lib.sh new file mode 100644 index 00000000..229eec1e --- /dev/null +++ b/pkgs/profpatsch/git-commit-index/lib.sh @@ -0,0 +1,102 @@ +set -euo pipefail + +# nix-shell -p cdb --run 'bash -c \'source ~/tmp/gitcdb.sh; for r in $(findRepos ~/kot); do genIndex . "$r"; done\'' + +findRepos () { + find "$1" -type d -name ".git" + # TODO check each repo is actually git repo +} + +genIndex () { + local indexDir=$(realpath -- "$1") + local path=$(realpath -- "$2") + if [ ! -d "$indexDir" ]; then + echo "index directory does not exist: $indexDir" + exit 111 + fi + # TODO: multimap failure + # + local filename="$indexDir/$(echo $path | sed -e 's|_|__|g' -e 's|/|_|g')" + local pathLength=$(echo "$path" | wc --bytes | tr -d '\n') + (pushd "$path" > /dev/null \ + && ( git log --all --format="format:%H" \ + | sed -e "s/^\(.*\)$/+40,0:\1->/" \ + ; echo \ + ; echo "+8,${pathLength}:git-path->${path}" \ + ; echo; echo \ + ) \ + | cdbmake "$filename" "$filename.tmp" \ + ) +} + +query () { + local indexDir=$(realpath -- "$1") + local key="$2" + + local found=0 + local result= + + # TODO make this parallel (and switch away from bash) + for f in "$indexDir"/*; do + + set +e + # don't need result because empty string + <"$f" cdbget "$key" >/dev/null + local ret=$? + set -e + + case $ret in + 0) + # TODO: back + found=1 + + set +e + # now find original path + local origDotGit=$(<"$f" cdbget "git-path") + local retGitPath=$? + set -e + + case $retGitPath in + 0) + : + ;; + 100) + echo "shouldn’t happen; git-path was not in $f" + exit 127 + ;; + 111) + echo "db error in $f" + exit 111 + ;; + *) + echo "shouldn’t happen; exitcode was $ret" + exit 127 + ;; + esac + + # return workspace file + result=$(dirname "$origDotGit") + break + ;; + 100) + # not found + : + ;; + 111) + echo "db error in $f" + exit 111 + ;; + *) + echo "shouldn’t happen; exitcode was $ret" + exit 127 + ;; + esac + done + + if [ $found -eq 0 ]; then + exit 100 + else + echo "$result" + exit 0 + fi +} -- cgit 1.4.1