Git
Chapters ▾ 2nd Edition

2.3 مقدمات گیت - دیدن تاریخچهٔ کامیت‌ها

دیدن تاریخچهٔ کامیت‌ها

پس از اینکه چندین کامیت انجام دادید، یا اگر مخزنی با یک تاریخچهٔ از پیش موجود را کلون کردید، احتمالاً می‌خواهید ببینید که در کامیت‌های پیشین چه پیش آمده است. اساسی‌ترین و قدرتمندترین ابزار برای این کار دستور git log است.

این مثال‌ها از یک پروژه بسیار ساده به نام «simplegit» استفاده می‌کنند. برای دریافت پروژه دستور زیر را اجرا کنید:

$ git clone https://github.com/schacon/simplegit-progit

هنگامی که git log را در این پروژه اجرا می‌کنید، باید خروجی ببینید که مشابه این است:

$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    Remove unnecessary test

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    Initial commit

به صورت پیش‌فرض، بدون هیچ آرگومانی، دستور git log کامیت‌های به ثبت رسیده در مخزن را از جدید‌ترین تا قدیمی‌ترین لیست می‌کند؛ یعنی جدیدترین کامیت اولین به نمایش در می‌آید. همانطور که مشاهده می‌کنید این دستور کامیت‌ها را به همراه هش کد SHA-1، نام و ایمیل نویسنده، تاریخ کامیت و پیام کامیت لیست می‌کند.

تعداد و انواع زیاید از آپشن‌ها برای دستور git log وجود دارند تا به شما دقیقاً همان چیزی را نمایش دهند که شما به دنبالش هستید. اینجا چندی از محبوب‌ترین‌ها را به شما نشان می‌دهیم.

یکی از آپشن‌های سودمند آپشن -p یا --patch است که تفاوت‌های (خروجی پچ) معرفی شده در هر کامیت را نشان می‌دهد. همچنین می‌توانید تعداد خروجی‌های لاگ نمایشی را محدود کنید، برای مثال استفاده از -2 فقط دو مورد آخر را نشان می‌دهد.

$ git log -p -2
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

diff --git a/Rakefile b/Rakefile
index a874b73..8f94139 100644
--- a/Rakefile
+++ b/Rakefile
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
 spec = Gem::Specification.new do |s|
     s.platform  =   Gem::Platform::RUBY
     s.name      =   "simplegit"
-    s.version   =   "0.1.0"
+    s.version   =   "0.1.1"
     s.author    =   "Scott Chacon"
     s.email     =   "schacon@gee-mail.com"
     s.summary   =   "A simple gem for using Git in Ruby code."

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    Remove unnecessary test

diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index a0a60ae..47c6340 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -18,8 +18,3 @@ class SimpleGit
     end

 end
-
-if $0 == __FILE__
-  git = SimpleGit.new
-  puts git.show
-end

این آپشن همان اطلاعات را نشان می‌دهد، لکن درجا پس از هر مورد یک دیف (تفاوت) به نمایش می‌گذارد. این برای بازنگری کد یا بررسی سریع اینکه در طی دسته‌ای از کامیت‌هایی که یک مشارکت‌کننده اضافه کرده چه اتفاقاتی افتاده بسیار مفید است. همچنین می‌توانید از دسته‌ای از آپشن‌های مختصرکننده با git log بهره ببرید. برای مثال اگر بخواهید مختصر آماری برای هر کامیت ببینید، میتوانید از آپشن --stat استفاده کنید:

$ git log --stat
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    Change version number

 Rakefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    Remove unnecessary test

 lib/simplegit.rb | 5 -----
 1 file changed, 5 deletions(-)

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    Initial commit

 README           |  6 ++++++
 Rakefile         | 23 +++++++++++++++++++++++
 lib/simplegit.rb | 25 +++++++++++++++++++++++++
 3 files changed, 54 insertions(+)

همانطور که مشاهده می‌کنید، آپشن --stat زیر هر کامیت لیستی از فایل‌های تغییر داده شده، تعداد فایل‌ها مورد تغییر قرار گرفته و تعداد خطوطی که به آن فایل‌ها اضافه و حذف شده را چاپ می‌کند. همچنین در آخر چکیده‌ای از اطلاعات را قرار می‌دهد.

یکی دیگر از آپشن‌های مفید --pretty است. این آپشن نوع فرمت لاگ خروجی را به حالت دیگری غیر از حالت پیش‌فرض تغییر می‌دهد. چندی آپشن از پیش ساخته شده برای این فلگ جهت استفاده شما در دسترس است. آپشن oneline هر کامیت را بر روی یک خط واحد چاپ می‌کند که در صورتی که در مواجهه با تعداد زیادی کامیت هستید مفید واقع است. علاوه‌بر آن، آپشن‌های short، full و fuller خروجی را تقریباً همانگونه نمایش می‌دهد اما با اطلاعات کمتر تا بیشتر:

$ git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 Change version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 Remove unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 Initial commit

جالب‌ترین آپشن format است که به شما اجازه می‌دهد نوع قالب خروجی لاگ شخصی خود را مشخص کنید. این بخصوص زمانی مفید است که می‌خواهید خروجی را برای تحلیل ماشین بسازید — چون شما قالب را به صراحت تعیین می‌کنید، می‌دانید که حتی با آپدیت گیت نیز تغییر نخواهد کرد:

$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 6 years ago : Change version number
085bb3b - Scott Chacon, 6 years ago : Remove unnecessary test
a11bef0 - Scott Chacon, 6 years ago : Initial commit

آپشن‌های مفید برای git log --pretty=format آپشن‌های مفیدی که format اختیار می‌کند را لیست می‌کند.

جدول 1. آپشن‌های مفید برای git log --pretty=format
‌آپشن توضیحات

%H

هش کد کامیت

%h

خلاصه شده هش کد کامیت

%T

درخت هش

%t

خلاصه شده درخت هش

%P

هش کد والد

%p

خلاصه شده هش کد والد

%an

نام نویسنده

%ae

ایمیل نویسنده

%ad

تاریخ نویسنده (با توجه به فرمت --date=option)

%ar

تاریخ نسبی نویسنده

%cn

نام کامیت‌کننده

%ce

ایمیل کامیت‌کننده

%cd

تاریخ کامیت‌کننده

%cr

تاریخ نسبی کامیت‌کننده

%s

موضوع

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

آپشن oneline و format به طور خاصی با آپشن دیگری از ‍log به نام --graph مفید واقع می‌شوند. این آپشن یک گراف ASCII کوچک و تمیز برای نمایش شاخه‌ها و تاریخچه مرج نشان می‌دهد:

$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 Ignore errors from SIGCHLD on trap
*  5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Add method for getting the current branch
* | 30e367c Timeout code and tests
* | 5a09431 Add timeout protection to grit
* | e1193f8 Support for heads with slashes in them
|/
* d6016bc Require time for xmlschema
*  11d191e Merge branch 'defunkt' into local

مادامی که وارد فصل بعدی که درباره برنچ‌ها و مرج است این نوع خروجی بیشتر مورد پسند واقع خواهد شد.

آنها تنها چند آپشن ساده برای خروجی با فرمت متفاوت هستند که در دستور git log مورد استفاده قرار می‌گیرد — تعداد خیلی بیشتری از این آپشن‌ها وجود دارد. آپشن‌های معمول git log آپشن‌هایی را که تا به اینجا بررسی کردیم، بعلاوه چندی فرمت آپشن معمول دیگر را که ممکن است برایتان مفید باشد را به همراه اینکه چطور خروجی دستور لاگ را تغییر می‌دهد را لیست می‌کند.

جدول 2. آپشن‌های معمول git log
آپشن‌ها توضیحات

-p

پچ‌های معرفی شده با هر کامیت را نشان بده.

--stat

آمار‌های فایل‌های ویرایش‌شده در هر کامیت را نشان بده.

--shortstat

فقط خطوط تغییریافته/اضافه‌شده/حذف‌شده را از دستور --stat نشان بده.

--name-only

لیست فایل‌های ویرایش‌شده را پس از اطلاعات کامیت نشان بده.

--name-status

لیست فایل‌های تأثیرگرفته را نیز با اطلاعات اضافه‌شده/ویرایش‌شده/حذف‌شده نشان بده.

--abbrev-commit

فقط چند حرف اول چک‌سام SHA-1 را به جای هر ۴۰ حرف آن نشان بده.

--relative-date

جای استفاده از قالب کامل تاریخ، آن را با قالب نسبی نمایش بده (به طور مثال «دو هفته پیش»).

--graph

یک گراف ASCII از برنچ‌ها و تاریخچهٔ مرج در کنار خروجی لاگ نمایش بده.

--pretty

کامیت‌ها را با حالت جایگزین نشان بده. دارای آپشن‌های، short، full، fuller و format (که در آن می‌توانید قالب خودتان را تعیین کنید).

--oneline

کوتاه‌شدهٔ --pretty=oneline --abbrev-commit که با هم استفاده می‌شوند.

محدود کردن خروجی لاگ

علاوه‌بر انواع آپشن‌های فرمت‌ خروجی، git log چندین آپشن محدودکننده مفید قبول می‌کند؛ این آپشن‌ها به شما این اجازه را می‌دهند که فقط یک زیرمجموعه از کامیت‌ها را ببینید. کمی قبل‌تر یکی از این آپشن‌ها را دیده بودید — آپشن -2 که دو کامیت آخر را نشان می‌داد. در حقیقت می‌توانید -<n> را وارد کنید که در آن n یک عدد برای نمایش n کامیت آخر است. در واقعیت، کم پیش می‌آید که از آن استفاده کنید، چراکه خود گیت به صورت پیش‌فرض همه‌ٔخروجی‌ها را به یک صفحه‌بند پایپ می‌کند تا شما فقط یک صفحه خروجی لاگ را در لحظه ببینید. با این حال، آپشن‌های محدودکننده زمان مانند --since و --until بسیار مفید هستند. برای مثال، این دستور لیست کامیت‌های ساخته شده در دو هفتهٔ گذشته را نشان می‌دهد:

$ git log --since=2.weeks

این دستور با انواع زیادی از قالب‌ها کار می‌کند — شما می‌توانید تاریخی معیین مانند "2008-01-15" یا تاریخی نسبی مانند "2 years 1 day 3 minutes ago" تعیین کنید.

همچنین این امکان را دارید که لیست کامیت‌ها را با الگوهای جستوجو فیلتر کنید و فقط یافته‌های مطابق با الگو یا شرط را ببینید. آپشن --author این اجازه را به شما می‌دهد که کامیت‌های یک نویسنده مشخص را فیلتر و آپشن --grep به شما این امکان را می‌دهد که به دنبال کلماتی کلیدی در پیام‌های کامیت‌ها بگردید.

یادداشت

می‌توانید بیش از یک نمونه از هر دو آپشن‌های --author و --grep برای معیار جست‌وجو تعیین کنید، که خروجی کامیت‌ها را به آنهایی محدود می‌کند که دارای هر نوع الگو مطابق با آپشن‌های --author و --grep باشند؛ با این حال اضافه کردن آپشن --all-match خروجی را به کامیت‌هایی محدود می‌کند که با تمام الگو‌های --grep تطبیق پیدا کنند.

یکی دیگر از فیلترهای مفید آپشن -S است (به طور محاوره‌ای به آن آپشن «pickaxe» گیت گفته می‌شود)، که یک رشته می‌گیرد و فقط کامیت‌هایی را نشان می‌دهد که تعداد این رشته را در خود تغییر داده‌اند. برای نمونه، اگر بخواهید که آخرین کامیتی که رفرنسی به یک تابع خاص را حذف یا اضافه کرده است پیدا کنید،‌ می‌توانید اینگونه فراخوانی کنید:

$ git log -S function_name

آخرین آپشن مفید که می‌توانید به git log بدهید، یک فیلتر مسیر است. اگر یک پوشه یا نام یک فایل را مشخص کنید، می‌توانید خروجی را به کامیت‌هایی محدود کنید که تغییری را به آن فایل‌ها معرفی کرده‌اند. این آپشن همیشه آخرین آپشن است و معمولاً با دو خط تیره (--) برای جدا سازی آدرس از آپشن‌ها استفاده می‌شود.

در آپشن‌های محدودکننده خروجی git log برای مراجعه شما این‌ها را بعلاوه چندی دیگر از آپشن‌های رایج لیست می‌کنیم.

جدول 3. آپشن‌های محدودکننده خروجی git log
آپشن‌ها توضیحات

-<n>

فقط تعداد n کامیت آخر را نشان بده

--since, --after

کامیت‌ها را به آنهایی که پس از تاریخ تعیین شده ساخته شده‌اند محدود کن

--until, --before

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

--author

فقط کامیت‌هایی را نشان بده که نویسندهٔ آنها با رشته متن تعیین شده تطبیق دارد

--committer

فقط کامیت‌هایی را نشان بده که کامیت‌کننده آنها با رشته متن تعیین شده تطبیق دارد

--grep

فقط کامیت‌هایی را نشان بده که پیام کامیت آنها رشته متن تعیین شده را داشته باشد

-S

فقط کامیت‌هایی را نشان بده که رشته متن تعیین شده در آنها حذف یا اضافه شده باشد

به عنوان مثال، اگر می‌خواهید ببینید چه کامیت‌هایی فایل‌های تست درون تاریخچهٔ سورس کد گیت را ویرایش کرده‌اند که توسط Junio Hamano در ماه اکتبر ۲۰۰۸ گرفته شده‌اند و مرج کامیت نیستند، می‌توانید چنین چیزی را اجرا کنید:

$ git log --pretty="%h - %s" --author='Junio C Hamano' --since="2008-10-01" \
   --before="2008-11-01" --no-merges -- t/
5610e3b - Fix testcase failure when extended attributes are in use
acd3b9e - Enhance hold_lock_file_for_{update,append}() API
f563754 - demonstrate breakage of detached checkout with symbolic link HEAD
d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths
51a94af - Fix "checkout --track -b newbranch" on detached HEAD
b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch

از ۴۰،۰۰۰ هزار کامیت در تاریخچه سورس کد گیت، این دستور ۶ مورد مطابق الگوهای مورد نظر را نشان داد.

نکته
جلوگیری از نمایش مرج کامیت‌ها

بسته به روند کاری مورد استفاده در مخزن شما، این امکان وجود دارد که درصد قابل توجهی از کامیت‌ها فقط مرج کامیت باشند که اطلاعات خاصی را ارائه نمی‌کنند. برای جلوگیری از نمایش مرج کامیت‌هایی که تاریخچهٔ لاگ شما را به هم می‌ریزند، کافیست آپشن لاگ --no-merges را اضافه کنید.