Implemente un proyecto usando Git push

412

¿Es posible implementar un sitio web usando git push? Tengo el presentimiento de que tiene algo que ver con el uso de git hooks para realizar una operación git reset --harden el lado del servidor, pero ¿cómo podría lograr esto?

Kyle Cronin
fuente
2
Supongo que esto solo se aplicaría en situaciones donde solo hay un servidor de producción, ¿verdad?
Rijk
66
@Rijk Bueno, puedes empujar a múltiples servidores simultáneamente con Git, pero una vez que alcances ese nivel, es posible que desees una solución real, no un truco como este.
Kyle Cronin
He tenido éxito usando capistrano con mis proyectos, que aunque originalmente fue diseñado para la implementación de la aplicación Ruby on Rails, funciona bien con PHP y otros proyectos.
Tradujo las respuestas al ruso en ru.so: ru.stackoverflow.com/questions/428483/…
Nick Volynkin

Respuestas:

287

Encontré este script en este sitio y parece funcionar bastante bien.

  1. Copie su directorio .git a su servidor web
  2. En su copia local, modifique su archivo .git / config y agregue su servidor web como control remoto:

    [remote "production"]
        url = username@webserver:/path/to/htdocs/.git
    
  3. En el servidor, reemplace .git / hooks / post-update con este archivo (en la respuesta a continuación)

  4. Agregue acceso de ejecución al archivo (nuevamente, en el servidor):

    chmod +x .git/hooks/post-update
    
  5. Ahora, solo presione localmente a su servidor web y debería actualizar automáticamente la copia de trabajo:

    git push production
    
Kyle Cronin
fuente
128
Asegúrese de tener una política .htaccess que proteja el directorio .git de ser leído. Alguien que siente que el buceo con URL podría tener un día de campo con todo el código fuente si es accesible.
Jeff Ferland
39
Alternativamente, solo haga que el directorio público sea un subdirectorio del repositorio git. Entonces puede tener archivos privados que puede estar seguro de que no se harán públicos.
tlrobinson
3
Este enlace está muerto. ¿Hay otro enlace al archivo posterior a la actualización?
Robert Hurst
66
Tal vez me estoy perdiendo algo, pero ¿no querrías que tus servidores de producción extraigan de una rama de producción de repositorios git maestros? ¿Supongo que el OP solo tiene un servidor? Por lo general, hago que mi servidor de integración continua realice la implementación de mi sitio (ejecutando algunas pruebas antes de la implementación).
Adam Gent
44
Seguir esos pasos desde un repositorio que ya tiene una secuencia de confirmaciones; al principio no puede presionar porque la rama maestra ya está desprotegida. Luego, si desprotege una rama alternativa en el control remoto, solo los diferentes archivos se desprotegen en el directorio de trabajo. Esperaba que el gancho se reiniciara - duro para mí
barrymac
80

Usando el archivo posterior a la actualización a continuación:

  1. Copie su directorio .git a su servidor web
  2. En su copia local, modifique su archivo .git / config y agregue su servidor web como control remoto:

    [remote "production"]
        url = username@webserver:/path/to/htdocs/.git
    
  3. En el servidor, reemplace .git / hooks / post-update con el archivo a continuación

  4. Agregue acceso de ejecución al archivo (nuevamente, en el servidor):

    chmod +x .git/hooks/post-update
    
  5. Ahora, solo presione localmente a su servidor web y debería actualizar automáticamente la copia de trabajo:

    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
fuente
55
Geez ... ¡solo escribe este script en un lenguaje que uses para el desarrollo, ya sea php, python, groovy o lo que sea! Nunca entendí este amor por los scripts de shell que tienen (subjetivamente) una sintaxis bastante extraña y muy pocas características funcionales.
dVaffection
44
@dVaffection en cualquier caso vas a escribir comandos de shell si estás usando git. así que en lugar de escribir un guión en otro idioma y constantemente hacer malabarismos entre ese idioma y el shell escribir todo en shell parece lógico, ¿no te parece?
Abderrahmane TAHRI JOUTI
Tuve que realizar 'git config send.denyCurrentBranch updateInstead' también en el servidor, para que aceptara el envío. Creo que es porque la sucursal fue retirada?
stackPusher
60

Después de muchos falsos comienzos y callejones sin salida, finalmente puedo implementar el código del sitio web con solo "git push remote " gracias a este artículo .

El script posterior a la actualización del autor solo tiene una línea de largo y su solución no requiere la configuración .htaccess para ocultar el repositorio de Git como lo hacen otros.

Un par de obstáculos si está implementando esto en una instancia de Amazon EC2;

1) Si usa sudo para crear el repositorio de destino desnudo, debe cambiar el propietario del repositorio a ec2-user o la inserción fallará. (Pruebe "chown ec2-user: ec2-user repo ").

2) La inserción fallará si no preconfigura la ubicación de su .pem amazon-private-key , ya sea en / etc / ssh / ssh_config como un parámetro IdentityFile o en ~ / .ssh / config usando "[ Host] - HostName - IdentityFile - Usuario "diseño descrito aquí ...

... SIN EMBARGO si el Host está configurado en ~ / .ssh / config y diferente de HostName, la inserción de Git fallará. (Eso es probablemente un error de Git)

Earl Zedd
fuente
Seguí los pasos en el artículo que mencionaste, y todo funcionó a las mil maravillas. Solo me pregunto si hay algunos inconvenientes relacionados con la seguridad o la estabilidad. ¿Algún consejo sobre esto?
xlttj
xl-t: Suponiendo que estés usando Git sobre SSH, diría que el peligro radica en cometer un error con Git. Puedes preguntarle al autor del artículo; él termina con "Preguntas y sugerencias son bienvenidas". Mi estrategia de replicación actual (con muerte cerebral) es usar Transmit by Panic Software.
Earl Zedd
1
El artículo vinculado tiene un requisito importante cuando usa ganchos. Los ganchos fallarán si .git se encuentra en el mismo esquema de nombres que el directorio de trabajo. es decir, / foo / bar (directorio de trabajo) y /foo/bar.git (repositorio barebone git). Así que asegúrese de cambiar el nombre de / foo / bar a otra cosa, como /foo/bar.live o / foo / blah Bueno, en caso de que se lo pregunte, el mensaje de error exacto que recibiría si su directorio de trabajo tiene el mismo nombre que el repositorio barebone es "remoto: fatal: no se pudo volver al cwd original: no existe tal archivo o directorio"
Antony
1
No entiendo por qué necesitarías un gancho posterior a la implementación para ejecutarse. Enviar los cambios de código a un repositorio remoto significa que el repositorio remoto está actualizado. ¿Qué me estoy perdiendo?
Charlie Schliesser
1
@CharlieS lo que te estás perdiendo es que git no te permitirá empujar una rama a un repositorio que tenga esa rama desprotegida. En este caso, la respuesta (en mi humilde opinión) es tener dos repositorios: un repositorio desnudo al que empuja y un segundo repositorio cuyo directorio de trabajo se actualiza a través del gancho cuando se empuja el repositorio desnudo.
Ben Hughes
21

no instale git en un servidor ni copie la carpeta .git allí. para actualizar un servidor desde un clon de git puede usar el siguiente comando:

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

Es posible que deba eliminar los archivos que se eliminaron del proyecto.

esto copia todos los archivos registrados. rsync usa ssh que está instalado en un servidor de todos modos.

cuanto menos software haya instalado en un servidor, más seguro será y más fácil será administrar su configuración y documentarla. tampoco es necesario mantener un clon git completo en el servidor. solo hace que sea más complejo asegurar todo correctamente.

cristiano
fuente
3
Una advertencia: sincronizará los archivos que tiene en su directorio de trabajo. Creo que se puede evitar utilizando un script que oculta los cambios actuales, limpia todo, implementa y luego revierte el alijo.
mateusz.fiolka
Los servidores son hombres?
Ian Warburton
12

En esencia, todo lo que necesita hacer es lo siguiente:

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

Tengo esas líneas en mi aplicación como un ejecutable llamado deploy.

Entonces, cuando quiero hacer una implementación, escribo ./deploy myserver mybranch.

Lloyd Moore
fuente
vea mi respuesta sobre cómo resolver el problema si necesita una clave privada o nombre de usuario diferente para ssh
Karussell
¡Esta solución es más rápida que la mía cuando se implementa en varios servidores! Simplemente empuje al repositorio principal y tire en paralelo de él. Y si no desea o no puede implementar sus claves en cada instancia, ¡use el agente de claves! ssh -A ...
Karussell el
1
Sería más fácil si incluyera una guía sobre la configuración de claves SSH en la que se basa esta respuesta para que funcione 'sin problemas'
Hengjie
Se git pulldebe evitar el uso de implementaciones automáticas porque la parte de fusión podría requerir una limpieza manual en caso de conflicto.
Quinn Commandado
9

La forma en que lo hago es que tengo un repositorio Git en mi servidor de implementación donde empujo los cambios. Luego inicio sesión en el servidor de implementación, cambio al directorio de documentos del servidor web real y hago un git pull. No uso ningún gancho para intentar hacer esto automáticamente, eso parece más problemas de lo que vale.

Greg Hewgill
fuente
En caso de error (s) en el nuevo código, ¿restablece por confirmación o toda la extracción? (¿O es solo 1 posible?)
Rudie
1
@Rudie: si necesita revertir los cambios en el servidor de implementación, puede usar git resetpara retroceder entre los últimos cambios (todas las confirmaciones, no solo toda la extracción). Si necesita revertir algo específico que no sea el último commit, entonces puede usarlo, git revertpero probablemente debería usarse solo en emergencias ( git revertcrea un nuevo commit que deshace el efecto de algún commit anterior).
Greg Hewgill
Solo por curiosidad: ¿por qué crees que los ganchos serían más problemáticos de lo que valen para esto?
Rijk
@Rijk: cuando se usan ganchos para esto, el directorio real de documentos del servidor web se modifica mediante un proceso en segundo plano automático. Iniciar sesión me permite tener más control sobre exactamente cuándo se aplican los cambios al directorio docs. Además, es más fácil de arreglar cuando las cosas salen mal. Los ganchos pueden ser más apropiados si los confirmadores no tienen acceso suficiente para iniciar sesión en el servidor web.
Greg Hewgill
Entonces, ¿tu carpeta de aplicaciones web real también es un repositorio .git? ¿Qué pasa con la carpeta .git, es visible para el mundo exterior?
Fernando
9

git config --local receive.denyCurrentBranch updateInstead

Agregado en Git 2.3, esta podría ser una buena posibilidad: https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155

Lo configura en el repositorio del servidor y también actualiza el árbol de trabajo si está limpio.

Ha habido nuevas mejoras en 2.4 con el push-to-checkoutgancho y el manejo de ramas no nacidas .

Uso de la muestra:

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

Salida:

a
b

Esto tiene las siguientes deficiencias mencionadas en el anuncio de GitHub :

  • Su servidor contendrá un directorio .git que contiene el historial completo de su proyecto. ¡Probablemente quieras asegurarte de que no se pueda servir a los usuarios!
  • Durante las implementaciones, será posible que los usuarios encuentren momentáneamente el sitio en un estado inconsistente, con algunos archivos en la versión anterior y otros en la nueva versión, o incluso archivos a medio escribir. Si esto es un problema para su proyecto, la implementación de inserción probablemente no sea para usted.
  • Si su proyecto necesita un paso de "compilación", tendrá que configurarlo explícitamente, tal vez a través de githooks.

Pero todos esos puntos están fuera del alcance de Git y deben ser atendidos por código externo. Entonces, en ese sentido, esto, junto con los ganchos Git, son la solución definitiva.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
Para configurarlo, ejecute este comando: 'git config Receive.denyCurrentBranch updateInstead' en el terminal
stackPusher
5

Actualización: ahora estoy usando la solución Lloyd Moore con el agente clave ssh -A .... Empujar a un repositorio principal y luego tirar de él en paralelo desde todas sus máquinas es un poco más rápido y requiere menos configuración en esas máquinas.


No veo esta solución aquí. simplemente presione a través de ssh si git está instalado en el servidor.

Necesitará la siguiente entrada en su .git / config local

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

Pero oye, ¿qué pasa con eso amazon:? En su configuración local de ~ / .ssh / deberá agregar la siguiente entrada:

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

ahora puedes llamar

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

(Por cierto: /path/to/project.git es diferente al directorio de trabajo real / ruta / a / proyecto)

Karussell
fuente
5

Para el escenario de implementación

En nuestro escenario, estamos almacenando el código en github / bitbucket y queremos implementarlo en servidores activos. En este caso, la siguiente combinación funciona para nosotros (que es un remix de las respuestas altamente votadas aquí) :

  1. Copie sobre su .gitdirectorio a su servidor web
  2. En su copia local git remote add live ssh://user@host:port/folder
  3. En remoto: git config receive.denyCurrentBranch ignore
  4. En remoto: nano .git/hooks/post-receivey agregue este contenido:

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

  5. En remoto: chmod +x .git/hooks/post-receive

  6. Ahora puedes empujar allí con git push live

Notas

  • Esta solución funciona con versiones anteriores de git (probadas con 1.7 y 1.9)
  • Primero debe asegurarse de presionar a github / bitbucket, para que tenga un repositorio constante en vivo
  • Si su .gitcarpeta está dentro de la raíz del documento, asegúrese de ocultarla desde el exterior agregando a .htaccess( fuente ):

    RedirectMatch 404 /\..*$

Attila Fulop
fuente
4

Utilizamos capistrano para gestionar la implementación. Construimos capistrano para implementar en un servidor provisional, y luego ejecutamos un rsync con todo nuestro servidor.

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

Con capistrano, podemos hacer una reversión fácil en caso de error

cap deploy:rollback
cap deploy:start_rsync
Supernini
fuente
¿Has integrado la implementación en vivo a través de rsync en capistrano?
Martin Abraham
1

Parece que debería tener dos copias en su servidor. Una copia simple, de la que puede empujar / extraer, desde la cual empujaría sus cambios cuando haya terminado, y luego clonaría esto en su directorio web y configuraría un cronjob para actualizar git pull desde su directorio web todos los días o entonces.

Fuego
fuente
1

Podrías configurar un git hook que cuando digamos que se realiza un commit para decir la rama "estable", extraerá los cambios y los aplicará al sitio PHP. El gran inconveniente es que no tendrá mucho control si algo sale mal y agregará tiempo a sus pruebas, pero puede tener una idea de cuánto trabajo involucrará cuando se fusiona, por ejemplo, para saber cuál es su rama troncal en la rama estable. cuántos conflictos puede encontrar. Será importante vigilar los archivos que son específicos del sitio (por ejemplo, archivos de configuración) a menos que solo tenga la intención de ejecutar un solo sitio.

Alternativamente, ¿ha buscado empujar el cambio al sitio?

Para obtener información sobre git hooks, consulte la documentación de githooks .

Chealion
fuente
1

Mi opinión sobre la solución de los cristianos .

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
  • Archiva la rama maestra en alquitrán
  • Extrae el archivo tar en el directorio de implementación en la carpeta temporal del sistema.
  • rsync cambia al servidor
  • elimine el directorio de implementación de la carpeta temporal.
Priit
fuente
1

Estoy usando la siguiente solución de toroid.org , que tiene un script de gancho más simple.

en el servidor:

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

e instale el gancho en el servidor:

$ 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

en su cliente:

$ 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

luego para publicar, simplemente escriba

$ git push web

Hay una descripción completa en el sitio web: http://toroid.org/ams/git-website-howto

Synox
fuente
de esta manera no elimine los archivos existentes en el repositorio.
RusAlex
2
¿Por qué en git push web +master:refs/heads/masterlugar de solo git push web master?
Matthieu Moy
1

Como respuesta complementaria, me gustaría ofrecer una alternativa. Estoy usando git-ftp y funciona bien.

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

Fácil de usar, solo escriba:

git ftp push

y git cargará automáticamente los archivos del proyecto.

Saludos

manuelbcd
fuente
0

Dado un entorno en el que tiene múltiples desarrolladores accediendo al mismo repositorio, las siguientes pautas pueden ayudar.

Asegúrese de tener un grupo Unix al que pertenezcan todos los desarrolladores y otorgue la propiedad del repositorio .git a ese grupo.

  1. En el .git / config del repositorio del servidor establezca sharedrepository = true. (Esto le dice a git que permita que múltiples usuarios sean necesarios para las confirmaciones y la implementación.

  2. configura la umask de cada usuario en sus archivos bashrc para que sea la misma - 002 es un buen comienzo

Lloyd Moore
fuente
0

Terminé creando mi propia herramienta de implementación rudimentaria que automáticamente desplegaría nuevas actualizaciones del repositorio - https://github.com/jesalg/SlimJim - Básicamente escucha el github post-reciben-hook y usa un proxy para activar un script de actualización

jesal
fuente
0

Utilizo dos soluciones para el gancho posterior a la recepción:

IMPLEMENTAR SOLUCIÓN 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

IMPLEMENTAR SOLUCIÓN 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

Ambas soluciones se basan en soluciones anteriores disponibles en este hilo.

Tenga en cuenta que BRANCH_REGEX = '^ $ {GIT_BRANCH1}. $ 'filtros para los nombres de rama que coinciden con "master cadena " o "dev *", y despliega el árbol de trabajo, si la rama empujada coincide. Esto hace posible implementar una versión de desarrollo y una versión maestra en diferentes lugares.

SOLUCIÓN DE IMPLEMENTACIÓN 1 elimina solo los archivos, que forman parte del repositorio, y se eliminó mediante una confirmación. Es más rápido que la Solución de implementación 2.

DEPLOY SOLUTION 2 tiene la ventaja de que eliminará cualquier archivo nuevo del directorio de producción, que se agregó en el lado del servidor, sin importar si se agregó al repositorio o no. Siempre estará limpio el engaño del repositorio. Es más lento que la Solución de implementación 1.

klor
fuente