96
votes

I'm trying to write a fabric script that does a git commit; however, if there is nothing to commit, git exits with a status of 1. The deploy script takes that as unsuccessful, and quits. I do want to detect actual failures-to-commit, so I can't just give fabric a blanket ignore for git commit failures. How can I allow empty-commit failures to be ignored so that deploy can continue, but still catch errors caused when a real commit fails?

def commit():
    local("git add -p && git commit")
5

5 Answers

176
votes

Catch this condition beforehand by checking the exit code of git diff?

For example (in shell):

git add -A
git diff-index --quiet HEAD || git commit -m 'bla'

EDIT: Fixed git diff command according to Holger's comment.

66
votes

From the git commit man page:

--allow-empty
    Usually recording a commit that has the exact same tree as its
    sole parent commit is a mistake, and the command prevents you
    from making such a commit. This option bypassesthe safety, and
    is primarily for use by foreign SCM interface scripts.
5
votes
with settings(warn_only=True):
  run('git commit ...')

This causes fabric to ignore the failure. Has the advantage of not creating empty commits.

You can wrap it in a additional layer of with hide('warnings'): to totally suppress output, otherwise you'll get a note in the fabric output that the commit failed (but the fabfile continues to execute).

0
votes

When going through a shell, you can use the ... || true technique to declare a failure to be expected and ignored:

git commit -a -m "beautiful commit" || true

This would also prevent a shell script from exiting when using the errexit option.

Instead of ... || true you can also use any other command that exits with a return code of 0, such as

git commit -a -m "beautiful commit" || echo "ignore commit failure, proceed"
-4
votes

try/catch baby!

from fabric.api import local
from fabric.colors import green


def commit(message='updates'):
    try:
        local('git add .')
        local('git commit -m "' + message + '"')
        local('git push')
        print(green('Committed and pushed to git.', bold=False))
    except:
        print(green('Done committing, likely nothing new to commit.', bold=False))