DJ Adams

git diff can emit different exit codes

Combining git diff exit codes and the POSIX negation operator to control GitHub Actions job step execution based on git changes.

When defining a job step in GitHub Actions, you can specify a condition that must be met for a job step to run (in a broadly similar way to how things were in Job Control Language). In my profile repo's builder workflow, I wanted only to proceed with a git commit step if there were actual changes that had been made in a previous step.

Supplying the --exit-code option to git diff makes it emit an exit code of 1 if there are differences, and 0 if not. This option is implicit in --quiet, too.

As exit code 1 represents a fail in job step conditionals, the output of git diff can be reversed with the POSIX ! operator. So in this pair of steps, the second one will only run if there are no differences detected in the first one:

- name: Check for changes (fail if none)
  run: |
    ! git diff --quiet

- name: Commit changes if required
  if: ${{ success() }}
  run: |
    git config --global user.email "qmacro-bot@example.com"
    git config --global user.name "qmacro bot"
    git add README.md
    git commit -m 'update README' || exit 0
    git push

I had to write the ! git diff --quiet within a YAML multiline expression (introduced with |) as the GitHub Actions runner didn't like it on the same line, i.e. run: ! git diff --quiet.