모든 것이 "최신"상태 인 경우에도 git이 수신 후 후크를 실행하도록합니다.
푸시 할 새 커밋이 없더라도 서버에서 강제 git
로 post-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-receive 및 post-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!
'IT박스' 카테고리의 다른 글
브랜치가 생성 된 트렁크에서 개정 찾기 (0) | 2020.11.15 |
---|---|
C #에서 속성을 재정의 할 수 있습니까? (0) | 2020.11.15 |
Java 8로 무한 스트림을 만드는 방법 (0) | 2020.11.15 |
RC.1에서는 바인딩 구문을 사용하여 일부 스타일을 추가 할 수 없습니다. (0) | 2020.11.15 |
Promise catch에서 오류 다시 던지기 (0) | 2020.11.15 |