Ask Your Question

Cannot execute catkin_make in githook

asked 2017-08-21 11:55:49 -0600

felixd gravatar image

updated 2017-08-21 12:44:47 -0600

I have a pre-push githook that tries to execute catkin_make before pushing, to only allow pushes that (at least) can compile. It works by git invoking invoking a bash script and depending on the return code allowing or denying the push "request". The githook is invoked locally: nothing is run on the server. The script looks like this (only the important parts):


# "This hook is called by git push and can be used to prevent a push from taking place.
#  If this hook exits with a non-zero status, git push will abort without pushing anything. 
#  Information about why the push is rejected may be sent to the user by writing to standard error."
# see:

# make the script fail if any line fails, see:
set -euo pipefail

# go to the project root
# taken from here:
repo_root=$( git rev-parse --show-toplevel )
cd $repo_root

# build the project once
# this still prints output *on error*, which is what we want
build_output=$( catkin_make )

if [ $build_exit_status -eq 0 ];

    then # it worked, let git push it

        # log success message 
        echo "build succeeded, pushing is allowed"

        # exit successfully
        exit 0

    else # it failed, prevent git from pushing

        # log fail message
        echo -e "--------------------\n\n"
        echo "Failed to build the project. Not pushing."

        # exit non-successfully
        exit $build_exit_status


When I execute it in the terminal by hand, everything works just fine. But when git invokes it, this error gets printed out: ".git/hooks/pre-push: line 19: catkin_make: command not found". Line 19 is the one containing build_output=$( catkin_make ). It strangely works on another machine having pretty much the same setup. We both have ROS Kinetic installed on Ubuntu LTS 16.04 and Kubuntu LTS 16.04.

What am I doing wrong?

I think catkin_make itself cannot be found. I have this in my ~/.bashrc:

source /opt/ros/kinetic/setup.bash
source /home/felix/sailing/bord-pc/devel/setup.bash
export BORD_PC_WORKSPACE=/home/felix/sailing/bord-pc # this is my workspace

And sourcing it in the script and/or in the subshell in line 19 did not work:

source ~/.bashrc
build_output=$( source ~/.bashrc && catkin_make )
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted

answered 2017-08-21 12:41:29 -0600

felixd gravatar image

updated 2017-08-21 12:44:35 -0600

I finally found the solution:

I had to add source /opt/ros/kinetic/setup.bash directly in the subshell, the indirect sourcing through the ~./bashrc did not work for some reason. Is that a bug?

Working solution:

build_output=$( source /opt/ros/kinetic/setup.bash && catkin_make )

Thanks @gvdhoorn for your support.

EDIT: This is why it didn't work:

This was the output of git invoking the githook script: /opt/ros/kinetic/ line 47: TMPDIR: unbound variable. Which is usually not a problem, but the strict script rules enforced by set -euo pipefail caused it to crash.

edit flag offensive delete link more


Could've solved this a lot sooner then. This is what I wrote in comment 4:

Try $(source .. && catkin_make).

Good to hear you got it to work.

gvdhoorn gravatar imagegvdhoorn ( 2017-08-21 14:12:45 -0600 )edit

Hm yeah, I thought you meant sourcing the ~/.bashrc ... which somehow didn't work. But thanks! :)

felixd gravatar imagefelixd ( 2017-08-21 14:22:10 -0600 )edit

the indirect sourcing through the ~./bashrc did not work for some reason. Is that a bug?

No, that is probably because the bash session that is running the hook is not interactive, as I wrote in my own answer. Check your .bashrc, you'll find the following lines at ..

gvdhoorn gravatar imagegvdhoorn ( 2017-08-21 14:53:58 -0600 )edit

.. the top of the file (at least on Ubuntu):

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
gvdhoorn gravatar imagegvdhoorn ( 2017-08-21 14:54:21 -0600 )edit

answered 2017-08-21 11:59:15 -0600

gvdhoorn gravatar image

updated 2017-08-21 12:18:23 -0600

You don't tell us what doesn't work, but assuming that you're getting complaints from catkin_make that it can't find certain ROS pkgs or that catkin_make itself can't be found: do you source /path/to/the/catkin_ws/devel/setup.bash (or equivalent for /opt/ros/$distro/setup.bash) before invoking catkin_make?


I think catkin_make itself cannot be found. I have this in my ~/.bashrc:

source /opt/ros/kinetic/setup.bash
source /home/felix/sailing/bord-pc/devel/setup.bash
export BOARD_PC_WORKSPACE=/home/felix/sailing/bord-pc

And is your $HOME/.bashrc used by whatever/who-ever is running the git server? If not, your .bashrc will not have any influence.

Edit2: So you have a pre-push hook that is run locally?

seems I missed that. Ignore all the server stuff then.

But the question remains: if the bash session this is run in is non-interactive, your .bashrc will not be seen.

Can you print the contents of $PATH in the hook?

edit flag offensive delete link more


And if you were my server admin, I'd very quickly start complaining that my pushes to your server are taking on the order of 5 min+ with any decent ROS project/application. Pushes should be fast.

Would checking the state of your code not be the responsibility of CI infrastructure?

gvdhoorn gravatar imagegvdhoorn ( 2017-08-21 12:02:42 -0600 )edit

Sorry, I immediately edited the question bu you were to fast. ;)

felixd gravatar imagefelixd ( 2017-08-21 12:05:50 -0600 )edit

Please add additional information to your original question. Comments are not suited for that.

gvdhoorn gravatar imagegvdhoorn ( 2017-08-21 12:06:24 -0600 )edit

Try $(source .. && catkin_make).

gvdhoorn gravatar imagegvdhoorn ( 2017-08-21 12:09:29 -0600 )edit

exactly that didn't work either

felixd gravatar imagefelixd ( 2017-08-21 12:10:47 -0600 )edit

Ohhh, now I get the comments about the server: The githook is invoked locally! Nothing is run on the server.

felixd gravatar imagefelixd ( 2017-08-21 12:14:18 -0600 )edit

Additionally: if the bash session that runs your hook is non-interactive, your .bashrc (or the one from the user that runs the git server) will not be sourced.

You could try adding something like source /path/to/the/.bashrc at the top.

gvdhoorn gravatar imagegvdhoorn ( 2017-08-21 12:14:50 -0600 )edit

That didn't work either. See my edit in the question at the bottom.

felixd gravatar imagefelixd ( 2017-08-21 12:17:45 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2017-08-21 11:55:49 -0600

Seen: 125 times

Last updated: Aug 21 '17