تالار گفتمان nCIS.ir

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

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

بعنوان مثال با اینا که clone میکنم:

git clone git@github.com:ferchang/reg8log.git
git clone https://github.com/ferchang/reg8log.git
بعد مثلا اگر بخوام برنچ dev رو بیارم که روش کار کنم:

git checkout dev

وقتی کار کردیم و یکسری فایلها ویرایش شد یکسری فایل هم احتمالا اضافه شده و حالا میخوایم کامیت کنیم اول این فرمان:

git add .

این باعث میشه تمام فایلهای ویرایش شده و جدید، برای کامیت شدن تعیین بشن (بقول خودش stage بشن).

خب بعد این فرمان:

git commit -a -m 'backup40'

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

خب و آخرین فرمان برای اینکه کلیه تغییرات و کامیت ها رو به origin (مثلا repo روی گیت هاب) هم صادر کنیم اینه:

git push

------------------------------------------------------------------------------

یه فرمانی که من زمانی لازم شد چون دنبال چند فایل خاص در پروژه میگشتم که خیلی وقت پیش کلا حذفشون کرده بودم (ولی الان به کدهاشون دوباره نیاز پیدا کرده بودم ولی نمیدونستم در کدام کامیت ها بودن و بخاطر زیاد بودن تعداد کامیت ها، پیدا کردن اونا به روش دستی مشکل بود):

git log --diff-filter=D --summary

این فرمان فایلهایی رو که یک زمانی حذف شدن نشون میده.

------------------------------------------------------------------------------

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

git reset --hard

تمام فایلها به حالت آخرین کامیت برمیگردن.

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

git reset --hard head~1

اون عدد 1 رو میشه بیشتر کردن که اینطوری به همون تعداد به کامیت های قبلی برمیگردیم.

ضمنا اگر یکسری فایل جدید هم ایجاد کرده باشیم که هنوز کامیت نشدن، میشه با این فرمان حذفشون کرد:

git clean -fd

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

------------------------------------------------------------------------------

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

git fetch

ظاهرا این باعث میشه اطلاعات وضعیت repository ریموت ما در لوکال آپدیت بشه. یعنی مثلا ممکنه از زمانیکه شما آخرین بار پروژه رو از ریموت گرفتید، کس دیگری به ریموت شما push کرده باشه، یا شاید حتی خودتون از یک مکان دیگر این کار رو کردید و الان درست یادتون نیست. پس باید اول ریموت رو fetch کنید تا اطلاعات وضعیتش در لوکال شما آپدیت بشه. البته من بصورت مفهومی و موردی خودم و بصورت غیرتخصصی و تاحدی غیردقیق میگم، چون رفرنس گیت رو دقیقا مطالعه نکردم و فقط دنبال یکسری موارد نیازهای موردی خودم بودم. این فرمانها هرکدام کلی آپشن و جزییات جانبی دارن که در شرایط مختلف ممکنه نیاز بشه. فکر نکنید در هر شرایطی اگر هر فرمانی رو همین شکلی که من میگم بزنید دقیقا همون کاری که میخواید انجام میشه.

حالا این فرمان:

git cherry

که معادل این فرمانه:

git cherry origin/master master

لیست کامیت هایی رو نشون میده که در repo لوکال ما هستن ولی در ریموت نیستن.

و برعکسش، این فرمان:

git cherry master origin/master

لیست کامیت هایی رو نشون میده که در ریموت هستن ولی در repo لوکال ما نیستن.

البته دقت داشته باشید که خیلی وقتا کارها رو در گیت میشه با چند روش انجام داد. انجام این کار هم روشهای دیگری هم داره. مثلا اینم بنظرم بد نیست حتی شاید بهتره از cherry:

git log origin/master ^master

این داره میگه واسم کامیت هایی رو لیست کن که در origin/master (ریپوزیتوری ریموت ما) هستن ولی در لوکال (برنچ master) نیستن. من رفرنس این فرمانها رو نخوندم ولی با کمی دقت میشه فهمید که ظاهرا اون ^ نقش not کردن رو انجام میده. بنابراین برای انجام عکس این کار، یعنی دیدن کامیت هایی که در لوکال هستن ولی در ریموت نیستن، میشه این فرمان رو استفاده کرد:

git log ^origin/master master

به همین سادگی!
واقعا این گیت عجب قدرتی داره، هر کاری بخوای میتونی باهاش بکنی هر اطلاعاتی بخوای میتونی ازش بیرون بکشی. شاهکاریه واقعا. دست لینوس درد نکنه یکی بابت لینوکس و دیگری بابت گیت!

البته باید بگم الان بصورت تصادفی متوجه شدم که فرمان git status هم اطلاعات کلی و مختصر خوبی در این موارد میده. مثلا نمونه ای از اطلاعاتی که به من داد:

# On branch master
# Your branch and 'origin/master' have diverged,
# and have 1 and 12 different commits each, respectively.
#
nothing to commit (working directory clean)

مشاهده میکنیم که به ما داره میگه ریموت و لوکال شما از هم جدا شدن (بخاطر اینکه الان سلسلهء کامیت های اونا رو بهم ریختم) و در لوکال شما یک کامیت هست که در ریموت نیست و در ریموت شما 12 کامیت هست که در لوکال شما نیستن.

راستی اگر بیشتر وارد این مسئله شدید و به هر علتی خواستید جزییات تفاوت ها (عین تمام تغییرات خود کدها) رو هم مشاهده کنید، جوابش دستور diff است. مثلا این فرمان:

git diff master origin/master

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

------------------------------------------------------------------------------

بعضی وقتا هست وارد حالتی میشیم بنام detached HEAD. مثلا موقعی که با این فرمان:

git checkout 24130733eb9d2

برگشتید به یک کامیت خاص.

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

حالا واقعا جالبه قدرت و انعطاف گیت و اینکه چه کارهای راه دستی میشه با این امکانات کرد. اما من بصورت تصادفی وارد این حالت شدم و دنبال این تحقیق کردم که حالا چطور برگردم به حالت نرمال، که البته جوابش ساده بود:

git checkout master

البته اگر در این حالت تغییرات کامیت نشده داشته باشید، پیام خطا میده و میگه اول یه فکری بحال تغییرات بکنید (مثلا اونا رو کامیت کنید).

------------------------------------------------------------------------------

من خودم همین اخیرا با نیاز و بررسی این موارد متوجه شدم که گیت واقعا چقدر ابزار قدرتمند و جالبیه چقدر کامل و منعطف است و چقدر میتونه در مدیریت پروژه های بزرگ و پیچیده و توزیع شده ابزاری عالی باشه. بهرحال گیت رو کسی مثل لینوس توروالدز درست کرده برای مدیریت پروژهء گسترده و پیچیده و توزیع شده ای مثل هستهء لینوکس؛ پس بیخود نیست که اینقدر خفنه!

راستی این هشدار رو دوباره تکرار میکنم که این فرمانها که من گذاشتم یه فرمانهای کلی و موردی نیاز و شرایط پروژهء من بودن و ممکنه برای شما به شکلی که فکر میکنید کار نکنن. مثلا ساده ترین موردش اینکه ممکنه شما در برنچ master نباشید، پس اگر فرمانی رو که با برنچ مستر کار میکنه وارد کنید، نتیجهء دیگری میده. همینطور موارد دیگر هم جزییات و نکاتی واسه خودشون دارن. مثالهایی که من زدم خیلی کلی و مختصر هستن و یک شرایط ساده و استانداردی رو فرض کردن. این مثالها رو اول برای رفرنس و یادآوری خودم جمع آوری کردم و بعد هم برای نشان دادن بعضی از قابلیت های مفید و قدرت و انعطاف گیت، که شما میتونید ازشون یاد بگیرید و الگوبرداری کنید، ولی برای جزییات و اطمینان بیشتر و کارهای جدی حتما احتیاط کافی به خرج بدید و قبلش تحقیق و آزمایش کنید و احیانا از فایلهاتون بکاپ بگیرید.
الان متوجه شدم یکسری فایلهایی که از پروژم حذف شده بودن (درواقع rename کرده بودمشون)، در آخرین کامیتی که داشتم حذف نشدن.
علتش ظاهرا این بوده که از آپشن a در فرمان کامیت استفاده نکرده بودم، و git add بصورت پیشفرض فایلهای حذف شده رو از ایندکس حذف نمیکنه.
پس الان اومدم و با این فرمان:
git add -u
فایلهای حذف شده رو از ایندکس حذف کردم. بعدش هم یه کامیت زدم و push کردم.
البته ظاهرا git add -A یک فرمان جامعی هست که تمام حذف و اضافه ها رو همزمان در ایندکس آپدیت میکنه. دیگه اینو تست نکردم.

پس در اینجا متوجه میشیم که آپشن a در فرمان commit خیلی مفیده، حتی اگر قبلش از git add استفاده کرده باشیم.
البته آپشن a باعث میشه فایلهای تغییر یافته یا حذف شده stage بشن، اما فایلهای جدیدا اضافه شده رو شناسایی نمیکنه. برای اضافه کردن فایلهای جدید باید قبل از commit از git add استفاده کنیم.

-------------------------------------------------------------------

فرمان مفید دیگر اینه:

git help command

بجای command اسم فرمانی رو که میخواید راهنمای اون رو بخونید میذارید.
مثلا:

git help commit

بعد راهنمای اون فرمان در مرورگر شما باز میشه.