How do I force git
to run a post-receive
hook on a server even if I don\'t have a new commit to push?
I use git to aut
If you want to avoid making a fake new commit, you can simply use
git commit --amend --no-edit
This will modify the last commit record and you will be able to use git push -f
(assuming from your answer that you're fine with the overwrite).
I use this command relatively often to fix something in the last commit before pushing, so I made an alias for it:
git config --global alias.amend 'commit --amend --no-edit'
Now I can use it directly for the use case as yours (git amend
), or
git amend -a
git amend -m 'better message'
I made a bash function to do this. It assumes that you have ssh access can ~/.ssh/config
set accordingly. The default remote is origin
kick-git() {
remote="${1:-origin}"
ssh $(echo $(git remote get-url "$remote")/hooks/post-receive | tr ':' ' ')
}
Source and run kick-git [remote]
Post-receive is the wrong place for artificial command responses.
You want your server-side goodies in the pre-receive exit, dependent on the updated ref -- do e.g. git update-ref refs/commands/update-hooks @
on the server, then you can e.g. git push server +@:commands/update-hooks
, and in the server's pre-receive you can
while read old new ref; do case $ref in
commands/update-hooks)
maybe check the incoming commit for authorization
update hooks here
echo the results from the update
denypush=1
;;
refs/heads/master)
extreme vetting on master-branch updates here
;;
esac; done
((denypush)) && exit $denypush
I like Jamie Carl's suggestion but it doesn't work, and I got the error:
remote: error: By default, deleting the current branch is denied, because the next error: 'git clone' won't result in any file checked out, causing confusion.
In my case I'm testing post-receive hooks on my localhost against a bare repository. Warning/super important, run this command only on the remote
server location!
git update-ref -d refs/heads/develop
It'll delete the reference for the develop branch (you may also need to delete any of the files you deployed for that branch too), then you can go ahead and do the git push deploy_localtest develop
or whatever push command you want for that branch.
I tried empty commits and delete upload branch.
But what about a direct ssh command:
ssh your_host /path/to/your_repo/hooks/post-receive
After the initial push replacing the script, you can do this :
git commit --allow-empty -m 'push to execute post-receive'
The --allow-empty
flag overrides git's default behavior of preventing you from making a commit when there are no changes.
Use an alias and make your life even easier
Add the following to ~/.gitconfig
[alias]
pushpr = "!f() { git push origin master;git commit --allow-empty -m 'push to execute post-receive';git push origin master; }; f"
Now Just do git pushpr
git pushpr
This will push any changes to master, which in your case will trigger your post receive replacement script, then it will push again (using the --allow-empty
flag) which will then execute your updated post-receive
script.