آموزش گیت (فصل ۱)

نصب Git روی سیستم‌عامل اوبونتو


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

$ sudo apt-get install git

پس از موفقیت‌آمیز بودن پروسهٔ‌ نصب،‌ با استفاده از کامند زیر می‌توان نسخهٔ نصبی را مشاهده کرد:

$ git --version
git version 2.17.1

در این مرحله از کار گیت به درستی روی سیستم نصب شده و اکنون می‌توانیم یک سری تنظیمات اولیه را انجام دهیم.

راهنمای کانفیگ کردن Git

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

$ git config --global user.name "Behzad"

در توضیح کامند فوق می‌توان گفت که ابتدا دستور git config را نوشته سپس از آپشن global-- استفاده کرده‌ایم بدان معنا که تنظیمات فوق در سراسر سیستم اِعمال خواهد شد سپس داخل علائم "" نام خود را درج نموده و اینتر می‌‌کنیم. در ادامه، همان‌طور که ملاحظه می‌شود ایمیل خود را نیز به گیت معرفی کرده‌ایم:

$ git config --global user.email "my.email.address@gmail.com"

حال برای اطمینان حاصل کردن از درست کانفیگ شدن نام و ایمیل، دستورات زیر را اجرا می‌‌کنیم:

$ git config user.name
Behzad
$ git config user.email
my.email.address@gmail.com

می‌بینیم که نام و ایمیل به درستی سِت شده‌اند و از این پس هر کامیتی که انجام دهیم، با این مشخصات در سیستم ثبت خواهد شد.

ساخت اولین پروژه با استفاده از Git

در این مرحله از آموزش، به منظور درک عملی کامندهای مختلف گیت، نیاز است تا پروژه‌ای واقعی ساخته و شروع به تمرین روی آن نماییم که برای همین منظور، در سیستم‌عامل اوبونتو با استفاده از کامند زیر پروژه‌ای با نامی دلخواه همچون git-tutorial در مسیر var/www/ یا هر مسیر دلخواه دیگری می‌سازیم:

$ mkdir /var/www/git-tutorial

mkdir ارتباطی با گیت نداشته بلکه کامندی به منظور ساخت یک پوشهٔ جدید در لینوکس است با این توضیح که دستور داده‌ایم تا در مسیر var/www/ پوشهٔ جدیدی تحت عنوان git-tutorial ساخته شود. پس از ورودی به این پوشه با استفاده از دستور cd، با استفاده از کامند زیر سیستم کنترل نسخهٔ گیت را فعال می‌سازیم:

var/www/git-tutorial$ git init

کامند init برگرفته از کلمهٔ Initialize به معنی «شروع کردن» است. پس از اجرای موفقیت‌آمیز این کامند،‌ پوشه‌ای تحت عنوان git. ساخته می‌شود اما اگر نگاهی به محتویات پروژهٔ git-tutorial بیندازیم، مسلماً چیزی مشاهده نخواهد شد چرا که در سیستم‌عامل گنو/لینوکس فایل‌هایی که با علامت . نام‌گذاری شده‌اند نمایش داده نمی‌شوند و مخفی هستند که برای نمایش آن‌ها می‌توان از کلیدهای ترکیبی Ctrl + H استفاده نمود که در این صورت خواهیم داشت:

git-tutorial
└── .git

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

/var/www/git-tutorial$ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

همان‌طور که مشخص است، خط اول حاکی از آن می‌باشد که روی شاخهٔ مَستر قرار داریم که شاخهٔ پیش‌فرض و اصلی هر ریپازیتوری می‌باشد و در عین حال هیچ گونه کامیتی نیز تاکنون صورت نگرفته است. فرض کنیم که قرار است در این پروژه یک صفحهٔ سادهٔ اچ‌تی‌ام‌ال طراحی کنیم. برای این منظور، با استفاده از کامند زیر فایلی تحت عنوان index.htmlمی‌سازیم:

/var/www/git-tutorial$ touch index.html

در لینوکس،‌ touch به منظور ساخت یک فایل جدید مورد استفاده قرار می‌‌گیرد به طوری که اگر مجدد نگاهی به محتویات این پروژه بیندازیم، خواهیم داشت:

git-tutorial
├── .git
└── index.html

اکنون با استفاده از ادیتور دلخواه خود، یک صفحهٔ سادهٔ اچ‌تی‌ام‌ال داخل فایل index.html به صورت زیر می‌سازیم:

<!DOCTYPE html>
<html>

<head>
    <title>Sokan Academy Git Tutorial</title>
</head>

<body>
    <h1>This is a Git tutorial</h1>
    <p>In this course, we`re learn the basics the Git</p>
</body>

</html>

حال مجدد دستور git status را اجرا می‌‌کنیم به طوری که در خروجی خواهیم داشت:

/var/www/git-tutorial$ git status
On branch master

No commits yet

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

        index.html

nothing added to commit but untracked files present (use "git add" to track)

نسبت به دفعه‌ٔ اولی که این کامند را اجرا کردیم، بخش جدیدی تحت عنوان Utracked files اضافه شده و دقیقاً نام فایل جدیدی که ساختیم در این بخش آمده است. پیش از این با مفهوم اِستیج آشنا شدیم با این توضیح که پروسهٔ نسخه‌بندی در این فاز آغاز شده و فایل‌ها آمادهٔ ثبت در تاریخچهٔ پروژه می‌شوند که برای این منظور می‌باید دستور زیر را اجرا نماییم:

/var/www/git-tutorial$ git add index.html

همان‌طور که ملاحظه می‌شود، کلیهٔ‌ کامندهای گیت با دستور git آغاز می‌شوند و برای مرحلهٔ اِستیج از دستور addاستفاده کرده و فایلی که قصد داریم در هیستوری ذخیره گردد را نوشته‌ایم و چنانچه اکنون مجدد وضعیت گیت را چک کنیم،‌ به عنوان خروجی خواهیم داشت:

/var/www/git-tutorial$ git status
On branch master

No commits yet

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

        new file:   index.html

می‌بینیم که بخشی تحت عنوان Changes to be commited در معرض دیدمان قرار می‌گیرد بدان معنا که با استفاده از دستور add تغییرات آمادهٔ ذخیره‌سازی شده‌اند اما این کار هنوز صورت نگرفته است که برای این منظور، با استفاده از دستور commit این کار را به صورت زیر عملی خواهیم ساخت:

/var/www/git-tutorial$ git commit -m "My First Commit"
[master (root-commit) bced368] My First Commit
 1 file changed, 13 insertions(+)
 create mode 100644 index.html

دستور commit یک آپشن اختیاری می‌گیرد تحت عنوان m- که برگرفته از واژهٔ Message به معنی «پیام» است و همان‌طور که ملاحظه می‌شود، داخل علائم "" پیامی دلخواه نوشته‌ و دکمهٔ اینتر را می‌زنیم و در خروجی این دستور زیر می‌بینیم که آمده یک فایل تغییر یافته و از آنجا که داخل این فایل سیزده خط کد نوشته‌ایم، تعداد خطوط کد هم درج شده است. اکنون اگر مجدد وضعیت را چک کنیم خواهیم داشت:

/var/www/git-tutorial$ git status
On branch master
nothing to commit, working tree clean

می‌بینیم که گفته شده هیچ تغییر باقی نمانده که کامیت نشده باشد و این بدان معنا است که ما توانسته‌ایم با موفقیت اولین ورژن از پروژهٔ خود را در سیستم کنترل نسخهٔ گیت ذخیره‌ سازیم.

جمع‌بندی
اساساً شروع کار با گیت چندان دشوار نیست چرا که با فراگیری کامندهای add و commit می‌توان پایه‌ای‌ترین کار در گیت که چیزی نیست جز وارد کردن تغییرات در اصطلاحاً Staging Area سپس ثبت تغییرات در پوشهٔ git. را عملی ساخت.

آشنایی با روش‌های مختلف ری‌سِت کردن تغییرات در Git


در ادامهٔ آموزش قبل، به منظور تست قابلیت‌های بیشتری از گیت، فایل index.html را به صورت زیر آپدیت می‌کنیم:

<!DOCTYPE html>
<html>

<head>
    <title>Sokan Academy Git Tutorial</title>
</head>

<body>
    <h1>This is a Git tutorial</h1>
    <p>In this course, we`re learning the basics the Git</p>
    <p>A new paragraphp</p>
</body>

</html>

اگر به خروجی لاگ نگاه کنیم نیز خواهیم داشت:

/var/www/git-tutorial$ git log --oneline
23d2256 (HEAD -> master) a new line added
fd728ca Yet another commit

فرض کنیم که اکنون می‌خواهیم به کامیتی با شناسهٔ fd728ca بازگردیم که برای این منظور خواهیم داشت:

/var/www/git-tutorial$ git checkout fd728ca
Note: checking out 'fd728ca'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at fd728ca Yet another commit

اکنون فرض کنیم که پشیمان شده و مجدد می‌خواهیم آخرین تغییرات را بازگردانی کنیم که در این صورت زیر می‌توان از کامند زیر استفاده کرد:

/var/www/git-tutorial$ git checkout master
Previous HEAD position was fd728ca Yet another commit
Switched to branch 'master'

می‌بینیم که آخرین تغییرات بازگردانی شده‌اند. علاوه بر دستور checkout کامند دیگری داریم به نام revert که به منظور بازگشت به گذشته مورد استفاده قرار می‌گیرد. برای درک بهتر سازوکار این کامند، فایل جدیدی تحت عنوانapp.js حاوی محتویات زیر می‌سازیم:

console.log('something ...');

سپس این فایل را کامیت کرده و لاگ می‌گیریم:

/var/www/git-tutorial$ git log --oneline
feb2252 (HEAD -> master) a js file added
23d2256 a new line added
fd728ca Yet another commit

فرض می‌کنیم که قصد داریم شرایط را به زمانی که این فایل جاوااسکریپتی را اضافه نکرده بودیم بازگردانیم که برای این منظور می‌توان از کامند revert به صورت زیر استفاده کرد:

/var/www/git-tutorial$ git revert feb2252

و به محض آن که دکمهٔ اینتر را فشار دهیم، ادیتور پیش‌فرض سیستم‌عامل (که در این آموزش nano است.) باز خواهد شد:

Revert "a js file added"

This reverts commit feb22521a412bbcd2e9dba26897522727a7ded2f.

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch master
# Changes to be committed:
#       deleted:    app.js
#

هشداری به کاربر داده می‌شود مبنی بر این که آیا مطمئن است قصد انجام این کار را دارد یا خیر که اگر از این بابت مطمئن بودیم، صرفاً نیاز است تا دکمه‌های Ctrl + X را فشرده تا تغییرات اِعمال گردند.به خاطر داشته باشیدلازم به یادآوری است که بسته به نوع سیستم‌عامل و ادیتوری که باز شده است،‌ ممکن است این شورت‌کات‌ها متفاوت باشند.

در ادامهٔ کار، اگر مجدد لاگ بگیریم خواهیم داشت:

/var/www/git-tutorial$ git log --oneline
935d66e (HEAD -> master) Revert "a js file added"
feb2252 a js file added
23d2256 a new line added
fd728ca Yet another commit

می‌بینیم که کامیت مذکور با شناسهٔ feb2252 کماکان در لیست کامیت‌ها قرار دارد اما لاگ جدیدی با شناسهٔ 935d66eافزوده شده که حاکی از حذف تغییرات صورت‌گرفته از طریق آن کامیت دارد و چنانچه به پوشهٔ پروژه نگاه کنیم، خواهیم دید که فایل app.js حذف شده است. در واقع،‌ با این کار تغییرات مذکور را به اصطلاح Undo کرده‌ایم.

دستور دیگری که در این ارتباط می‌تواند مورد استفاده قرار گیرد، reset است که برای درک بهتر این موضوع، تغییر کوچکی داخل فایل index.html قرار داده و آن را کامیت می‌کنیم:

<!DOCTYPE html>
<html>

<head>
    <title>Sokan Academy Git Tutorial</title>
</head>

<body>
    <h1>This is a Git tutorial</h1>
    <p>In this course, we`re learning the basics the Git</p>
    <p>A new paragraphp</p>
    <p>This is a change</p>
</body>

</html>

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

/var/www/git-tutorial$ git log --oneline
6382718 (HEAD -> master) a minor change happened
935d66e Revert "a js file added"
feb2252 a js file added
23d2256 a new line added
fd728ca Yet another commit

می‌بینیم که پیام آخرین کامیت با شناسهٔ 6382718 حاکی از آن است که یک تغییر کوچک رخ داده است؛ حال تصور کنیم که می‌خواهیم با کامیتی به پیام a new line added برگردیم که برای این منظور از کامند زیر استفاده خواهیم کرد:

/var/www/git-tutorial$ git reset 23d2256
Unstaged changes after reset:
M       index.html

اگر مجدد لاگ بگیریم نیز خواهیم دید:

/var/www/git-tutorial$ git log --oneline
23d2256 (HEAD -> master) a new line added
fd728ca Yet another commit

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

برای آن که تغییرات جدید شامل نشوند،‌ به صورت زیر می‌توان از فلگ hard-- استفاده کرد:

/var/www/git-tutorial$ git reset 23d2256 --hard
HEAD is now at 23d2256 a new line added

اکنون اگر به فایل index.html نگاهی بیندازیم، خواهیم دید:

<!DOCTYPE html>
<html>

<head>
    <title>Sokan Academy Git Tutorial</title>
</head>

<body>
    <h1>This is a Git tutorial</h1>
    <p>In this course, we`re learning the basics the Git</p>
    <p>A new paragraphp</p>
</body>

</html>

می‌بینیم که دقیقاً به همان نقطه‌ای بازگشتیم که مد نظر داشتیم. در ادامه، با استفاده از دستور زیر فایل دیگری تحت عنوانtmp.html می‌سازیم:

/var/www/git-tutorial$ touch tmp.html

سپس با استفاده از دستور زیر آن را وارد فاز اِستیج می‌کنیم:

/var/www/git-tutorial$ git add tmp.html

و اگر وضعیت گیت را به صورت زیر چک کنیم:

/var/www/git-tutorial$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   tmp.html

می‌بینیم که این فایل آمادهٔ کامیت شدن است اما فرض کنیم که قصد داریم تا این فایل را از پروسهٔ کامیت حذف کنیم که برای این منظور،‌ می‌توان از دستور git reset tmp.html استفاده کرد و اگر مجدد وضعیت را چک کنیم نیز خواهیم داشت:

/var/www/git-tutorial$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        tmp.html

nothing added to commit but untracked files present (use "git add" to track)

از این پس دیگر هرگز کامیت‌های بعدی شامل این فایل نخواهند بود. حال فرض کنیم که بیش از یک فایل به پروژه افزوده شده و یا دستخوش تغییر شده است و به جای آن که بخواهیم یک به یک آن‌ها را وارد مرحلهٔ اِستیج کنیم، می‌توانیم با یک دستور تمامی آن‌ها را آمادهٔ کامیت شدن نماییم. به طور مثال، دو فایل جدید تحت عناوین tmp1.htmlو tmp2.html ساخته سپس وضعیت را چک می‌کنیم:

/var/www/git-tutorial$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        tmp1.html
        tmp2.html

nothing added to commit but untracked files present (use "git add" to track)

می‌بینیم که دو فایل داخل پروژهٔ خود داریم که آماده‌اند تا وارد فاز اِستیج شوند و برای آن که هر دو را به یک باره بیفزاییم، می‌توانیم از کامند زیر استفاده کنیم:

/var/www/git-tutorial$ git add .

اگر مجدد وضعیت را چک کنیم، خواهیم داشت:

/var/www/git-tutorial$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   tmp1.html
        new file:   tmp2.html

می‌بینیم که افزودن یک . پس از کامند add بدان معنا است که تمام فایل‌های تغییریافته شامل خواهند شد (همچنین از آپشن جایگزین git add -A نیز می‌توان استفاده کرد با این توضیح که این آپشن می‌باید حتماً با حرف بزرگ نوشته شود.)

آشنایی با کاربرد Branch در Git


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

یکی از مزایای وجود شاخه‌ها در سیستم کنترل نسخهٔ گیت آن است که می‌توان به تعداد توسعه‌دهندگانی که در تیم حضور دارند برنچ‌های اختصاصی ساخته و در آنِ واحد تمامی اعضای تیم بتوانند اقدام به توسعهٔ نرم‌افزار کنند. برای درک بهتر این موضوع، فرض کنیم دولوپری داریم به نام بهزاد قرار است قابلیت درگاه پرداخت را به پروژه بیفزایید و دولوپر دیگری به نام سهند قرار است تا رابط کاربری را تکمیل کند؛ در چنین شرایطی، می‌توان دو شاخهٔ‌ فرعی از شاخهٔ مستر ایجاد کرده تحت عنوان دلخواهی همچون behzad-branch-gateway و sahand-branch-ui و هر کدام از ایشان با سهولت هرچه تمام‌تر شروع به کدنویسی کرده و چنانچه در نهایت کدهای نوشته‌شده مورد تأیید مدیر فنی بود،‌ با شاخهٔ اصلی (مستر) ادغام خواهند شد.

همان‌طور که در تصویر فوق ملاحظه می‌شود، خط عمومی که در سراسر نمودار ملاحظه می‌شود به عنوان بِرَنچ اصلی یا مِستر است که فرض می‌کنیم توسط توسعه‌دهندهٔ اصلی پروژه کامیت‌هایی تحت عناوین C1 و C2 انجام شده است. سپس یک شاخه از شاخهٔ اصلی جدا شده و نامی دلخواه همچون Branch1 برای آن در نظر گرفته‌ایم که فرضاً توسط یکی از اعضای تیم هندل می‌گردد به طوری که وی سه کامیت داخل این شاخه انجام داده است. در آنِ واحد،‌ برای یکی دیگر از اعضای تیم شاخه‌ای به نام Branch2 ساخته شده و او نیز یک کامیت انجام داده است. در نهایت، دولوپر اصلی این پروژه کلیهٔ تغییرات اِعمال‌شده در دو بِرَنچ فوق را با بِرَنچ اصلی (مَستر) ادغام کرده و کلیهٔ‌ این تغییرات را تحت عنوان C7 کامیت کرده است.

با این توضیحات تئوریک،‌ در ادامهٔ‌ این آموزش خواهیم دید که به چه شکل به صورت عملی می‌توانیم اقدام به ساخت بِرَنچ‌های مختلف کرده سپس آن‌ها را با یکدیگر ادغام نمود

جمع‌بندی
مفهوم شاخه‌ها در گیت را به نوعی می‌توان به عنوان یکی از کلیدی‌ترین خصیصه‌های این سیستم ورژن کنترل تلقی کرد چرا که اساساً این امکان در اختیار تیم‌های مهندسی قرار می‌گیرد تا بتوانند به هر تعداد که بخواهند شاخهٔ جدید ایجاد کرده و در آنِ واحد روی پروژه کار کنند. در عین حال، احتمال رخداد کانفلیکت در چنین شرایط بسیار زیاد خواهد بود و یک توسعه‌دهنده‌ای که ادعا می‌کند به گیت مسلط است حتماً می‌باید با راه‌کارهای مختلف رفع این تداخل‌ها آشنا باشد.

مطالب مرتبط

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *