?를 사용하여 웹 사이트를 배포 할 수 git push
있습니까? 서버 측에서 git hooks 를 사용 하여 수행 할 수있는 직감이 git reset --hard
있지만 어떻게 이것을 달성 할 수 있습니까?
?를 사용하여 웹 사이트를 배포 할 수 git push
있습니까? 서버 측에서 git hooks 를 사용 하여 수행 할 수있는 직감이 git reset --hard
있지만 어떻게 이것을 달성 할 수 있습니까?
답변:
이 사이트 에서이 스크립트 를 찾았 는데 꽤 잘 작동하는 것 같습니다.
로컬 사본에서 .git / config 파일을 수정하고 웹 서버를 원격으로 추가하십시오.
[remote "production"]
url = username@webserver:/path/to/htdocs/.git
서버에서 .git / hooks / post-update를 이 파일로 바꿉니다 (아래 답변 참조).
서버에 파일에 대한 실행 액세스를 추가하십시오.
chmod +x .git/hooks/post-update
이제 웹 서버에 로컬로 푸시하면 작업 복사본이 자동으로 업데이트됩니다.
git push production
아래의 업데이트 후 파일 사용 :
로컬 사본에서 .git / config 파일을 수정하고 웹 서버를 원격으로 추가하십시오.
[remote "production"]
url = username@webserver:/path/to/htdocs/.git
서버에서 .git / hooks / post-update를 아래 파일로 바꿉니다.
서버에 파일에 대한 실행 액세스를 추가하십시오.
chmod +x .git/hooks/post-update
이제 웹 서버에 로컬로 푸시하면 작업 복사본이 자동으로 업데이트됩니다.
git push production
#!/bin/sh
#
# This hook does two things:
#
# 1. update the "info" files that allow the list of references to be
# queries over dumb transports such as http
#
# 2. if this repository looks like it is a non-bare repository, and
# the checked-out branch is pushed to, then update the working copy.
# This makes "push" function somewhat similarly to darcs and bzr.
#
# To enable this hook, make this file executable by "chmod +x post-update".
git-update-server-info
is_bare=$(git-config --get --bool core.bare)
if [ -z "$is_bare" ]
then
# for compatibility's sake, guess
git_dir_full=$(cd $GIT_DIR; pwd)
case $git_dir_full in */.git) is_bare=false;; *) is_bare=true;; esac
fi
update_wc() {
ref=$1
echo "Push to checked out branch $ref" >&2
if [ ! -f $GIT_DIR/logs/HEAD ]
then
echo "E:push to non-bare repository requires a HEAD reflog" >&2
exit 1
fi
if (cd $GIT_WORK_TREE; git-diff-files -q --exit-code >/dev/null)
then
wc_dirty=0
else
echo "W:unstaged changes found in working copy" >&2
wc_dirty=1
desc="working copy"
fi
if git diff-index --cached HEAD@{1} >/dev/null
then
index_dirty=0
else
echo "W:uncommitted, staged changes found" >&2
index_dirty=1
if [ -n "$desc" ]
then
desc="$desc and index"
else
desc="index"
fi
fi
if [ "$wc_dirty" -ne 0 -o "$index_dirty" -ne 0 ]
then
new=$(git rev-parse HEAD)
echo "W:stashing dirty $desc - see git-stash(1)" >&2
( trap 'echo trapped $$; git symbolic-ref HEAD "'"$ref"'"' 2 3 13 15 ERR EXIT
git-update-ref --no-deref HEAD HEAD@{1}
cd $GIT_WORK_TREE
git stash save "dirty $desc before update to $new";
git-symbolic-ref HEAD "$ref"
)
fi
# eye candy - show the WC updates :)
echo "Updating working copy" >&2
(cd $GIT_WORK_TREE
git-diff-index -R --name-status HEAD >&2
git-reset --hard HEAD)
}
if [ "$is_bare" = "false" ]
then
active_branch=`git-symbolic-ref HEAD`
export GIT_DIR=$(cd $GIT_DIR; pwd)
GIT_WORK_TREE=${GIT_WORK_TREE-..}
for ref
do
if [ "$ref" = "$active_branch" ]
then
update_wc $ref
fi
done
fi
많은 잘못된 시작과 막 다른 길 끝에 마침내이 기사 덕분에 "git push remote " 만으로 웹 사이트 코드를 배포 할 수있게되었습니다 .
작성자의 업데이트 후 스크립트는 한 줄로되어 있으며 다른 솔루션과 마찬가지로 Git 저장소를 숨기려면 .htaccess 구성이 필요하지 않습니다.
Amazon EC2 인스턴스에 배포하는 경우 몇 가지 걸림돌이 있습니다.
1) 기본 목적지 저장소를 작성하기 위해 sudo를 사용하는 경우 저장소의 소유자를 ec2-user로 변경해야합니다. 그렇지 않으면 푸시가 실패합니다. ( "chown ec2-user : ec2-user repo를 시도하십시오 .")
2) amazon-private-key .pem 의 위치를 / etc / ssh / ssh_config에서 IdentityFile 매개 변수로 또는 ~ / .ssh / config를 사용하여 사전 구성하지 않으면 "[ 호스트] - 호스트 이름 - IdentityFile이 - 사용자 "레이아웃 설명 여기 ...
...하지만 호스트가 ~ / .ssh / config에 구성되어 있고 HostName과 다른 경우 Git 푸시가 실패합니다. (아마도 Git 버그 일 것입니다)
서버에 git을 설치하거나 .git 폴더를 복사하지 마십시오. git clone에서 서버를 업데이트하려면 다음 명령을 사용할 수 있습니다.
git ls-files -z | rsync --files-from - --copy-links -av0 . user@server.com:/var/www/project
프로젝트에서 제거 된 파일을 삭제해야 할 수도 있습니다.
이것은 체크인 된 모든 파일을 복사합니다. rsync는 어쨌든 서버에 설치된 ssh를 사용합니다.
서버에 설치 한 소프트웨어가 적을수록 더 안전하고 구성을 관리하고 문서화하는 것이 더 쉽습니다. 서버에 완전한 git clone을 유지할 필요도 없습니다. 모든 것을 올바르게 보호하는 것이 더 복잡해집니다.
본질적으로 필요한 것은 다음과 같습니다.
server = $1
branch = $2
git push $server $branch
ssh <username>@$server "cd /path/to/www; git pull"
내 응용 프로그램에이라는 실행 파일로 해당 줄이 deploy
있습니다.
배포를하고 싶을 때 입력 ./deploy myserver mybranch
합니다.
ssh -A ...
git pull
충돌이있을 경우 그것의 병합 부분은 수동으로 정리를 필요로 할 수 있기 때문에 자동화 된 배포 피해야한다.
내가하는 방법은 배포 서버에 변경 사항을 적용하는 베어 Git 저장소가 있다는 것입니다. 그런 다음 배포 서버에 로그인하여 실제 웹 서버 문서 디렉토리로 변경하고 git pull을 수행하십시오. 나는 이것을 자동으로 시도하기 위해 후크를 사용하지 않는다. 그것은 가치보다 더 문제가있는 것처럼 보인다.
git reset
으로 되돌릴 수 있습니다 . 최신 커밋이 아닌 특정 항목을 롤백해야하는 경우 사용할 수는 있지만 응급 상황에서만 사용해야합니다 ( 이전 커밋의 영향을 취소하는 새 커밋 생성). git revert
git revert
git config --local receive.denyCurrentBranch updateInstead
Git 2.3에 추가되면 다음과 같은 가능성이 있습니다. https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155
서버 저장소에서 설정하고 작업 트리가 깨끗하면 업데이트합니다.
태어나지 않은 가지 의 고리와 처리로 2.4에서 더 개선되었습니다.push-to-checkout
.
샘플 사용법 :
git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead
cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master
cd ../server
ls
산출:
a
b
이것은 GitHub 발표에 다음과 같은 단점 이 있습니다 .
그러나 이러한 모든 사항은 Git의 범위를 벗어나므로 외부 코드로 처리해야합니다. 따라서 Git 후크와 함께 이것이 궁극적 인 해결책입니다.
업데이트 : 나는 지금 사용하고있다 핵심 에이전트와 함께 Lloyd Moore 솔루션을 사용하고 ssh -A ...
있습니다. 메인 리포지토리로 푸시 한 다음 모든 머신에서 병렬로 가져 오는 것이 약간 빠르며 해당 머신의 설정이 덜 필요합니다.
이 솔루션을 보지 못했습니다. git이 서버에 설치되어 있으면 ssh를 통해 밀어 넣으십시오.
로컬 .git / config에 다음 항목이 필요합니다.
[remote "amazon"]
url = amazon:/path/to/project.git
fetch = +refs/heads/*:refs/remotes/amazon/*
하지만 이봐 amazon:
뭐야? 로컬 ~ / .ssh / config에 다음 항목을 추가해야합니다.
Host amazon
Hostname <YOUR_IP>
User <USER>
IdentityFile ~/.ssh/amazon-private-key
이제 전화 할 수 있습니다
git push amazon master
ssh <USER>@<YOUR_IP> 'cd /path/to/project && git pull'
(BTW : /path/to/project.git은 실제 작업 디렉토리 / path / to / project와 다릅니다)
이 시나리오에서는 github / bitbucket에 코드를 저장하고 라이브 서버에 배포하려고합니다. 이 경우 다음 조합이 우리에게 효과적입니다 (여기서 고도로 찬성 된 답변의 리믹스입니다) .
.git
디렉토리를 웹 서버로git remote add live ssh://user@host:port/folder
git config receive.denyCurrentBranch ignore
원격에서 : nano .git/hooks/post-receive
이 컨텐츠를 추가하십시오.
#!/bin/sh
GIT_WORK_TREE=/var/www/vhosts/example.org git checkout -f
원격에서 : chmod +x .git/hooks/post-receive
git push live
.git
폴더가 문서 루트 내에있는 경우 .htaccess
( source )를 추가하여 외부에서 폴더를 숨기십시오 .
RedirectMatch 404 /\..*$
배포를 관리하기 위해 capistrano 를 사용 합니다. 준비 서버에 배포하기 위해 capistrano를 빌드 한 다음 모든 서버와 rsync를 실행합니다.
cap deploy
cap deploy:start_rsync (when the staging is ok)
Capistrano를 사용하면 버그 발생시 쉽게 롤백 할 수 있습니다
cap deploy:rollback
cap deploy:start_rsync
Giddyup 은 언어에 구애받지 않는 just-add-water git hook으로 git push를 통한 배포를 자동화합니다. 또한 웹 서버 재시작, 캐시 예열 등을위한 사용자 정의 시작 / 정지 후크를 가질 수 있습니다.
https://github.com/mpalmer/giddyup
예제를 확인하십시오 .
커밋이 "안정된"브랜치라고 말하면 변경 사항을 가져와 PHP 사이트에 적용하는 git hook을 설정할 수 있습니다. 가장 큰 단점은 문제가 발생하면 많은 통제력을 갖지 못하고 테스트에 시간이 추가된다는 것입니다.하지만 트렁크 분기를 안정적인 분기로 병합하여 알기 위해 얼마나 많은 작업이 포함되는지 알 수 있습니다 얼마나 많은 갈등이 있을지 있습니다. 한 사이트 만 실행하려는 경우가 아니라면 사이트 특정 파일 (예 : 구성 파일)을 주시하는 것이 중요합니다.
또는 대신 사이트에 변경 사항을 적용 해 보셨습니까?
git hooks에 대한 정보는 githooks 문서를 참조하십시오 .
더 간단한 후크 스크립트가있는 toroid.org 의 다음 솔루션을 사용하고 있습니다.
서버에서 :
$ mkdir website.git && cd website.git
$ git init --bare
Initialized empty Git repository in /home/ams/website.git/
서버에 후크를 설치하십시오.
$ mkdir /var/www/www.example.org
$ cat > hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/var/www/www.example.org git checkout -f
GIT_WORK_TREE=/var/www/www git clean -f -d # clean directory from removed files
$ chmod +x hooks/post-receive
클라이언트에서 :
$ mkdir website && cd website
$ git init
Initialized empty Git repository in /home/ams/website/.git/
$ echo 'Hello, world!' > index.html
$ git add index.html
$ git commit -q -m "The humble beginnings of my web site."
$ git remote add web ssh://server.example.org/home/ams/website.git
$ git push web +master:refs/heads/master
그런 다음 게시하려면
$ git push web
웹 사이트에 대한 전체 설명이 있습니다 : http://toroid.org/ams/git-website-howto
git push web +master:refs/heads/master
대신에 git push web master
?
보완 답변으로 대안을 제시하고 싶습니다. git-ftp를 사용하고 있으며 제대로 작동합니다.
https://github.com/git-ftp/git-ftp
사용하기 쉽고 유형 만 :
git ftp push
git은 자동으로 프로젝트 파일을 업로드합니다.
문안 인사
https://github.com/jesalg/SlimJim- 자동으로 저장소에서 새 업데이트를 풀다운하는 기본 배포 도구를 만들었습니다. 기본적으로 github post-receive-hook을 듣고 프록시를 사용하여 업데이트 스크립트.
수신 후 후크에는 두 가지 솔루션을 사용합니다.
배포 솔루션 1
#!/bin/bash
# /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 1
export GIT_DIR=/git/repo-bare.git
export GIT_BRANCH1=master
export GIT_TARGET1=/var/www/html
export GIT_BRANCH2=dev
export GIT_TARGET2=/var/www/dev
echo "GIT DIR: $GIT_DIR/"
echo "GIT TARGET1: $GIT_TARGET1/"
echo "GIT BRANCH1: $GIT_BRANCH1/"
echo "GIT TARGET2: $GIT_TARGET2/"
echo "GIT BRANCH2: $GIT_BRANCH2/"
echo ""
cd $GIT_DIR/
while read oldrev newrev refname
do
branch=$(git rev-parse --abbrev-ref $refname)
BRANCH_REGEX='^${GIT_BRANCH1}.*$'
if [[ $branch =~ $BRANCH_REGEX ]] ; then
export GIT_WORK_TREE=$GIT_TARGET1/.
echo "Checking out branch: $branch";
echo "Checking out to workdir: $GIT_WORK_TREE";
git checkout -f $branch
fi
BRANCH_REGEX='^${GIT_BRANCH2}.*$'
if [[ $branch =~ $BRANCH_REGEX ]] ; then
export GIT_WORK_TREE=$GIT_TARGET2/.
echo "Checking out branch: $branch";
echo "Checking out to workdir: $GIT_WORK_TREE";
git checkout -f $branch
fi
done
배포 솔루션 2
#!/bin/bash
# /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 2
export GIT_DIR=/git/repo-bare.git
export GIT_BRANCH1=master
export GIT_TARGET1=/var/www/html
export GIT_BRANCH2=dev
export GIT_TARGET2=/var/www/dev
export GIT_TEMP_DIR1=/tmp/deploy1
export GIT_TEMP_DIR2=/tmp/deploy2
echo "GIT DIR: $GIT_DIR/"
echo "GIT TARGET1: $GIT_TARGET1/"
echo "GIT BRANCH1: $GIT_BRANCH1/"
echo "GIT TARGET2: $GIT_TARGET2/"
echo "GIT BRANCH2: $GIT_BRANCH2/"
echo "GIT TEMP DIR1: $GIT_TEMP_DIR1/"
echo "GIT TEMP DIR2: $GIT_TEMP_DIR2/"
echo ""
cd $GIT_DIR/
while read oldrev newrev refname
do
branch=$(git rev-parse --abbrev-ref $refname)
BRANCH_REGEX='^${GIT_BRANCH1}.*$'
if [[ $branch =~ $BRANCH_REGEX ]] ; then
export GIT_WORK_TREE=$GIT_TARGET1/.
echo "Checking out branch: $branch";
echo "Checking out to workdir: $GIT_WORK_TREE";
# DEPLOY SOLUTION 2:
cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR1;
export GIT_WORK_TREE=$GIT_TEMP_DIR1/.
git checkout -f $branch
export GIT_WORK_TREE=$GIT_TARGET1/.
rsync $GIT_TEMP_DIR1/. -v -q --delete --delete-after -av $GIT_TARGET1/.
rm -rf $GIT_TEMP_DIR1
fi
BRANCH_REGEX='^${GIT_BRANCH2}.*$'
if [[ $branch =~ $BRANCH_REGEX ]] ; then
export GIT_WORK_TREE=$GIT_TARGET2/.
echo "Checking out branch: $branch";
echo "Checking out to workdir: $GIT_WORK_TREE";
# DEPLOY SOLUTION 2:
cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR2;
export GIT_WORK_TREE=$GIT_TEMP_DIR2/.
git checkout -f $branch
export GIT_WORK_TREE=$GIT_TARGET2/.
rsync $GIT_TEMP_DIR2/. -v -q --delete --delete-after -av $GIT_TARGET2/.
rm -rf $GIT_TEMP_DIR2
fi
done
두 솔루션 모두이 스레드에서 사용 가능한 이전 솔루션을 기반으로합니다.
BRANCH_REGEX = '^ $ {GIT_BRANCH1}입니다. $ '는 "master "또는 "dev *"문자열과 일치하는 분기 이름을 필터링 하고 푸시 된 분기가 일치하면 작업 트리를 배포합니다. 이를 통해 개발 버전과 마스터 버전을 다른 위치에 배포 할 수 있습니다.
DEPLOY SOLUTION 1은 저장소의 일부이며 커밋에 의해 제거 된 파일 만 제거합니다. Deployment Solution 2보다 빠릅니다.
DEPLOY SOLUTION 2는 저장소에 추가되었는지 여부에 관계없이 서버 측에 추가 된 프로덕션 디렉토리에서 새 파일을 제거한다는 이점이 있습니다. 항상 repo의 깨끗한 속임수입니다. Deployment Solution 1보다 느립니다.