سرفصل‌های آموزشی
آموزش کاربردی گیت برای برنامه نویسان
git reflog  چیست؟

git reflog چیست؟

 

در این بخش از آموزش، بحث مفصلی درباره دستور git reflog ارائه شده است. Git با استفاده از مکانیزمی به نام reference logs یا "reflogs"، به روزرسانی های شاخه ها را پیگیری می کند. بسیاری از دستورهای Git، پارامتری را برای تعیین یک منبع یا "ref"، که نشانگر یک commit است، می پذیرند. نمونه های متداول عبارتند از:

  • git checkout
  • git reset
  • git merge

reflog ها هنگام به روزرسانی منابع Git، در مخزن محلی ردیابی می شوند. افزون بر reflog های شاخه ها، یک reflog ویژه، برای Git stash (git stash دستوری برای ذخیره ی موقتی تغییرها) نگهداری می شود. reflog ها در دایرکتوری های زیر مخزن محلی دایرکتوری .git ذخیره می شوند. اگر git stash در مخزن استفاده شده باشد، دایرکتوری های git reflog را می توان در .git/logs/refs/heads/.، .git/logs/HEAD و همچنین .git / logs / refs / stash یافت.

در مورد git reflog در سطح بالاتری در Rewriting History Page صحبت کرده ایم. این آموزش شامل موارد زیر است: 

  • گزینه های پیکربندی git reflog
  • موارد استفاده معمول و مشکلات git reflog
  • نحوه لغو تغییرها در git reflog
  • و برخی موارد دیگر

کاربرد اصلی

ابتدایی ترین کاربرد reflog به صورت زیر است:

git reflog

که یک میان بر است برای:

git reflog show HEAD

با این کار، HEAD مربوط به reflog مشاهده می شود. باید خروجی مشابه زیر را ببینید:

eff544f HEAD@{0}: commit: migrate existing content
bf871fd HEAD@{1}: commit: Add Git Reflog outline
9a4491f HEAD@{2}: checkout: moving from master to git_reflog
9a4491f HEAD@{3}: checkout: moving from Git_Config to master
39b159a HEAD@{4}: commit: expand on git context 
9b3aa71 HEAD@{5}: commit: more color clarification
f34388b HEAD@{6}: commit: expand on color support 
9962aed HEAD@{7}: commit: a git editor -> the Git editor

برای دیدن مثال دیگری از دسترسی مشترک به reflog، از Rewriting History Page دیدن کنید.

Reflog منابع

به صورت پیش فرض، git reflog، reflog منابع HEAD را به عنوان خروجی، نمایش می دهد. HEAD اشاره ای نمادین به شاخه ی جاری فعال است. reflog ها برای سایر منابع نیز موجود هستند. Syntax دسترسی به git ref، به صورت name@{qualifier} است. افزون بر منابع HEAD، سایر شاخه ها، برچسب ها، remote ها و stash Git نیز، می توانند منبع دهی شوند. 

با انجام موارد زیر می توانید از همه منابع، دوباره یک reflog کامل بگیرید:

git reflog show --all 

برای مشاهده ی reflog یک شاخه ی خاص، نام شاخه را در ادامه ی دستور git reflog show بیاورید:

git reflog show otherbranch 9a4491f otherbranch@{0}: commit: seperate articles into branch PRs 35aee4a otherbranch{1}: commit (initial): initial commit add git-init and setting-up-a-repo docs 

اجرای این مثال، یک reflog برای شاخه ی otherbranch را نشان می دهد. مثال زیر فرض می کند که شما قبلا با استفاده از دستور git stash برخی از تغییرها را ذخیره کرده اید.

git reflog stash 0d44de3 stash@{0}: WIP on git_reflog: c492574 flesh out intro

با این کار برای stash Git یک reflog در خروجی نشان داده می شود.

Reflog های زمان دار

به هر reflog وارد شده به سیستم، یک timestamp متصل است. این timestamp ها می توانند به عنوان Syntax ای برای توصیف Git ref استفاده شوند. بنابراین امکان فیلتر reflog های Git بر اساس زمان را فراهم می کند. در زیر چند نمونه توصیف کننده ی زمان، قابل استفاده در git reflog را مشاهده می کنید:

  • 1.minute.ago
  • 1.hour.ago
  • 1.day.ago
  • yesterday
  • 1.week.ago
  • 1.month.ago
  • 1.year.ago
  • 2011-05-17.09:00:00

توصیف کننده ی زمان را می توان ترکیب کرد (برای مثال 1.day.2.hours.ago)، افزون بر این، به شکل جمع نیز، می توان استفاده کرد. (برای مثال 5.minutes.ago).

ref های تعیین کننده ی زمان را می توان با سایر دستورهای git استفاده کرد.

git diff master@{0} master@{1.day.ago} 

این مثال تفاوت شاخه ی master کنونی با master یک روز پیش، را مشخص می کند. اگر می خواهید تغییرهایی را که در یک بازه ی زمانی رخ داده است بدانید، این مثال بسیار مفید است.

subcommand ها و گزینه های پیکربندی

git reflog، چند ورودی اضافی را که subcommand محسوب می شوند، می پذیرد.

Show: git reflog show

show به طور پیش فرض در دستور reflog اجرا می شود. برای مثال، دو دستور زیر با هم برابرند:

git reflog master@{0} 

 و

git reflog show master@{0}

افزون بر این، git reflog show نام مستعاری برای git log -g --abbrev-commit --pretty=oneline است. اجرای git reflog show، log گذشته را نشان می دهد.

Expire: git reflog expire

دستور expire ورودی های  reflogقدیمی یا غیرقابل دسترس را پاک می کند. با اجرای دستور expire احتمال از دست رفتن اطلاعات وجود دارد. کاربرهای نهایی به طور معمول از این دستور استفاده نمی کنند، اما git به صورت داخلی از آن استفاده می کند. قرار دادن گزینه ی -n یا --dry-run با git reflog expire ، یک "dry run" اجرا می کند که ورودی هایی را که برای هرس مشخص شده اند، نشان می دهد؛ اما آن ها را هرس نمی کند. 

به طور پیش فرض، تاریخ انقضای reflog، ۹۰ روز تنظیم شده است. زمان انقضا را می توان با قرار دادن یک ورودی expire=time-- به git reflog expire یا با تنظیم gc.reflogExpire، در پیکربندی git تعیین کرد.

Delete: git reflog delete

دستور delete به خودی خود توضیح داده شده است و ورودی منتقل شده در reflog را حذف می کند. مانند expire، با اجرای دستور delete نیز امکان از دست رفتن داده ها وجود دارد و معمولا کاربرهای نهایی آن را فراخوانی نمی کنند.

بازیابی commit های از دست رفته

Git هرگز چیزی را از دست نمی دهد، حتی هنگام انجام کارهای بازنویسی تاریخچه، مانند rebasing یا commit amending. برای مثال بعدی بیایید فرض کنیم که تغییرهای جدیدی در مخزن خود ایجاد کرده ایم. git log --pretty=oneline به صورت زیر است:

338fbcb41de10f7f2e54095f5649426cb4bf2458 extended content 1e63ceab309da94256db8fb1f35b1678fb74abd4 bunch of content c49257493a95185997c87e0bc3a9481715270086 flesh out intro eff544f986d270d7f97c77618314a06f024c7916 migrate existing content bf871fd762d8ef2e146d7f0226e81a92f91975ad Add Git Reflog outline 35aee4a4404c42128bee8468a9517418ed0eb3dc initial commit add git-init and setting-up-a-repo docs 

سپس تغییرهایی را commit کرده و دستور زیر را اجرا می کنیم:

#make changes to HEAD git commit -am "some WIP changes" 

با اضافه کردن commit جدید، log به شکل زیر خواهد بود:

37656e19d4e4f1a9b419f57850c8f1974f871b07 some WIP changes 338fbcb41de10f7f2e54095f5649426cb4bf2458 extended content 1e63ceab309da94256db8fb1f35b1678fb74abd4 bunch of content c49257493a95185997c87e0bc3a9481715270086 flesh out intro eff544f986d270d7f97c77618314a06f024c7916 migrate existing content bf871fd762d8ef2e146d7f0226e81a92f91975ad Add Git Reflog outline 35aee4a4404c42128bee8468a9517418ed0eb3dc initial commit add git-init and setting-up-a-repo docs 

در این مرحله یک rebase با شاخه master به صورت زیر اجرا خواهیم کرد:

git rebase -i origin/master 

هنگام اجرای rebase با وارد کردن s (که یک subcommand برای rebase است)، commit ها را برای یکی کردن، علامت گذاری کردیم. در حین rebase، تعدادی از commit ها را با آخرین commit (با پیام “some WIP changes”)، یکی کردیم.

از آنجایی که commit ها یکی شدند، خروجی git log به صورت زیر خواهد بود:

40dhsoi37656e19d4e4f1a9b419f57850ch87dah987698hs some WIP changes 35aee4a4404c42128bee8468a9517418ed0eb3dc initial commit add git-init and setting-up-a-repo docs 

اگر git log را در این مرحله بررسی کنیم، به نظر می رسد که commit هایی که برای یکی کردن، علامت گذاری کردیم را دیگر نداریم.

اگر بخواهیم روی یکی از commit هایی که یکی کرده ایم، کار کنیم، چه می کنیم؟ مثلا بخواهیم تغییرهای آن را از تاریخچه حذف کنیم! وقت به کار بردن reflog است.

git reflog 37656e1 HEAD@{0}: rebase -i (finish): returning to refs/heads/git_reflog 37656e1 HEAD@{1}: rebase -i (start): checkout origin/master 37656e1 HEAD@{2}: commit: some WIP changes

reflog های ثبت شده برای شروع و پایان rebase را می توانیم ببینیم و قبل از آن ها، commit با پیام “some WIP changes” وجود دارد. می توانیم منبع reflog را با git reset بیاوریم و به  commit ای که قبل از rebase بود، reset کنیم. 

git reset HEAD@{2} 

اجرای این دستور reset، HEAD را به commit با پیام “some WIP changes” جا به جا می کند. در اصل بقیه commit های یکی شده را بازیابی می کند.

خلاصه

در این بخش از آموزش، ما درباره دستور git reflog بحث کردیم. برخی از نکات کلیدی بیان شده عبارت اند از:

  • شیوه ی مشاهده reflog برای شاخه های خاص
  • شیوه ی لغو git rebase با استفاده از reflog
  • شیوه ی مشخص کردن و مشاهده ی ورودی های reflog مبتنی بر زمان

به طور خلاصه اشاره کردیم که git reflog را می توان با سایر دستورهای git مانند git checkout ، git reset و git merge استفاده کرد. برای بحث بیشتر در مورد refs و reflog ، می توانید از اینجا بیشتر بیاموزید.

منبع

https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog

online-support-icon