در این مثال، روش بهتری برای به روز رسانی سرور  واقعی در حال کار نشان می دهیم. این کار را بوسیله مدل push-to-deploy انجام میدهیم به اینصورت که هر زمان تغییرات به مخزن سرور اعمال (push) شدند، سرور بروزرسانی شود.
می توانیم از از همان سروری که برای توسعه کد استفاده میکنیم برای این کار استفاده کنیم. این سروری خواهد بود که کدمان را روی آن می نویسیم. بعد از هر کامیت قادر خواهیم بود که تغییرات اعمال شده را ببینیم.

در سرور اصلی، یک وب سرور و یک مخزن خالص (bare) گیت راه اندازی خواهیم کرد که تغییرات بر روی آن اعمال خواهد شد. هم چنین یک هوک گیت تنظیم خواهیم کرد که هر گاه یک تغییر اعمال میشود (push) بصورت اتوماتیک اجرا خواهد شد. مراحل زیر را به عنوان یک کاربر عادی با سطح دسترسی sudo اجرا کنید.
راه اندازی هوک پس-دریافت (post-receive) بر روی سرور اصلی

با نصب وب سرور آپاچی روی سرور اصلی کارمان را شروع میکنیم:

 sudo apt-get update

 sudo apt-get install apache2

به یاد داشته باشید که مالکیت (ownership) دایرکتوری ریشه وب سایت را به کاربری که از آن استفاده میکنیم بدهیم:

sudo chown -R `whoami`:`id -gn` /var/www/html

از کد زیر هم برای نصب گیت روی سرور استفاده خواهیم کرد:

sudo apt-get install git

حال میتوانیم در پوشه home خودمان یک دایرکتوری برای نگهداری مخزن مورد نظر ایجاد کنیم. سپس وارد آن شده و یک مخزن bare در آن ایجاد میکنیم. مخزن bare مخزنی است که داره پوشه کاری نمی باشد و بطور مستقیم کدی در آن مشاهده نمیکنید. از این لحاظ که نمیتوانید مستقیما با کدهایتان در آن کار کنید بهتر است.

mkdir ~/proj
cd ~/proj
git init --bare

از آن جهت که این یک مخزن bare است، هیچ پوشه کاری در آن  وجود ندارد و همه فایلهایی که در یک راه اندازی معمولی در .git قرار داده می شوند، در پوشه اصلی قرار دارند. 

ما نیاز به ایجاد یک هوک دیگر داریم. این بار به هوک post-receive علاقمند هستیم که در هنگام دریافت یک git push اجرا میشود.

این فایل را در ویرایشگر خود باز کنید:

nano hooks/post-receive

دوباره باید نوع اسکریپتی  را که در حال نوشتن آن هستیم را مشخص نماییم.  سپس میتوانیم از همان دستور checkout که در فایل post-commit استفاده کردیم با کمی تغییر  در این ماشین استفاده کنیم:

#!/bin/bash
git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout –f

از آن جهت که این یک مخزن خالص (bare) است، --git-dir بایدبه دایرکتوری سطح بالای مخزن اشاره کند. بقیه تقریبا مشابه است.
هر چند به کمی منطق بیشتر در این اسکریپت نیاز خواهیم داشت. اگر بصورت تصادفی یک شاخه ویژگی تستی (test-feature) را به سرور push کنیم، این شاخه نباید روی سرور اعمال شود. در واقع میخواهیم مطمئن باشیم که فقط تغییرات انجام شده روی شاخه master بر روی سرور وب اعمال خواهند شد.
برای هوک post-recieve، ممکن است متوجه شده باشید که در جدول قبلی (مقاله قبلی) گیت سه پارامتر را به عنوان ورودی استاندارد به اسکریپت پاس میدهد: کد هش کامیت نسخه قبلی، کد هش کامیت نسخه جدید و مرجعی که push شده است. از این موضوع میتوانیم استفاده کنیم تا متوجه شویم مرجع (ref) ما شاخه اصلی است یا نه.
ابتدا نیاز داریم ورودی استاندارد را بخوانیم. برای هر ref ی که ارسال میشود، سه بخش از اطلاعات (نسخه قدیمی، نسخه جدید و مرجع) به عنوان ورودی استاندارد به  اسکریپت فرستاده می شود با فاصله از هم جدا شده اند. ما می توانیم این را به وسیله یک حلقه while  که دستور git را احاطه کرده است، بخوانیم.

#!/bin/bash
while read oldrevnewrev ref
do
git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout -f
done

بنابراین حالا، ما سه مجموعه متغیر براساس آنچه که ارسال شده،‌ خواهیم داشت. برای هر push شاخه اصلی، شیء ref شامل چیزی شبیه به ref/heads/master خواهد بود. با استفاده از یک دستور if میتوانیم بررسی کنیم که ref ای که سرور دریافت میکند همان فرمت را دارد یا نه:

#!/bin/bash
while read oldrevnewrev ref
do
if [[ $ref =~ .*/master$ ]];
then
git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout -f
fi
done

برای hookهای سمت سرور، در واقع gitمی تواند پیامها را به کلاینت برگرداند. هر چیزی  که به خروجی استاندارد فرستاده میشود به سمت کلاینت هدایت (redirect) خواهد شد. این به ما فرصت میدهد که صریحا از تصمیمی که در سرور گرفته شده است آگاهی یابیم.

 میتوانیم برخی متن ها را که توصیف می کند چه وضعیتی تشخیص داده شده و چه اقدامی انجام گرفته است،را به خروجی اضافه نماییم. همچنین  باید بلوک دیگری را برای اطلاع رسانی به کاربر زمانی که یک شاخه غیراصلی (غیر سرور) بصورت موفقیت آمیز دریافت شد، اضافه کنیم حتی اگر این عمل هیچ انتشاری را راه اندازی نکرد:

#!/bin/bash
while read oldrevnewrev ref
do
if [[ $ref =~ .*/master$ ]];
then
echo "Master ref received. Deploying master branch to production..."
git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout -f
else
echo "Ref $ref successfully received. Doing nothing: only the master branch may be deployed on this server."
fi
done

هنگامی که کارتان به پایان رسید، پرونده را ذخیره کرده و ببندید. به یاد داشته باشد که، ما باید اسکریپت انجام پذیر را در کار برای hook ایجاد کنیم.

chmod +x hooks/post-receive

حالا ما می توانیم دستیابی به این سرور را از راه دور برای کلاینت خودمان راه اندازی کنیم.

 پیکربندی سرور از راه دور بر روی دستگاه کلاینت

خب، برمیگردیم به ماشین کلاینت خودمان (development). وارد دایرکتوری کاری پروژه خودتان شوید:

cd ~/proj

در داخل، سرور از راه دور را به عنوان یک محصول که از راه دور نامیده شده، اضافه کنید. شما نیاز به دانستن نام کاربری دارید که در سرور محصول خود استفاده کردید، همچنین آدرس IP یا نام دامنه آن. شما همچنین نیاز به دانستن مکان مخزن خالی که در رابطه بادایرکتوری اصلی کاربر تنظیم می کنید، خواهید داشت. دستوری که شما تایپ می کنید باید چیزی شبیه به این باشد:

git remote add production demo@server_domain_or_IP:proj

بیایید شاخه اصلی کنونی مان را به سرور محصول مان ارسال کنیم:

git push production master

اگر شما کلیدهای SSH پیکربندی شده را ندارید،‌ ممکن است مجبور شوید رمز عبور کاربر سرور محصول تان را وارد کنید. شما باید چیزی که اینگونه بنظر میرسد ببینید :

Counting objects: 8, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 473 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
remote: Master ref received. Deploying master branch...
To demo@107.170.14.32:proj
009183f..f1b9027 master -> master

همانطور که میبینید،‌ متن از ما پس از دریافت hook ،‌ در خروجی دستور وجود دارد. اگر ما نام دامنه سرور محصولمان یا آدرس IPرا در مرورگر وب ببینیم، باید نسخه فعلی پروژه مان را ببینیم :

pushed

به نظر می رسد که hookکد ما را بصورت موفقیت آمیزی به محصول ارسال کرده است یکبار آن اطلاعات را دریافت کرد. حالا بیایید برخی کدهای جدید را امتحان کنیم. برگردید به ماشین توسعه، ما یک شاخه جدید را برای نگهداری تغییرات خود ایجاد خواهیم کرد. به این ترتیب می توانیم مطمین شویم که قبل از گسترش در محصول، همه چیز برای رفتن آماده است. یک اخه جدید به نام test_feature ایجاد کرده و با تایپ کردن عبارت زیر شاخه جدید را بررسی کنید:

git checkout -b test_feature

حالا ما در شاخه test_feature کار می کنیم. بیایید تغییری ایجاد کنیم که ما ممکن است بخواهیم به محصول حرکت کنیم. ما آن را به این شاخه ذخیره خواهیم کرد:

echo "

New Feature Here

" >> index.html
git add .
git commit -m "Trying out new feature"

در این مرحله، اگر شما به آدرس IP یا نام دامنه ماشین توسعه خود بروید، شما باید تغییرات بصورتی که در زیر نشان داده شده ببینید:

این امر به این علت است که ماشین توسعه ما هنوز در هر ذخیره سازی در حال گسترش مجدد است. این جریان کار برای آزمودن تغییرات قبل از انتقال (جابجایی) آنها به محصول بسیار عالی است. ما می توانیم شاخه test_featureرا به سرورمحصول از راه دور خود ارسال کنیم:

git push production test_feature

شما باید پیام دیگری را از hook ارسال و دریافت ما در خروجی ببینید:

Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 301 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Ref refs/heads/test_feature successfully received. Doing nothing: only the master branch may be deployed on this server
To demo@107.170.14.32:proj
83e9dc4..5617b50 test_feature ->test_feature

اگر شما سرور محصول را مجدداً در مرورگرتان بررسی کنید، شما باید ببینید که هیچ چیز تغییر نکرده است. این چیزی است که ما انتظار داریم، زیرا تغییراتی که ما ارسال کردیم در شاخه اصلی نبود. حالا که ما تغییراتمان را در ماشین توسعه خود امتحان کرده ایم، مطمئنیم که می خواهیم این ویژگی را دد شاخه اصلیمان ثبت و ترکیب کنیم. ما می توانیم شاخه اصلی خود را وارسی کرده و آن را در شاخه test_feature بر روی ماشین توسعه خود ادغام نماییم.

git checkout master
git merge test_feature

حالا شما ویژگی جدید را در شاخه اصلی ادغام کرده اید. با ارسال کردن به سرور محصول تغییرات ما را گسترش خواهد داد:

git push production master

اگر ما آدرس IP یا نام دامنه سرور محصول خود را وارسی کنیم، تغییراتمان را مشاهده خواهیم کرد:

با استفاده از این گردش کار، ما می توانیم یک ماشین توسعه داشته باشیم که بلافاصله هر تغییر ذخیره شده ای را نشان خواهد داد. ماشین محصول هر زمان که ما شاخه اصلی را ارسال کنیم، به روز خواهد شد.

ترجمه توسط :‌ali.fcb