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

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

Я предполагаю, что это применимо только в ситуациях, когда есть только один производственный сервер, верно?

Rijk 13.03.2012 20:24

@Rijk Что ж, вы можете отправлять запросы на несколько серверов одновременно с помощью Git, но как только вы дойдете до этого уровня, вам может понадобиться реальное решение, а не такой взлом.

Kyle Cronin 13.03.2012 20:32

Мне удалось успешно использовать капистрано в моих проектах, который, хотя изначально был разработан для развертывания приложений Ruby on Rails, хорошо работает с PHP и другими проектами.

user1559306 28.07.2012 11:56

Перевел ответы на русский язык на ру.со: ru.stackoverflow.com/questions/428483/…

Nick Volynkin 07.06.2015 01:15
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
415
4
122 243
19
Перейти к ответу Данный вопрос помечен как решенный

Ответы 19

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

В случае ошибок в новом коде, вы сбрасываете для каждой фиксации или для всего извлечения? (Или возможно только 1?)

Rudie 27.09.2010 17:19

@Rudie: Если вам нужно откатить изменения на сервере развертывания, вы можете использовать git reset для возврата между изменениями последний (все коммиты, а не только весь запрос). Если вам нужно откатить что-то конкретное, не последнее, то вы можете использовать git revert, но его, вероятно, следует использовать только в экстренных случаях (git revert создает новую фиксацию, которая отменяет эффект некоторой предыдущей фиксации).

Greg Hewgill 27.09.2010 22:06

Просто из любопытства: как вы думаете, почему хуки могут доставить больше хлопот, чем они того стоят?

Rijk 13.03.2012 20:29

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

Greg Hewgill 13.03.2012 22:00

Итак, ваша фактическая папка webapp также является репозиторием .git? А как насчет папки .git, она видна внешнему миру?

Fernando 25.07.2014 19:31

@ Фернандо: В моем случае, да, здесь нет ничего секретного. Однако для многих типов приложений вы можете захотеть поместить каталог .git в другое место (с GIT_DIR или GIT_WORK_TREE).

Greg Hewgill 26.07.2014 00:16

Да, спасибо. Например, просто скрыть .git через apache conf.

Fernando 26.07.2014 00:28

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

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

В качестве альтернативы, вы пытались вместо этого разместить изменение на сайте?

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

Ответ принят как подходящий

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

  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
    

Убедитесь, что у вас есть политика .htaccess, которая защищает каталог .git от чтения. Кто-то, кто чувствует себя так, будто погружается в URL, мог бы потрудиться со всем исходным кодом, если он доступен.

Jeff Ferland 11.05.2010 01:41

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

tlrobinson 08.06.2010 23:54

Не уверен, что понимаю это. Где мне создать свое первое репозиторий git, на рабочем веб-сервере или на тестовом веб-сервере?

Eric Martindale 23.06.2010 08:55

эта ссылка мертва. есть еще ссылка на файл пост-обновления?

Robert Hurst 28.07.2010 03:27

Если вы используете подмодули, вы можете добавить git submodule update --init --recursive в сценарий post-update.

Eric 03.01.2011 00:59

Мне нравится идея сделать общедоступный каталог подкаталогом. Я думаю, что могу просто создать символическую ссылку в моем каталоге / var / www на каталог / public в моем репо.

freedrull 14.02.2011 00:48

Мне это нравится, но пользователь, с которым вы сталкиваетесь, должен иметь правильный доступ к htdocs. Это, безусловно, пользователь git. Как тебе это удается? Вы помещаете пользователя git в группу www-pub и даете этой группе разрешение на запись в / path / htdoc / *?

gagarine 05.04.2011 16:53

Возможно, мне что-то не хватает, но вы бы не хотели, чтобы ваш производственный сервер (-ы) был тянуть из ветки producttion главного репозитория git. Я предполагаю, что у OP только один сервер? Обычно я заставляю свой сервер непрерывной интеграции выполнять развертывание моего сайта (выполняя некоторые тесты перед развертыванием).

Adam Gent 16.09.2011 15:15

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

barrymac 12.10.2011 14:15

нужно добавить еще один шаг, чтобы разрешить нажатие на удаленный, добавлю к ответу

barrymac 12.10.2011 14:27

Это не очень хорошо работает с гитолитом из-за следующей строки: die "$ repo заканчивается косой чертой; мне это не нравится \ n" if $ repo = ~ / \ / $ /;

olive 20.10.2011 21:32

Возможно, мне что-то не хватает, но похоже, что после того, как вы отправите код в производство, вам все равно придется git клонировать этот голый репозиторий .git, прежде чем вы сможете полностью развернуть? Итак, это двухэтапный процесс?

Antony 26.02.2012 09:36

@Antony Вот для чего нужен хук после обновления на стороне сервера - он заботится об этом автоматически при нажатии

Kyle Cronin 26.02.2012 09:39

когда используются подмодули - они все равно будут содержать .git - верно?

Stann 04.05.2012 22:40

если у вас порт ssh не 22, используйте следующий синтаксис: url = ssh: // user @ server: 44000 / home / fold / er / .git

Laurent Debricon 12.12.2012 17:26

Вам стоит взглянуть на это очень тривиальное решение: danbarber.me/using-git-for-deployment

Matthieu Lucas 31.01.2013 08:45

Если вы встретите ошибку отказ от обновления извлеченной ветки, вы можете решить ее, запустив git config receive.denyCurrentBranch ignore на сервере.

Kir Novak 24.11.2015 11:04

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

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

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

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

см. мой ответ, как решить проблему, если вам нужен другой закрытый ключ или имя пользователя для ssh

Karussell 26.11.2011 20:22

Это решение быстрее моего собственного при развертывании на нескольких серверах! Просто нажмите на основное репо и вытяните из него параллельно. А если вы не хотите или не можете развертывать свои ключи для каждого экземпляра, используйте ключевой агент! ssh -A ...

Karussell 31.10.2012 14:13

Было бы проще, если бы вы включили руководство по настройке ключей SSH, на которые этот ответ полагается, чтобы работать «без проблем».

Hengjie 31.10.2012 15:41

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

Quinn Comendant 14.04.2015 03:37

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

  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

Боже ... просто напишите этот скрипт на языке, который вы используете для разработки, будь то php, python, groovy или что-то еще! Я никогда не понимал этой любви к сценариям оболочки, которые имеют (субъективно) довольно странный синтаксис и так мало функциональных возможностей.

dVaffection 10.11.2014 07:55

@dVaffection в любом случае вы собираетесь писать команды оболочки, если используете git. поэтому вместо того, чтобы писать сценарий на другом языке и постоянно переключаться между этим языком и оболочкой. написание всего этого в оболочке кажется логичным, не так ли?

Abderrahmane TAHRI JOUTI 14.01.2016 13:44

Мне также пришлось выполнить git config receive.denyCurrentBranch updateInstead на сервере, чтобы он принял push. Я думаю, это потому, что ветка была проверена?

stackPusher 30.03.2017 18:43

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

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

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

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

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

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

Я выполнил шаги из упомянутой вами статьи, и все сработало как шарм. Мне только интересно, есть ли какие-то недостатки, касающиеся безопасности или стабильности. Есть какие-нибудь советы по этому поводу?

xlttj 07.12.2011 02:43

xl-t: Предполагая, что вы используете Git поверх SSH, я бы сказал, что опасность заключается в ошибке с Git. Вы можете спросить автора статьи; он заканчивает его словами «Вопросы и предложения приветствуются». Моя текущая (безумная) стратегия репликации - использовать Transmit by Panic Software.

Earl Zedd 07.12.2011 21:21

В связанной статье есть одно важное требование при использовании хуков. Перехватчики завершатся ошибкой, если .git находится в той же схеме именования, что и рабочий каталог. т.е. / foo / bar (рабочий каталог) и /foo/bar.git (репозиторий barebone git). Поэтому убедитесь, что вы переименовали / foo / bar во что-то другое, например, /foo/bar.live или / foo / blah Ну, если вам интересно, точное сообщение об ошибке, которое вы получите, если ваш рабочий каталог имеет то же имя, что и репозиторий barebone - «удаленный: фатальный: не удалось вернуться в исходный cwd: нет такого файла или каталога»

Antony 26.02.2012 11:15

Я не понимаю, зачем вам нужен хук после развертывания для запуска. Отправка изменений кода в удаленное репо означает, что удаленное репо обновлено. Что мне не хватает?

Charlie Schliesser 30.06.2012 00:12

@CharlieS вам не хватает того, что git не позволит вам отправить ветку в репозиторий, в котором эта ветка проверена. В этом случае (ИМХО, очень хороший) ответ состоит в том, чтобы иметь два репозитория: голое репо, которое вы нажимаете, и второе репо, рабочий каталог которого обновляется с помощью крючка, когда голое репо отправляется.

Ben Hughes 16.02.2013 14:27

Отличный ответ. Намного чище, чем все, что я нашел

Ben Hughes 16.02.2013 14:28

Самое простое решение. Это должен быть ответ, получивший наибольшее количество голосов и принятых.

Oliver Angelil 06.07.2017 19:11

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

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

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

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

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

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

mateusz.fiolka 23.07.2012 00:23

Серверы мужские?

Ian Warburton 27.03.2017 22:56

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

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

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

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

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

https://github.com/mpalmer/giddyup

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

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

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

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

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

С capistrano мы можем легко откатиться в случае ошибки

cap deploy:rollback
cap deploy:start_rsync

интегрировали ли вы живое развертывание через rsync в capistrano?

Martin Abraham 19.09.2014 16:53

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

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

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

таким образом не удаляйте существующие файлы в репозитории.

RusAlex 28.04.2015 17:34

Почему git push web +master:refs/heads/master, а не просто git push web master?

Matthieu Moy 29.04.2015 10:00

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 является окончательным решением.

Чтобы установить его, запустите эту команду: 'git config receive.denyCurrentBranch updateInstead' в терминале

stackPusher 30.03.2017 18:44

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

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

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

git ftp push

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

С уважением

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

В нашем сценарии мы храним код на 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 /\..*$

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

РАЗВЕРТЫВАНИЕ РЕШЕНИЯ 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

РАЗВЕРТЫВАНИЕ РЕШЕНИЯ 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 * "и развертывает дерево работ, если отправленная ветвь совпадает. Это позволяет развернуть версию разработчика и основную версию в разных местах.

РАЗВЕРНУТЬ РЕШЕНИЕ 1 удаляет только файлы, которые являются частью репо и были удалены фиксацией. Это быстрее, чем Deployment Solution 2.

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

Другие вопросы по теме