IT박스

모든 것이 "최신"상태 인 경우에도 git이 수신 후 후크를 실행하도록합니다.

itboxs 2020. 11. 15. 11:03
반응형

모든 것이 "최신"상태 인 경우에도 git이 수신 후 후크를 실행하도록합니다.


푸시 할 새 커밋이 없더라도 서버에서 강제 gitpost-receive후크 를 실행하려면 어떻게해야 합니까?

배경

git을 사용하여 웹 사이트를 서버에 자동으로 배포합니다. 서버의 보호 영역에 베어 저장소가 있고 post-receive내용을 확인하고 특정 파일을 public_html폴더에 체계적으로 복사 하는 후크가 있습니다. ( 이 튜토리얼에서 영감을 얻음 )

post-receive서버에서 수동으로 후크 를 수정하는 데 지쳤 으므로 post-receive이제 후크가 실제로 저장소에서 새 버전을 복사합니다.

#!/bin/sh

rm -rf ~/../protected/*
GIT_WORK_TREE=~/../protected git checkout -f

# Rewrite over this file with any updates from the post-receive file
cp ~/../protected/post-receive hooks/post-receive

# Delete public_html
# Copy stuff public_html

물론 문제는 새로운 post-receive후크가 실행되지 않는다는 것입니다. 겉보기에 간단한 해결책은 단순히 다시 밀어 붙이는 것이지만 이제 모든 것이 이미 최신 상태입니다. post-receive훅을 업데이트 할 때마다 새 커밋을 가짜로 만들어야하기 때문에 성가신 일 입니다. post-receive커밋을 위조하거나 참여하지 않고 후크 를 호출하는 방법이 ssh있습니까?

내가 시도한 것

git push
git push -f

'--allow-empty'사용

스크립트를 대체하는 초기 푸시 후 다음을 수행 할 수 있습니다.

git commit --allow-empty -m 'push to execute post-receive'

--allow-empty플래그는 변경 사항이 없을 때 커밋하지 못하도록하는 git의 기본 동작을 재정의합니다.

별칭을 사용하여 삶을 더 쉽게 만드세요

다음에 추가 ~/.gitconfig

[alias]
    pushpr = "!f() { git push origin master;git commit --allow-empty -m 'push to execute post-receive';git push origin master; }; f"

이제 그냥 해 git pushpr

git pushpr

이렇게하면 변경 사항이 마스터에 푸시되며,이 경우 포스트 수신 대체 스크립트를 트리거 한 다음 다시 푸시 ( --allow-empty플래그 사용)하여 업데이트 된 post-receive스크립트 를 실행합니다 .


나는 이것이 아마도 "위험한"것으로 간주 될 것이라는 것을 알고 있지만 나는 가장자리에서 사는 것을 좋아합니다.

원격 분기를 삭제 한 다음 다시 푸시합니다. 물건을 잃을 가능성을 제한하기 위해 먼저 현지 지점이 최신 상태인지 확인하십시오.

따라서 수신 후 트리거를 트리거하려는 경우 제 경우에는 테스트 분기를 프로비저닝 할 수 있습니다.

$ git push origin :testing
$ git push origin testing

그래도 이것을 대답으로 받아들이지 마십시오. 그것은 단지 FYI 일에 가깝습니다.


서버에 ssh하고 후크 스크립트를 수동으로 실행해야합니다. 아무것도 추가 git push되지 않은 경우 서버가 pre-push , pre-receivepost-receive 후크를 실행하도록 만들지 않습니다 (즉, git이 Everything을 최신으로 인쇄 할 때 ).

나머지 대답은 수신 후 후크 의 버전 추적에 관한 것이므로 서버에 sshing하지 않고도 수정할 수 있습니다.

do-post-receive로컬 저장소에 셸 스크립트를 추가 합니다.

$ ls -ld .git
$ echo 'echo "Hello, World!"' >do-post-receive
$ git add do-post-receive
$ git commit do-post-receive -m 'added do-post-receive'

hooks/post-receive서버 후크를 다음으로 바꿉니다 .

#! /bin/sh
while read OLDID NEWID BRANCH; do
  test "$BRANCH" = refs/heads/master && eval "$(git show master:do-post-receive)"
done

( chmod 755 hooks/post-receive서버에서 확인하십시오 .)

로컬 리포지토리에서 서버로 변경 사항을 푸시하고 do-post-receive코드 실행을 확인합니다.

$ git push origin master
...
remote: Hello, World!
...

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'

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

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 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]


In my case i login into remote and run:

$ sh project.git/hooks/post-receive

works fine!

참고URL : https://stackoverflow.com/questions/13677125/force-git-to-run-post-receive-hook-even-if-everything-is-up-to-date

반응형