٢، ٣، رؤية تاريخ الإيداعات

بعدما صنعت عددًا من الإيداعات، أو استنسخت مستودعًا ذا تاريخ من الإيداعات بالفعل، قد تود الالتفات إلى الماضي ورؤية ماذا حدث. أسهل وأقوى أداة لفعل هذا هي أمر السجل 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 فقط، فإنه بطبيعته يسرد لك الإيداعات التي في هذا المستودع بترتيب زمني عكسي؛ أيْ أن الإيداع الأحدث يظهر أولًا. كما ترى، يسرد هذا الأمر كل إيداع مع بصمته واسم مؤلفه وعنوان بريده الشابكي وتاريخ الإيداع ورسالته.

يتيح أمر السجل عددًا عظيمًا متنوعًا من الخيارات لتُظهر بالضبط ما تريد. سنعرض لك هنا بعضًا من أشهرها.

واحد من أكثر الخيارات إفادةً هو -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

يعرض هذا الخيار المعلومات نفسها أيضا ولكن مع إتباع كل بيان بالفروقات. هذا مفيد جدا لمراجعة الرُّقَع (‪“code review”‬) أو للنظر السريع فيما حدث في سلسلة من الإيداعات التي أضافها زميل. ولدى أمر السجل كذلك عددًا من خيارات التلخيص. فمثلا إذا أردت رؤية إحصاءات مختصرة عن كل إيداع، جرّب خيار الإحصاء --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 («صياغة»)، التي تتيح لك تعيين صيغة ناتج السجل بدقة. هذا مفيد خصوصًا عندما تولّد ناتجًا لكي يقرؤه ويحلله برنامج أو بُريمج (script) — فلأنك تعيّن الصيغة بصراحة ووضوح، فإنك تطمئن أنها لن تتغيّر مع تحديثات جت.

$ 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:

جدول ١. متغيرات مفيدة لصياغة السجلات باستخدام git log --pretty=format
المتغير وصف الناتج

%H

بصمة الإيداع

%h

بصمة الإيداع المختصرة

%T

بصمة الشجرة

%t

بصمة الشجرة المختصرة

%P

بصمات الآباء

%p

بصمات الآباء المختصرة

%an

اسم المؤلف

%ae

بريد المؤلف

%ad

تاريخ التأليف (الصيغة تتبع --date=option)

%ar

تاريخ التأليف، نسبي

%cn

اسم المودِع

%ce

بريد المودِع

%cd

تاريخ الإيداع

%cr

تاريخ الإيداع، نسبي

%s

الموضوع (عنوان رسالة الإيداع)

ربما تتساءل عن الفرق بين المؤلف والمودِع. المؤلف هو من كتب العمل في الأصل، والمودِع هو من طبّـق العمل في النهاية. فمثلا إذا أرسلت رقعة إلى مشروع، وطبّـقها أحد الأعضاء الأساسيين، فيجب الاعتراف بالفضل لكليكما: أنت مؤلفًا، والعضو الأساسي مودِعًا. سنتناول هذا التمييز بالتفصيل في باب جت المتوزع.

القيمتان oneline و format مفيدتان خصوصًا مع خيار آخر لأمر السجل يسمى «رسم» --graph. يضيف هذا الخيار رسمًا لطيفًا بالمحارف لإظهار تاريخ التفريع والدمج.

$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 Ignore errors from SIGCHLD on trap
*  5e3ee11 Merge branch 'master' of https://github.com/dustin/grit.git
|\
| * 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 اليسيرة؛ متاح عدد أكبر من ذلك كثيرًا. يسرد جدول خيارات شائعة لأمر السجل الخيارات التي تناولناها حتى الآن، وكذلك بعض خيارات التنسيق الشائعة الأخرى التي قد تفيد، إضافةً إلى كيفية تغيير ناتج أمر السجل.

جدول ٢. خيارات شائعة لأمر السجل
الخيار الوصف

-p

أظهر الرقعة التي أتى بها كل إيداع.

--stat

أظهر إحصاءات الملفات المعدّلة في كل إيداع.

--shortstat

اعرض فقط سطر التعديلات/الإضافات/الإزالات من أمر --stat.

--name-only

اسرد أسماء الملفات المعدلة بعد كل إيداع.

--name-status

اسرد أسماء الملفات مرفقة بحالتها: معدّل/مضاف/م‍زال.

--abbrev-commit

أظهر فقط الحروف القليلة الأولى من البصمة، بدلًا من الأربعين جميعًا.

--relative-date

اعرض التاريخ بصيغة نسبية (مثلا ‪“2 weeks ago”‬) بدلا من صيغة التاريخ الكاملة.

--graph

اعرض رسمًا بالمحارف لتاريخ التفريع والدمج بجانب ناتج السجل.

--pretty

اعرض الإيداعات بصيغة أخرى. قيم الخيار المتاحة تشمل oneline و short و full و fuller و format (التي تتيح لك تحديد صياغتك المخصوصة).

--oneline

اختصار الخيارين --pretty=oneline --abbrev-commit معًا.

تقييد ناتج السجل

إضافةً إلى خيارات صياغة الناتج، يتيح أمر السجل عددًا من خيارات تقييد الناتج؛ أيْ إظهار جزء من الإيداعات فقط. لقد رأيت أحد هذه الخيارات بالفعل: خيار -2 الذي يُظهر آخر إيداعين فقط. الحقيقة أن استخدام -«ن»، حيث ن هو أي عدد صحيح موجب، يُظهر لك آخر ن إيداعًا. لن تحتاج هذا كثيرًا في الواقع، لأن جت بطبيعته يمرر الناتج كله إلى برنامج عرض (‪“pager”‬ مثل less) حتى ترى ناتج السجل صفحةً صفحة.

لكن خيارات التقييد بالزمن مثل --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 (المعروف بالاسم الدارج: خيار «فأس» جت)، الذي يُعطى سلسلة نصية ولا يظهر إلا الإيداعات التي عدّلت عدد مرات وجودها. فمثلًا إذا أردت إظهار آخر إيداع أضاف أو أزال إشارة إلى دالة معينة، يمكنك تنفيذ:

$ git log -S function_name

آخر خيار تصفية مفيد حقا لأمر السجل هو إعطاؤه مسار. فإذا أعطيته مجلدًا أو ملفًا، فإنه يقيّد ناتج السجل إلى الإيداعات التي عدّلت هذه الملفات. يكون هذا دائما آخر خيار وفي الغالب يُسبق بشرطتين (--) لفصل المسارات عن الخيارات:

$ git log -- path/to/file

نسرد في جدول خيارات تقييد ناتج أمر السجل هذه الخيارات وبعض الخيارات الأخرى حتى تكون مرجعًا لك.

جدول ٣. خيارات تقييد ناتج أمر السجل
الخيار الوصف

-«ن»

أظهر فقط آخر ن إيداعًا.

--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.