1

I'm trying to create a pre-push hook to run php-cs-fixer before every push.

This is the current pre-push hook I have:

#!/bin/sh

exec php-cs-fixer fix . --config-file=".php_cs" && git commit -am 'PSR-2'

The first command gets trigger without a problem. Only the git commit -am 'PSR-2 doesn't. To be more precise, the php-cs-fixer runs followed by this error error: failed to push some refs to ..

I also tried the following without luck:

#!/bin/sh

php-cs-fixer fix . --config-file=".php_cs" && git commit -am 'PSR-2'

-

#!/bin/sh

(php-cs-fixer fix . --config-file=".php_cs" && git commit -am 'PSR-2')

According to this stackoverflow question, it should run only if cmd1 has succeeded.

Community
  • 1
  • 1
Nicolas Widart
  • 1,187
  • 4
  • 13
  • 30
  • Did you try `exec (php-cs-fixer fix . --config-file=".php_cs" ; git commit -am 'PSR-2')`? – VonC Feb 13 '15 at 08:14
  • 2
    Remove `exec`: `exec` replaces the current process by the command given in argument and never returns. It's both wrong and useless here. – gniourf_gniourf Feb 13 '15 at 08:15
  • As a side note, your shebang is wrong: it should be `#!/bin/sh` (with no spaces between `#!` and `/bin/sh`). – gniourf_gniourf Feb 13 '15 at 08:48
  • Same happens when removing `exec`. I edited the question with the error given after `php-cs-fixer` runs. – Nicolas Widart Feb 13 '15 at 08:58
  • So your first command failed (you have explicit errors—fix them!) and the second command is not executed. So all is as expected, isn't it? By the way, you second version with enclosing parentheses is useless! VonC mislead you with wrong/useless/random/inappropriate informations. Now your problem is about fixing `php-cs-fixer`. Good luck. – gniourf_gniourf Feb 13 '15 at 09:07
  • Yes the first command 'failed', in the sence that `php-cs-fixer` fixed some files. This is expected behaviour, nothing wrong with `php-cs-fixer`. That is why there's a `git commit -am` command to commit those changes before pushing. – Nicolas Widart Feb 13 '15 at 09:09
  • 1
    The `git commit -am` _will be executed_ ***only if*** _`php-cs-fixer`_ ***succeeds***. – gniourf_gniourf Feb 13 '15 at 09:10
  • Oh I see! need to use `;` instead of `&&`. Thank you!, works like a charm now :) – Nicolas Widart Feb 13 '15 at 09:16
  • Or just put the two commands on separate lines. – gniourf_gniourf Feb 13 '15 at 09:18

1 Answers1

3

The exec builtin command replaces the shell with the given program. It does NOT fork a new process to execute php-cs-fixer.

Since the shell is replaced by the php-cs-fixer program the && git commit ... is never executed.

Take a look at the manpage of exec

If command is specified, it replaces the shell. No new process is created.

The first line of php-cs-fixer should look like this

#!/usr/bin/env php

and the php-cs-fixer should have execute permissions chmod +x php-cs-fixer.

Than you can just use it

php-cs-fixer fix . --config-file=".php_cs" && git commit -am 'PSR-2'
René Link
  • 48,224
  • 13
  • 108
  • 140
  • Since OP's shebang is `#!/bin/sh`, maybe the POSIX reference is more appropriate than the Bash reference about `exec`: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_20_01 – gniourf_gniourf Feb 13 '15 at 08:52
  • Hm thanks for you reply. Using `#!/usr/bin/env php php-cs-fixer fix . --config-file=".php_cs" && git commit -am 'PSR-2'` shows the text (line break in between), but doesn't execute it. php-cs-fixer has executable rights. (I can run it outside the git hook) – Nicolas Widart Feb 13 '15 at 08:56