10 مشکل رایج گیت Git و نحوه رفع آنها

اگر آموزش گیت را شروع کرده باشید، احتمالا با برخی از مشکلات رایج گیت رو به رو شده باشید. در اینجا برخی از رایج ترین مشکلات گیت را مورد بررسی قرار دادیم و روش حل مشکلات رایج GIT را نیز بررسی کرده ایم تا بتوانید به راحتی در مدت زمان کوتاهی از پس این مشکلات بر بیایید.
نحوه لغو commit ها، برگرداندن commit ها، ویرایش پیام های commit، حذف فایل های محلی، حل تداخل ادغام و موارد دیگر، برخی از مشکلاتی هستند که در گیت بررسی خواهیم کرد.
1. بازگردانی فایل به حالت اولیه
گاهی اوقات بهترین راه برای درک یک مشکل، شیرجه رفتن و بازی کردن با کد است. متاسفانه، تغییرات ایجاد شده در فرآیند گاهی اوقات کمتر از حد مطلوب ظاهر می شود، در این صورت بازگرداندن فایل به حالت اولیه خود می تواند سریع ترین و ساده ترین راه حل باشد:
git checkout -- Gemfile # reset specified path
git checkout -- lib bin # also works with multiple arguments
اگر تعجب می کنید، خط تیره دوتایی (–) یک راه متداول برای ابزارهای کامند لاین برای نشان دادن پایان گزینه های فرمان است.
2. لغو commit های محلی
گاهی اوقات کمی بیشتر طول می کشد تا متوجه شویم که در مسیر اشتباهی هستیم و تا آن زمان ممکن است یک یا چند تغییر به صورت محلی انجام شده باشد. این زمانی است که git reset مفید است:
git reset HEAD~2 # undo last two commits, keep changes
git reset --hard HEAD~2 # undo last two commits, discard changes
مراقب گزینه –hard باشید! درخت کار شما و همچنین شاخص را بازنشانی می کند، بنابراین تمام تغییرات شما برای همیشه از بین می رود.
3. حذف یک فایل از GIT بدون پاک شدن از سیستم
اگر در حین افزودن فایل به git مراقب نباشید، ممکن است در نهایت فایلهایی را اضافه کنید که نمیخواستید روی آنها کار کنید. با این حال، git rm آن را هم از ناحیه مرحله بندی شما و هم از سیستم فایل شما حذف می کند، که ممکن است آن چیزی نباشد که شما می خواهید. در این صورت مطمئن شوید که فقط نسخه مرحله ای را حذف کردهاید و فایل را به .gitignore خود اضافه کنید تا از تکرار اشتباه مشابه جلوگیری شود:
git reset filename # or git remove --cached filename echo filename
>> .gitignore # add it to .gitignore to avoid re-adding it
4. یک پیام commit را ویرایش کنید
اشتباهات تایپی اتفاق می افتد، اما خوشبختانه در مورد پیام های commit، رفع آنها بسیار آسان است:
git commit --amend # start $EDITOR to edit the message
git commit --amend -m "New message" # set the new message directly
اما این تمام کاری نیست که git-amend می تواند برای شما انجام دهد. فراموش کردید فایل اضافه کنید؟ فقط آن را اضافه کنید و commit قبلی را اصلاح کنید!
git add forgotten_file
git commit --amend
لطفاً به خاطر داشته باشید که -amend در واقع یک commit جدید ایجاد می کند که جایگزین قبلی می شود، بنابراین از آن برای اصلاح commit هایی که قبلاً به یک مخزن مرکزی منتقل شده اند استفاده نکنید.
اگر کاملاً مطمئن باشید که هیچ توسعه دهندهای قبلاً نسخه قبلی را بررسی نکرده و کار خود را بر اساس آن انجام نداده است، میتوان یک استثنا از این قاعده ایجاد کرد، در این صورت PUSH اجباری (git push –force) ممکن است هنوز قابل استفاده باشد. گزینه –force در اینجا ضروری است زیرا تاریخچه درخت به صورت محلی اصلاح شده، به این معنی که فشار توسط سرور راه دور رد می شود زیرا امکان ادغام سریع به جلو وجود ندارد.
5. قبل از PUSH کردن، commit های محلی را تمیز کنید
–amend بسیار مفید است، اما اگر commit که میخواهید بازنویسی کنید اخرین مورد نباشد کمکی نمیکند. در این صورت یک rebase تعاملی مفید است:
git rebase --interactive
# if you didn't specify any tracking information for this branch
# you will have to add upstream and remote branch information:
git rebase --interactive origin branch
با این کار ویرایشگر پیکربندی شده شما باز می شود و منوی زیر به شما ارائه می شود:
pick 8a20121 Upgrade Ruby version to 2.1.3
pick 22dcc45 Add some fancy library
# Rebase fcb7d7c..22dcc45 onto fcb7d7c
#
# Commands: # p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
در بالا لیستی از commit های محلی را می بینید که به دنبال آن دستورات موجود را توضیح داده شده است. فقط commit (هایی) را که می خواهید به روز کنید انتخاب کرده، انتخاب را به reword (یا به اختصار r) تغییر دهید. با این کار به نمای جدیدی هدایت می شوید که در آن می توانید پیام را ویرایش کنید.
با این حال، همانطور که از فهرست بالا مشاهده میشود، rebases تعاملی چیزهای بیشتری از ویرایش پیام commit ساده ارائه میدهند: شما میتوانید commitها را با حذف آنها از فهرست، و همچنین ویرایش، مرتبسازی مجدد و له کردن آنها کاملاً حذف کنید. Squashing به شما امکان می دهد چندین commit را در یک مورد ادغام کنید، کاری که من دوست دارم قبل از Push کردن آنها به ریموت، روی شاخه های ویژگی انجام دهم. با این کار،دیگر خبری از “افزودن فایل فراموش شده” و “رفع اشتباه تایپی” که یکی از مشکلات رایج گیت می باشد، برای ابدیت نیست!
6. برگرداندن commit های pushed شده
علیرغم اصلاحاتی که در مشکلات قبلی GIT و راه حل آنها نشان داده شد، commit های معیوب گهگاه به مخزن مرکزی وارد می شوند. هنوز هم این مشکل خیلی بزرگی به حساب نمی آید و قابل اصلاح است. زیرا git یک راه آسان برای برگرداندن commit های یک یا چندگانه ارائه می دهد:
git revert c761f5c # reverts the commit with the
specified id
git revert HEAD^ # reverts the second to last
commit
git revert develop~4..develop~2 # reverts a whole range of commits
در صورتی که نمی خواهید commit های بازگشتی اضافی ایجاد کنید بلکه فقط تغییرات لازم را در درخت کار خود اعمال می کنید، می توانید از گزینه –no-commit/-n بهره ببرید.
# undo the last commit, but don’t create a revert commit
git revert -n HEAD
صفحه دستی در man 1 git-revers گزینه های بیشتر را فهرست کرده و چند نمونه اضافی را ارائه می دهد.
7. از تضادهای مکرر merge خودداری کنید
همانطور که هر توسعه دهندهای میداند، رفع تضادهای ادغام میتواند خسته کننده باشد، اما حل دقیقاً همان تضاد به طور مکرر (مثلاً در شاخههای ویژگی طولانی مدت) کاملاً آزاردهنده است. این مشکل یکی از مشکلات رایج گیت می باشد که معمولا توسط افراد مبتدی در نظر گرفته نمی شود. اگر در گذشته از این مشکل GIT رنج می بردید، خوشحال می شوید که در مورد ویژگی وضوح ضبط شده استفاده مجدد (reuse recorded resolution) بدانید. آن را به پیکربندی جهانی خود اضافه کنید تا برای همه پروژه ها فعال شود:
git config –global rerere.enabled true
همچنین میتوانید با ایجاد دستی دایرکتوری git/rr-cache، آن را بر اساس هر پروژه فعال کنید.
مطمئناً این ویژگی برای همه کاربردی نیست، اما برای افرادی که به آن نیاز دارند، میتواند باعث صرفه جویی در زمان شود. تصور کنید تیم شما همزمان روی شاخه های ویژگی های مختلف کار می کند. اکنون می خواهید همه آنها را با هم در یک شاخه قابل آزمایش پیش از انتشار ادغام کنید.
همانطور که انتظار می رود، چندین تضاد ادغام وجود دارد که شما آنها را حل می کنید. متأسفانه معلوم می شود که یکی از شاخه ها هنوز کاملاً وجود ندارد، بنابراین تصمیم می گیرید دوباره آن را لغو کنید. چند روز (یا هفتهها) بعد، وقتی branch آماده شد، دوباره آن را ادغام میکنید، اما به لطف قطعنامه های ثبت شده، دیگر مجبور نخواهید بود همان تضادهای ادغام را حل کنید.
8. commit را پیدا کنید که پس از merge چیزی را شکست
ردیابی commit که پس از یک merge بزرگ یک اشکال را به وجود آورد، می تواند بسیار وقت گیر باشد. خوشبختانه git یک امکان جستجوی باینری عالی را در قالب git-bisect ارائه می دهد. ابتدا باید تنظیمات اولیه را انجام دهید:
git bisect start # starts the bisecting session
git bisect bad # marks the current revision as bad
git bisect good revision # marks the last known good revision
پس از این گیت به طور خودکار یک بازبینی را در نیمه راه بین نسخه های شناخته شده “خوب” و “بد” بررسی می کند. اکنون می توانید مشخصات خود را دوباره اجرا کنید و بر این اساس commit را به عنوان “خوب” یا “بد” علامت گذاری کنید.
git bisect good # or git bisec bad
این روند تا زمانی ادامه می یابد که به commit که باگ را معرفی کرده است برسید.
9. از اشتباهات متداول با git hooks اجتناب کنید
برخی از اشتباهات به طور مکرر اتفاق میافتند، اما با اجرای برخی از بررسیها یا کارهای پاکسازی در یک مرحله تعریف شده از گردش کار git، جلوگیری از آنها آسان است. این دقیقاً همان سناریویی است که hook ها برای آن طراحی شده اند. برای ایجاد یک hook جدید، یک فایل اجرایی به git/hooks. اضافه کنید.
نام اسکریپت باید با یکی از hook های موجود مطابقت داشته باشد که لیست کامل آن در صفحه دستی (man githooks) موجود است. همچنین میتوانید با ایجاد یک دایرکتوری قالبی که git در هنگام راه اندازی یک مخزن جدید از آن استفاده میکند، hook های جهانی را برای استفاده در همه پروژههای خود تعریف کنید (برای اطلاعات بیشتر به man git-init مراجعه کنید).
[init]
templatedir = ~/.git_template
tree .git_template→
git_template.
hooks──└
pre-commit ──└
هنگامی که یک مخزن جدید را مقداردهی اولیه می کنید، فایل های موجود در دایرکتوری الگو در محل مربوطه در دایرکتوری git. پروژه شما کپی می شوند. آنچه در ادامه میآید یک نمونه کمی ساختگی commit-msg hook است که تضمین میکند هر پیام commit به شماره بلیطی مانند “#123” ارجاع شود.
ruby
usr/bin/env ruby/!#
message = File.read(ARGV[0])
/+unless message =~ /\s*#\d
".puts "[POLICY] Your message did not reference a ticket
exit 1
end
10. وقتی همه چیز مشکل دارد
تا اینجا ما موارد زیادی از مشکلات رایج گیت را به همراه راه حل رفع آنها پوشش داده ایم. بسیاری از مشکلات رایج GIT راه حل های به اندازه کافی آسان دارند، با این حال مواقعی وجود دارد که باید همه چیز را کنار بگذارید و تاریخ یک شاخه کامل را بازنویسی کنید. یکی از موارد استفاده رایج برای این کار، حذف داده های حساس (مانند اعتبار ورود به سیستم برای سیستم های تولید) است که به یک مخزن عمومی متعهد شده اند:
\ git filter-branch --force --index-filter
\ 'git rm --cached --ignore-unmatch secrets.txt'
prune-empty --tag-name-filter cat -- --all--
با این کار فایل Secrets.txt از هر شاخه و تگ حذف می شود. همچنین تمامی commit هایی را که در نتیجه عملیات فوق خالی می شوند حذف می کند. به خاطر داشته باشید که این کار کل تاریخچه پروژه شما را بازنویسی می کند و می تواند در یک گردش کار توزیع شده بسیار مخرب باشد. همچنین در حالی که فایل مورد نظر اکنون حذف شده است، اعتبارنامه موجود در آن همچنان باید در معرض خطر تلقی شود!
کلام آخر
در نظر داشته باشید که همیشه باید کارهای گروهی را با بالاترین دقت انجام داد. اشتباهات رایج در گیت در برخی از مواقع می تواند بسیاری از بخش های یک پروژه را تخریب کند. شما می توانید از دستورات مهم گیت به صورت استاندارد استفاده کنید. بهتر است در زمان کار بر روی git حتما چیزی مثل برگه تقلب گیت را باز نگه دارید تا برای بخش های مهم از آن استفاده کنید و مشکلات رایج گیت را به حداقل برسانید.
درباره مدیریت
من عاشق برنامه نویسی و تکنولوژی هستم و 10 سال در این زمینه مشغول به فعالیت هستم و پروژه های مختلفی رو در زمینه های سایت و شبکه های کامپیوتری و امنیت اطلاعات انجام دادم و در حال حاضر مدیر و موسس شرکت انفورماتیک طراحی پایا آنوش هستم که در زمینه ی طراحی سایت و سیستم های هوشمند و برقراری امنیت اطلاعات سیستم های کامپیوتری و همچنین آموزش فعالیت دارد و میخواهم هر آنچه که در طی این 10 سال یاد گرفتم و تجربه کردم رو با شما به اشتراک بگذارم.
نوشته های بیشتر از مدیریت
دیدگاهتان را بنویسید