آیا با Git آشنایی دارید؟

آیا با Git آشنایی دارید؟

استفاده از قابلیت های Git در سال های اخیر رشد چشم گیری داشته است.نسخه ای از کنترل سیستم که توسط اکثر سیستم عامل های متن باز شبیه لینوکس و… مورد استفاده قرار میگیرد.به دلیل کمبود آموزش در این زمینه به زبان فارسی ،گروه برنامه نویسان نوین پندار تصمیم گرفت تا یک پست آموزشی در این زمینه تهیه و ترجمه نماید.امیدواریم مورد توجه شما عزیزان قرار بگیرد.در ادامه با ما همراه باشید.

مفاهیم اولیه

Git شامل تعدادی دستور کاربردی برای ذخیره تغییرات در یک فایل می باشد(اغلب در سورس کد مورد استفاده قرار می گیرد ولی شما در مورد هر چیزی که خواستید از آن استفاده نمایید).شما با استفاده از آن میتوانید نسخه های قدیمی پروژه،مقایسه ها،آنالیزها،ترکیب تغییرات و…را برگردانید.از این فرایند با نام کنترل نسخه نیز نام برده میشود.تعدادی از کنترل نسخه های سیستمی که توسط Git انجام میشوند شاید برای شما آشنا باشند مثل SVN،CVSو…

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

شما میتوانید یک مخرن بصورت آنلاین هم برای کدهای خود ایجاد نمایید  و به تمام کسانی که خواهان اعمال تغییرات بر روی کدها شما هستند،اجازه دسترسی بدهید،دقیقا همان کاری که سایت هایی مثل  GitHub  و BitBucket انجام می دهند.

روش نصب

نصب Git بسیار ساده است.

لینوکس:به سادگی یک ترمینال جدید ایجاد کرده وGit خود را با اسفاده از نصب کننده مورد نظر،آن را نصب نمایید.برای مثال در نسخه Ubuntu با دستور زیر میتوانید آن را نصب نمایید.

sudo apt-get install git

ویندوز:ما توصیه می کنیم که نسخه مخصوص ویندوز Git که هم رابط گرافیکی کاربر و هم شبیه ساز خط دستوری BASH را پشتیبانی می کند استفاده نمایید.

سیستم عامل های دیگر:توصیه ما نصب از طریق  homebrew است.سپس دستور زیر را در ترمینال مورد نظر اجرا نمایید.

brew install git

اگر شما تازه کار باشید،ما به شما  GitHub Desktop  و Sourcetree را برای شروع توصیه می کنیم.البته آشنایی با دستورات پایه ای Git حتی در صورت کار با یک رابط کاربری مهم است.پس ما در ادامه درس بر روی  آنها تمرکز خواهیم کرد.

پیکربندی Git

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

$ git config --global user.name "My Name"
$ git config --global user.email myEmail@example.com

هرکاری که ما بر روی Git انجام دهیم با استفاده از نام ما و آدرس ما بر روی آن علامت گذاری خواهد شد.به این ترتیب کاربران همیشه خواهند دانست که چه کاری میخواستند انجام بدهند و در نتیجه همه چیز سازمان یافته و مرتب خواهد بود.

ایجاد یک مخزن git init

همانطور که قبلا اشاره کردیم،Git فایل ها را ذخیره کرده ویک پوشه برای نگه داری تاریخچه تغییرات ایجاد می کند.برای ایجاد یک مخزن جدید،ما نیاز به باز کردن یک ترمینال جدید،مسیر دهی مستقیم به پروژه و اجرای git init   داریم..این کد باعث ایجاد یک پوشه خاص و ایجاد یک داریکتوری مخفی با پسوند git. برای نگه داری تاریخ و پیکربندی های انجام شده میشود.

یک پوشه جدید در دسکتاب خود ایجاد نمایید و نام آن را git_exercise بگذارید،سپس یک ترمینال باز کرده و کد زیر را بنویسید

$ cd Desktop/git_exercise/
$ git init

خط دستور باید نسبت به دستورات وارد شده واکنش نشان دهد:

Initialized empty Git repository in /home/user/Desktop/git_exercise/.git/

پیغام بالا نشان می دهد که مخزن ما به درستی ایجاد شده است ولی هنوز خالی است.پس یک فایل متنی با نام hello.txt ایجاد کنید  و در داخل پوشه ای که قبلا ایجاد کردیم ذخیره کنید.

بررسی شرایط git status

دستور فوق یکی از دستوراتی است که اطلاعاتی در مورد شرایط و وموقعیت مخزن برای ما برمیگرداند:چه چیزهای جدید افزوده شده است،چه چیزی به روزسانی شده است،و… . دستور  git status در مخزن جدید ایجاد شده اجرا نمایید،باید خروجی زیر را داشته باشد:

$ git status

On branch master

Initial commit

Untracked files:
  (use "git add ..." to include in what will be committed)

	hello.txt

پیام برگشتی وضعیت hello.txt را بصورت untracked نمایش می دهد.به این معنی که این فایل جدید بوده و Git هنوز نمیداند که باید تغییرات آن را اعمال نماید یا از آن چشم پوشی کند.ما برای شناختن فایل های جدید،به مرحله git add نیاز داریم که در ادامه به آن دستور خواهیم پرداخت.

مرحله بندی git add

Git به مفهوم “منطقه عملیاتی”است.شما میتوانید این را شبیه یک بوم خالی (blank canvas)تصور کنید،که تغییراتی را که شما commit  کرده اید را برایتان نگه دارد.هنگام شروع آن،خالی میشود ولی شما میتوانید به آن فایلی را با استفاده از دستور git add  اضافه نمایید و سپس هر چیزی را با استفاده از دستور git commit. میتوانید commit نمایید.

در اینجا ما فقط یک فایل داریم پس ابتدا آن را اضافه می نماییم.

$ git add hello.txt

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

$ git add -A

دوباره وضعیت را بررسی کنید،این بار باید جواب متفاوتی برگردانده بشود

$ git status

On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached ..." to unstage)

	new file:   hello.txt

همانطور که مشاهده می کنید فایل ما commit  شده است.همچنین پیام مربوط وضعیت به ما نمایش می دهد که آخرین فایل تغییر داده شده در “منطقه عملیاتی”(staging area) (که در اینجا از نوع فایل جدید می باشد)کدام و از چه نوعی است.

دستور Commiting -git commit

commit نشان دهنده وضعیت مخزن در یک زمان خاص است.در واقع شبیه snapshot است به این معنی که میتوانید به گذشته ی تغییرات اعمال شده روی فایل نگاهی بیاندازید.ما برای ایجاد یک commit نیاز به آخرین تغییرات اعمال شده در “منطقه عملیاتی” داریم و میتوانیم با استفاده از دستور زیر آن را اجرا نماییم

$ git commit -m "Initial commit."

این دستور،یک commit  شامل تمام تغییرات اعمال شده از منطقه عملیاتی بر روی فایل ایجاد می کند.بخش  -m "Initial commmit" برای نوشتن توضیحاتی خلاصه در مورد تغییرات اعمال شده بر روی آن Commit میباشد.

مخزنهای از راه دور(Remote repositories)

تا اینجای آموزش ما از مخزن های محلی استفاده می کردیم که بسیار هم کاربردی و مفید هستند ولی معمولا ما میخواهیم کار خود را با دیگران به اشتراک بگذاریم و مخازن خود را روی سرور یا خدمات هاستینگ قرار بدهیم که در این صورت بحث مخزن های از راه دور به میان می آیند.در ادامه بیشتر در این مورد بحث می کنیم.

اتصال به یک مخزن از راه دور git remote add

برای اینکه ما بتوانیم چیزی را روی یک مخزن از راه دور بارگذاری کنیم ابتدا باید بتوانیم با آن ارتباط برقرار نماییم.ما برای ادامه درس از آدرس وبسایت منبع آموزش استفاده خواهیم کرد ولی برای شما کاربران عزیز توصیه می کنیم که در یکی از سایتهای GitHub, BitBucket و یا هر سایت دیگری که خدمات Git ارائه می کنند ثبت نام کنید تا بتوانید مباحث آموزش را قدم به قدم اجرایی نمایید.ثبت نام در سایت ها وقت زیادی از شما نمی گیرند.

برای ایجاد ارتباط با مخزن خود از دستور زیر استفاده خواهیم کرد.این دستور را در ترمینال اجرا نمایید:

# این آدرس فقط برای مثال است.آدس مورد نظر خود را با آدرس زیر جایگزین نمایید
$ git remote add origin https://github.com/tutorialzine/awesome-project.git

ممکن است پروژه شما دارای چندین مخزن از راه دور  به طور همزمان باشد،به همین جهت ما برای هر یک از آنها  نام های مختلفی را انتخاب خواهیم کرد.معمولا مخزن اصلی را با نام origin مشخص می کنند.

بارگذاری روی سرور git push

اکنون زمان انتقال commitها به روی سرور میباشد.این فرآیند push نامیده میشود و این کار هر موقع که ما بخواهیم اطلاعات مخزن را بروز رسانی نماییم،انجام می پذیرد.دستوری که این کار را برای ما انجام می دهد git push می باشد که دارای ۲ پارامتر است–یکی نام مخزن که ما در این درس آن را origin نامیدیم و دیگری فایلی که عمل push بر روی آن اعمال خواهد شد که ما نام آن را master قرار داده ایم.

$ git push origin master

Counting objects: 3, done.
Writing objects: 100% (3/3), 212 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/tutorialzine/awesome-project.git
 * [new branch]      master -> master

بسته به سرویسی که شما استفاده می کنید،شما برای اعمال تغییرات روی فایل باید تایید اعتبار بشوید.اگر همه چیز را به درستی انجام بدهید هنگامی که شما از طریق مرورگر خود بخواهید به مخزن از راه دوری که ایجاد کرده اید وارد شوید فایل hello.txt در آنجا در دسترس شما خواهد بود.

شبیه سازی مخزن git clone

در این مرحله،کاربران میتوانند مخزنی را که در Githup ایجاد کرده اید را ببینند و آن را بررسی نمایند.آنها میتوانند آن را بر روی سیستم خود دریافت نموده و با استفاده از دستور git clone یک کپی کامل از روی پروژه شما ایجاد نمایند.

$ git clone https://github.com/tutorialzine/awesome-project.git

یک مخزن محلی به طور خودکار ایجاد شده و با توجه به نسخه github پیکربندی های لازم صورت میگیرد.

دریافت تغییرات از سرور git pull

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

$ git pull origin master

From https://github.com/tutorialzine/awesome-project
 * branch            master     -> FETCH_HEAD
Already up-to-date.

چون تغییری در مخزن ما اعمال نشده است هیچ چیزی برای نمایش موجود نیست.

شاخه ها–Branches

هنگام توسعه دادن یک ویژگی،در نظر گرفتن یک راه حل برای تمرین بر روی یک کپی از فایل اصلی  است که اصطلاحا به آن branche میگویند.شاخه ها (branches) دارای تاریخچه متفاوت بوده و تغییرات اعمال شده بر روی هر یک متفاوت از دیگری است،البته تا زمانی که شما نخواهید تا آنها را با یکدیگر ادغام نمایید.این کار به دلایل زیر انجام میپذیرد:

  • هنگام کار  بروی آن،نسخه اصلی کد دچار مشکل نمیشود.
  • ویژگی های متفاوتی بطور همزمان توسط چندین نفر بطور ایمن بر روی کد اعمال میشود.
  • هر توسعه دهنده بطور مشخص بر روی شاخه خود فعالیت می کند بدون اینکه بر روی کدهای سایر توسعه دهندگان تاثیر بگذارد.
  • هنگامی که نمیدانید بهترین نسخه کدام است،ویژگی های مختلفی را میتوانید به صورت مجزا توسعه دهید و سپس برای انتخاب بهترین آنها را با هم مقایسه نمایید.

ا یجاد یک شاخه جدید  git branch

شاخه اصلی هر مخزنی master نامیده میشود.برای ایجاد یک مخزن جدید از دستور <نام مخزن> git branch  استفاده می کنیم.

$ git branch amazing_new_feature

این دستور  یک مخزن جدید ایجاد می کند.

تعویض(swich) بین شاخه ها git checkout

خوب،حالا اگر ما دستور git branch رو اجرا نماییم،دو گزینه برای ما نمایش داده خواهد شد:

$ git branch
  amazing_new_feature
* master

شاخه اصلی که master میباشد با علامت * مشخص شده است،با این حال چون ما میخواهیم روی شاخه جدید کار بکنیم بنابراین باید به شاخه جدید تعویض(swich) کنیم،برای انجام این کار از دستور git checkout که فقط دارای یک پارامتر است استفاده می کنیم:

$ git checkout amazing_new_feature

ترکیب شاخه ها git merge

ویژگی ای که ما بصورت آزمایشی استفاده خواهیم کرد یک فایل متنی با نام feature.txt است.ما اون رو ایجاد می کنیم،سپس آن را اضافه کرده و در آخر commit می کنیم.

$ git add feature.txt
$ git commit -m "New feature complete."

ویژگی جدید کامل شد و حالا ما به شاخه اصلی یعنی master برمیگردیم:

$ git checkout master

حالا اگر ما پروژه خود را با یک مرورگر فایل() باز کنیم،مشاهده خواهیم کرد feature.txt ناپدید شده است و علت آن این است که ما به شاخه اصلی برگشته ایم که در آن جا اصلا فایل feature.txt ایجاد نشده است.برای دسترسی به این فایل ما نیاز داریم تا با استفاده از دستور git merge دو شاخه را با همدیگر ادغام کنیم و تغییرات جدیداعمال شده را در  amazing_new_feature برای نسخه اصلی پروژه ثبت نماییم.

git merge amazing_new_feature

الان دیگه شاخه اصلی بروز شده است و شاخه awesome_new_feature دیگر نیازی بهش نداریم و میتوانیم آن را حذف نماییم.

git branch -d awesome_new_feature

مباحث پیشرفته

مادر بخش آخر مربوط به این درس،بخشی از مباحث پیشرفته و انتخابی را برایتان معرفی و توضیح می دهیم که کار را برای شما راحتتر می کند.

بررسی تفاوت های بین دو commit

هر commit دارای یک آیدی متشکل از رشته،عدد و سیمبل های مختلفی است.ما برای مشاهده و بدست آوردن آیدی commitها میتوانیم از دستور git log استفاده نماییم

$ git log

commit ba25c0ff30e1b2f0259157b42b9f8f5d174d80d7
Author: Tutorialzine
Date:   Mon May 30 17:15:28 2016 +0300

    New feature complete

commit b10cc1238e355c02a044ef9f9860811ff605c9b4
Author: Tutorialzine
Date:   Mon May 30 16:30:04 2016 +0300

    Added content to hello.txt

commit 09bd8cc171d7084e78e4d118a2346b7487dca059
Author: Tutorialzine
Date:   Sat May 28 17:52:14 2016 +0300

    Initial commit

همانطور که در بالا مشاهده می کنیدآیدی هر commit بسیار بلند است،ولی نیاز نیست هنگام استفاده از آنها تمام آیدی را بنویسیم(معمولا چند کاراکتر اولیه برای شناسایی کافی است)

برای اینکه تغییرات جدید اعمال شده در هر commit را مشاهده کنیم،کافیست دستور [git show [commit را اجرا نماییم

$ git show b10cc123

commit b10cc1238e355c02a044ef9f9860811ff605c9b4
Author: Tutorialzine
Date:   Mon May 30 16:30:04 2016 +0300

    Added content to hello.txt

diff --git a/hello.txt b/hello.txt
index e69de29..b546a21 100644
--- a/hello.txt
+++ b/hello.txt
@@ -۰,۰ +۱ @@
+Nice weather today, isn't it?

برای مشاهده تغییرات اعمال شده بین دو commit کافیست از دستور git diff و نام [commit-from]..[commit-to] استفاده نماییم

$ git diff 09bd8cc..ba25c0ff

diff --git a/feature.txt b/feature.txt
new file mode 100644
index 0000000..e69de29
diff --git a/hello.txt b/hello.txt
index e69de29..b546a21 100644
--- a/hello.txt
+++ b/hello.txt
@@ -۰,۰ +۱ @@
+Nice weather today, isn't it?

ما اولین commit را با آخرین آن مقایسه می کنیم و به این ترتیب میتوانیم تغییرات اعمال شده بر روی هر یک را مشاهده نماییم،البته ما برای این کار میتوانیم از دستور  git difftool برای نمایش گرافیکی تفاوت ها استفاده نماییم.

برگرداندن فایل به نسخه قبلی

Git به ما این اجازه را میدهد تا هر فایلی را از هر مخزنی به حالت اولیه خود برگردانیم.این کار توسط دستور git checkout انجام میپذیرد که ما کمی قبلتر از آن برای تعویض بین دو شاخه استفاده کردیم،البته از آن برای تعویض بین دو commit نیز استفاده میشود.(این دستور یکی از دستورهایی است که دارای چندین عملکرد مختلف در Git میباشد.)

در ادامه با استفاده از این دستور تمام تغییرات اعمال شده بر روی فایل hello.txt  را دریافت کرده و تمام آن ها را به حالت اولیه برمیگردانیم.

$ git checkout 09bd8cc1 hello.txt

رفع ایرادات commit

اگر شما متوجه این شدید که در commit شما ایراداتی از جمله خطاهای تایپی،یا فراموشی اضافه کردن فایل و… است میتوانید با استفاده از دستور git commit –amend آن ایرادات را رفع نمایید.این دستور همه چیز را از آخرین Commit تا منطقه عملیاتی اضافه می کند و یک commit جدید برای شما ایجاد مینماید.

برای رفع ایرادات پیچیده که در آخرین commit نیستند شما میتوانید از دستور git revert استفاده نمایید.این دستور تمام تغییرات اعمال شده بر روی commit را دریافت کرده و آن ها را برگردانده و یک Commit جدید برای شما ایجاد می کند.

به commit جدید میتوانید با نام مستعار HEAD دسترسی داشته باشید

$ git revert HEAD

برای سایر commitها بهتر است از آیدی آنها استفاده نماییم

$ git revert b10cc123

هنگامی که commitهای قدیمی را بازگرداندید،به خاطر داشته باشید که احتمال ترکیب اشتباهی بسیار زیاد است.این اتفاق زمانی می افتد که یک فایل توسط Commitهای مختلفی دچار تغییر شده است و هنگام بازگردانی Git نمیتواند خط درست برای بازگردانی را پیدا کند زیرا دیگر آنها وجود ندارند.

حل مشکلات مربوط به ترکیب اشتباهی

ترکیب های اشتباهی معمولا هنگام ترکیب شاخه ها یا هنگام دریافت تغییرات توسط دیگران به وقوع می پیوندند.بعضی مواقع این اختلاف به طور خودکار توسط Git مورد دستکاری واقع میشود،اما در اکثر مواقع شخص تصمیم میگرد کدام کد باقی بماند و کدام یک حذف بشود.

اجازه بدهید ادامه کار را با یک مثال ادامه دهیم که در آن قصد داریم دو شاخه با نام ها john_branch و tim_branch را با هم ترکیب نماییم.john و tim هر دو یک تابع برای نمایش عناصر موجود در یک آرایه را بر روی یک فایل یکساننوشته اند.

john از یک حلقه استفاده کرد است:

for(var i=0; i<arr.length; i++) {
    console.log(arr[i]);
}

و tim از forEach استفاده کرده است

arr.forEach(function(item) {
    console.log(item);
});

آنها از کد خود بر روی یک شاخه استفاده کرده اند،حال اگر ما دو کد بالا را بخواهیم ترکیب کنیم با پیغام خطا زیر مواجه خواهیم شد

$ git merge tim_branch 

Auto-merging print_array.js
CONFLICT (content): Merge conflict in print_array.js
Automatic merge failed; fix conflicts and then commit the result.

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

<<<<<<< HEAD
for(var i=0; i<arr.length; i++) {
    console.log(arr[i]);
}
=======
arr.forEach(function(item) {
    console.log(item);
});
>>>>>>> Tim's commit.

ما در بالای ===== کامیت HEAD رو داریم و در زیر کامیتی که با آن تعارض دارد.با این روش ما میتوانیم تفاوت ها را مشاهده نماییم و تصمیم بگیریم که کدام نسخه از کد بهتر است.برای رفع تعارض پیش آمده ما به آخر کد رفته و تغییرات لازم را اعمال کنیم.

// Not using for loop or forEach.
// Use Array.toString() to console.log contents.
console.log(arr.toString());

زمانی که همه تنظیمات را انجام دادید،ترکیب commit انجام گرفته و پردازش به اتمام می رسد.

$ git add -A
$ git commit -m "Array printing conflict resolved."

همانطور که مشاهده می کنید روش بالا بسیار وقت گیر و خسته کننده است و در پروژه های بزرگ عملا کاربردی نیست.بیشتر توسعه دهندگان برای رفع تعارض ها از  GUI client استفاده می کنند که کارها را بسیار آسان کرده است.برای فعال کردن آن از دستور              git mergetool استفاده می کنیم.

راه اندازی gitignore.

در هر پروژه ای تعدادی فایل و پوشه وجود دارند که ما هرگز نمیخواهیم آنها را Commit کنیم.ما میتوانیم با استفاده از فایل gitignore مانع از اضافه شدن تصادفی آنها توسط git add -A بشویم.

۱-ابتدا یک فایل متنی با نام gitignore ایجاد می کنیم و آن را در مسیر اصلی پروژه خود ذخیره می نماییم.

۲-در داخل آن،لیست نام فایلهایی که باید چشم پوشی بشوند را مینویسیم البته هر کدام در یک سطر جدید

۳-gitignore به طور مجزا عملیات اضافه کردن،commit و push را مثل سایر فایل های موجود در داخل پروژه انجام خواهد داد.

بهترین مثال برای فایلهایی که باید چشم پوشی کنیم عبارتند از:

*فایل های log

*ساختار اجرای دستور

*پوشه node_modules در داخل پروژه node.js

*پوشه های ایجاد شده توسط IDEs مانندNetbeans وIntelliJ

*نکات نوشته شده هنگام توسعه

تمام نکات بالا را در قالب یک تکه کد برایتان می آوریم

*.log
build/
node_modules/
.idea/
my_notes.txt

علامت / در پایان هر فایل به معنی این است که آن یک پوشه بوده و تمام محتویات داخل آن نیز باید مورد چشم پوشی قرار بگیرد.

 

خوب، آموزش  ما به پایان رسید و امیدواریم توانسته باشیم  شما را تا اندازه ای با مبحث Git آشنا بکنیم.

 


0
0


هرگونه انتشار مطالب اختصاصي و محصولات اين سايت بجز با درج لينک مستقيم شرعا حرام بوده و پيگرد قانوني دارد.
طبق ماده 12 فصل سوم قانون جرائم رايانه هرگونه کپي برداري ممنوع بوده و پيگرد قانوني دارد. براي اطلاعات بيشتر کليک کنيد.

درباره‌ی مدیر سایت

در اردیبهشت سالی از سال های خدا بدنیا آمدم.درس خواندم و مهندس شدم.ازآنجایی که علاقه شدیدی به برنامه نویسی و ترجمه وآموزش داشتم در راستای اهدافم این وبسایت رو راه اندازی کردم تا دین خود را به جامعه برنامه نویسی ادا کرده باشم.

یک دیدگاه

  1. با سلام ممنون از سایتتون

دیدگاه خود را بنویسید

آدرس پست الکترونیک شما منتشر نخواهد شد.خانه های ضروری نشانه گذاری شده اند. *

*


− یک = 1

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>