از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
نحوه تجسم دستورات گیج کننده Git با Git-Sim
سرفصلهای مطلب
Git یک ابزار ضروری برای توسعه دهندگان است تا بتوانند به طور مؤثر در کد منبع همکاری کنند. اما یادگیری برخی از مفاهیم و دستورات Git برای توسعه دهندگان بسیار دشوار است.
نه تنها این، بلکه دستورات Git اغلب دارای تفاوتهایی هستند که منجر به نتایج متفاوتی در وضعیت مخزن محلی شما میشود. علاوه بر این، حتی زمانی که یک دستور Git خاص را یاد می گیرید، ممکن است قبل از اینکه دوباره به آن نیاز پیدا کنید، مدت زمان زیادی از آن دستور استفاده نکنید.
این امر توسعه دهندگان را به جستجوی مکرر در Google یا Stackoverflow برای دستورات موقعیتی خاص Git بارها و بارها سوق می دهد و دعا می کند که نتایج موازی هنگام اجرای دستور به صورت محلی رخ دهد.
این معمولاً با دستورات گیج کننده معروف Git مانند git reset
، git merge
، و git rebase
.
در این مقاله، با استفاده از یک ابزار خط فرمان به نام Git-Sim برای شبیهسازی بصری عملیات Git در مخزن محلی شما، مروری بر این 3 دستور ارائه میکنیم. این ابزار ما را قادر می سازد تا به راحتی نمودارها و انیمیشن های مفیدی ایجاد کنیم که نشان می دهد چگونه هر دستور Git بر وضعیت مخزن Git شما تأثیر می گذارد.
git reset
– نحوه بازنشانی Git HEAD در حین مدیریت تغییرات
دستور git reset یکی از دستورات است که من دائماً قبل از اینکه نیاز به استفاده از آن داشته باشم در گوگل جستجو می کنم.
این تا حدی به این دلیل است که چندین دستور وجود دارد که میتوانید از آنها برای لغو تغییرات در Git استفاده کنید، و من میخواهم مطمئن شوم که درست را انتخاب میکنم.
همچنین، هر دستوری که به طور تصادفی منجر به “از دست دادن کار” شود، مانند git reset --hard
ارزش این را دارد که چند ثانیه قبل از آن وقت بگذارید تا مطمئن شوید که به کاری که می خواهید انجام دهید اطمینان دارید.
چه می کند git reset
انجام دادن؟
به طور خلاصه، git reset به سادگی نوک شاخه فعلی را به commit قبلی برمیگرداند. از این نظر می توان از آن برای “لغو” تغییرات اعمال شده توسط commit ها بین commit فعلی و commitی که می خواهید به آن بازنشانی کنید استفاده کرد.
از نظر فنی، یک شاخه Git فقط یک نام (یا برچسب) است که به جدیدترین commit در زنجیره ای از commit ها اشاره می کند. هر بار که یک commit جدید در یک شاخه ایجاد می کنید، این کار به جلو منتقل می شود و بنابراین همیشه آنچه را که به عنوان سر شاخه مرتکب شدن.
را git reset
دستور این برچسب شاخه را به یک commit قبلی برمیگرداند، که به سر شاخه جدید تبدیل میشود – عملاً تمام تغییرات بین آنها لغو میشود.
بیایید یک مثال ساده را در نظر بگیریم. فرض کنید ما یک مخزن داریم که فقط 1 فایل فراخوانی شده را ردیابی می کند cheese.txt
. مخزن دارای 5 commit است که هر کدام محتوای متن داخل فایل را به نام پنیر متفاوتی تغییر می دهد.
ما میتوانیم با استفاده از Git-Sim این را به صورت بصری با اجرای آن نشان دهیم $ git-sim log
دستور شبیه سازی بصری خروجی $ git log
دستور:
همانطور که می بینید، ما یک main
شعبه ای که به commit با ID اشاره می کند 14c121...
با پیام commit Cheddar
.
حال فرض کنید میخواهیم تعهدات تغییر محتوای آن را لغو کنیم cheese.txt
به «چدار» و «سوئیس». ما می توانیم این کار را با استفاده از git reset
دستور ریست کردن main
شعبه 2 به “گودا” متعهد می شود:
$ git reset HEAD~2
اما اگر در مورد تأثیر این دستور مطمئن نیستیم، میتوانیم ابتدا با استفاده از Git-Sim آن را شبیهسازی کنیم:
$ git-sim reset HEAD~2
یا اگر ترجیح می دهید، شبیه سازی را می توان به عنوان یک انیمیشن ویدیویی پویا با استفاده از Git-Sim ارائه کرد. --animate
به صورت زیر پرچم گذاری کنید:
$ git-sim --animate reset HEAD~2
همانطور که می بینید، خروجی شبیه سازی شده Git-Sim در بالا نشان می دهد که main
شاخه و HEAD
اشاره گر به عقب بازنشانی می شوند 2 متعهد به تعهد “Gouda”.
علاوه بر این، می بینیم که Git-Sim یک جدول با 3 ستون ایجاد کرده است:
- تغییرات حذف شده از
- تغییرات دایرکتوری کار
- منطقه صحنه سازی
به طور پیش فرض، git reset
فرمان اعمال می شود --mixed
رفتار پرچم، که هر گونه تغییر در commit های بازنشانی را به دایرکتوری کاری منتقل می کند.
Git-Sim این را در خروجی شبیه سازی شده بالا با افزودن فایل منعکس می کند cheese.txt
به درون تغییرات دایرکتوری کار ستون
اکنون که شما آن را شبیه سازی کرده اید git reset
دستور با استفاده از Git-Sim و می توانید به وضوح نتیجه مورد انتظار را در خروجی تصویر بالا ببینید، می توانید دستور واقعی Git را اجرا کنید. $ git reset HEAD~2
با اعتماد به نفس.
بعلاوه --mixed
، Git-Sim می فهمد --soft
و --hard
بازنشانی می کند. دستور $ git-sim reset --soft HEAD~2
تغییرات انجام نشده را در منطقه صحنه سازی ستون، در حالی که فرمان $ git-sim reset --hard HEAD~2
تغییرات انجام نشده را در تغییرات حذف شده از ستون از آنجایی که یک هارد ریست تغییرات به فایل های متعهد را نادیده می گیرد.
توجه داشته باشید که git reset
هیچ کامیتی را حذف نمی کند (حتی در هنگام استفاده از --hard
گزینه)، به این معنی که در زمان اجرای آن هیچ کاری را از دست نمی دهید. اما به خاطر داشته باشید که تعهدات می توانند تبدیل شوند یتیم شده، به این معنی که برخی از تعهدات توسط هر شعبه ای غیرقابل دسترس می شود. Git در نهایت این موارد را از طریق جمعآوری زباله حذف میکند، اما در صورت نیاز برای مدتی قابل بازیابی هستند!
git merge
– نحوه ادغام تغییرات از چندین شاخه
دستور ادغام git یکی دیگر از دستورات دشوار برای کاربران مبتدی و متوسط Git است که می توانند سر خود را به اطراف بپیچند. چندین نوع مختلف ادغام وجود دارد که Git بسته به شرایط انجام می دهد.
برای ارائه یک پایه، این دنباله از دو دستور نحوه عملکرد نحو ادغام را برجسته می کند:
$ git checkout <merge-into>
$ git merge <merge-from>
دستور اول نشان می دهد که <merge-into>
شعبه شاخه فعالی است که شما در حال حاضر در فهرست کاری خود بررسی کرده اید. سپس زمانی که ادغام را اجرا می کنید، مشخص می کنید <merge-from>
همانطور که شاخه ای که می خواهید ادغام کنید از آن به شاخه فعال تغییر می کند.
بنابراین برای مثال، دستورات زیر تغییرات را با هم ادغام می کنند dev
شاخه به main
:
$ git checkout main
$ git merge dev
Git سه طرفه ادغام
رایج ترین مورد ادغام زمانی رخ می دهد که تاریخچه دو شاخه از هم جدا شده باشد و توسعه دهنده بخواهد تغییرات را دوباره ترکیب کند. در این سناریو، Git چیزی را انجام می دهد که به عنوان a ادغام سه طرفه.
این ادغام سه طرفه نامیده می شود زیرا Git از سه commit برای تعیین نحوه ترکیب تغییرات در شاخه های واگرا استفاده می کند:
- تعهد در نوک شاخه A
- تعهد در نوک شاخه B
- ادغام پایه دو شاخه
ما میتوانیم از Git-Sim برای شبیهسازی یک ادغام سهطرفه استفاده کنیم که تغییرات در دو commit جدید را ادغام میکند. dev
شاخه به main
:
$ git checkout main
$ git-sim merge dev
در مثال بالا، نوک از main
قبل از ادغام، شاخه کنید 14c121
(“چدار”)، و نوک از dev
شعبه است f42fee
(“آسیاگو”). سومین commit مورد استفاده در الگوریتم ادغام سه طرفه Git commit است 640bb5
که هست پایه ادغام از دو شاخه شما می توانید این را با ردیابی هر دو شاخه تا زمانی که اولین جد مشترک را پیدا کنید شناسایی کنید.
با استفاده از محتوای این 3 commit، Git یک جدید ایجاد می کند ادغام commit (برچسب abcdef
در نمودار Git-Sim بالا) که تغییرات هر دو شاخه را ترکیب می کند.
بر خلاف commit های معمولی، یک commit ادغام به جای یک پدر، دو والد دارد که مربوط به نوک دو شاخه ای است که با هم ادغام شده اند. این دو رابطه والد با دو خط نقطه چین در تصویر بالا مشخص می شوند.
Git ادغام سریع به جلو
آ ادغام سریع به جلو در Git زمانی اتفاق میافتد که شاخهای که از آن ادغام میشوید، درست در همان خط توسعهای که شاخه فعال است، باشد. به مثال زیر توجه کنید:
$ git-sim log
در این مورد، dev
و main
شاخه ها واقعاً از هم جدا نشده اند – هر دو در امتداد یک خط توسعه قرار دارند. در نتیجه، اگر بررسی کنید dev
شعبه کنید و سعی کنید در آن ادغام شوید main
، Git حتی نیازی به ادغام محتوا از دو شاخه ندارد.
در عوض، Git می تواند به سادگی به آن اشاره کند dev
شعبه ref به همان commit که main
اشاره به، که است 14c121
. (به یاد داشته باشید که یک شاخه در Git فقط یک برچسب است که به یک commit خاص اشاره می کند).
Git-Sim می داند که چگونه این نوع ادغام را شبیه سازی کند:
$ git checkout dev
$ git-sim merge main
توجه داشته باشید که پس از بررسی dev
شاخه و ادغام main
به آن، dev
برچسب شاخه به سادگی بود فوروارد سریع به همان تعهدی که main
، و هیچ تعهد ادغام جدیدی ایجاد نشد.
با این حال، در برخی موارد ممکن است بخواهید زور Git برای ایجاد یک commit ادغام حتی در هنگام انجام یک ادغام سریع به جلو.
اگر بخواهید تاریخچه همه ادغام ها را حفظ کنید تا تیم شما بداند چه زمانی ادغام انجام شده است، این ممکن است مفید باشد. شما می توانید این کار را با استفاده از --no-ff
flag که توسط Git-Sim نیز پشتیبانی می شود:
$ git checkout dev
$ git-sim merge --no-ff main
در تصویر خروجی شبیه سازی شده بالا، Git یک commit جدید ادغام ایجاد کرد abcdef
که dev
برچسب شاخه اکنون به آن اشاره می کند، حتی اگر امکان انتقال سریع به تعهدی که توسط آن اشاره شده بود وجود داشت main
.
به خاطر داشته باشید که حتی در هنگام اجبار به ادغام commit به این روش، هیچ گونه واگرایی در تاریخچه شاخه رخ نداده است. هر دو شاخه هنوز در یک خط توسعه قرار می گیرند.
git rebase
– نحوه انتقال کامیت فعلی به یک کامیت پایه جدید
در نهایت، ما به طور خلاصه یک سناریوی خاص از دستور استاندارد git rebase را پوشش خواهیم داد. به جای ادغام محتویات دو شاخه، git rebase <new-base>
commit های قابل دستیابی توسط شاخه فعلی را مجدداً روی یک تعهد پایه جدید اعمال می کند، مشخص شده توسط <new-base>
.
به صورت پیش فرض، git rebase
وارد می شود حالت استاندارد، چیزی است که ما در اینجا در مورد آن بحث خواهیم کرد. را -i
flag اجازه می دهد تا rebase اجرا شود حالت تعاملی، اما از حوصله این مقاله خارج است.
با استفاده از مخزن نمونه قبلی خود، بیایید به 2 commit جدید اضافه شده به آن توجه کنیم dev
شاخه ead5cc
(“فونتینا”) و f42fee
(“آسیاگو”):
سپس میخواهیم این 2 commit جدید را به نوک آن منتقل کنیم main
شاخه با استفاده از git rebase
فرمان این را می توان با استفاده از دستورات شبیه سازی کرد:
$ git checkout dev
$ git-sim rebase main
در خروجی شبیه سازی شده در بالا، خطوط نقطه چین نشان می دهد که چگونه 2 new commit می شوند dev
شاخه ها بر روی نوک مجدد قرار می گیرند main
.
در یک rebase استاندارد، Git با عقب رفتن از نوک شاخه فعال تا زمانی که یک تعهد اجداد مشترک بین دو شاخه پیدا شود، تعداد تعهدات برای rebase را مشخص می کند.
البته، این جد مشترک از قبل در شاخه مقصد وجود دارد، بنابراین rebase نیازی به گنجاندن آن ندارد و می تواند در آن نقطه به پایان برسد.
در این مورد، این دو متعهد به dev
شاخه ای که هنوز وجود ندارد main
هستند ead5cc
(“فونتینا”) و f42fee
(“آسیاگو”). اینها مجدداً بر اساس آن هستند main
همانطور که با خطوط نقطه چین بالا نشان داده شده است. از زمان ارتکاب 640bb5
(“Gouda”) از قبل موجود است main
، در rebase گنجانده نشده است.
توجه داشته باشید که rebasing در Git در واقع تاریخچه commit را بازنویسی می کند، زیرا هر شناسه commit به محتوای آن commit بستگی دارد. و تاریخ پیش از آن
حتی اگر محتوای موجود در دو commit مبتنی بر مجدد در مثال بالا کاملاً در مورد آن اعمال شود main
شعبه، شناسههای commit جدید باید محاسبه شوند، زیرا تاریخچه آنها اکنون با زمانی که در آن اعمال شدهاند متفاوت است dev
شاخه.
به همین دلیل، یک قانون کلی خوب این است که فقط rebase به صورت محلی انجام می شود که هنوز به یک مخزن راه دور منتقل نشده است. این تضمین می کند که شما و تیمتان در طول زمان یک وضعیت مخزن ثابت برای پروژه خود حفظ کنید.
خلاصه
در این مقاله، ما از ابزار Git-Sim برای ارائه یک نمای کلی از 3 دستور گیج کننده Git استفاده می کنیم. git reset
، git merge
، و git rebase
.
ما نشان دادیم که چگونه نشانگر HEAD Git را به یک commit قبلی بازنشانی کنیم، در حالی که فایلهای متعهد، فایلهای مرحلهای و فایلهای دایرکتوری کار را به دلخواه مدیریت میکنیم. --soft
، --mixed
، یا --hard
پرچم ها
سپس انواع اصلی ادغام را در Git بیان کردیم، از جمله ادغام سه طرفه و ادغام سریع به جلو.
در نهایت، ما در مورد rebasing شاخه ها بحث کردیم، که به معنای انتقال مجموعه ای از commit ها به یک commit پایه جدید است.
برای هر یک از این دستورات، ما نشان دادیم که چگونه میتوان از ابزار خط فرمان Git-Sim برای ایجاد شبیهسازیهای منحصربهفرد و سفارشیسازی شده از افکتهای فرمان Git قبل از اجرای خود فرمان واقعی Git استفاده کرد.
مراحل بعدی
اگر شما یک یادگیرنده بصری و کاربر Git هستید، توصیه می کنم قبل از اجرای دستورات واقعی، Git-Sim را برای شبیه سازی دستورات Git در مخازن محلی خود امتحان کنید.
این به شما اطمینان میدهد که دستورات واقعی Git را اجرا کنید و حتی محتوای بصری برای کمک به مستندسازی، اشتراکگذاری محتوا و آموزش استفاده از Git به دیگران ارائه میدهد.
Git-Sim یک ابزار رایگان و منبع باز است که به زبان پایتون نوشته شده است، بنابراین اگر علاقه مند به مشارکت هستید یا اگر اشکالی پیدا کردید، می توانید پروژه Git-Sim را در GitHub بررسی کنید و/یا با من در jacob@ تماس بگیرید. initialcommit.io!
منتشر شده در 1402-12-26 18:48:04