How to git commit nothing without an error?

Question:

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")
Asked By: kojiro

||

Answers:

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 bypasses the safety, and
    is primarily for use by foreign SCM interface scripts.
Answered By: Sven Marnach
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).

Answered By: Tyler Eaves

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

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.

Answered By: Tobi

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))
Answered By: devpascoe

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"

Just extending Tobi & Holger‘s answer with an explicit if statement.

git add -A
if ! git diff-index --quiet HEAD; then
  git commit -m "Message here"
  git push origin main
fi

Let’s give it a bit explanation.

  1. git add -A: staged your changes (required for the next step)

  2. git diff-index --quiet HEAD will compare your staged changes with the HEAD.

    --quiet is impotant as it will imply --exit-code which "makes the program exit with codes 1 if there were differences and 0 means no differences".

See –quiet.

Answered By: Ninh Pham

What, if you’d just prevent failures caused by empty commits instead of ignoring them?

git diff --quiet && git diff --staged --quiet || git commit -am 'Commit message'

With this script: If there are no changes, it does not commit. If there are changes, it commits them.

Source: https://stackoverflow.com/a/40255467/6836871

Answered By: ndsvw
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.