是否可以使用git push
部署網站?我有一個預感,它與使用git hooks在服務器端執行git reset --hard
有關,但我將如何去完成此操作?使用Git push部署項目
回答
我發現this script在this site,它似乎工作得很好。
- 在你的.git目錄複製到你的Web服務器
在本地複製,修改您的.git/config文件,並添加您的Web服務器作爲遠程:
[remote "production"] url = [email protected]:/path/to/htdocs/.git
在服務器,用this file替換.git/hooks/post-update(在下面的答案中)
添加對文件的再次執行訪問(再次,在服務器上):
chmod +x .git/hooks/post-update
現在,只需在當地推到你的Web服務器,它會自動更新工作副本:
git push production
我這樣做的方式是我的部署服務器上有一個裸露的Git存儲庫,我推送更改。然後我登錄到部署服務器,切換到實際的Web服務器文檔目錄,並執行git pull。我沒有使用任何鉤子來自動執行此操作,這看起來更麻煩而不值得。
如果新代碼中存在錯誤,您是否重置每次提交或整個拉? (或者只有1個可能?) – Rudie 2010-09-27 13:19:23
@Rudie:如果您需要回滾部署服務器上的更改,那麼您可以使用`git reset`在* latest *更改中移回(所有提交,而不僅僅是整個提交)。如果您需要回滾一些具體的事情,這不是最新的承諾,那麼你可以使用`git的revert`但也許應該在緊急情況下使用只(`git的revert`創建一個新的提交是撤銷一些以前的承諾的效果)。 – 2010-09-27 18:06:25
聽起來像你應該在你的服務器上有兩個副本。一個裸拷貝,你可以推/拉,當你完成後你會推動你的修改,然後你將它克隆到你的web目錄中,並設置一個cronjob來每天更新web目錄中的git pull,或者所以。
你可以設想一個git鉤子,當說一個提交被稱爲「穩定」的分支時,它將把這些改變應用到PHP站點。最大的缺點是,如果出現問題,您將無法控制,並且會增加測試的時間 - 但您可以瞭解在合併時將涉及多少工作,請將您的幹線分支插入穩定分支以瞭解可能會碰到多少衝突。除非您僅打算只運行一個站點,否則請務必留意任何特定於站點的文件(例如,配置文件)。
或者,您是否已着眼於將更改推向網站?
有關git掛鉤的信息,請參閱githooks文檔。
在本質上,所有你需要做的有以下幾種:
server = $1
branch = $2
git push $server $branch
ssh <username>@$server "cd /path/to/www; git pull"
我在我的應用程序中有一行叫做deploy
的可執行文件。
所以當我想要做一個部署我輸入./deploy myserver mybranch
。
使用下面的更新後文件:
- 複製在你的.git目錄到Web服務器
在本地複製,修改您的.git/config文件,並添加您的網站服務器作爲遠程:與文件
[remote "production"] url = [email protected]:/path/to/htdocs/.git
在服務器上,取代的.git /鉤/更新後的下面
添加執行訪問該文件(再次,在服務器上):
chmod +x .git/hooks/post-update
現在,只需在當地推到你的Web服務器,它會自動更新工作副本:
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 [email protected]{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 [email protected]{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
你能幫我理解這個更新是什麼嗎? – 2011-05-27 03:30:12
經過很多虛假的開始和死衚衕,我終於能夠部署網站代碼,只是「git push remote「感謝this article。
作者的更新後腳本只有一行,他的解決方案不需要.htaccess配置來隱藏Git倉庫,就像其他倉庫一樣。
如果您在Amazon EC2實例上部署此功能,可能會遇到一些絆腳石;
1)如果您使用sudo創建裸露的目標存儲庫,則必須將該存儲庫的所有者更改爲ec2用戶,否則推送將失敗。 (嘗試「CHOWN EC2用戶:EC2用戶回購」)
2)如果你不預先配置亞馬遜私鑰。質子交換膜的位置推送會失敗,無論是在/ etc/ssh/ssh_config中作爲IdentityFile參數或在〜/ .ssh/config中使用「[Host] - HostName - IdentityFile - User」佈局描述here ...
...但是,如果主機已配置在〜/ .ssh/config中,並且與HostName不同,Git推送將失敗。 (這可能是一個Git bug)
不要在服務器上安裝git或將.git文件夾複製到那裏。要從git克隆更新服務器,您可以使用以下命令:
git ls-files -z | rsync --files-from - --copy-links -av0 . [email protected]:/var/www/project
您可能需要刪除從項目中刪除的文件。
這將複製所有簽入的文件。無論如何,rsync使用安裝在服務器上的ssh。
您安裝在服務器上的軟件越少,他就越安全,管理其配置和記錄越容易。也不需要在服務器上保留一個完整的git克隆。它只會讓事情變得更加複雜,以確保一切正常。
鑑於您有多個開發人員訪問同一個存儲庫的環境,以下準則可能會有所幫助。
確保您有一個所有開發人員都屬於的unix組,並將該.git存儲庫的所有權交給該組。
在服務器存儲庫的.git/config中設置sharedrepository = true。 (這告訴混帳允許這是需要提交和部署多個用戶
集他們的.bashrc文件中的每個用戶的umask是相同的 - 002是一個良好的開端
Giddyup是語言無關只需加水混帳掛鉤自動通過混帳推的部署,也可以讓你有自定義的啓動/停止掛鉤重新啓動Web服務器,升溫緩存等
https://github.com/mpalmer/giddyup
結賬examples。
更新:我現在使用勞埃德摩爾解決方案與關鍵代理ssh -A ...
。推入主倉庫,然後從所有機器並行拖出,這會更快一些,並且需要更少的設置。
在這裏沒有看到這個解決方案。只要通過ssh推送,如果git安裝在服務器上。
你需要在你本地的.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是不同的到實際的工作目錄/路徑/到/項目)
我最終創建了我自己的基本部署工具,它會自動從回購拉下新的更新 - https://github.com/jesalg/SlimJim - 基本上它聽取github post-receive-hook和使用代理來觸發更新腳本。
我們使用capistrano來管理部署。 我們將capistrano構建爲在臨時服務器上部署,然後使用我們的所有服務器運行rsync。
cap deploy
cap deploy:start_rsync (when the staging is ok)
隨着Capistrano的,我們可以在錯誤
cap deploy:rollback
cap deploy:start_rsync
我拿上Christians解決方案的情況下輕鬆回滾。
git archive --prefix=deploy/ master | tar -x -C $TMPDIR | rsync $TMPDIR/deploy/ --copy-links -av [email protected]:/home/user/my_app && rm -rf $TMPDIR/deploy
- 檔案館主分支成焦油
- 提取tar歸檔到系統臨時文件夾部署目錄。
- 將rsync更改爲服務器
- 從temp文件夾中刪除部署目錄。
我正在使用以下解決方案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
receive.denyCurrentBranch updateInstead在Git的2.3增加是可能的。
將其設置在服務器存儲庫上,並且如果它乾淨,它也會更新工作樹。
2.4的進一步改進與push-to-checkout
hook and handling of unborn branches。
使用範例:
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
這確實具有以下缺點提到on the GitHub announcement:
- 您的服務器中將包含整個歷史.git目錄你的項目。您可能想要確保它不能提供給用戶!
- 在部署過程中,用戶可能會偶爾遇到站點處於不一致狀態,其中一些文件位於舊版本,其他文件位於新版本,甚至一半爲文件。如果這對於您的項目來說是一個問題,則推送部署可能不適合您。
- 如果你的項目需要一個「構建」步驟,那麼你將不得不明確地設置,也許通過githooks。
但所有這些點都超出了Git的範圍,必須由外部代碼來處理。所以從這個意義上說,這與Git鉤子一起是最終的解決方案。
作爲補充答案,我想提供一個替代方案。我使用的是git-ftp,它工作正常。
https://github.com/git-ftp/git-ftp
易於使用,唯一類型:
git ftp push
和git會自動上傳項目文件。
問候
對於部署方案
在我們的場景中,我們要存儲在GitHub上/到位桶的代碼,並要部署到Live服務器。 在這種情況下,下列組合爲我們工作(也就是這裏的高度upvoted答案的混音):
- 在你
.git
目錄複製到你的Web服務器 - 在您的本地副本
git remote add live ssh://[email protected]: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(1.7和1.9測試)
- 您需要確保先推送到github/bitbucket,這樣您才能擁有一致的回購直播
如果您
.git
文件夾是文件根目錄中確保你從外面隱藏它通過增加.htaccess
(source):RedirectMatch 404 /\..*$
我用了兩個解決方案後收到鉤:
部署的解決方案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 *」字符串的分支名稱的過濾器,並在推送的分支匹配時部署工作樹。 這使得可以將dev版本和主版本部署到不同的地方。
部署解決方案1僅刪除文件,這些文件是回購的一部分,並被提交刪除。它比部署解決方案2更快。
部署解決方案2的優點是,它將刪除從服務器端添加的生產目錄中的任何新文件,而不管它是否添加到回購站。這將永遠是乾淨的回購協議。它比Deployment Solution 1慢。
- 1. 在git push上自動部署
- 2. 使用git和免費git存儲庫部署PHP項目
- 3. 使用Maven部署項目
- 4. 使用Git部署
- 5. 在OVH「Mutualisé」(共享)部署GIT項目
- 6. git部署項目 - 文件權限 - (chmod)
- 7. git部署項目 - 存儲警告
- 8. 使用現有項目的Git自動部署
- 9. 項目部署
- 10. 使用Web引用部署項目
- 11. 部署VB.Net項目
- 12. 使用Git自動部署
- 13. 使用git進行部署
- 14. 使用Git自動部署
- 15. 使用git自動部署
- 16. PHP項目部署
- 17. 部署scrapy項目
- 18. 部署maven項目
- 19. Maven項目部署
- 20. 使用git push命令部署後在heroku應用中發送路由錯誤
- 21. 使用msbuild部署BizTalk 2009項目
- 22. 使用Tomcat部署Dynamic Web項目
- 23. 使用TFS部署Biztalk項目
- 24. Qt5項目部署 - QProxyStyle使用
- 25. 使用Maven部署PHP庫項目
- 26. 使用Fabricly crashlytic部署unity3d ios項目
- 27. 使用LINQ to SQL部署項目
- 28. 從Eclipse部署Web項目使用JRebel
- 29. 使用項目部署來組織SSISDB
- 30. 使用apache2部署Django項目
確保您有一個.htaccess策略來保護.git目錄不被讀取。如果URL可以訪問,那麼感覺像URL跳躍的人可能會有整個源代碼的一天。 – 2010-05-10 21:41:04
或者只是將公共目錄作爲git倉庫的子目錄。那麼你可以有私人文件,你可以肯定不會公開。 – tlrobinson 2010-06-08 19:54:40
我不確定我是否理解這一點。我應該在生產Web服務器上還是在測試Web服務器上創建我的第一個git repo? – 2010-06-23 04:55:01