انتقل إلى المحتوى

الحالة

تحسب Pitmaster حالة شجرة العمل بمقارنة ثلاث حالات: شجرة الالتزام HEAD، والفهرس (منطقة التجهيز)، وشجرة العمل (الملفات الفعلية على القرص). وتطبع CLI ملخصًا بأسلوب git status، بينما تطبع statusPorcelainV2() تنسيق git porcelain v2.

الاستخدام الأساسي

PHP
$entries = $repo->status();

foreach ($entries as $entry) {
    echo $entry->shortFormat() . "\n";
}

تطبع shortFormat() التنسيق المختصر لـ git:

الكود
M  src/Modified.php          (staged modification)
 M src/WorktreeModified.php  (unstaged modification)
A  src/NewFile.php           (staged new file)
 D src/Deleted.php           (deleted in worktree)
?? untracked.txt             (untracked file)

StatusEntry

تُمثّل حالة كل ملف بواسطة StatusEntry:

PHP
use Pitmaster\Status\StatusEntry;

$entry->path;       // File path relative to repo root
$entry->index;      // FileStatus: HEAD-to-index state
$entry->worktree;   // FileStatus: index-to-worktree state
$entry->origPath;   // Original path for renamed entries, otherwise null
$entry->renameScore; // Similarity score for renamed entries, otherwise null
$entry->shortFormat(); // "XY path", "?? path", or "R  old -> new"

تعداد FileStatus

PHP
use Pitmaster\Status\FileStatus;

FileStatus::Added;      // 'A' - new file
FileStatus::Modified;   // 'M' - content changed
FileStatus::Deleted;    // 'D' - file removed
FileStatus::Renamed;    // 'R' - file renamed
FileStatus::Copied;     // 'C' - file copied
FileStatus::Unmerged;   // 'U' - unresolved merge conflict
FileStatus::Untracked;  // '?' - not in index
FileStatus::Ignored;    // '!' - matched by .gitignore
FileStatus::Unmodified; // ' ' - no change

لا تعرض status() الملفات المتجاهلة، لذا لا يظهر Ignored في نتيجتها.

مخرجات Porcelain v2

لإخراج حالة قابل للقراءة آليًا ومتوافق مع git status --porcelain=v2:

PHP
echo $repo->statusPorcelainV2();

المخرجات:

الكود
1 .M N... 100644 100644 100644 ce013625030ba8dba906f756967f9e9ca394464a ce013625030ba8dba906f756967f9e9ca394464a modified-file.txt
? untracked-file.txt

تأتي المدخلات المتعقبة أولًا، ثم غير المتعقبة. تستخدم عمليات إعادة التسمية أسطر 2، وتستخدم التعارضات أسطر u. لا تُطبع ترويسات # branch الخاصة بـ git status --porcelain=v2 --branch، ولا تُدرج الملفات المتجاهلة.

كيفية حساب الحالة

تجري الفئة WorkingTreeStatus المقارنة الثلاثية:

PHP
use Pitmaster\Status\WorkingTreeStatus;

$status = new WorkingTreeStatus($repo->objectDatabase(), $repo->workDir(), $repo->gitDir());
$entries = $status->compute($repo->index(), $repo->resolve('HEAD'));

الخطوة 1: إنشاء خريطة شجرة HEAD

تحوّل شجرة الالتزام HEAD إلى خريطة من path => blob hash. وتمثل هذه الخريطة آخر حالة جرى الالتزام بها.

الخطوة 2: مقارنة HEAD بالفهرس

لكل ملف في شجرة HEAD والفهرس:

  • موجود في HEAD وغير موجود في الفهرس: Deleted في عمود الفهرس
  • موجود في الفهرس وغير موجود في HEAD: Added في عمود الفهرس
  • موجود في كليهما مع اختلاف التجزئة: Modified في عمود الفهرس
  • موجود في كليهما مع تطابق التجزئة: Unmodified في عمود الفهرس

الخطوة 3: مقارنة الفهرس بشجرة العمل

لكل ملف في الفهرس وشجرة العمل:

  • موجود في الفهرس وغير موجود على القرص: Deleted في عمود شجرة العمل
  • موجود في كليهما مع اختلاف المحتوى: Modified في عمود شجرة العمل
  • موجود في كليهما مع تطابق المحتوى: Unmodified في عمود شجرة العمل

الخطوة 4: اكتشاف الملفات غير المتعقبة

افحص مجلد شجرة العمل، وتجاوز .git/ والمسارات المستثناة، وأبلغ عن الملفات غير الموجودة في الفهرس بوصفها Untracked في كلا العمودين.

دعم .gitignore

تحلل Pitmaster ملفات .gitignore لتحديد الملفات غير المتعقبة التي ينبغي الإبلاغ عنها بوصفها مستثناة أو غير متعقبة.

PHP
use Pitmaster\Status\GitIgnore;

تحلل الفئة GitIgnore أنماط gitignore من:

  • .gitignore في جذر المستودع
  • .gitignore في المجلدات الفرعية
  • .git/info/exclude

صياغة الأنماط المدعومة:

  • أنماط Glob (*.log، build/)
  • النفي (!important.log)
  • الأنماط الخاصة بالمجلدات (/ في النهاية)
  • / في البداية للأنماط النسبية إلى الجذر
  • ** للمطابقة التكرارية

تصنيف إدخالات الحالة

نمط شائع لعرض UI:

PHP
$staged = [];
$unstaged = [];
$untracked = [];

foreach ($repo->status() as $entry) {
    if ($entry->index === FileStatus::Untracked) {
        $untracked[] = $entry;
    } elseif ($entry->index !== FileStatus::Unmodified) {
        $staged[] = $entry;
    }

    if ($entry->worktree !== FileStatus::Unmodified
        && $entry->index !== FileStatus::Untracked
    ) {
        $unstaged[] = $entry;
    }
}

استخدام CLI

سطر الأوامر
./vendor/bin/pitmaster status

المخرجات:

الكود
On branch main

Changes to be committed:
	new file:   src/Feature.php

Changes not staged for commit:
	modified:   src/Existing.php

Untracked files:
	notes.txt

مراقبة نظام الملفات

تتضمن Pitmaster أداة مساعدة لبروتوكول fsmonitor في git:

PHP
use Pitmaster\Status\Fsmonitor;

يمكن للفئة Fsmonitor الاستعلام عن خطاف core.fsmonitor (مع الرجوع إلى فحص أوقات التعديل) لمعرفة الملفات التي تغيرت منذ رمز مميز. وتعطّل نفسها عند فتح المقابض باستخدام ['processes' => false]. لا تستدعيها status() حاليًا؛ إذ تقارن بيانات stat والمحتوى مباشرة.