شرح Git Diff: دليل كامل مع أمثلة

Git diff هو نافذتك لرؤية التغييرات التي تحدث في مستودع الشفرة الخاص بك. في جوهره، إنه أمر يظهر لك الاختلافات بين حالات مختلفة من ملفاتك – سواء كان ذلك بمقارنة عملك الحالي مقابل ما قمت بتجهيزه بالفعل أو مقارنة التغييرات بين الفروع والتعهدات. فكر فيه على أنه طريقة Git للإجابة على السؤال، “ما الذي تغير؟” عند تشغيلgit diff، يقوم Git بتحليل محتوى الملفات سطراً بسطر، محدداً ما تمت إضافته أو إزالته أو تعديله، ويقدم هذه المعلومات في شكل موحد يسلط الضوء بدقة على ما تغير وأين.

يساعد Git diff المطورين على ضمان جودة الشفرة عن طريق توفير رؤية واضحة للتعديلات قبل أن يتم تأكيدها. هنا، سنغطي كيفية استخدام هذا الأمر الأساسي بفعالية، من المقارنات الأساسية إلى التقنيات المتقدمة التي ستحسن سير العمل التطويري وتعاون الفريق.

المتطلبات الأولية

للمتابعة مع هذا الدليل، يجب أن تكون على دراية بهذه المفاهيم الخاصة بـ Git:

  • تدفق العمل الأساسي في Git (init, add, commit)
  • مستودعات Git وبنيتها
  • الفروع وكيفية عملها
  • التcommit والتاريخ الخاص به
  • منطقة الإعداد (index)

إذا كنت بحاجة إلى مراجعة هذه المفاهيم، ستساعدك هذه الموارد:

سوف تحتاج Git المثبت على نظامك لمتابعة الأمثلة. يمكن تشغيل جميع الأوامر في وحدة الطرفية أو موجه الأوامر.

لماذا يعتبر Git Diff أساسيًا للمطورين

يحتاج كل مطور إلى معرفة ما تغير في كوده، سواء كان يعمل بمفرده أو ضمن فريق يضم مئات الأشخاص. بدون git diff، ستتركك تخمينات حول السطور التي قمت بتعديلها، مما يجعل عملية الاستكشاف والتعاون تقريبًا مستحيلة.

Git diff ضروري لإدارة التغيير ويعتبر أساسًا لبناء البرمجيات عالية الجودة من خلال عمليات مراجعة فعالة. عند فحص التغييرات، يوفر git diff السياق اللازم لفهم ليس فقط ما تغير ولكن لماذا تلك التغييرات مهمة.

هذه الرؤية المباشرة في تطور الشفرة تساعد الفرق على الحفاظ على المعايير ومنع الأخطاء من الوصول إلى الإنتاج.

مع تعقيد المشاريع، يصبح git diff لا غنى عنه لعدة أسباب رئيسية:

  • التحقق من التغييرات:  تأكيد بالضبط ما ستقوم برفعه، مما يمنع الإدراج العرضي لشفرة تصحيح الأخطاء أو التغييرات غير المتعلقة
  • نقل المعرفة : افهم ما فعله زملاء الفريق دون الحاجة لقراءة الملفات بالكامل
  • حل النزاعات:  حدد بالضبط أين وكيف تتعارض التغييرات أثناء الدمج
  • تحليل تاريخي :  تتبع متى تم إدخال تغييرات معينة للبحث عن الأخطاء أو لفهم تطور الميزات
  • مراجعات الشيفرة المستهدفة: تركيز الاهتمام على أجزاء الشيفرة التي تغيرت فعليًا، مما يوفر الوقت ويحسن جودة المراجعة

لاستخدام git diff بفعالية، من الضروري فهم الهندسة المعمارية الأساسية التي تمكّن هذه المقارنات – نموذج “الثلاثة أشجار” في Git.

هندسة الثلاثة أشجار في Git

لفهم git diff، تحتاج أولاً إلى فهم الهندسة المعمارية الأساسية لـ Git والتي تُعرف بـ “ثلاثة أشجار”. على الرغم من الاسم، هذه ليست أشجار فعلية في نظام الملفات بل ثلاث حالات متميزة حيث تتواجد شيفرتك.

فكر في هذه الحالات على أنها ثلاث نسخ مختلفة من مشروعك التي يتتبعها Git في نفس الوقت: دليل العمل (الملفات الفعلية الخاصة بك)، منطقة التجهيز (أو الفهرس، حيث يتم تحضير التغييرات للتأكيد)، والمستودع (تاريخ مشروعك المؤكد المخزن في الدليل .git).

المصدر: Hashnode

يحتوي دليل العمل على الملفات التي تقوم بتحريرها بنشاط – هذا هو المكان الذي تكتب فيه الشفرة، وتجري التغييرات، وتختبر عملك. تعمل منطقة التجهيز كمنطقة تحضير حيث تختار فيها التغييرات التي يجب تضمينها في التأكيد القادم الخاص بك. يمكنك التفكير فيها كمحطة تحميل حيث يتم تنظيم الحزم (التغييرات الخاصة بك) قبل الشحن.

أخيرًا، يخزن المستودع السجل الكامل لمشروعك كسلسلة من التعهدات، وهي لقطات لرمزك في نقاط زمنية محددة، مرتبطة معًا لتشكيل سلسلة تاريخية.

يعمل Git diff عن طريق مقارنة هذه الحالات الثلاث في تركيبات مختلفة. عند تشغيل git diff بدون وسيطات، يقارن دليل العمل الخاص بك بمنطقة التجميع، مبينًا التغييرات التي قمت بها ولم تقم بتجميعها بعد.

باستخدام git diff --staged يقارن منطقة التجميع بآخر تعهد، مبينًا ما سيتم تضمينه في التعهد القادم الخاص بك.

و git diff HEAD يقارن دليل العمل الخاص بك مباشرةً مع آخر التزامات، ويظهر جميع التغييرات غير الملتزم بها بغض النظر عن حالة الإعداد.

تشكل هذه نقاط المقارنة الأساس لجميع عمليات الفرق في Git:

  • دليل العمل ↔ منطقة الإعداد: ما التغييرات التي قمت بها ولكن لم أقم بإعدادها بعد؟ (git diff)
  • المنطقة التجريبية ↔ المستودع: ما هي التغييرات التي قمت بتجميعها وستتم تأكيدها لاحقًا؟ (git diff --staged)
  • الدليل العامل ↔ المستودع: ما هو الفرق الكلي بين ملفاتي العاملة وآخر تأكيد؟ (git diff HEAD)
  • بين التعهدات: كيف تطورت الشفرة بين نقاط محددة في التاريخ؟ (git diff commit1-hash commit2-hash)

فهم هذه الهندسة يمنحك النموذج الذهني اللازم لاستخدام git diff بفعالية لتحديد بالضبط ما تغير، وأين، ومتى في قاعدة بيانات الشفرة الخاصة بك.

بعد فهم هذه الهندسة، يمكننا الآن استكشاف كيفية استخدام أوامر git diff في الممارسة لاكتساب رؤى حول تطور الشفرة عبر هذه الحالات الثلاث.

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

لنقم بإنشاء مشروع تحليل بيانات نموذجي لتوضيح كيفية عمل git diff. سنقوم بإعداد مستودع صغير يحتوي على سكربتات بايثون وبيانات CSV وملفات نصية يمكننا تعديلها طوال هذا الدليل.

# إنشاء وتهيئة مشروعنا mkdir data-analysis-project cd data-analysis-project git init # إنشاء الملفات الأولية echo "# Data Analysis Project\nA sample project to demonstrate git diff functionality." > README.md echo "import pandas as pd\n\ndef load_data(filename):\n return pd.read_csv(filename)\n\ndef analyze_data(data):\n return data.describe()" > analysis.py echo "id,name,value\n1,alpha,10\n2,beta,20\n3,gamma,30" > data.csv echo "DEBUG=False\nDATABASE_PATH=./data/" > config.txt echo "def normalize_data(data):\n return (data - data.min()) / (data.max() - data.min())" > utils.py # إجراء أول عملية التزام git add . git commit -m "Initial commit with basic project structure" # فحص هيكل الدليل > tree . ├── README.md ├── analysis.py ├── config.txt ├── data.csv └── utils.py

مشروعنا الآن يحتوي على خمسة ملفات تحت التحكم في الإصدار، مما يوفر لنا أساسًا لتوضيح سيناريوهات diff المختلفة. مع تقدمنا، سنقوم بتعديل هذه الملفات لإظهار كيف يكشف git diff عن التغييرات في سياقات مختلفة.

فهم نتائج git diff

عند تشغيل أمر git diff، يتبع الناتج تنسيقًا موحدًا مصممًا للإشارة بوضوح إلى ما تم تغييره. دعونا نقم بتعديل ملف analysis.py لنرى عملية diff في العمل:

# تحديث analysis.py بدالة جديدة echo "import pandas as pd\n\ndef load_data(filename):\n return pd.read_csv(filename)\n\ndef analyze_data(data):\n return data.describe()\n\ndef visualize_data(data):\n return data.plot(kind='bar')" > analysis.py

الآن دعونا نفحص الناتج الناتج عن git diff:

git diff

سترى ناتجًا مشابهًا لهذا:

ملاحظة: للخروج من ناتج git diff، اضغط على “q” في جهازك الطرفي.

دعونا نفصل هذا الناتج:

  1. الرأس (diff --git a/analysis.py b/analysis.py) يظهر أي ملف يتم مقارنته، وهو analysis.py
  2. المعلومات الوصفية للملف (index db0e049..a7a7ab0 100644) تظهر معرفات Git الداخلية للنسخ قبل وبعد
  3. العلامات الملفات (--- a/analysis.py and +++ b/analysis.py) تشير إلى الملفين “قبل” و “بعد”
  4. العنوان للقطعة (@@ -5,3 +5,6 @@) يُظهر الأسطر التي تم تأثيرها. يمكن تفسير هذا العلامات على أنها:
  • -5,3 يعني ابتداءً من السطر 5 في الملف الأصلي، يتم عرض 3 أسطر في التغيير
  • +5,6 يعني ابتداءً من السطر 5 في الملف المعدل، يتم عرض 6 أسطر في التغيير
  • الفارق بين هذه الأرقام يشير إلى أنه تمت إضافة 3 أسطر

5. تغيير المحتوى بالأسطر التي تبدأ بـ+ تظهر الإضافات

في الملفات الأكبر، يقوم git diff بتجميع التغييرات في “كتل” – أقسام من الملف تحتوي على تغييرات. كل كتلة تحتوي على رأس خاص بها مع أرقام الأسطر لمساعدتك في تحديد مواقع التغييرات في الملف.

مقارنة دليل العمل ومنطقة الإعداد

تشغيل git diff بدون أي معلمات يقارن دليل العمل الخاص بك (الحالة الحالية للملفات) بمنطقة الإعداد (التغييرات الجاهزة للتأكيد). هذا مفيد لمراجعة ما قمت بتغييره ولكنك لم تقم بعد بإعداده لتأكيدك التالي.

دعنا نعدل عدة ملفات لإظهار ذلك:

# تحديث README.md echo "# Data Analysis Project\nA sample project to demonstrate git diff functionality.\n\n## Installation\nRun \pip install -r requirements.txt" > README.md # تحديث data.csv echo "id,name,value\n1,alpha,10\n2,beta,20\n3,gamma,30\n4,delta,40" > data.csv

الآن دعنا نقوم بإعداد تغييرات README.md فقط:

git add README.md

تشغيل git diff الآن سيظهر فقط التغييرات غير المضافة إلى data.csv وملف analysis.py أعلاه:

هذا يساعدك على التركيز على ما لم تقم بإضافته بعد. إذا كنت ترغب في رؤية ما قمت بإضافته بالفعل:

git diff --staged # or git diff --cached (they're synonyms)

سيظهر هذا التغييرات في README.md التي تم إضافتها وجاهزة للتأكيد. هذه العمليات ضرورية لبناء تأكيدات نظيفة ومنطقية. يمكنك إضافة أجزاء من عملك التي تتناسب معًا، مراجعة الفرق المضاف للتحقق من أنها وحدة تغيير متماسكة، ثم تأكيدها.

مقارنة منطقة الإضافة وآخر تأكيد

يعمل الأمر git diff --staged على مقارنة منطقة التحضير الخاصة بك مع آخر التزاماتك. هذا يظهر لك بالضبط ما سيتم تضمينه في التزامك التالي إذا قمت بتشغيل git commit الآن.

لنقم بتحضير التغييرات في data.csv ونفحص ما تم تحضيره:

git add data.csv git diff --staged

ستظهر المخرجات الآن التغييرات في كل من README.md و data.csv، حيث تم تحضير كلاهما. تعتبر هذه الخطوة من المراجعة حاسمة قبل الالتزام – فهي تعمل كخط الدفاع الأخير ضد الالتزام بالتغييرات غير المقصودة.

قد يبدو سير العمل الشائع كما يلي:

  1. قم بإجراء تغييرات على عدة ملفات
  2. قم بتشغيل git diff لمراجعة جميع التغييرات
  3. استخدم git add <file> بشكل انتقائي لتجميع مجموعات من التغييرات المنطقية
  4. قم بتشغيل git diff --staged للتحقق مما هو على وشك أن يتم الالتزام به
  5. قم بالتزام التغييرات المجمعة باستخدام git commit -m "رسالتك"
  6. كرر ذلك لمجموعات أخرى من التغييرات المنطقية

تساعد هذه الطريقة المنهجية في الحفاظ على تاريخ التزام نظيف وذو معنى، مما يسهل فهم كيفية تطور مشروعك وتحديد مكان ظهور المشكلات. مع اكتسابك الخبرة، ستصبح أوامر الفرق هذه طبيعة ثانية، مما يجعلها رفقاءك الدائمين في عملية التطوير.

دعنا نقوم بعمليات الالتزام قبل الانتقال إلى المرحلة التالية:

# سيتم الالتزام بملف data.csv و README.md git commit -m "Modify data.csv and README.md files" # تحليل stage والالتزام بملف analysis.py git add analysis.py git diff --staged # Review the changes one more time git commit -m "Add a new function to analysis.py"

تقنيات Git Diff المتوسطة

الآن بعد أن فهمنا أساسيات git diff، دعنا نستكشف تقنيات أكثر قوة ستعزز قدرتك على تتبع وتحليل التغييرات في مشاريعك. سنواصل العمل مع مشروع تحليل البيانات لدينا لتوضيح هذه المفاهيم المتوسطة.

المقارنة بين المراجع المختلفة

تم بناء Git حول مفهوم المراجع – مؤشرات إلى حالات محددة من شفرتك. تشمل هذه المراجع الفروع، والالتزامات، والتسميات. يمكن لأمر git diff مقارنة أي اثنين من هذه المراجع لإظهار ما تغير بينهما.

دعنا ننشئ فرعًا جديدًا لتطوير ميزة معينة ونقوم ببعض التغييرات:

# إنشاء والتبديل إلى فرع جديد git checkout -b feature/advanced-analytics # تعديل ملف analysis.py بوظيفة جديدة echo "import pandas as pd import numpy as np def load_data(filename): return pd.read_csv(filename) def analyze_data(data): return data.describe() def visualize_data(data): return data.plot(kind='bar') def perform_advanced_analysis(data): """Performs advanced statistical analysis on the dataset""" results = {} results['correlation'] = data.corr() results['skew'] = data.skew() return results" > analysis.py # تنفيذ التغييرات git add analysis.py git commit -m "Add advanced analysis function"

الآن يمكننا مقارنة فرع الميزة الخاص بنا بالفرع الرئيسي:

git diff main feature/advanced-analytics

هذا الأمر يعرض جميع الاختلافات بين الفرعين – كل ملف تم تعديله أو إضافته أو حذفه. سترى التغييرات التي قمنا بها في ملف analysis.py، بما في ذلك وظيفتنا الجديدة والواردات الجديدة (اضغط عدة مرات على مفتاح الإدخال حيث يتم قص الفارق الكامل في الطرفية).

لمقارنة مع تعيين معين، يمكنك استخدام تعيين التعهد:

git log --oneline # Find the commit hash you want to compare with

git diff 7b3105e # Replace 7b3105e with the actual commit hash you want to compare

تصبح هذه القدرة على المقارنة لا تقدر بثمن عندما:

  • الاستعداد لمراجعات الشفرة من خلال رؤية جميع التغييرات في فرع الميزة
  • التحقق من التغييرات التي سيقدمها فرع زميل قبل الدمج
  • فهم كيف تطورت قاعدة الشيفرة الخاصة بك بين الإصدارات أو النسخ

مقارنة ملفات معينة

عند العمل مع مستودعات كبيرة، غالبًا ما ترغب في التركيز على التغييرات في ملفات أو دلائل محددة بدلاً من رؤية جميع الاختلافات. يجعل Git diff هذا سهلاً من خلال السماح لك بتحديد المسارات.

لنقم بتغييرات على ملفات متعددة:

# تحديث ملف config.txt echo "DEBUG=True DATABASE_PATH=./data/ LOG_LEVEL=INFO" > config.txt # تحديث ملف utils.py echo "def normalize_data(data): return (data - data.min()) / (data.max() - data.min()) def clean_data(data): return data.dropna()" > utils.py

لرؤية التغييرات في ملف config فقط:

git diff config.txt

أو لمقارنة ملف معين بين الفروع:

# مقارنة ملف analysis.py بين الفرعين main و feature/advanced-analytics git diff main feature/advanced-analytics -- analysis.py

ال-- في الأمر أعلاه يساعد Git في التمييز بين المراجع ومسارات الملفات. وهذا مفيد بشكل خاص عندما:

  • العمل في مستودعات تحتوي على العديد من الملفات ولكن التركيز على مكونات محددة (وهذا سيحدث في كثير من الأحيان)
  • فحص كيفية تغيير التكوين عبر الفروع
  • مراجعة فقط الملفات الأكثر أهمية في مجموعة كبيرة من التغييرات

خيارات الفارق السياقي

يوفر Git diff العديد من الخيارات لضبط كيفية عرض الفروقات، مما يجعل من الأسهل التركيز على التغييرات المعنوية.

على سبيل المثال، عند التعامل مع تغييرات تنسيق الشفرة، يمكن أن تخفي الفروقات في المسافات التغييرات الدلالية المهمة. لنقدم ذلك بتغيير في التنسيق:

# قم بتغيير في المسافات في analysis.py sed -i '' 's/ return/ return/g' analysis.py # Reduce indentation

الآن، عند المقارنة باستخدام git diff القياسي يُظهر تغييرات في المسافات (لاحظ كيف تم تنسيق عبارات العودة بشكل غير صحيح):

git diff analysis.py # OUT: --- a/analysis.py +++ b/analysis.py @@ -2,17 +2,17 @@ import pandas as pd import numpy as np def load_data(filename): - return pd.read_csv(filename) + return pd.read_csv(filename) def analyze_data(data): - return data.describe() + return data.describe() def visualize_data(data): - return data.plot(kind='bar') + return data.plot(kind='bar') def perform_advanced_analysis(data): Performs advanced statistical analysis on the dataset results = {} results['correlation'] = data.corr() results['skew'] = data.skew() - return results + return results

ولكن يمكننا تجاهل تغييرات المسافات (يُظهر ذلك عدم وجود تغييرات حيث أننا قمنا فقط بإزالة مسافات):

git diff -w analysis.py # or --ignore-all-space

خيار مفيد آخر هو التحكم في خطوط السياق – الأسطر غير المتغيرة المعروضة حول التعديلات:

git diff -U1 analysis.py # Show only 1 line of context (default is 3) git diff -U5 analysis.py # Show 5 lines of context

هذه الخيارات السياقية قيمة بشكل خاص عندما:

  • تُراجع الشفرة التي مرت بتنسيق تلقائي
  • تركيزك على التغييرات الوظيفية بدلاً من التغييرات في الأسلوب
  • تحتاج إلى مزيد من السياق لفهم تغيير معين
  • العمل مع ملفات كبيرة حيث سينشأ السياق الافتراضي الكثير من الإخراج

من خلال اتقان هذه التقنيات المتقدمة، ستحصل على تحكم أدق في كيفية مراجعة وفهم التغييرات في قاعدة الشفرة الخاصة بك، مما يجعل سير عمل التطوير الخاص بك أكثر كفاءة ومراجعات الشفرة أكثر فعالية.

لنقم بتأكيد التغييرات الأخيرة قبل أن ننتقل إلى تطبيقات git diff المتقدمة:

git add . git commit -m "Modify analysis.py, config.txt, and utils.py"

تطبيقات Git Diff المتقدمة

بناءً على فهمنا لتقنيات git diff المتوسطة، دعونا نستكشف بعض التطبيقات المتقدمة التي سترتقي بمهاراتك في Git إلى المستوى التالي. هذه التقنيات المتقدمة مفيدة بشكل خاص عند العمل على قواعد الشفرات المعقدة أو التعاون مع فرق أكبر.

استخدام أدوات الفرق الخارجية

بينما يعد الفرق المدمج في Git قويًا، فإن أداة الفرق البصرية تقدم أحيانًا وضوحًا أفضل، خاصةً للتغييرات المعقدة. يسمح لك Git بتكوين أدوات خارجية لتعزيز تجربة الفرق الخاصة بك.

دعونا نثبت أداة فرق بصرية شهيرة. سنستخدم VSCode كمثال، ولكن تكوينًا مشابهًا يعمل لأدوات مثل Beyond Compare، Meld، أو KDiff3:

# تكوين Git لاستخدام VSCode كأداة فرق (خاصة بالمشروع) git config diff.tool vscode git config difftool.vscode.cmd "code --wait --diff \$LOCAL \$REMOTE" # لاستخدام أدوات شعبية أخرى، يمكنك استخدام: # لـ Beyond Compare (خاصة بالمشروع): git config diff.tool bc3 git config difftool.bc3.path "/path/to/beyond/compare" # أوامر التثبيت: # لـ Beyond Compare: # على macOS: brew install --cask beyond-compare # على Ubuntu: sudo apt-get install beyond-compare # على Windows: تحميل من https://www.scootersoftware.com/download.php # ملاحظة: لتطبيق هذه الإعدادات عالميًا بدلاً من مجرد المشروع الحالي، # أضف علامة --global إلى كل أمر، على سبيل المثال: # git config --global diff.tool vscode

الآن بدلاً من استخدام git diff، يمكنك استخدام:

git difftool main feature/advanced-analytics

سيفتح هذا أداة الفارق البصرية المكونة لديك لعرض التغييرات. إليك كيف يبدو Beyond Compare:

توفر أدوات الفارق البصري عدة مزايا:

  1. المقارنة جنبًا إلى جنب تجعل من السهل رؤية السياق
  2. تحديد بناء الجمل متماشي مع تفضيلات محرر النص
  3. التنقل المتقدم بين التغييرات
  4. القدرة على تحرير الملفات مباشرة أثناء مراجعة الفروقات

عند مراجعة تغييرات كبيرة أو ملفات بنية معقدة (مثل JSON المتداخل أو XML)، يمكن أن تحسن أدوات الفارق البصري بشكل كبير الفهم والكفاءة.

أوامر فارق متخصصة

يقدم Git أوامر فارق متخصصة تمنحك تحكمًا دقيقًا لحالات الاستخدام المحددة. دعنا نستكشف بعض هذه الأوامر القوية:

git diff-tree يفحص الفروقات بين كائنات الشجر (المجلدات):

# احصل على تجزء الهاش للتعديلين الأخيرين LAST_COMMIT=$(git rev-parse HEAD) PREV_COMMIT=$(git rev-parse HEAD~1) # عرض التغييرات في التعديل الأخير git diff-tree --patch $PREV_COMMIT $LAST_COMMIT

git diff-index يقارن دليل العمل مع الفهرس (منطقة الإيداع) أو شجرة:

# قارن دليل العمل مع الفهرس git diff-index --patch HEAD

git diff-index مفيد بشكل خاص للبرمجة النصية والتأتير. يسمح لك بفحص التغييرات التي سيتم تضمينها في التعهد التالي الخاص بك بشكل برمجي، مما يجعله قيمًا للهوكات قبل التعهد والنصوص التحققية.

على سبيل المثال، قد تستخدمه في خط أنابيب CI/CD للتحقق من أنه لم يتم تعديل ملفات معينة أو لضمان أن تغيرات التكوين تتبع أنماط محددة قبل السماح بالتعهدات.

git diff-files يظهر التغييرات بين الملفات في دليل العمل والفهرس:

# التحقق من الاختلافات في الملفات المحددة git diff-files --patch config.txt

تكون هذه الأوامر المتخصصة مفيدة بشكل خاص ل:

  • إنشاء سيناريوهات Git المخصصة والنصوص
  • تصحيح المشاكل في الأدوات الداخلية لـ Git
  • إجراء تحليل مستهدف لحالة المستودع
  • بناء أدوات التأتير التي تتفاعل مع Git

تحليل تاريخ الكود

إحدى التطبيقات الأكثر قوة لجت ديف هو تحليل تطور الكود مع مرور الوقت، الأمر الذي قد يكون حاسمًا لتصحيح الأخطاء أو فهم تطوير الميزات.

لنفحص تعهدًا محددًا باستخدام ^!تعليمة:

# احصل على تجزئة تعهد تحليلاتنا المتقدمة ANALYTICS_COMMIT=$(git log --oneline | grep "advanced analysis" | cut -d ' ' -f 1) # اعرض الإصلاحات المقدمة في هذا التعهد المحدد git diff $ANALYTICS_COMMIT^!

يعد ^!بناء الجملة اختصارًا لمقارنة تعهد بأبيه، موضحًا بالضبط ما تغير في هذا التعهد فقط.

لتتبع كيف تطور ملف محدد مع مرور الوقت:

# تحليل كيف تغير analysis.py خلال آخر 3 تعهدات git log -p -3 analysis.py

عند البحث عن خلل، يمكنك استخدام git diff مع git bisect:

# أضف خللا لتحاكي انحرافًا echo "import pandas as pd import numpy as np def load_data(filename): # خلل: إرجاع None عن طريق الخطأ بدلاً من البيانات pd.read_csv(filename) return None def analyze_data(data): return data.describe() def visualize_data(data): return data.plot(kind='bar') def perform_advanced_analysis(data): results = {} results['correlation'] = data.corr() results['skew'] = data.skew() return results" > analysis.py git add analysis.py git commit -m "Update analysis.py with a hidden bug" # الآن استخدم git bisect للعثور على متى تم إدخال الخطأ git bisect start git bisect bad # Mark current commit as containing the bug git bisect good main # Mark the main branch as working correctly # سيقوم Git بفحص التعهدات لك للاختبار # بمجرد العثور، يمكنك فحص التغيير الدقيق الذي أدى إلى الخطأ git diff HEAD^!

Git bisect هو أداة تصحيح أخطاء قوية تقوم بإجراء بحث ثنائي عبر سجل تعهيدك للعثور على التعهيد الذي قدم خطأ. بالاقتران مع git diff، ينشئ تدفق عمل فعال:

1. ابدأ عملية التقطيع باستخدام git bisect start

2. ضع العلامة على الالتزام الحالي كسيئ (يحتوي على الخطأ) باستخدام git bisect bad

3. ضع علامة على التزام معروف بأنه جيد (حيث لا يوجد الخطأ) باستخدام git bisect good <commit-hash>

4. يقوم Git تلقائيًا بتحديد التزام في منتصف تاريخك لاختباره.

5. بعد اختبار الالتزام الحالي، أخبر git بالنتيجة:

  • إذا كان الخطأ موجودًا في هذا الالتزام: git bisect bad
  • إذا لم يكن الخطأ موجودًا في هذا الالتزام: git bisect good

6. سيستمر Git في التحقق من الالتزامات المختلفة بناءً على ملاحظاتك (بعد كل git bisect bad/good أمر)، مما يضيق نطاق البحث في كل مرة. كرر عملية الاختبار والتوسيم حتى يتمكن Git من تحديد أول التزام سيء.

7. بمجرد أن يجد Git الالتزام المسبب للمشكلة، سيعرض رسالة تشير إلى الالتزام الذي أدخل الخطأ.

8. تحقق بالضبط مما تغير في الالتزام المحدد باستخدام: git diff HEAD^!

9. تُظهر لك هذه الأمر بالضبط أي كود تم تعديله في الالتزام الذي أدخل الخطأ، مما يسمح لك بتركيز جهود تصحيح الأخطاء على تلك التغييرات المحددة.

10. اخرج من عملية البحث التقسيمي في أي وقت باستخدام: git bisect reset ستعيدك إلى الفرع الذي كنت عليه قبل بدء عملية البحث التقسيمي.

11. يمكنك أيضًا أتمتة عملية البحث التقسيمي باستخدام: git bisect run <test-script> حيث هو أمر يعيد قيمة 0 للتعهدات الجيدة وقيمة غير صفرية للتعهدات السيئة.

تقلل هذه السير العمل من وقت تصحيح الأخطاء بشكل كبير، خاصة في رموز المصدر الكبيرة التي تحتوي على العديد من التعهدات بين حالات العمل والتالفة.

تقنيات تحليل التاريخ هذه لا تقدر بثمن ل:

  • العثور على متى ولماذا تم إدخال خطأ
  • فهم تطور ميزة أو مكون
  • مراجعة التغييرات لاستعراض الأمان
  • توثيق عملية اتخاذ القرار وراء تغييرات الكود

من خلال الاحتراف في تطبيقات git diff المتقدمة هذه، ستتمكن من تصفح تاريخ مشروعك بدقة، وتصحيح المشاكل بكفاءة أكبر، واكتساب رؤى أعمق حول تطور قاعدة الكود الخاصة بك.

مرجع أمر Git Diff

يقدم Git diff مجموعة واسعة من الخيارات لتخصيص مخرجاته وسلوكه لمواقف معينة. إليك مرجع شامل لأكثر المعلمات استخدامًا لتعزيز تحليلك التفاضلي:

خيارات المقارنة الأساسية

  • git diff – قارن بين دليل العمل ومنطقة الإعداد
  • git diff --staged (أو --cached) – قارن بين منطقة الإعداد وآخر التزام
  • git diff HEAD – قارن بين دليل العمل وآخر التزام
  • git diff <commit> – قارن بين دليل العمل والتزام محدد
  • git diff <commit1> <commit2> – قارن بين تعديلات تعيينتين محددتين
  • git diff <branch1> <branch2> – قارن بين فرعين

تحديد المسار

  • git diff -- <path> – قيد المقارنة إلى ملف أو دليل محدد
  • git diff --stat – عرض ملخص للتغييرات (الملفات التي تم تغييرها، الإضافات، الحذف)، خيار مفيد للتعديلات الكبيرة جدًا
  • git diff --name-only – عرض أسماء الملفات التي تم تغييرها فقط
  • git diff --name-status – عرض أسماء الملفات وحالتها (مضافة، معدلة، محذوفة) للملفات المتغيرة

عرض التحكم

  • git diff -w (أو –ignore-all-space) – تجاهل تغييرات المسافات البيضاء
  • git diff --ignore-space-change – تجاهل التغييرات في كمية المسافات البيضاء
  • git diff --color-words – عرض الفروقات على مستوى الكلمات بالألوان
  • git diff --word-diff – عرض الفروق على مستوى الكلمات بتنسيق مختلف
  • git diff -U<n> – عرض n أسطر من السياق (الافتراضي هو 3)
  • git diff --no-prefix – عدم عرض بادئات a/ و b/ في إخراج الفروق

تصفية المحتوى

  • git diff --binary – عرض التغييرات على الملفات الثنائية
  • git diff -S<string> – البحث عن التغييرات التي تضيف أو تحذف السلسلة المحددة
  • git diff -G<regex> – البحث عن التغييرات التي تتطابق مع نمط التعبير المنتظم المحدد
  • git diff --pickaxe-all – عند استخدام -S أو -G، أظهر جميع التغييرات في الملف، ليس فقط تلك التي تتطابق

خيارات التنسيق

  • git diff --patch-with-stat – إظهار الباتش وملخص الإحصاءات
  • git diff --compact-summary – عرض ملخص الإحصاءات بتنسيق مُدمج
  • git diff --numstat – عرض الإحصاءات بتنسيق صديق للآلة
  • git diff --summary – عرض ملخص الإنشاء/الحذف

يمكن دمج هذه الخيارات لإنشاء مقارنات قوية وموجهة. على سبيل المثال، لرؤية التغييرات على مستوى الكلمات في ملف معين مع تجاهل المسافات البيضاء:

git diff --color-words -w -- analysis.py

أو للعثور على جميع الأماكن التي قد تمت إضافة أو إزالة دالة معينة:

git diff -S"def perform_advanced_analysis" main feature/advanced-analytics

فهم هذه الخيارات يساعدك على تجاوز الضوضاء والتركيز بدقة على التغييرات التي تهم، مما يجعل مراجعة الكود وتحليل سير العمل لديك أكثر كفاءة. سواء كنت تبحث عن أخطاء، أو تستعد لطلب سحب، أو تحاول فقط فهم ما الذي تغير، فإن الخيار الصحيح في git diff يمكن أن يجعل مهمتك أسهل بكثير.

الخاتمة

على مدار هذه المقالة، استكشفنا الأمر git diff كأداة متعددة الاستخدامات لرؤية تغييرات الكود. تناولنا مقارنة الملفات العاملة مقابل التغييرات المهيأة، وفحص الاختلافات بين الفروع والتغييرات، واستخدام أوامر متخصصة للحصول على رؤى أعمق. يساعد دمج git diff في سير العمل الخاص بك على بناء تغييرات أنظف، واكتشاف المشكلات مبكرًا، وتسهيل مراجعات الكود بشكل أفضل.

سواء كنت تعمل بمفردك أو في فريق، فإن إتقان git diff يرفعك من مجرد كتابة الكود إلى فهم كيف يتطور قاعدة الكود الخاصة بك مع مرور الوقت.

للاستمرار في تعزيز خبرتك في Git، تحقق من هذه الموارد القيمة:

سيساعدك هذه الموارد في بناء ما تعلمته حول git diff ورفع مستوى احترافية التحكم بالإصدارات إلى المستوى التالي.

Source:
https://www.datacamp.com/tutorial/git-diff-guide