Kullanarak bir web sitesi dağıtmak mümkün mü git push
? Ben sunucu tarafında gerçekleştirmek için git kanca kullanarak bir şey var bir önsezi var git reset --hard
, ama bunu başarmak hakkında nasıl gitmek?
Kullanarak bir web sitesi dağıtmak mümkün mü git push
? Ben sunucu tarafında gerçekleştirmek için git kanca kullanarak bir şey var bir önsezi var git reset --hard
, ama bunu başarmak hakkında nasıl gitmek?
Yanıtlar:
Bulduğum bu senaryoyu üzerinde bu site ve oldukça iyi iş gibi görünüyor.
Yerel kopyanızda .git / config dosyanızı değiştirin ve web sunucunuzu uzaktan kumanda olarak ekleyin:
[remote "production"]
url = username@webserver:/path/to/htdocs/.git
Sunucuda, .git / hooks / post-update dosyasını bu dosyayla değiştirin (aşağıdaki cevapta)
Dosyaya yürütme erişimi ekleyin (yine sunucuda):
chmod +x .git/hooks/post-update
Şimdi, yerel olarak web sunucunuza itin ve çalışan kopyayı otomatik olarak güncellemelidir:
git push production
Aşağıdaki güncelleme sonrası dosyasını kullanarak :
Yerel kopyanızda .git / config dosyanızı değiştirin ve web sunucunuzu uzaktan kumanda olarak ekleyin:
[remote "production"]
url = username@webserver:/path/to/htdocs/.git
Sunucuda .git / hooks / post-update dosyasını aşağıdaki dosyayla değiştirin
Dosyaya yürütme erişimi ekleyin (yine sunucuda):
chmod +x .git/hooks/post-update
Şimdi, yerel olarak web sunucunuza itin ve çalışan kopyayı otomatik olarak güncellemelidir:
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
Birçok yanlış başlangıç ve çıkmazdan sonra, nihayet bu makale sayesinde sadece "git push remote " ile web sitesi kodunu dağıtabiliyorum .
Yazarın güncelleme sonrası komut dosyası yalnızca bir satır uzunluğundadır ve çözümü, bazılarının yaptığı gibi Git deposunu gizlemek için .htaccess yapılandırması gerektirmez.
Bunu bir Amazon EC2 örneğine dağıtıyorsanız birkaç engel;
1) Çıplak hedef havuzu oluşturmak için sudo kullanırsanız, repo sahibini ec2 kullanıcısı olarak değiştirmeniz gerekir, aksi takdirde push başarısız olur. ("Chown ec2-user: ec2-user repo " yu deneyin .)
2) amazon-private-key .pem'inizin konumunu bir IdentityFile parametresi olarak / etc / ssh / ssh_config içinde veya "/ .ssh / config içinde" [ Host] - HostName - IdentityFile - User "düzeni burada açıklanmıştır ...
Ancak, Host ~ / .ssh / config içinde yapılandırılmışsa ve HostName'den farklıysa Git push başarısız olur. (Bu muhtemelen bir Git hatasıdır)
git'i bir sunucuya kurmayın veya .git klasörünü oraya kopyalayın. bir sunucuyu git klonundan güncellemek için aşağıdaki komutu kullanabilirsiniz:
git ls-files -z | rsync --files-from - --copy-links -av0 . user@server.com:/var/www/project
projeden kaldırılan dosyaları silmeniz gerekebilir.
bu, teslim edilen tüm dosyaları kopyalar. rsync zaten bir sunucuya kurulan ssh kullanır.
bir sunucuya ne kadar az yazılım yüklerseniz o kadar güvenli olur ve yapılandırmasını yönetip belgelemek o kadar kolay olur. sunucuda tam bir git klonu tutmaya da gerek yoktur. sadece her şeyi düzgün bir şekilde korumayı daha karmaşık hale getirir.
Özünde yapmanız gereken tek şey şudur:
server = $1
branch = $2
git push $server $branch
ssh <username>@$server "cd /path/to/www; git pull"
Uygulamamda çalıştırılabilir olarak adlandırılan bu satırlar var deploy
.
dağıtımı yapmak istediğimde yazıyorum ./deploy myserver mybranch
.
ssh -A ...
git pull
herhangi bir çatışma varsa bunun birleştirme parçası elle temizleme gerektirebilir çünkü otomatik dağıtımlar için kaçınılmalıdır.
Bunu yapmanın yolu, dağıtım sunucumda değişiklikleri zorladığım yerde çıplak bir Git deposum var. Sonra dağıtım sunucusunda oturum açıyorum, gerçek web sunucusu dokümanlar dizinine geçiyorum ve bir git çekme işlemi yapıyorum. Bunu otomatik olarak yapmaya çalışmak için kanca kullanmıyorum, bu değerinden daha fazla sorun gibi görünüyor.
git reset
en son değişiklikler arasında (yalnızca tüm çekme değil, tüm işlemler) geri gitmek için kullanabilirsiniz . En son taahhüt olmayan belirli bir şeyi geri almanız gerekiyorsa, kullanabilirsiniz, git revert
ancak muhtemelen sadece acil durumlarda kullanılmalıdır ( git revert
önceki bazı taahhütlerin etkisini geri alan yeni bir taahhüt oluşturur).
git config --local receive.denyCurrentBranch updateInstead
Git 2.3'e eklendiğinde, bu iyi bir olasılık olabilir: https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155
Sunucu deposuna ayarlarsınız ve temizse çalışma ağacını da güncelleştirir.
2.4'te push-to-checkout
doğmamış dalların kancası ve işlenmesi ile ilgili daha fazla gelişme olmuştur .
Örnek kullanım:
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
Çıktı:
a
b
Bu , GitHub duyurusunda belirtilen aşağıdaki eksikliklere sahiptir :
Ancak bu noktaların tümü Git'in kapsamı dışındadır ve harici kodla ilgilenilmelidir. Bu anlamda, bu, Git kancaları ile birlikte nihai çözümdür.
Güncelleme: Şimdi anahtar ajan ile Lloyd Moore çözümünü kullanıyorum ssh -A ...
. Ana bir repoya itmek ve daha sonra tüm makinelerinizden paralel olarak çekmek biraz daha hızlıdır ve bu makinelerde daha az kurulum gerektirir.
Bu çözümü burada görmüyorum. git sunucuya kuruluysa ssh üzerinden itmeniz yeterlidir.
Yerel .git / config dosyasında aşağıdaki girişe ihtiyacınız olacak
[remote "amazon"]
url = amazon:/path/to/project.git
fetch = +refs/heads/*:refs/remotes/amazon/*
Ama hey, bununla ne amazon:
? Yerel ~ / .ssh / config dosyasında aşağıdaki girişi eklemeniz gerekir:
Host amazon
Hostname <YOUR_IP>
User <USER>
IdentityFile ~/.ssh/amazon-private-key
şimdi arayabilirsin
git push amazon master
ssh <USER>@<YOUR_IP> 'cd /path/to/project && git pull'
(BTW: /path/to/project.git, gerçek çalışma dizininden / path / to / project'dan farklıdır)
Senaryomuzda kodu github / bitbucket üzerinde saklıyoruz ve canlı sunuculara dağıtmak istiyoruz. Bu durumda, aşağıdaki kombinasyon bizim için çalışır (bu, burada yüksek derecede oylanan cevapların bir remiksidir) :
.git
web sunucunuza kopyalayıngit remote add live ssh://user@host:port/folder
git config receive.denyCurrentBranch ignore
Uzaktan kumandada: nano .git/hooks/post-receive
ve şu içeriği ekleyin:
#!/bin/sh
GIT_WORK_TREE=/var/www/vhosts/example.org git checkout -f
Uzaktan kumandada: chmod +x .git/hooks/post-receive
git push live
Senin Eğer .git
klasör belge kök marka içindedir emin ekleyerek dışarıdan gizlemek .htaccess
( kaynağı ):
RedirectMatch 404 /\..*$
Konuşlandırmayı yönetmek için capistrano kullanıyoruz . Bir hazırlama sunucusunda dağıtmak için capistrano oluşturduk ve ardından tüm sunucumuzla bir rsync çalıştırıyoruz.
cap deploy
cap deploy:start_rsync (when the staging is ok)
Capistrano ile hata durumunda kolay geri dönüş yapabiliriz
cap deploy:rollback
cap deploy:start_rsync
Giddyup , git push ile konuşlandırmayı otomatikleştirmek için dile agnostik just-add-water git kancalarıdır. Ayrıca, web sunucusunu yeniden başlatmak, önbelleği ısıtmak için özel başlatma / durdurma kancalarına sahip olmanızı sağlar.
https://github.com/mpalmer/giddyup
Örneklere göz atın .
Muhtemelen bir git kancası, "kararlı" dal söylemek için bir taahhüt yapıldığında değişiklikleri çekecek ve PHP sitesine uygulayacağını ayarlayabilirsiniz. Büyük dezavantajı, bir şeylerin yanlış gitmesi durumunda çok fazla kontrole sahip olmayacağınız ve testinize zaman katacağıdır - ancak bilmek için gövde dalınızı istikrarlı dalda birleştirdiğinizde ne kadar işin olacağı hakkında bir fikir edinebilirsiniz. kaç çatışma yaşayabilirsiniz . Yalnızca tek bir siteyi çalıştırma niyetinde değilseniz, siteye özgü dosyaları (örneğin, yapılandırma dosyaları) izlemeniz önemlidir.
Alternatif olarak, bunun yerine değişikliği siteye aktarmaya çalıştınız mı?
Git kancaları hakkında bilgi için githooks belgelerine bakın.
Hıristiyanlar çözümünü benim almam .
git archive --prefix=deploy/ master | tar -x -C $TMPDIR | rsync $TMPDIR/deploy/ --copy-links -av username@server.com:/home/user/my_app && rm -rf $TMPDIR/deploy
Daha basit bir kanca komut dosyası olan toroid.org tarafından aşağıdaki çözümü kullanıyorum .
sunucuda:
$ mkdir website.git && cd website.git
$ git init --bare
Initialized empty Git repository in /home/ams/website.git/
ve kancayı sunucuya takın:
$ 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
müşterinizde:
$ 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
sonra yayınlamak için yazın
$ git push web
Web sitesinde tam bir açıklama var: http://toroid.org/ams/git-website-howto
git push web +master:refs/heads/master
sadece yerine git push web master
?
Tamamlayıcı cevap olarak bir alternatif sunmak istiyorum. Git-ftp kullanıyorum ve iyi çalışıyor.
https://github.com/git-ftp/git-ftp
Kullanımı kolay, sadece yazın:
git ftp push
ve git proje dosyalarını otomatik olarak yükleyecektir.
Saygılarımızla
Aynı veri havuzuna erişen birden fazla geliştiricinizin bulunduğu bir ortam göz önüne alındığında, aşağıdaki yönergeler yardımcı olabilir.
Tüm geliştiricilerin ait olduğu ve bu gruba .git deposunun sahipliğini veren bir unix grubunuz olduğundan emin olun.
Sunucu deposu kümesinin .git / config dosyasında sharedrepository = true. (Bu, git'e taahhütler ve dağıtım için gerekli olan birden fazla kullanıcıya izin vermesini söyler.
her kullanıcının bashrc dosyalarındaki umask değerini aynı olacak şekilde ayarlayın - 002 iyi bir başlangıçtır
Yeni güncellemeleri otomatik olarak repodan çekecek kendi temel dağıtım aracımı oluşturdum - https://github.com/jesalg/SlimJim - Temelde github post-hook'u dinler ve komut dosyasını güncelle.
Alınan kanca için iki çözüm kullanıyorum:
DEPLOY ÇÖZÜM 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
DEPLOY ÇÖZÜM 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
Her iki çözüm de bu konudaki daha önceki çözümlere dayanmaktadır.
BRANCH_REGEX = '^ $ {GIT_BRANCH1}' a dikkat edin. "master ile eşleşen şube adları için $ 'filtreleri " veya "dev *" dizesiyle ve itilen şube eşleşirse çalışma ağacını dağıtır. Bu, dev sürümünü ve ana sürümü farklı yerlere dağıtmayı mümkün kılar.
DEPLOY SOLUTION 1 yalnızca repo'nun bir parçası olan ve bir taahhüt tarafından kaldırılan dosyaları kaldırır. Dağıtım Çözümü 2'den daha hızlıdır.
DEPLOY SOLUTION 2, repoya eklenip eklenmediğine bakılmaksızın, sunucu tarafında eklenen tüm yeni dosyaları üretim dizininden kaldırması avantajına sahiptir. Her zaman repo temiz bir dupe olacaktır. Dağıtım Çözümü 1'den daha yavaştır.