3

I'm trying to commit/push changes to a remote Git server with the below sample code:

#!/bin/sh

USER='username'
REPO='/home/'${USER}'/Sites/git/bitbucket/kb'
COMMIT_TIMESTAMP=`date +'%Y-%m-%d %H:%M:%S %Z'`
DATELOG=`date +'%Y-%m-%d-%H-%M-%S'`
LOG="/tmp/${DATELOG}.txt"

MKDOCS=`which mkdocs`
GIT=`which git`
NOTIFY=`which notify-send`

# Only proceed if we have a valid repo.
if [ ! -d ${REPO}/.git ]; then
  echo "${REPO} is not a valid git repo! Aborting..." >> ${LOG}
  exit 0
else
  echo "${REPO} is a valid git repo! Proceeding..." >> ${LOG}
fi

cd ${REPO}
${MKDOCS} build --clean >> ${LOG}
${GIT} add --all . >> ${LOG}
${GIT} commit -m "Automated commit on ${COMMIT_TIMESTAMP}" >> ${LOG}
${GIT} push git@bitbucket.org:username/repo.git master >> ${LOG}

# Depends on libnotify
${NOTIFY} 'KB notification' 'Changes were pushed to Bitbucket.' --icon=dialog-information >> ${LOG}

If I invoke the shell script manually (e.g. ./commit.sh) it works immediately. On the contrary, when triggered via a cron job everything works just fine until the git push which then never seems to be triggered for some odd reason.

Here's my crontab line:

*/20 * * * * /home/username/Sites/git/repo/commit.sh

And some verbosity for git push

09:53:32.732216 git.c:349               trace: built-in: git 'push' 'git@bitbucket.org:username/repo.git' 'master'
09:53:32.732514 run-command.c:341       trace: run_command: 'ssh' 'git@bitbucket.org' 'git-receive-pack '\''username/repo.git'\'''
09:53:39.665197 run-command.c:341       trace: run_command: 'pack-objects' '--all-progress-implied' '--revs' '--stdout' '--thin' '--delta-base-offset' '--progress'
09:53:39.665526 exec_cmd.c:134          trace: exec: 'git' 'pack-objects' '--all-progress-implied' '--revs' '--stdout' '--thin' '--delta-base-offset' '--progress'
09:53:39.666778 git.c:349               trace: built-in: git 'pack-objects' '--all-progress-implied' '--revs' '--stdout' '--thin' '--delta-base-offset' '--progress'
Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (7/7), 4.23 KiB | 0 bytes/s, done.
Total 7 (delta 4), reused 0 (delta 0)
To git@bitbucket.org:username/repo.git
   0ef4905..91437d0  master -> master

How come git push would be triggered only when the script is invoked manually and not when run via the crontab?

anavarre
  • 173
  • 1
    Did cron send you any e-mail? – Arkadiusz Drabczyk Aug 31 '15 at 20:30
  • It could rely on environment variables like $HOME or $USER. – myaut Aug 31 '15 at 20:30
  • cron is not the culprit it seems as the cron job is executed and logged just fine under /var/log/syslog e.g. Aug 31 22:44:01 laptop CRON[9364]: (username) CMD (/home/username/Sites/git/repo/commit.sh) – anavarre Aug 31 '15 at 20:47
  • Did you find out any solution? I have the same problem. (btw, I don't know where to look for email sent by deamon. Do I have to do anything to receive it? In Mac, I receive it automatically in a folder, but not on Ubuntu) – user1859675 May 31 '16 at 13:10

2 Answers2

6

What director(ies|y) are you looking to do this in? It is not clear from you script. Try going into the directory1, something like:

#!/bin/sh

GIT=`which git`
REPO_DIR=/home/username/Sites/git/repo/
cd ${REPO_DIR}
${GIT} add --all .
${GIT} commit -m "Test commit"
${GIT} push git@bitbucket.org:username/repo.git master

Or you can do a git add --all /path/to/git/repo/files.

Edit:

Running a script from the command line is not necessarily the same as running it from cron; see this Q&A: What is the 'working directory' when cron executes a job, especially Gilles' answer.

1Some ideas on how to check if a command succeeded

KM.
  • 2,224
  • That's going to be hilarious when the unchecked cd call fails. set -e or check the result of the cd. – thrig Aug 31 '15 at 20:38
  • Just a suggestion to do cd; checking is left to the user (-: Great suggestion nonetheless! – KM. Aug 31 '15 at 20:39
  • That's the reason I think. I asked OP to check any mail sent by cron daemon for him to make sure. However, there are 2 problems with this script: 1. what if there is no git installed? 2. what if cd fails? – Arkadiusz Drabczyk Aug 31 '15 at 20:40
  • 1
    Not to mention the issues with the use of which, http://unix.stackexchange.com/q/85249/4252 – KM. Aug 31 '15 at 20:47
  • @KM. The script lives in the same directory as the files/dirs to be committed. As I said in the summary, this is only a code sample, the full script is a tad bit more advanced. – anavarre Aug 31 '15 at 20:48
  • @Arkadiusz Drabczyk checking that git is installed or cd works fine is not in the equation here. I 100% agree it makes the script more solid but this is not what's failing here. Only the git push is. – anavarre Aug 31 '15 at 20:50
  • @KM. I didn't know for which. Thanks, will refactor. – anavarre Aug 31 '15 at 20:52
  • @anavarre: ok, it's a shame that you just didn't show us your whole script at the beginning. We try to help you here. It's also a shame that didn't check mail from cron as I asked you to. – Arkadiusz Drabczyk Aug 31 '15 at 20:52
  • @ Arkadiusz Drabczyk Thought this would derail the conversation by pointing out all the wrong things I did like which or not enough checks (is git available? etc.) instead of answering the git push issue. Edited the original post in the hopes it helps understanding what's wrong better. – anavarre Aug 31 '15 at 20:57
  • I didn't ask you for /var/log/syslog – Arkadiusz Drabczyk Aug 31 '15 at 21:06
  • @Arkadiusz Drabczyk I didn't get what you were asking earlier but I think I do now. Found Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights with mailx. Odd, since the user running the script doesn't have any issue with perms since ssh-add is run at startup... – anavarre Aug 31 '15 at 21:30
  • Is the above crontab for the same user that is running the script? If not, that might be a for this error. Also, how is ssh-add run for this script? – KM. Aug 31 '15 at 22:29
  • @KM. yes, same user exactly, thus my surprise. ssh-add is run at startup time for this user, which never requires me authenticating again for SSH/Git connections, at least in the context of the prompt. Looks like via a script things might be different. – anavarre Sep 01 '15 at 07:03
  • 1
    Might be time for sanity checks. Ensure keys are in place, with proper permissions, and they match those on bitbucket. Also, try GIT_CURL_VERBOSE=1 GIT_TRACE=1 git push git@bitbucket.org:username/repo.git master and see/post what you get. – KM. Sep 01 '15 at 13:26
  • @KM. - git push works well interactively. So are my SSH keys. It's only in the context of the shell script that it fails with the above permission denied issue. I've edited the original post for you to see the result of the verbose/trace mode when run interactively. The same verbose message fails with a permission denied issue when run via the script. Thanks for that. – anavarre Sep 02 '15 at 07:58
0

I faced the same problem and that is how I fixed it:

  1. First, try to find out why what is the error of your push. You can get the error log by adding 2>&1 at the end of your script. In your case it would be:

    ${GIT} push git@bitbucket.org:username/repo.git master >> ${LOG} 2>&1
    
  2. Several reason can cause your push is not working from within your shell. Check these criteria:

    • your user name and password is Stored/Cached correctly. You can push to git URL directly including your User/Pass just for test (DON'T forget to remove them). e.g.:

      ${GIT} push --repo https://YOUR_USER_NAME:YOUR_PASSWORD@bitbucket.org/repo.git  
      
    • Make sure Git is not complaining about SSL (You can temporarily ignore it by adding this command before your push in your script:

      export GIT_SSL_NO_VERIFY=1
      
  3. In case you are not if git push is executed in the right directory, you can go to your desired directory before your script is executed by adding pre-step to your cron job as follow:

    */20 * * * * cd /home/'${USER}'/Sites/git/bitbucket/kb && /home/username/Sites/git/repo/commit.sh
    
Chris Davies
  • 116,213
  • 16
  • 160
  • 287