Reading through the thread about subtree I noticed Avery mentioning using inotify to speed up git status & co. Here is a quick hack I did some time ago to test this out, to use it call "igit" instead of "git" for all commmands you want to speed up. There is one minor nit: The speedup gain is zero :) git still traverses all directories to look for .gitignore files, which seems to totally kill the optimisation. To use it, put igit and git-inotify-daemon.pl in path, and do git config core.ignorestat=true in the repositories you want to test it with. The igit wrapper will run git update-index --no-assume-unchanged on all modified files before running any real git commands. To get inotify to ignore all changes that the git commands themselves perform, the "igit" wrapper kills the currently running daemon. Then it reads the list of updates files, and does git-update-index --no-assume-unchanged on them. Then the git command is run, and finally the daemon is fired up again. I had to do one tiny modification to git to make update-index ignore bad paths. igit - a git wrapper with an inotify daemon Linux only - requires inotifytools installed. This is juct a quick hack/proof of concept! update-index: Do not error out on bad paths, just warn --- .gitignore | 1 + builtin/update-index.c | 2 +- git-inotify-daemon.pl | 28 ++++++++++++++++++++++++++++ igit | 22 ++++++++++++++++++++++ 4 files changed, 52 insertions(+), 1 deletions(-) create mode 100755 git-inotify-daemon.pl create mode 100755 igit diff --git a/.gitignore b/.gitignore index 14e2b6b..fa67132 100644 --- a/.gitignore +++ b/.gitignore @@ -204,3 +204,4 @@ *.pdb /Debug/ /Release/ +.igit-* diff --git a/builtin/update-index.c b/builtin/update-index.c index 3ab214d..c905d78 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -282,7 +282,7 @@ static void update_one(const char *path, const char *prefix, int prefix_length) } if (mark_valid_only) { if (mark_ce_flags(p, CE_VALID, mark_valid_only == MARK_FLAG)) - die("Unable to mark file %s", path); + fprintf(stderr, "Unable to mark file %s\n", path); goto free_return; } if (mark_skip_worktree_only) { diff --git a/git-inotify-daemon.pl b/git-inotify-daemon.pl new file mode 100755 index 0000000..a57ceef --- /dev/null +++ b/git-inotify-daemon.pl @@ -0,0 +1,28 @@ +#!/usr/bin/env perl +# Run from igit + +use warnings; +use strict; + +die "Usage: $0 <output-file>" unless $#ARGV == 0; +my $output = $ARGV[0]; +my $pid = open(INOTIFY, "exec inotifywait -q --monitor --recursive --exclude .git -e attrib,moved_to,moved_from,move,create,delete,modify --format '%w%f' .|") or die "Cannot run inotifywait: $!\n"; + +$| = 1; +print "$pid\n"; + +my %modified_files; +while (<INOTIFY>) { + s=^./==; + chomp; + $modified_files{$_} = 1; +} + +# Output file must be opened as late as possible, it is a named pipe +# and the listener won't be here before inotifywait exits. +# open would just hang if it was done earlier. +open(OUT, ">$output"); +foreach my $key (sort keys %modified_files) { + print OUT "$key\000"; +} +exit 0; diff --git a/igit b/igit new file mode 100755 index 0000000..60c5bb2 --- /dev/null +++ b/igit @@ -0,0 +1,22 @@ +#!/bin/sh + +TOPDIR=`git rev-parse --show-cdup` || exit 1 + +if [ ! "$TOPDIR" ]; then + TOPDIR="./" +fi + +PIPE=.igit-pipe +PIDFILE=.igit-pid + +if [ -p ${TOPDIR}${PIPE} ] && kill -TERM `cat ${TOPDIR}${PIDFILE}`; then + ( cd $TOPDIR && git update-index --verbose --no-assume-unchanged -z --stdin < $PIPE ) +fi + +git "$@" + +cd $TOPDIR +rm -f $PIPE +mkfifo $PIPE +git-inotify-daemon.pl $PIPE > $PIDFILE 2>> .igit-errors </dev/null & + -- 1.7.2.rc0 - Finn Arne -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html