6

When working on a git project in vim, I use the fugitive plugin.

I like to open a :Gstatus split, press - to add file and then press C to commit my changes. I also have a git pre-commit hook, it runs some test. In case of an error, it prompts me to make sure if I still want to commit.

But, when following this pattern, I don't see the output for the tests, neither the final prompt. Instead, vim freezes while the tests are running.

How would I make fugitive and a pre-commit hook get along together smoothly?

Update: This is the prompt in the git pre-commit hook:

#!/bin/bash
exec < /dev/tty

while true; do
  read -p "There were some errors in the test, do you still want to commit? (Y/n) " yn
  if [ "$yn" = "" ]; then
    yn='Y'
  fi
  case $yn in
      [Yy] ) break;;
      [Nn] ) exit;;
      * ) echo "Answer y or n.";;
  esac
done
  • I assume the pre-commit hook works fine when you just use git commit? What happens if you use a very simple pre-commit hook like only exit 0 or exit 1? – Martin Tournoij Mar 13 '15 at 23:08
  • It does work. It's really the output generated and the prompt. – Samuel Masuy Mar 14 '15 at 1:17
  • 1
    As, so you mean "Vim freezes while the tests are running"? And not "Vim freezes indefinitely and I need to kill it"? – Martin Tournoij Mar 15 '15 at 6:54
  • As soon as I press C, Vim goes to the terminal view and there is no output. I will add the part of the script which has the prompt – Samuel Masuy Mar 15 '15 at 17:14
3

On line 1019 of plugin/fugive.vim we can see how the :Gcommit command executes git:

noautocmd silent execute '!'.command.' > '.outfile.' 2> '.errorfile

With the variables replaced, the command looks like:

!env GIT_EDITOR=false git --git-dir=/home/martin/git-test/.git commit  > /tmp/vC4Lbak/1 2> /tmp/vC4Lbak/2

Notice the env GIT_EDITOR=false, this is just to prepare the .git/COMMIT_EDITMSG and checking if any error occurred! We then open a new buffer with COMMIT_EDITMSG which the user can edit, and after this is saved, we run git commit again.

Fugitive also uses stderr for error checking, and the pre-commit hook outputs to stderr (not stdout!)

You could work around this by extensively modifying this function, but I would say that running interactive pre-commit hooks is incompatible with how :Gcommit works, the hook would be run twice, and you lose error detection.

So you'll have to run git commit from outside of Vim, or use !git commit from Vim which will work fine, except that it will launch a second Vim instance for the commit message (unless you use -m).

You can create a command for this like so:

:command! Commit !git commit

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.