Git push kullanarak bir proje dağıtma


412

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?


2
Bu sadece bir üretim sunucusu olduğu durumlarda geçerli olacağını tahmin ediyorum, değil mi?
Rijk

6
@Rijk Git ile eşzamanlı olarak birden fazla sunucuya geçebilirsiniz, ancak bu seviyeye ulaştığınızda gerçek bir çözüm isteyebilirsiniz, bunun gibi bir kesmek değil.
Kyle Cronin

Başlangıçta Ruby on Rails uygulama dağıtımı için tasarlanmasına rağmen PHP ve diğer projelerle iyi çalışan projelerimle capistrano kullanmayı başardım .

Cevapları ru.so'da Rusçaya çevirdi: ru.stackoverflow.com/questions/428483/…
Nick Volynkin

Yanıtlar:


287

Bulduğum bu senaryoyu üzerinde bu site ve oldukça iyi iş gibi görünüyor.

  1. .Git dizininizi web sunucunuza kopyalayın
  2. 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
    
  3. Sunucuda, .git / hooks / post-update dosyasını bu dosyayla değiştirin (aşağıdaki cevapta)

  4. Dosyaya yürütme erişimi ekleyin (yine sunucuda):

    chmod +x .git/hooks/post-update
    
  5. Şimdi, yerel olarak web sunucunuza itin ve çalışan kopyayı otomatik olarak güncellemelidir:

    git push production
    

128
.Git dizininin okunmasını önleyen bir .htaccess ilkeniz olduğundan emin olun. URL dalışı gibi görünen birisinin, erişilebilir olması durumunda tüm kaynak kodunu içeren bir alan günü olabilir.
Jeff Ferland

39
Alternatif olarak, genel dizini git repo'nun bir alt dizini yapın. Ardından, herkese açık hale getirilmeyeceğinden emin olabileceğiniz özel dosyalarınız olabilir.
tlrobinson

3
bu bağlantı öldü. güncelleme sonrası dosyaya başka bir bağlantı var mı?
Robert Hurst

6
Belki bir şeyler eksik ama üretim sunucusu (ler) istemem çekin bir ana git depoları producttion daldan. Bence OP sadece bir sunucu var? Genellikle sürekli entegrasyon sunucumun sitemin dağıtımını yapmasını sağlarım (dağıtımdan önce bazı testleri çalıştırıyorum).
Adam Gent

4
Halihazırda bir dizi taahhüt içeren bir depodan bu adımları takip ederek; ilk önce ana dal zaten kullanıma alınmış olduğundan itemezsiniz. Daha sonra, uzaktan kumandadaki alternatif bir dalda ödeme yaparsanız, çalışma dizinine yalnızca farklı dosyalar teslim alınır. Kancayı sıfırlamam bekleniyor
zor

80

Aşağıdaki güncelleme sonrası dosyasını kullanarak :

  1. .Git dizininizi web sunucunuza kopyalayın
  2. 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
    
  3. Sunucuda .git / hooks / post-update dosyasını aşağıdaki dosyayla değiştirin

  4. Dosyaya yürütme erişimi ekleyin (yine sunucuda):

    chmod +x .git/hooks/post-update
    
  5. Ş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

5
Tanrım ... bu senaryoyu php, python, groovy ya da her neyse geliştirme için kullandığınız bir dile yazın! (Subjektif olarak) oldukça tuhaf sözdizimi ve çok az işlevsel özelliğe sahip kabuk komut dosyalarına olan bu sevgiyi hiç anlamadım.
dVaffection

4
@dVaffection her durumda git komutunu kullanırsanız shell komutları yazacaksınız. bu yüzden başka bir dilde bir senaryo yazmak ve sürekli olarak bu dil ve kabuk arasında dengelemek yerine. hepsini kabuğa yazmak mantıklı görünüyor değil mi?
Abderrahmane TAHRI JOUTI

Ben de sunucuda 'git config take.denyCurrentBranch updateInstead' gerçekleştirmek zorunda kaldı, böylece itme kabul ediyorum. Sanırım şube teslim edildi çünkü?
Mart'ta

60

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)


Bahsettiğiniz makaledeki adımları izledim ve her şey bir cazibe gibi çalıştı. Sadece güvenlik veya istikrar konusunda bazı dezavantajlar olup olmadığını merak ediyorum. Bu konuda bir tavsiye var mı?
xlttj

xl-t: Git'i SSH üzerinden kullandığınızı varsayarsak, tehlikenin Git ile ilgili bir hata yapmak olduğunu söyleyebilirim. Makalenin yazarına sorabilirsiniz; "Sorular ve önerilerinizi bekliyoruz" ile bitiriyor. Şu anki (beyin ölüleri) çoğaltma stratejim Panmit Software tarafından Transmit kullanmaktır.
Earl Zedd

1
Bağlantılı makalenin kanca kullandığınızda önemli bir gereksinimi vardır. .Git çalışma diziniyle aynı adlandırma düzeninde olursa kancalar başarısız olur. yani / foo / bar (çalışma dizini) ve /foo/bar.git (barebone git deposu). Bu yüzden / foo / bar'ı /foo/bar.live veya / foo / blah gibi başka bir adla yeniden adlandırdığınızdan emin olun. Merak ediyorsanız, çalışma dizininiz aynı ada sahipse alacağınız tam hata mesajını barebone deposu "uzak: ölümcül: Orijinal cwd'ye geri atlanamadı: Böyle bir dosya veya dizin yok"
Antony

1
Çalıştırmak için neden dağıtım sonrası bir kancaya ihtiyacınız olduğunu takip etmiyorum. Kod değişikliklerinin uzak bir repoya aktarılması, uzak repo'nun güncel olduğu anlamına gelir. Neyi kaçırıyorum?
Charlie Schliesser

1
@CharlieS, eksik olanın git, bir dalı bir şubeye teslim aldığınız bir havuza göndermenize izin vermeyeceğidir. Bu durumda, (IMHO çok güzel) cevabı iki depoya sahip olmaktır: çıplak repo ittiğiniz ve çalışma dizini çıplak repo itildiğinde kanca ile güncellenen ikinci bir repo.
Ben Hughes

21

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.


3
Bir uyarı: çalışma dizininizdeki dosyaları yeniden senkronize eder. Geçerli değişiklikleri saklayan, her şeyi temizleyen, dağıtan ve sonra sakla geri döndüren bir komut dosyası kullanılarak önlenebilir düşünüyorum.
mateusz.fiolka

Sunucular erkek mi?
Ian Warburton

12

Ö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 için farklı bir özel anahtara veya kullanıcı adına ihtiyacınız varsa sorunun nasıl çözüleceğini görün
Karussell

Birden fazla sunucuya dağıtım yaparken bu çözüm benimkinden daha hızlı! Sadece ana depoya itin ve paralel olarak çekin. Ve anahtarlarınızı her örneğe dağıtmak istemiyorsanız veya uygulayamıyorsanız, anahtar aracısını kullanın! ssh -A ...
Karussell

1
Bu cevabın 'sorunsuz bir şekilde' çalışmaya dayandığı SSH anahtarlarının ayarlanması için bir rehber eklerseniz daha kolay olurdu
Hengjie

Kullanımı git pullherhangi bir çatışma varsa bunun birleştirme parçası elle temizleme gerektirebilir çünkü otomatik dağıtımlar için kaçınılmalıdır.
Quinn Comendant

9

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.


Yeni kodda hata (lar) olması durumunda, kesinleştirme başına veya tüm çekme başına sıfırlama yapar mısınız? (Yoksa sadece 1 mümkün mü?)
Rudie

1
@Rudie: Dağıtım sunucusundaki değişiklikleri geri almanız gerekirse, git reseten 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 revertancak muhtemelen sadece acil durumlarda kullanılmalıdır ( git revertönceki bazı taahhütlerin etkisini geri alan yeni bir taahhüt oluşturur).
Greg Hewgill

Sadece meraktan: Kancaların neden buna değdiğinden daha fazla sorun olacağını düşünüyorsun?
Rijk

@Rijk: Bunun için kancalar kullanıldığında, gerçek web sunucusu dokümanlar dizini otomatik bir arka plan işlemiyle değiştirilir. Giriş yapmak, docs dizinine değişiklikler uygulandığında tam olarak daha fazla kontrol sahibi olmamı sağlıyor. Ayrıca, işler ters gittiğinde düzeltmek daha kolaydır. Taahhüt edenlerin web sunucusunda oturum açmak için yeterli erişimi yoksa kancalar daha uygun olabilir.
Greg Hewgill

Yani gerçek webapp klasörünüz de bir .git deposudur? Dış dünya tarafından görülebilen .git klasörü ne olacak?
Fernando

9

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-checkoutdoğ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 :

  • Sunucunuz, projenizin tüm geçmişini içeren bir .git dizini içerecektir. Muhtemelen kullanıcılara sunulamayacağından emin olmak istersiniz!
  • Konuşlandırmalar sırasında, kullanıcıların eski sürümdeki bazı dosyalar ve yeni sürümdeki diğer dosyalar veya hatta yarı yazılı dosyalar ile tutarsız bir durumda siteyle anlık olarak karşılaşmaları mümkün olacaktır. Bu projeniz için bir sorunsa, bas-konuş dağıtma muhtemelen sizin için değildir.
  • Projenizin bir "derleme" adımına ihtiyacı varsa, bunu belki de githooks aracılığıyla açıkça ayarlamanız gerekir.

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.


Ayarlamak için şu komutu çalıştırın: terminalde 'git config take.denyCurrentBranch updateInstead'
stackPusher 30:17

5

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)


5

Dağıtım Senaryosu için

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) :

  1. Dizininizi .gitweb sunucunuza kopyalayın
  2. Yerel kopyanızda git remote add live ssh://user@host:port/folder
  3. Uzaktan kumandada: git config receive.denyCurrentBranch ignore
  4. Uzaktan kumandada: nano .git/hooks/post-receiveve şu içeriği ekleyin:

    #!/bin/sh GIT_WORK_TREE=/var/www/vhosts/example.org git checkout -f

  5. Uzaktan kumandada: chmod +x .git/hooks/post-receive

  6. Şimdi oraya git push live

notlar

  • Bu çözüm eski git sürümleriyle çalışır (1.7 ve 1.9 ile test edilmiştir)
  • Önce github / bitbucket'e bastığınızdan emin olmanız gerekir, böylece canlı bir şekilde tutarlı bir repoya sahip olursunuz
  • Senin Eğer .gitklasör belge kök marka içindedir emin ekleyerek dışarıdan gizlemek .htaccess( kaynağı ):

    RedirectMatch 404 /\..*$


4

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

rsync üzerinden canlı konuşlandırmayı capistrano'ya entegre ettiniz mi?
Martin Abraham


1

Sunucunuzda iki kopya olması gerektiği anlaşılıyor. Bitirdiğinizde / değiştirebileceğiniz çıplak bir kopya, işiniz bittiğinde değişikliklerinizi iter ve ardından bunu web dizininize kopyalar ve her gün web dizininizden git pull'u güncellemek için bir cronjob kurarsınız veya yani.


1

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.


1

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
  • Ana dalı katran olarak arşivler
  • Katran arşivini sistem temp klasöründeki deploy dizinine ayıklar.
  • rsync sunucuda değişir
  • geçici klasörden deploy dizinini silin.

1

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


bu şekilde depodaki mevcut dosyaları silmeyin.
RusAlex

2
Neden git push web +master:refs/heads/mastersadece yerine git push web master?
Matthieu Moy

1

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


0

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.

  1. 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.

  2. her kullanıcının bashrc dosyalarındaki umask değerini aynı olacak şekilde ayarlayın - 002 iyi bir başlangıçtır



0

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.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.