Déployer un projet à l'aide de Git push

412

Est-il possible de déployer un site Web en utilisant git push? J'ai un pressentiment que cela a quelque chose à voir avec l'utilisation de hooks git pour effectuer un git reset --hardcôté serveur, mais comment pourrais-je y parvenir?

Kyle Cronin
la source
2
Je suppose que cela ne s'appliquerait que dans les situations où il n'y a qu'un seul serveur de production, non?
Rijk
6
@Rijk Eh bien, vous pouvez pousser sur plusieurs serveurs simultanément avec Git, mais une fois que vous aurez atteint ce niveau, vous voudrez peut-être une solution réelle, pas un hack comme celui-ci.
Kyle Cronin
J'ai réussi à utiliser capistrano avec mes projets, qui, bien que conçu à l'origine pour le déploiement d'applications Ruby on Rails, fonctionne bien avec PHP et d'autres projets.
Traduit les réponses en russe sur ru.so: ru.stackoverflow.com/questions/428483/…
Nick Volynkin

Réponses:

287

J'ai trouvé ce script sur ce site et il semble très bien fonctionner.

  1. Copiez votre répertoire .git sur votre serveur Web
  2. Sur votre copie locale, modifiez votre fichier .git / config et ajoutez votre serveur Web en tant que télécommande:

    [remote "production"]
        url = username@webserver:/path/to/htdocs/.git
    
  3. Sur le serveur, remplacez .git / hooks / post-update par ce fichier (dans la réponse ci-dessous)

  4. Ajoutez un accès d'exécution au fichier (encore une fois, sur le serveur):

    chmod +x .git/hooks/post-update
    
  5. Maintenant, il suffit de pousser localement vers votre serveur Web et il devrait automatiquement mettre à jour la copie de travail:

    git push production
    
Kyle Cronin
la source
128
Assurez-vous que vous disposez d'une stratégie .htaccess qui protège le répertoire .git contre la lecture. Quelqu'un qui se sent comme la plongée URL pourrait avoir une journée de terrain avec le code source entier s'il est accessible.
Jeff Ferland
39
Alternativement, faites simplement du répertoire public un sous-répertoire du dépôt git. Ensuite, vous pouvez avoir des fichiers privés dont vous pouvez être sûr qu'ils ne seront pas rendus publics.
tlrobinson
3
ce lien est mort. existe-t-il un autre lien vers le fichier post-mise à jour?
Robert Hurst
6
Peut - être que je manque quelque chose , mais ne vous voulez que votre serveur de production (s) à tirer d'un des dépôts git maître branche producttion. Je suppose que l'OP n'a qu'un seul serveur? Je fais généralement mon serveur d'intégration continue faire le déploiement de mon site (en exécutant quelques tests avant le déploiement).
Adam Gent
4
Suivre ces étapes à partir d'un référentiel qui a déjà une séquence de validations; au début, vous ne pouvez pas pousser car la branche principale est déjà extraite. Ensuite, si vous extrayez une branche alternative sur la télécommande, seuls les différents fichiers sont extraits dans le répertoire de travail. Je m'attendais à ce que le crochet fasse une réinitialisation - difficile pour moi
barrymac
80

Utilisation du fichier post-mise à jour ci-dessous:

  1. Copiez votre répertoire .git sur votre serveur Web
  2. Sur votre copie locale, modifiez votre fichier .git / config et ajoutez votre serveur Web en tant que télécommande:

    [remote "production"]
        url = username@webserver:/path/to/htdocs/.git
    
  3. Sur le serveur, remplacez .git / hooks / post-update par le fichier ci-dessous

  4. Ajoutez un accès d'exécution au fichier (encore une fois, sur le serveur):

    chmod +x .git/hooks/post-update
    
  5. Maintenant, il suffit de pousser localement vers votre serveur Web et il devrait automatiquement mettre à jour la copie de travail:

    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
Darío Javier Cravero
la source
5
Décidément ... écrivez simplement ce script sur un langage que vous utilisez pour le développement que ce soit php, python, groovy ou autre! Je n'ai jamais compris cet amour pour les scripts shell qui ont (subjectivement) une syntaxe assez étrange et si peu de fonctionnalités fonctionnelles.
dVaffection
4
@dVaffection dans tous les cas, vous allez écrire des commandes shell si vous utilisez git. donc au lieu d'écrire un script dans une autre langue et de jongler constamment entre cette langue et le shell. tout écrire en shell semble logique, vous ne trouvez pas?
Abderrahmane TAHRI JOUTI
J'ai également dû exécuter 'git config receive.denyCurrentBranch updateInstead' sur le serveur, afin qu'il accepte la poussée. Je pense que c'est parce que la succursale a été vérifiée?
stackPusher
60

Après de nombreux faux départs et impasses, je suis enfin capable de déployer du code de site web avec juste "git push remote " grâce à cet article .

Le script post-mise à jour de l'auteur ne comprend qu'une seule ligne et sa solution ne nécessite pas de configuration .htaccess pour masquer le dépôt Git comme d'autres le font.

Quelques pierres d'achoppement si vous déployez cela sur une instance Amazon EC2;

1) Si vous utilisez sudo pour créer le référentiel de destination nu, vous devez changer le propriétaire du référentiel en ec2-user ou le push échouera. (Essayez "chown ec2-user: ec2-user repo .")

2) Le push échouera si vous ne préconfigurez pas l'emplacement de votre .pem amazon-private-key , soit dans / etc / ssh / ssh_config en tant que paramètre IdentityFile, soit dans ~ / .ssh / config en utilisant le "[ Hôte] - HostName - IdentityFile - Présentation de l'utilisateur "décrite ici ...

... TOUTEFOIS, si l'hôte est configuré dans ~ / .ssh / config et différent de HostName, le push Git échouera. (C'est probablement un bug Git)

Earl Zedd
la source
J'ai suivi les étapes de l'article que vous avez mentionné, et tout a fonctionné comme un charme. Je me demande seulement s'il y a des inconvénients concernant la sécurité ou la stabilité. Un conseil à ce sujet?
xlttj
xl-t: En supposant que vous utilisez Git sur SSH, je dirais que le danger réside dans une erreur avec Git. Vous pouvez demander à l'auteur de l'article; il termine avec "Les questions et suggestions sont les bienvenues." Ma stratégie de réplication actuelle (morte de cerveau) consiste à utiliser Transmit by Panic Software.
Earl Zedd
1
L'article lié a une exigence importante lorsque vous utilisez des crochets. Les hooks échoueront si .git se trouve être dans le même schéma de nommage que le répertoire de travail. ie / foo / bar (répertoire de travail) et /foo/bar.git (dépôt barebone git). Assurez-vous donc de renommer / foo / bar en quelque chose d'autre, comme /foo/bar.live ou / foo / blah Eh bien, au cas où vous vous poseriez la question, le message d'erreur exact que vous recevriez si votre répertoire de travail porte le même nom que le dépôt barebone est "distant: fatal: impossible de revenir dans le document d'origine: aucun fichier ou répertoire de ce type"
Antony
1
Je ne comprends pas pourquoi vous auriez besoin d'un hook post-déploiement pour fonctionner. Pousser les modifications de code vers un référentiel distant signifie que le référentiel distant est à jour. Qu'est-ce que je rate?
Charlie Schliesser
1
@CharlieS ce qui vous manque, c'est que git ne vous laissera pas pousser une branche vers un référentiel qui a extrait cette branche. Dans ce cas, la réponse (à mon humble avis) est d'avoir deux référentiels: un référentiel nu vers lequel vous poussez et un deuxième référentiel dont le répertoire de travail est mis à jour via le hook lorsque le référentiel nu est poussé vers.
Ben Hughes
21

n'installez pas git sur un serveur ou copiez-y le dossier .git. pour mettre à jour un serveur à partir d'un clone git, vous pouvez utiliser la commande suivante:

git ls-files -z | rsync --files-from - --copy-links -av0 . [email protected]:/var/www/project

vous devrez peut-être supprimer les fichiers qui ont été supprimés du projet.

cela copie tous les fichiers archivés. rsync utilise ssh qui est de toute façon installé sur un serveur.

moins vous avez installé de logiciel sur un serveur, plus il est sécurisé et plus il est facile de gérer sa configuration et de la documenter. il n'est pas non plus nécessaire de conserver un clone git complet sur le serveur. cela ne fait que rendre plus complexe de sécuriser tout correctement.

Christian
la source
3
Une mise en garde: il synchronisera les fichiers que vous avez dans votre répertoire de travail. Je pense que cela peut être évité en utilisant un script qui cache les modifications en cours, nettoie tout, déploie puis rétablit la cachette.
mateusz.fiolka
Les serveurs sont des hommes?
Ian Warburton
12

En substance, tout ce que vous devez faire est le suivant:

server = $1
branch = $2
git push $server $branch
ssh <username>@$server "cd /path/to/www; git pull"

J'ai ces lignes dans ma demande en tant qu'exécutable appelé deploy .

donc quand je veux faire un déploiement je tape ./deploy myserver mybranch.

Lloyd Moore
la source
voir ma réponse comment résoudre le problème si vous avez besoin d'une clé privée ou d'un nom d'utilisateur différent pour ssh
Karussell
Cette solution est plus rapide que la mienne lors du déploiement sur plusieurs serveurs! Poussez simplement vers le référentiel principal et tirez en parallèle. Et si vous ne voulez pas ou ne pouvez pas déployer vos clés sur chaque instance, utilisez l'agent clé! ssh -A ...
Karussell
1
Il serait plus facile si vous incluiez un guide sur la configuration des clés SSH sur lequel cette réponse s'appuie pour fonctionner de manière transparente
Hengjie
L'utilisation de git pulldoit être évitée pour les déploiements automatisés car la partie de fusion pourrait nécessiter un nettoyage manuel en cas de conflit.
Quinn Comendant
9

La façon dont je le fais est que j'ai un référentiel Git nu sur mon serveur de déploiement où je pousse les modifications. Ensuite, je me connecte au serveur de déploiement, je passe au répertoire de documentation du serveur Web et je fais un pull git. Je n'utilise pas de crochets pour essayer de le faire automatiquement, cela semble plus difficile que cela ne vaut.

Greg Hewgill
la source
En cas d'erreur (s) dans le nouveau code, réinitialisez-vous par commit ou le pull entier? (Ou est-ce seulement 1 possible?)
Rudie
1
@Rudie: Si vous devez annuler les modifications sur le serveur de déploiement, vous pouvez utiliser git resetpour revenir en arrière parmi les dernières modifications (toutes les validations, pas seulement l'ensemble). Si vous devez annuler quelque chose de spécifique qui n'est pas le dernier commit, vous pouvez l'utiliser, git revertmais cela devrait probablement être utilisé uniquement en cas d'urgence ( git revertcrée un nouveau commit qui annule l'effet de certains commit précédents).
Greg Hewgill
Juste par curiosité: pourquoi pensez-vous que les crochets seraient plus problématiques que cela en vaut la peine?
Rijk
@Rijk: Lorsque vous utilisez des hooks pour cela, le répertoire de documentation du serveur Web réel est modifié par un processus d'arrière-plan automatique. La connexion me permet d'avoir plus de contrôle sur le moment exact où les modifications sont appliquées au répertoire des documents. En outre, il est plus facile de résoudre les problèmes. Les crochets pourraient être plus appropriés si les committers n'ont pas un accès suffisant pour se connecter au serveur Web.
Greg Hewgill
Donc, votre dossier webapp réel est également un référentiel .git? Qu'en est-il du dossier .git, il est visible pour le monde extérieur?
Fernando
9

git config --local receive.denyCurrentBranch updateInstead

Ajouté dans Git 2.3, cela pourrait être une bonne possibilité: https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155

Vous le définissez sur le référentiel du serveur et il met également à jour l'arborescence de travail s'il est propre.

Il y a eu d'autres améliorations dans 2.4 avec le push-to-checkoutcrochet et la manipulation des branches à naître .

Exemple d'utilisation:

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

Production:

a
b

Cela présente les lacunes suivantes mentionnées dans l'annonce GitHub :

  • Votre serveur contiendra un répertoire .git contenant l'historique complet de votre projet. Vous voulez probablement vous assurer qu'il ne peut pas être servi aux utilisateurs!
  • Pendant les déploiements, il sera possible pour les utilisateurs de rencontrer momentanément le site dans un état incohérent, avec certains fichiers dans l'ancienne version et d'autres dans la nouvelle version, ou même des fichiers à moitié écrits. S'il s'agit d'un problème pour votre projet, push-to-deploy n'est probablement pas pour vous.
  • Si votre projet a besoin d'une étape de "build", vous devrez le configurer explicitement, peut-être via githooks.

Mais tous ces points sont hors de portée de Git et doivent être pris en charge par un code externe. En ce sens, cela, avec les crochets Git, est la solution ultime.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
Pour le définir, exécutez cette commande: 'git config receive.denyCurrentBranch updateInstead' dans le terminal
stackPusher
5

Mise à jour: j'utilise maintenant la solution Lloyd Moore avec l'agent clé ssh -A .... Pousser vers un référentiel principal puis le retirer en parallèle de toutes vos machines est un peu plus rapide et nécessite moins de configuration sur ces machines.


Ne pas voir cette solution ici. il suffit de pousser via ssh si git est installé sur le serveur.

Vous aurez besoin de l'entrée suivante dans votre .git / config local

[remote "amazon"]
    url = amazon:/path/to/project.git
    fetch = +refs/heads/*:refs/remotes/amazon/*

Mais bon, avec quoi ça amazon:? Dans votre ~ / .ssh / config local, vous devrez ajouter l'entrée suivante:

Host amazon
    Hostname <YOUR_IP>
    User <USER>
    IdentityFile ~/.ssh/amazon-private-key

maintenant tu peux appeler

git push amazon master
ssh <USER>@<YOUR_IP> 'cd /path/to/project && git pull'

(BTW: /path/to/project.git est différent du répertoire de travail réel / path / to / project)

Karussell
la source
5

Pour le scénario de déploiement

Dans notre scénario, nous stockons le code sur github / bitbucket et voulons déployer sur des serveurs en direct. Dans ce cas, la combinaison suivante fonctionne pour nous (c'est-à-dire un remix des réponses très appréciées ici) :

  1. Copiez votre .gitrépertoire sur votre serveur Web
  2. Sur votre copie locale git remote add live ssh://user@host:port/folder
  3. Sur la télécommande: git config receive.denyCurrentBranch ignore
  4. À distance: nano .git/hooks/post-receiveet ajoutez ce contenu:

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

  5. Sur la télécommande: chmod +x .git/hooks/post-receive

  6. Vous pouvez maintenant y pousser avec git push live

Remarques

  • Cette solution fonctionne avec les anciennes versions de git (testées avec 1.7 et 1.9)
  • Vous devez d'abord vous assurer de pousser vers github / bitbucket, donc vous aurez un repo cohérent en direct
  • Si votre .gitdossier est dans la racine du document, assurez-vous de le cacher de l'extérieur en ajoutant à .htaccess( source ):

    RedirectMatch 404 /\..*$

Attila Fulop
la source
4

Nous utilisons capistrano pour gérer le déploiement. Nous construisons capistrano pour le déployer sur un serveur intermédiaire, puis exécutons un rsync avec l'ensemble de notre serveur.

cap deploy
cap deploy:start_rsync (when the staging is ok)

Avec capistrano, nous pouvons faire un rollback facile en cas de bug

cap deploy:rollback
cap deploy:start_rsync
Supernini
la source
avez-vous intégré le déploiement en direct via rsync dans capistrano?
Martin Abraham
2

Giddyup sont des crochets git gnostiques juste pour ajouter de l'eau pour automatiser le déploiement via git push. Il vous permet également d'avoir des crochets de démarrage / arrêt personnalisés pour redémarrer le serveur Web, réchauffer le cache, etc.

https://github.com/mpalmer/giddyup

Découvrez des exemples .

Artur Bodera
la source
1

On dirait que vous devriez avoir deux copies sur votre serveur. Une copie nue, à partir de laquelle vous pouvez pousser / tirer, à partir de laquelle vous pousserez vos modifications lorsque vous aurez terminé, puis vous clonerez cela dans votre répertoire Web et configurerez un cronjob pour mettre à jour git pull à partir de votre répertoire Web tous les jours ou donc.

Flamme
la source
1

On pourrait imaginer mettre en place un hook git qui, quand on dit qu'un commit est fait pour dire la branche "stable", il tirera les changements et les appliquera au site PHP. Le gros inconvénient est que vous n'aurez pas beaucoup de contrôle si quelque chose ne va pas et cela ajoutera du temps à vos tests - mais vous pouvez avoir une idée de la quantité de travail qui sera impliquée lorsque vous fusionnerez, par exemple, votre branche de tronc dans la branche stable pour savoir combien de conflits vous pouvez rencontrer. Il sera important de garder un œil sur tous les fichiers spécifiques au site (par exemple, les fichiers de configuration), sauf si vous avez uniquement l'intention d'exécuter un seul site.

Sinon, avez-vous plutôt envisagé de pousser le changement sur le site?

Pour plus d'informations sur les hooks git, consultez la documentation des githooks .

Chealion
la source
1

Ma vision de la solution chrétienne .

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
  • Archive la branche principale dans tar
  • Extrait l'archive tar dans le répertoire de déploiement dans le dossier temporaire du système.
  • rsync se transforme en serveur
  • supprimer le répertoire de déploiement du dossier temporaire.
Priit
la source
1

J'utilise la solution suivante de toroid.org , qui a un script de hook plus simple.

sur le serveur:

$ mkdir website.git && cd website.git
$ git init --bare
Initialized empty Git repository in /home/ams/website.git/

et installez le crochet sur le serveur:

$ 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

sur votre client:

$ 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

puis pour publier, tapez simplement

$ git push web

Il y a une description complète sur le site: http://toroid.org/ams/git-website-howto

Synox
la source
de cette façon, ne supprimez pas les fichiers existants dans le référentiel.
RusAlex
2
Pourquoi git push web +master:refs/heads/masterau lieu de juste git push web master?
Matthieu Moy du
1

Comme réponse complémentaire, je voudrais proposer une alternative. J'utilise git-ftp et cela fonctionne bien.

https://github.com/git-ftp/git-ftp

Facile à utiliser, tapez uniquement:

git ftp push

et git téléchargera automatiquement les fichiers du projet.

Cordialement

manuelbcd
la source
0

Dans un environnement où plusieurs développeurs accèdent au même référentiel, les instructions suivantes peuvent vous aider.

Assurez-vous que vous disposez d'un groupe Unix auquel tous les développeurs appartiennent et donnez la propriété du référentiel .git à ce groupe.

  1. Dans le .git / config du référentiel du serveur, définissez sharedrepository = true. (Cela indique à git d'autoriser plusieurs utilisateurs, ce qui est nécessaire pour les validations et le déploiement.

  2. définissez le umask de chaque utilisateur dans leurs fichiers bashrc pour être le même - 002 est un bon début

Lloyd Moore
la source
0

J'ai fini par créer mon propre outil de déploiement rudimentaire qui retirerait automatiquement les nouvelles mises à jour du dépôt - https://github.com/jesalg/SlimJim - En gros, il écoute le github post-receive-hook et utilise un proxy pour déclencher un script de mise à jour.

jesal
la source
0

J'utilise deux solutions pour le crochet post-réception:

DÉPLOYER LA SOLUTION 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

DÉPLOYER LA SOLUTION 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

Les deux solutions sont basées sur des solutions antérieures disponibles dans ce fil.

Notez que BRANCH_REGEX = '^ $ {GIT_BRANCH1}. $ 'filtre les noms de branche correspondant à la chaîne "master " ou "dev *" et déploie l'arborescence de travail, si la branche poussée correspond. Cela permet de déployer une version de développement et une version principale à différents endroits.

DEPLOY SOLUTION 1 supprime uniquement les fichiers, qui font partie du référentiel, et a été supprimé par une validation. Il est plus rapide que la solution de déploiement 2.

DEPLOY SOLUTION 2 a l'avantage de supprimer tous les nouveaux fichiers du répertoire de production, qui a été ajouté côté serveur, qu'il ait été ajouté au référentiel ou non. Ce sera toujours dupe propre du repo. Il est plus lent que la solution de déploiement 1.

klor
la source