فرمانهای مفید 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

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

——————————————————————-

ایجاد یک branch بصورت لوکال و سپس push کردن آن به ریموت:

git checkout -b tmp
<create/edit some files ...>
<git add & commit>
git push -u origin tmp

پ.ن: بعدا ممکنه فرمانهای بیشتری رو به این پست اضافه کنم.

پاسخ دهید

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

*

شما می‌توانید از این دستورات HTML استفاده کنید: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>