Разверните проект с помощью Git push

412

Можно ли развернуть сайт с помощью git push? У меня есть предчувствие, что это как-то связано с использованием git-хуков для выполнения git reset --hardна стороне сервера, но как мне это сделать?

Кайл Кронин
источник
2
Я предполагаю, что это применимо только в ситуациях, когда есть только один производственный сервер, верно?
Рейк
6
@Rijk Ну, вы можете использовать несколько серверов одновременно с помощью Git, но как только вы достигнете этого уровня, вы можете захотеть найти реальное решение, а не взломать, как этот.
Кайл Кронин
Я успешно использовал capistrano в своих проектах, хотя изначально он был разработан для развертывания приложений Ruby on Rails, но он хорошо работает с PHP и другими проектами.
Переводы ответов на русский язык на ru.so: ru.stackoverflow.com/questions/428483/…
Ник Волынкин

Ответы:

287

Я нашел этот скрипт на этом сайте, и он, кажется, работает довольно хорошо.

  1. Скопируйте каталог .git на свой веб-сервер.
  2. В локальной копии измените файл .git / config и добавьте свой веб-сервер в качестве удаленного:

    [remote "production"]
        url = username@webserver:/path/to/htdocs/.git
    
  3. На сервере замените этот файл на .git / hooks / post-update (ответ ниже)

  4. Добавить исполняемый доступ к файлу (опять же на сервере):

    chmod +x .git/hooks/post-update
    
  5. Теперь просто локально нажмите на ваш веб-сервер, и он должен автоматически обновить рабочую копию:

    git push production
    
Кайл Кронин
источник
128
Убедитесь, что у вас есть политика .htaccess, которая защищает каталог .git от чтения. У кого-то, кто чувствует себя, как URL-дайвинг, может быть день поля со всем исходным кодом, если он доступен.
Джефф Ферланд
39
В качестве альтернативы просто сделайте публичный каталог подкаталогом git repo. Тогда вы можете иметь личные файлы, которые вы можете быть уверены, что не будут обнародованы.
tlrobinson
3
эта ссылка мертва есть ли другая ссылка на файл после обновления?
Роберт Херст
6
Может быть , я что - то отсутствует , но не вы хотите , чтобы ваша продукция сервер (ы) , чтобы вытащить из мастер мерзавца хранилищами producttion отрасли. Я полагаю, что у ОП есть только один сервер? Я обычно заставляю свой сервер непрерывной интеграции выполнять развертывание моего сайта (выполняя некоторые тесты перед развертыванием).
Адам Гент
4
После этих шагов из репозитория, который уже имеет последовательность коммитов; сначала вы не можете нажать, потому что основная ветвь уже извлечена. Затем, если вы извлекаете альтернативную ветку на пульте, в рабочий каталог извлекаются только разные файлы. Я ожидал, что хук сделает сброс - тяжело для меня
barrymac
80

Используя файл пост-обновления ниже:

  1. Скопируйте каталог .git на свой веб-сервер.
  2. В локальной копии измените файл .git / config и добавьте свой веб-сервер в качестве удаленного:

    [remote "production"]
        url = username@webserver:/path/to/htdocs/.git
    
  3. На сервере замените .git / hooks / post-update файлом ниже

  4. Добавить исполняемый доступ к файлу (опять же на сервере):

    chmod +x .git/hooks/post-update
    
  5. Теперь просто локально нажмите на ваш веб-сервер, и он должен автоматически обновить рабочую копию:

    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
Боже ... просто напишите этот скрипт на языке, который вы используете для разработки, будь то php, python, groovy или что-то еще! Я никогда не понимал эту любовь к сценариям оболочки, которые имеют (субъективно) довольно странный синтаксис и так мало функциональных особенностей.
dVaffection
4
@dVaffection в любом случае вы собираетесь писать команды оболочки, если вы используете git. так что вместо написания сценария на другом языке постоянно жонглируйте между этим языком и оболочкой. писать все это в оболочке кажется логичным, не правда ли?
Абдеррахман ТАХРИ ДЖОУТИ
Мне также пришлось выполнить «git config receive.denyCurrentBranch updateInstead» на сервере, чтобы он мог принять push. Я думаю, потому что ветка была проверена?
stackPusher
60

После многих фальстартов и тупиков, я наконец-то смог развернуть код сайта просто с помощью «git push remote » благодаря этой статье .

Сценарий автора после обновления занимает всего одну строку, и его решение не требует настройки .htaccess, чтобы скрыть репозиторий Git, как это делают некоторые другие.

Пара камней преткновения, если вы развертываете это на экземпляре Amazon EC2;

1) Если вы используете sudo для создания чистого конечного репозитория, вы должны сменить владельца репо на ec2-user, иначе загрузка не удастся. (Попробуйте "chown ec2-user: ec2-user repo .")

2) Push не удастся, если вы предварительно не сконфигурируете расположение вашего amazon-private-ключа .pem, либо в / etc / ssh / ssh_config в качестве параметра IdentityFile, либо в ~ / .ssh / config, используя "[[ Host] - HostName - IdentityFile - User "макет описан здесь ...

... ОДНАКО, если Host настроен в ~ / .ssh / config и отличается от HostName, Git push не удастся. (Это, вероятно, ошибка Git)

Эрл Зедд
источник
Я следовал за шагами в статье, которую вы упомянули, и все работало как шарм. Я только удивляюсь, есть ли некоторые недостатки, касающиеся безопасности или стабильности. Любой совет по этому поводу?
xlttj
XLT: Предполагая, что вы используете Git вместо SSH, я бы сказал, что опасность заключается в том, чтобы ошибиться с Git. Вы можете спросить у автора статьи; он заканчивает это словами «Вопросы и предложения приветствуются». Моя текущая (безмозглая) стратегия репликации заключается в использовании Transmit by Panic Software.
Эрл Зедд
1
Связанная статья имеет одно важное требование при использовании хуков. Перехватчики потерпят неудачу, если .git окажется в той же схеме именования, что и рабочий каталог. т.е. / foo / bar (рабочий каталог) и /foo/bar.git (barebone-репозиторий git). Поэтому убедитесь, что вы переименовали / foo / bar во что-то другое, например, /foo/bar.live или / foo / blah. Ну, если вам интересно, точное сообщение об ошибке вы получите, если ваш рабочий каталог имеет то же имя, что и репозиторий barebone является «удаленным: fatal: не удалось перейти обратно к исходному cwd: нет такого файла или каталога»
Antony
1
Я не понимаю, зачем вам нужен хук после развертывания. Нажатие изменения кода на удаленном репо означает, что удаленное репо обновлено. Что мне не хватает?
Чарли Шлиссер
1
@CharlieS, чего вам не хватает, так это того, что git не позволит вам выдвинуть ветку в репозиторий, в котором эта ветка проверена. В этом случае (IMHO очень хороший) ответ состоит в том, чтобы иметь два репозитория: пустое хранилище, на которое вы нажимаете, и второе хранилище, рабочий каталог которого обновляется через ловушку, когда на пустое хранилище помещается.
Бен Хьюз
21

не устанавливайте git на сервер и не копируйте туда папку .git. чтобы обновить сервер из клона git, вы можете использовать следующую команду:

git ls-files -z | rsync --files-from - --copy-links -av0 . user@server.com:/var/www/project

Возможно, вам придется удалить файлы, которые были удалены из проекта.

это копирует все проверенные файлы. rsync использует ssh, который в любом случае установлен на сервере.

чем меньше программного обеспечения установлено на сервере, тем более он безопасен и тем проще управлять его конфигурацией и документировать его. также нет необходимости хранить полный git-клон на сервере. это только усложняет, чтобы защитить все должным образом.

Кристиан
источник
3
Одно предупреждение: он rsync файлы, которые у вас есть в вашем рабочем каталоге. Я думаю, что этого можно избежать, используя скрипт, который хранит текущие изменения, очищает все, развертывает и затем восстанавливает тайник.
mateusz.fiolka
Серверы мужские?
Ян
12

По сути, все, что вам нужно сделать, это следующее:

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

У меня есть эти строки в моем приложении в качестве исполняемого файла deploy.

поэтому, когда я хочу сделать развертывание, я печатаю ./deploy myserver mybranch.

Ллойд Мур
источник
см. мой ответ, как решить проблему, если вам нужен другой закрытый ключ или имя пользователя для ssh
Karussell
Это решение быстрее моего при развертывании на нескольких серверах! Просто нажмите на основной репо и потяните параллельно с ним. А если вы не хотите или не можете развернуть ключи в каждом экземпляре, используйте агент ключей! ssh -A ...
Карусселл
1
Было бы проще, если бы вы включили руководство по настройке ключей SSH, от которого зависит этот ответ, чтобы работать «без проблем»
Hengjie
Использование git pullследует избегать автоматического развертывания , поскольку слияние часть может потребовать ручной очистки , если есть какие - либо конфликты.
Куинн Комендант
9

То, как я это делаю, это то, что у меня есть пустой Git-репозиторий на моем сервере развертывания, куда я помещаю изменения. Затем я захожу на сервер развертывания, перехожу на фактический каталог документов веб-сервера и выполняю git pull. Я не использую никаких хуков, чтобы попытаться сделать это автоматически, это кажется большим количеством проблем, чем оно того стоит.

Грег Хьюгилл
источник
В случае возникновения ошибок в новом коде, вы сбрасываете данные за коммит или за весь процесс? (Или только 1 возможен?)
Руди
1
@Rudie: Если вам нужно откатить изменения на сервере развертывания, то вы можете использовать git resetдля возврата к последним изменениям (все фиксации, а не только весь запрос). Если вам нужно откатить что-то конкретное, что не является последним коммитом, то вы можете использовать его, git revertно, вероятно, его следует использовать только в чрезвычайных ситуациях ( git revertсоздает новый коммит, который отменяет эффект некоторого предыдущего коммита).
Грег Хьюгилл
Просто из любопытства: как вы думаете, почему с крючками будет больше проблем, чем оно того стоит?
Рейк
@Rijk: при использовании хуков для этого фактический каталог документов веб-сервера изменяется автоматическим фоновым процессом. Вход в систему позволяет мне лучше контролировать, когда изменения применяются к каталогу документов. Кроме того, это легче исправить, когда что-то идет не так. Хуки могут быть более подходящими, если коммиттеры не имеют достаточного доступа для входа на веб-сервер.
Грег Хьюгилл,
То есть ваша настоящая папка webapp также является репозиторием .git? Как насчет папки .git, она видна внешнему миру?
Фернандо
9

git config --local receive.denyCurrentBranch updateInstead

Добавленная в Git 2.3, это может быть хорошей возможностью: https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155

Вы устанавливаете его в хранилище сервера, и оно также обновляет рабочее дерево, если оно чистое.

В 2.4 были улучшены улучшения с push-to-checkoutобработкой нерожденных веток .

Пример использования:

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

У этого есть следующие недостатки, упомянутые в объявлении GitHub :

  • Ваш сервер будет содержать каталог .git, содержащий всю историю вашего проекта. Вы, вероятно, хотите убедиться, что он не может быть предоставлен пользователям!
  • Во время развертывания пользователи могут на мгновение встретиться с сайтом в несогласованном состоянии, с некоторыми файлами в старой версии и другими в новой версии, или даже наполовину записанными файлами. Если это проблема для вашего проекта, возможно, push-to-deploy не для вас.
  • Если ваш проект нуждается в шаге «сборки», то вам придется настроить его явно, возможно, через githooks.

Но все эти моменты выходят за рамки Git и должны решаться внешним кодом. Таким образом, в этом смысле это, вместе с хуками Git, является окончательным решением.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
источник
Чтобы установить его, выполните следующую команду: «git config receive.denyCurrentBranch updateInstead» в терминале
stackPusher
5

Обновление: сейчас я использую решение Ллойда Мура с ключевым агентом 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'

(Кстати: /path/to/project.git отличается от фактического рабочего каталога / path / to / project)

Karussell
источник
5

Для сценария развертывания

В нашем сценарии мы храним код в github / bitbucket и хотим развернуть его на живых серверах. В этом случае у нас работает следующая комбинация (это ремикс ответов с большим количеством голосов здесь) :

  1. Скопируйте ваш .gitкаталог на ваш веб-сервер
  2. На вашей локальной копии git remote add live ssh://user@host:port/folder
  3. На пульте: git config receive.denyCurrentBranch ignore
  4. На удаленном: nano .git/hooks/post-receiveи добавить этот контент:

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

  5. На пульте: chmod +x .git/hooks/post-receive

  6. Теперь вы можете нажать там с git push live

Ноты

  • Это решение работает со старыми версиями git (протестировано с 1.7 и 1.9)
  • Вы должны сначала убедиться, что нажали на github / bitbucket, чтобы вы имели постоянное репо в прямом эфире.
  • Если ваша .gitпапка находится в корневом каталоге документа, убедитесь, что вы скрыли ее снаружи, добавив в .htaccess( источник ):

    RedirectMatch 404 /\..*$

Аттила Фулоп
источник
4

Мы используем Capistrano для управления развертыванием. Мы строим capistrano для развертывания на промежуточном сервере, а затем запускаем rsync со всеми нашими серверами.

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

С Capistrano, мы можем сделать легкий откат в случае ошибки

cap deploy:rollback
cap deploy:start_rsync
Supernini
источник
Вы интегрировали живое развертывание через rsync в capistrano?
Мартин Авраам,
2

Giddyup - это не зависящие от языка git-хуки типа " просто добавь воды", которые автоматизируют развертывание с помощью git push. Это также позволяет вам иметь пользовательские перехватчики запуска / остановки для перезапуска веб-сервера, разогрева кеша и т. Д.

https://github.com/mpalmer/giddyup

Проверьте примеры .

Артур Бодера
источник
1

Похоже, у вас должно быть две копии на вашем сервере. Чистая копия, из которой вы можете нажать / вытащить, после чего вы внесете изменения, когда вы закончите, и затем вы клонируете это в свой веб-каталог и настроите cronjob для обновления git pull из вашего веб-каталога каждый день или так.

пламя
источник
1

Можно предположить, что можно настроить git hook, чтобы, когда говорят, что сделан коммит, чтобы сказать «стабильную» ветвь, он будет тянуть изменения и применять их к PHP-сайту. Большим недостатком является то, что у вас не будет большого контроля, если что-то пойдет не так, и это добавит время к вашему тестированию - но вы можете получить представление о том, сколько работы потребуется, когда вы объединитесь, скажем, ваша магистральная ветка с стабильной веткой, чтобы знать сколько конфликтов вы можете столкнуться. Будет важно следить за любыми файлами, относящимися к конкретному сайту (например, файлами конфигурации), если только вы не собираетесь запускать только один сайт.

В качестве альтернативы вы рассматривали возможность изменения сайта?

Для получения информации о git hooks смотрите документацию githooks .

Chealion
источник
1

Мой взгляд на решение христиан .

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
  • Архивирует главную ветку в tar
  • Распаковывает архив tar в каталог deploy в системную временную папку.
  • rsync превращается в сервер
  • удалить каталог развертывания из временной папки.
Прийт
источник
1

Я использую следующее решение от 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

Synox
источник
таким образом, не удаляйте существующие файлы в хранилище.
RusAlex
2
Почему git push web +master:refs/heads/masterвместо просто git push web master?
Матье Мой
1

В качестве дополнительного ответа я хотел бы предложить альтернативу. Я использую git-ftp, и он отлично работает.

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

Простой в использовании, только тип:

git ftp push

и git автоматически загрузит файлы проекта.

С уважением

manuelbcd
источник
0

В условиях, когда у нескольких разработчиков есть доступ к одному и тому же репозиторию, могут помочь следующие рекомендации.

Убедитесь, что у вас есть группа Unix, к которой принадлежат все разработчики, и передайте права собственности на репозиторий .git этой группе.

  1. В .git / config хранилища сервера установите sharedrepository = true. (Это говорит git разрешить нескольким пользователям, что необходимо для фиксации и развертывания.

  2. установите umask каждого пользователя в своих файлах bashrc одинаковым - 002 - хорошее начало

Ллойд Мур
источник
0

Я закончил тем, что создал свой собственный элементарный инструмент развертывания, который будет автоматически извлекать новые обновления из репозитория - https://github.com/jesalg/SlimJim - По сути, он слушает github post-receive-hook и использует прокси для запуска обновить скрипт.

jesal
источник
0

Я использую два решения для ловушки после получения:

DEPLOY 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

DEPLOY 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

Оба решения основаны на более ранних решениях, доступных в этой теме.

Обратите внимание, BRANCH_REGEX = '^ $ {GIT_BRANCH1}.$ 'фильтрует имена ветвей, совпадающие со строкой "master " или "dev *", и развертывает рабочее дерево, если соответствующая ветвь совпадает. Это позволяет развернуть версию dev и master версию в разных местах.

DEPLOY SOLUTION 1 удаляет только те файлы, которые являются частью репо и были удалены коммитом. Это быстрее, чем Deployment Solution 2.

Преимущество DEPLOY SOLUTION 2 состоит в том, что он удалит все новые файлы из производственного каталога, который был добавлен на стороне сервера, независимо от того, был ли он добавлен в репозиторий или нет. Это всегда будет чистый дуп из репо. Это медленнее, чем Deployment Solution 1.

Klor
источник