Git post-receive script hangs indefinitely - bash

I have a remote machine which I use ssh to connect to.
I have configured an empty git repo on it with git init --bare and made the working tree be a folder called test.
Then, I configured the machine locally so I can use git push to push branches to it.
This whole process alone works fine.
The problem is - I have a post-receive script which executes a few commands (including a shell script) and no matter which commands I put there, after a git push to that remote machine, after the post-receive gets executed (and it does get executed successfully, at least it seems so) my git bash which I used to git push hangs forever until I do CTRL+C...
What could be causing this?

Try with a simple hook, named post-receive (no extension, set in your bare repo folder/.hooks) and make sure it is executable.
#!/bin/sh
echo "my post-receive hook"
exit 0
including a shell script
As mentioned here, depending on how your post-receive hook is calling that shell script, Git might wait for all the children processes left over by said post-receive hook.

Related

How can I `git push` from a script initiated by a cronjob?

I have the following script:
cd ~/path/to/repo ;
git pull ;
git add . ;
git commit -m "autocommit for repo" ;
git push ;
cd ~ ;
I have it run in a cronjob every minute. It works up until the git push command and then it does nothing. If I run the script manually it works fine. I updated the cronjob to write the output of running the script to a temp text file to see if git push was failing. It is not failing, it just isn't being ran at all it seems. The only output present is related to the git commit command. What might be going wrong?
I'm on a Mac running the latest macOS but I have tried it on my Linux machine as well with the same result.
I updated the cronjob to write the output of running the script to a temp text file to see if git push was failing
Make sure to redirect both stdout and stderr, since most Git command produce outputs to stderr
*/1 * * * * /your/script.sh >> /your/script.log 2>&1
But a post-commit client-side local hook is a good alternative approach.
(As noted here, that means creating a push script named post-commit, without extension, as executable in your .git/hooks folder)

Execute Bash Script After Git Post-Receive Hook executes

I have a bash script on my test server that will export my wordpress db, rsync the db to the prod server, and git push all of my files to prod sever.
Within the prod server's git repo I have a git post-receive hook correctly configured.
#!/bin/bash
#Receive Git Push from Test
git --work-tree=/home/username/public_html --git-dir=/home/username/public_html/git/production-site.git checkout -f
Within the working tree directory (WordPress directory) on the prod server I also have a bash script that will import the newly uploaded db. /home/username/public_html/db-import-script.sh
#!/bin/bash
#bunch of commands
...
...
...
Question:
How can I automatically execute the db import script immediately following a git push?
troubleshooting:
inside of post-receive, I have tried using an absolute paths to execute the script, no luck
#!/bin/bash
#Receive Git Push from Test
git --work-tree=/home/username/public_html --git-dir=/home/username/public_html/git/production-site.git checkout -f
#execute script with absolute path
/home/username/public_html/db-import-script.sh
db-import-script.sh does not execute. NOTE: this script must remain located in the Wordpress directory b/c it uses wp-cli commands for various actions.
any tips?
I use e.g. gitea and on server one has to simply copy a script in post-receive.d/ folder. The post-receive hook (see below and you may use it as a template) will scan this folder and execute scripts in it.
#!/usr/bin/env bash
# AUTO GENERATED BY GITEA, DO NOT MODIFY
data=$(cat)
exitcodes=""
hookname=$(basename $0)
GIT_DIR=${GIT_DIR:-$(dirname $0)/..}
for hook in ${GIT_DIR}/hooks/${hookname}.d/*; do
test -x "${hook}" && test -f "${hook}" || continue
echo "${data}" | "${hook}"
exitcodes="${exitcodes} $?"
done
for i in ${exitcodes}; do
[ ${i} -eq 0 ] || exit ${i}
done
kiss rule... (keep it simple stupid)
rather than spending days trying to learn sysdig well enough to trace a process that I have never previously heard of and it subprocesses. (no offence intended Charles, just need to actually get tasks done. Your bash debug-log snippet highly useful)
and rather than creating some git / gitea hybrid (no offence #m19v, I did try your solution, but didn't work)
knowing that production server db-import.sh worked properly and that my test server git push / db upload push.sh worked properly.
My final solution was to leave the production server's post-receive properly configured and to.... remotely execute my db-import.sh script via ssh directly within the directory in which it needs to be executed.
In a nutshell, I added this to the end of push.sh script on my test server:
#Remotely execute db import
ssh -p22 -i /home/username/.ssh/id_rsa username#1233.456.789.12 'cd public_html && bash' << EOF
./db-import.sh
EOF
Bang problem solved...

Git Portable 64 Bash not working in Windows Server 2016 Task Scheduler

I need help trying to figure out why Git repository commands are not not executing when run in a script in Windows Server 2016 Task scheduler. All works OK when I execute them in a command console.
In the Windows Server 2016 Task Scheduler, my Action "Start a Program" is: C:\Apps\repo.scripts\UpdateMyRepo.bat
The UpdateMyRepo.bat cmd code is:
SET HOME=C:\Users\Repo
REM change to MyRepo git working repository
C:
cd \MyRepo
REM execute my script bash script to update my repository
C:\Apps\Git\bin\bash.exe --login -i -c "/c/Apps/repo.scripts/UpdateMyRepo.sh"
The UpdateMyRepo.sh bash code is
#!/c/Apps/Git/bin/bash.exe -x
export HOME=/c/Users/Repo
cd /c/MyRepo
# write a log entry so we know we are in the repository folder
ls -al > /c/Apps/repo.scripts/myrepofolder.log
# write the git --version to a log file so we know git is working
/c/Apps/Git/bin/git.exe --version > /c/Apps/repo.scripts/version.log
# write the git status to a log file so we know git repository commands work
/c/Apps/Git/bin/git.exe status > /c/Apps/repo.scripts/status.log
# write a done log entry and quit the bash shell
echo done > /c/Apps/repo.scripts/done.log
exit
Everything works in Windows 2016 Task Scheduler except the git status command. The git status writes an empty blank status.log file. Actually, it seems like any other commands, like git add, git commit, git push, etc., that act on the repository yield blank output.
If I execute the command manually when logged in as the Repo user and double clicking on the C:\Apps\repo.scripts\UpdateMyRepo.bat in Windows file explorer or running in a console, all works perfectly and the repository git status is written to the status.log. I get the "null" results when executing the task from the Task Scheduler either manually or on trigger.
Please help me figure out how to run git repository commands in Windows Server 2016 task scheduler. I have already tried too many variations of commands, scripts, and permissions to list each that did not work here.
Platform Details:
Windows Server 2016 Standard, all current updates
Git Portable 64bit, 2.17.1.windows.2
Repository files are stored on in the operating system and task scheduler's local hard drive, not in a network share
update: When I run the Git repository tasks in the WS2016 Task Scheduler and figured out how to log some of the output, I get the following error:
fatal: this operation must be run in a work tree
The repository folder is NOT a "bare" repository. So I am suspecting that the WS2016 Task Scheduler is applying additional permission constraints that do not apply to the user account assigned in the task. I get this same error if I try to run the tasks in an Admin Console instead of a normal user console.
First, most of Git commands writes their output to stderr, not stdout
So you need to redirect stderr to stdout, using for instance &> instead of >.
Second, to be sure all your Git command will be executed in the right working tree/repo, you can add environment variables for the repository location
export GIT_WORK_TREE=/c/path/to/my/repo
export GIT_DIR=/c/path/to/my/repo/.git

Docker unable to start an interactive shell if the image has an entry script

My custom-made image ends with
ENTRYPOINT [ "/bin/bash", "-c", "/home/tool/entry_script.sh" ]
This is absolutely needed because at runtime, the first thing the user must do is to update an already cloned github project, and users will often forget to do it.
But then, when i try to launch using
docker run -it --rm my_image /bin/bash
i can see that the ENTRYPOINT script is being executed, but then the container exit.
I expect to have /bin/bash being executed and the shell to remain in interactive mode, due to -it flags.
What am I doing wrong?
UPDATE: I add my entry script
#!/bin/bash
echo "UPDATING GIT REPO";
cd /home/tool/cloned_github_tools_root
git pull
git submodule init
git submodule update
echo "Entrypoint ended";
Actually I've not kind of errors at runtime
When you set and entry point in a docker container. It is the only thing it will run. It's the one and only process that matters (PID 1). Once your entry_point.sh script finishes running and returns and exit code, docker thinks the container has done what it needed to do and exits, since the only process inside it exits.
If you want to launch a shell inside the container, you can modify your entry point script like so:
#!/bin/bash
echo "UPDATING GIT REPO";
cd /home/tool/cloned_github_tools_root
git pull
git submodule init
git submodule update
echo "Entrypoint ended";
/bin/bash "$#"
This starts a shell after the repo update has been done. The container will now exit when the user quits the shell.
The -i and -t flags will make sure the session gives you an stdin/stdout and will allocate a psuedo-tty for you, but they will not automatically run bash for you. Some containers don't even have bash in them.
I think the original question and answer are pretty good (thank you!). However I had the same exact problem but the provided solution did not work for me. I ended up wasting a lot of time figuring out what I was doing wrong. Hence I came up with a solution that should work all the time, if this could save time for others. In my docker entry point I'm sourcing a shell script file from Intel compiler and the received parameters $# are somewhat changed by the 'source' command. Then when ending the script with /bin/bash "$#" the original parameters are gone. Here is my updated version that would be safer for all use cases:
#!/bin/bash
# Save original parameters
allparams=("$#")
echo "UPDATING GIT REPO";
cd /home/tool/cloned_github_tools_root
git pull
git submodule init
git submodule update
echo "Entrypoint ended";
# Forward initial parameters
/bin/bash "${allparams[#]}"

git commit and push via batch file on Windows

I do same task often of committing and pushing changes to remote branch. Being lazy sometimes, I needed to put set of git commands to automatically perform these steps:
cd D:\wamp\www\projectName
git checkout dev
git add .
git commit -am "made changes"
git push
pause
I also tried:
cd D:\wamp\www\projectName
call git checkout dev
call git add .
call git commit -am "made changes"
call git push
pause
and
cd D:\wamp\www\projectName
git.exe checkout dev
git.exe add .
git.exe commit -am "made changes"
git.exe push
pause
Everything works excpet for the final push command. Here is output:
D:\wamp\www\givingcircle>git checkout dev
Already on 'dev'
Your branch is ahead of 'origin/dev' by 1 commit.
D:\wamp\www\givingcircle>git add .
D:\wamp\www\givingcircle>git commit -am "made changes"
# On branch dev
# Your branch is ahead of 'origin/dev' by 1 commit.
#
nothing to commit, working directory clean
D:\wamp\www\givingcircle>git push
Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
D:\wamp\www\givingcircle>pause
Press any key to continue . . .
As you can see, for push, I am getting:
D:\wamp\www\givingcircle>git push
Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
When I run above commands via git shell itself, everything works fine. I have also added git to Windows Path env variables.
Does anyone have an idea of why it works on git shell and not on batch command ? (even though other commands work but not push)
For me, by default, Windows executes .sh files correctly using Git Bash. So I would write your script as a regular bash shell script:
#!/bin/sh
cd /d/wamp/www/projectName
git checkout dev
git add .
git commit -am "made changes"
git push
echo Press Enter...
read
I had a similar need, to be able to move code from BBCloud to our development test servers, for stage 1 testing.
To do this, I created a Windows scheduled task:
Under "Actions", I added "C:\Program Files\Git\bin\bash.exe" in Program/script field (the quotes were required).
In the "Add arguments" field, I entered c:\path\to\bash script\pull.sh.
I then completed the Task Scheduler wizard (run frequency, time, etc.).
I then created a bash script, using Nano in Git Bash for Windows containing:
#!/bin/bash
cd /c/path/to/bash script
git pull
I would prefer a push to the repository automatically pushing down to the test server, but Pipes, Webhooks, and DeployHQ don't seem to be a solution for our environment.
Try this one !!
cd c://TESTS/path
set HOME=%USERPROFILE%
GIT COMMAND GOES HERE
pause

Resources