Force git to run post-receive hook, even if everything is “up-to-date”

后端 未结 9 1730
再見小時候
再見小時候 2020-11-30 19:27

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?

Background

I use git to aut

相关标签:
9条回答
  • 2020-11-30 19:32

    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).

    • convenient: it doesn't create an extra commit
    • good: it doesn't use explicit path for the hook in the remote repo
    • bad: you overwrite history, which is fine in your use case, but shouldn't be used in a shared repository

    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

    • to add (all) modified files to the last commit: git amend -a
    • to modify the message: git amend -m 'better message'
    0 讨论(0)
  • 2020-11-30 19:39

    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]

    0 讨论(0)
  • 2020-11-30 19:39

    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
    
    0 讨论(0)
  • 2020-11-30 19:41

    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.

    0 讨论(0)
  • 2020-11-30 19:42

    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
    
    0 讨论(0)
  • 2020-11-30 19:44

    Use '--allow-empty'

    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.

    0 讨论(0)
提交回复
热议问题