أساسيات الـ Git لتتبع التغييرات في المشاريع
السلام عليكم ورحمة الله وبركاته
يمكنك متابعة السلسلة بالترتيب أو الانتقال مباشرة إلى أي مقال:
المقدمة
اليوم لدينا مقالة دسمة إلى حد ما، سأتكلم في هذه المقالة عن الـ Git وكيف يعمل وكيف نستفيد منه ونستخدمه وما أهم الأوامر الخاصة به
وكيف يفيدنا في تنظيم مشاريعنا وتنظيم طريق العمل ضمن فريق
في هذه المقالة سأركز على الـ Git في بيئة عمل Local أي على جهازك الشخصي
وسأشرح الأساسيات التي تحتاجها لكي تبدأ في استخدامه
ثم في مقالة أخرى سنتكلم عن أوامر أكثر مثل git reset و git checkout و git stash وغيرها
ويمكنكم قراءتها من هنا تكملة أوامر الـ Git والتحكم بالـ HEAD
ثم في مقالة أخرى سنتكلم عن مفهوم الـ Branch
ويمكنكم قراءتها من هنا Git Branches آلة السفر عبر الأبعاد
ثم في مقالة أخرى سنتطرق لجزء الـ Remote الخاص بالـ Git وكيف نتعامل مع GitHub وكل تلك الأمور إن شاء الله
يمكنكم قراءتها من هنا التعامل مع Remote Repository وموقع GitHub
ما هو الـ Git
الـ Git هو باختصار آلة السفر بين الزمن والأبعاد ... أقصد أنه أشهر Version Control System
بمعنى أنه نظام متكامل تم إنشاؤه لتنظيم وإدارة المشروعات بسلاسة ويسجل كل التغيرات والإضافات التي حدثت لمشروع على مر الزمن
بعض من أهم ما يقدمه:
- يتابع تاريخ المشروع بالكامل عبر الزمن، بما في ذلك على سبيل المثال الإضافات والتعديلات وما الذي تم حذفه
والإشارة إلى من قام بالتغير ومتى قام به - يمكن أيضا استخدام
Gitكآلة للسفر عبر الزمن، حيث يمكنك العودة إلى نسخة قديمة من مشروعك في أي وقت ومقارنة التعديلات السابقة بالحالية - من بين أهم مزاياه أيضا أنه يمكنك استنساخ المشروع لعدة نسخ، وكل نسخة تطور فيها وتعدل وتفعل ما تريده دون أن تأثر على نسخة المشروع الأساسية
- أو تقسم العمل ضمن الفريق حيث يمكن لكل عضو العمل على نسخته من الكود في فرع مختلف بشكل مستقل عن باقي الفريق
(... همس: قلت لك أنه جهاز سفر عبر الأبعاد)
سنتكلم عن كل هذه التفاصيل وأكثر
كيف يتعامل الـ Git مع مشروعك ؟
هناك عدة مراحل يتخذها الـ Git للتنقل الحالات المختلفة لمشروعك والتعديلات
وهذه المراحل مهمة جدًا في أن تستوعبها وتفهمها جيدًا لأنها ستكون أساس كل شيء سنشرحه في باقي هذه المقالة
ملحوظة: أول شيء عليك معرفته هو أن الـGitينشيء مجلد يدعى.gitداخل المشروع الخاص بك
وهو المنزل الخاص بـGitالذي يضم كل شيء متعلق به
بما في ذلك الـLocal RepositoryوالـStaging AreaوStashوكل شيء متعلق ويستخدمه الـGit
Working Directory
الـ Working Directory وأيضًا يطلق عليه الـ Working Tree
هو المجلد الأساسي الذي يحتوي على ملفات المشروع على جهازك
Local Repository
الـ Local Repository هو مستودع يستخدمه الـ Git ليحتفظ ويتابع التعديلات الموجودة في الـ Working Directory الخاص بك على جهازك
ويطلق عليه عدة مسميات مثل Git Repository أو Git Directory أو Git History
Upstream Repository
الـ Upstream Repository أو الـ Remote Repository
هو كالـ Local Repository لكنه نسخة رئيسية من المشروع يتم استضافتها في مكان ما على الانترنت مثل GitHub أو GitLab أو غيرهم كثير
ويسهل العمل مع فريق من أماكن مختلفة ويقدم مميزات كثيرة تساعد على ها وتحقيق اقصى استفادة ممكنة في العمل ضمن فريق
بمعنى أن كل عضو لديه نسخته من المشروع ويعدل في الـ Local Repository الخاص به ثم في النهاية يرفع تلك التعديلات على الـ Remote Repository ليتشاركها مع الجميع وكل الفريق يتابع آخر التعديلات التي قام بها كل عضو
Staging Area
الـ Staging Area وتسمى أيضًا بالـ Index أو Cache هي مرحلة وسيطة ما بين الـ Working Directory والـ Local Repository
تستخدم لوضع التعديلات التي قمنا بها في الـ Working Directory قبل نقلها إلى الـ Local Repository
أو العكس لوضع التعديلات التي ترغب في التراجع عنها من الـ Local Repository قبل إزالتها من الـ Working Directory
هذه المنطقة الوسيطة وجدت لتجنب التعديل والتغير المباشر ما بين الـ Working Directory و الـ Local Repository
لكي يتم مراجعتها جيدًا والتأكد من كل شيء قبل تنفيذ العملية التي نريدها سواء إضافة أو تعديل أو حذف
ومن المهم دائمًا وجود مرحلة تأكيدية كتلك لتجنب الأخطاء الغير مقصودة أو الاستعجالية التي تحدث عندما نفذ التعديل بشكل مباشر
وأيضًا يحتفظ بالملفات الـ Tracked ليتابعها ويقارنها مع النسخة التي في الـ Working Directory ليتأكد هل تم تعديلها أم لا
Stash
الـ Stash هو مكان يستخدم لحفظ التعديلات التي قمت بها بشكل مؤقت، ثم يمكنك العمل على شيء آخر أو أن تنتقل
إلى branch آخر، ثم بعد انتهائك يمكنك أن تعود وتستحضر التعديلات المحفوظة التي قمت بها من الـ Stash في أي وقت
كيف يتعامل Git مع ملفات المشروع ؟
نستطيع أن نقول أن Git يصنف الملفات لعدة حالات ليسهل عليه التعامل معها ويتابعها ويراقب التغيرات
Untracked Files
الـ Untracked Files هي الملفات التي لا يتم متابعتها من قبل Git
بمعنى أنها ملفات موجودة في الـ Working Directory ولكن Git لا يعرف شيئًا عنها ولم يتخذ أي إجراء تجاهها من قبل
أي أنها لم تُنقل إلى الـ Staging من قبل أو تم حذفها من الـ Staging والـ Git لم يعد يتابعها
Tracked Files
الـ Tracked Files هي الملفات التي أصبح Git يدرك وجودها ويتابع أي تغير فيها
ويملك نسخة منها في الـ Staging ليتابعها
Modified Files
هي الملفات التي كان Git يتابعها أي أنها Tracked بالفعل لكن حصل لها تعديل ولم تنقل إلى مرحلة الـ Staging بعد
بمعنى أن نسختها التي في الـ Working Directory مختلفة عن نسختها التي يتم متابعتها في الـ Staging
Staged Files
هي الملفات التي كان Git يتابعها أي أنها Tracked بالفعل وحصل لها تعديل ثم نُقلت إلى مرحلة الـ Staging
أي أن نسختها التي في الـ Staging مختلفة عن نسختها التي في الـ Local Repository
أهم أوامر الـ Git
حسنًا سنتخذ مثال وهمي بسيط وسنشرح أهم الأوامر الخاصة بـ Git عن طريق المثال
حسنًا لنتخيل أننا لدينا مشروع لمدونة جميلة وهذا المشروع حاليا فيه ملف واحد يمثل مقالة واحدة
> ls
article_1.txt
التعريف بنفسك
أول شيء نفعله وهو أن تعرف نفسك لـ Git
لذا نستخدم git config --global user.email "your@email.com" و git config --global user.name "your name"
لتسجيل اسمك وبريدك الإلكتروني في Git على مستوى جهازك الشخصي
أما اذا اردت على مستوى المشروع الحالي فيمكنك ازالة --global
> git config --global user.email "eltabaraniahmed@gmail.com"
> git config --global user.name "AhmedEl-Tabarani"
git init
نستخدم git init لمرة واحدة فقط داخل المجلد الذي فيه المشروع أي الـ Working Directory لنخبر الـ Git
أن يبدأ بإنشاء مجلد الـ .git الذي يضم كل شيء متعلق به
بما في ذلك الـ Local Repository والـ Staging Area و Stash
يبدأ في مراقبة ومتابعة أي تعديلات في هذا الـ Working Directory
> git init
Initialized empty Git repository in blog/.git/
لاحظ أنه يخبرنا أنه أنشيء Git Repository وهو مجلد يدعى .git وهو المنزل الخاص بـ Git الذي الذي يضم كل شيء متعلق به كما قلنا
وهو مجلد خفي لكن يمكنك ان تراه وتتأكد من وجوده عن طريق أمر بسيط
> ls --all
./ ../ .git/ article_1.txt
ملحوظة: وعندما نقوم بعملgit initلاول مرة لمشروعنا يبدأGitبعملbranchفارغ يدعىmainلا يحتوي على أيcommitبعد
git status
نستخدم git status لمعرفة حالة المشروع والملفات التي لدينا
هل تم تعديل الملفات أم لا ؟ هل يوجد ملفات جديدةUntracked أم لا
أو هل هناك ملفات نُقلت للـ Staging أم لا ... إلخ
وأيضا دائمًا ما يساعدك على اقتراح لك بعض الأوامر التي يمكنك أن تقوم بها في الحالة التي أنت فيها
> git status
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
article_1.txt
nothing added to commit but untracked files present (use "git add" to track)
لاحظ أن git status أخبرنا بالكثير من المعلومات، بما في ذلك:
- أننا في الـ
branchالأساسيmainالذي ينشئهGitلنا ليضم كل الـcommitالخاصة بمشروعنا - أننا لا نملك أي
commitبعد وهذا منطقي لأننا لم نفعل شيء بعد - أن هناك ملف في الـ
Working Directoryيسمىarticle_1.txtمن ضمن الـUntracked Files
وGitلا يعرف عنه أي شيء - أيضًا بعض النصائح حول كيفية التصرف، مثل استخدام
git addلتحويل الملف إلىTrackedمن قبلGitوأيضًا لنقل الملف إلى مرحلة الـStaging
git add file-name
نستخدم git add عندما نريد نقل التعديلات من الـ Working Directory إلى مرحلة الـ Staging
ويحول الملفات من حالة Untracked إلى Tracked
يمكنك git add ثم اسم الملف أو اسم المجلد الذي تريد نقله إلى مرحلة الـ Staging
أو يمكنك القيام بكتابة git add ثم . أو * لنقل كل التعديلات
> git add article_1.txt
الآن، بعد إضافة الملف article_1.txt إلى مرحلة الـ Staging، يمكننا أن نستخدم git status مجددًا إذا اردنا لكي نرى حالة الملفات الآن
> git status
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: article_1.txt
لاحظ أنه لم يعد يقول لنا أن الملف article_1.txt انه Untracked
بل يخبرنا أنه الآن في مرحلة الـ Staging وأنه اصبح جاهزًا لكي نقوم بعمل commit لننقله إلى الـ Local Repository
ويقول استخدم git rm --cached <file> لك إن أردنا حذف الملف من مرحلة الـ Staging وإرجاعه مجددا لحالة الـ Untracked
git commit -m nice-message
نستخدم git commit عندما نريد نقل التعديلات من مرحلة الـ Staging إلى الـ Local Repository
وعندما نقوم بعمل commit فهكذا كأننا نقوم بحفظ نسخة جديدة من المشروع والتعديلات التي حصلت فيه
وقد تسمع أن commit ينشيء snapshot لمشروع أي نسخة من المشروع
ويمكننا القول أن الـ Local Repository هو مجموعة من الـ snapshot التي تم حفظها من المشروع
ولاحظ أن git commit تقوم بنقل كل الملفات والتغيرات المتواجدة في مرحلة الـ Staging كحزمة واحدة إلى الـ Local Repository في commit واحد فقط
بمعنى أن commit واحد قد يضم أكثر من ملف وتعديل
ونستخدم -m لكتابة رسالة توضح التغييرات التي تمت في هذا الـ commit
لتساعدك أنت والفريق الذي معك بتبع تاريخ كل التغيرات التي حصلت في المشروع فيما بعد
ويفضل أن تكون الرسالة مختصرة ومعبرة وغالبًا ما تتفق أنت وباقي الفريق على صيغة معينة لكتابة تلك الرسائل التوضحية
> git commit -m "add new article to the blog"
[main (root-commit) 4032898] add new article to the blog
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 article_1.txt
لاحظ أن Git يخبرنا ببعض المعلومات الجميلة منها
- الـ
commitهذا هو الـroot-commitلفرع الرئيسي للمشروع وهوbranchالـmain - يخبرنا بعدد الملفات التي حدث فيها التغير، وفي حالتنا ملف واحد فقط
- يخبرنا بعدد الاسطر التي اضيفت والتي حذفت، وبما ان الملف الذي اضفناه كان فارغًا فلا يوجد اسطر
وأمر لم يخبرنا به وهو أنه أصبح لدينا مؤشر يدعى HEAD ويؤشر على آخر commit تم اضافته إلى الـ main
وسنتحدث عن هذا بالتفصيل لاحقًا في هذه المقالة
ملحوظة: الـHEADيتواجد داخل الـLocal Repositoryبالطبع، والـcommitالذي يشاور عليه هو ما نراه في الـWorking Directoryوسنفهم معنى هذا لاحقًا
حسنًا لنقم بعمل git status مجددًا لكي نرى حالة الملفات الآن
> git status
On branch main
nothing to commit, working tree clean
الآن، يخبرنا Git أنه لا توجد تغييرات جديدة
وبالتالي لا توجد أي ملفات تحتاج إلى الانتقال إلى مرحلة الـ Staging أو عمل لها commit ونقلها إلى الـ Local Repository
ولذا يقول لك أن الـ Working Tree أي الـ Working Directory الخاص بالمشروع نظيف ولا يحتاج إلى أي شيء
git restore file-name
نستخدم git restore ثم اسم الملف عندما يكون الملف حالته Tracked بالنسبة للـ Git لكن تم التعديل عليه
أي أن نسخته التي في الـ Working Directory مختلفة عن نسخته التي في الـ Staging
ونريد التراجع عن هذا التعديل وإرجاع الملف لحالته الأصلية التي كان عليها
ما يقوم به git restore حقًا هو أنه يأخذ نسخة الملف التي في الـ Staging ويستبدلها مع الملف الذي في الـ Working Directory
الـ Staging هو أيضًا يحتفظ بنسخة بالملفات التي يتابعها وعن طريقها يستطيع معرفة إن حدث تعديل أم
بالتالي إن كان هناك ملف تم تعديله في الـ Working Directory فنستطيع عن طريق استخدام git restore استبدالها لترجع وتصبح طبق الأصل لنسختها التي في الـ Staging كما كانت
ونكون قد تخلصنا من التعديلات التي حدثت للملف في الـ Working Directory
لنرى مثال توضيحي، أولًا لنعدل في ملف المقالة article_1.txt ونضيف أي شيء
> echo "In this article we will prove that git is a time machine!" > article_1.txt
بعد ما اضفنا سطر وعدلنا في article_1.txt، لنقم بعمل git status لكي نرى حالة الملف
> git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: article_1.txt
no changes added to commit (use "git add" and/or "git commit -a")
أنظر كيف يقوم الأمر git status بتوضيح كل شيء لك ويساعدك على اتخاذ القرارات
يقول لك هنا:
- أنه لا يوجد ملفات حالتها
Untrackedلكن يوجد ملفTrackedتم التعديل عليه
بمعنى أن نسخته في الـWorking Directoryمختلفة عن نسخته في الـStaging - ويقول لك أنك يمكنك أن تضيف هذا الملف إلى مرحلة الـ
Stagingعن طريقgit add - أو يمكنك التراجع عن التعديل وجعل الملف يرجع لحالته الأصلية التي كان عليها عن طريق
git restore
لذا لكي نخبره أننا نريد التراجع عن التعديل فسنقول له git restore article_1.txt
> git restore article_1.txt
هكذا سيقوم Git بالذهاب إلى الـ Staging واحضار نسخة الملف article_1.txt المتواجده فيه ويستبدلها
بالملف الذي في الـ Working Directory
git restore --staged file-name
هذا هو نفس الأمر السابق لكن مع زيادة --staged
والفرق هنا ان الملف الذي تم التعديل عليه دخل إلى مرحلة الـ Staging بالفعل عن طريق git add
والآن نريد أن نخرجه فقط من مرحلة الـ Staging دون أن نتراجع عن التعديلات التي في الملف في الـ Working Directory
لذا مع زيادة --staged يقوم Git بإحضار نسخة الملف من الـ HEAD المتواجد في الـ Local Repository
ثم يستبدله بالملف الذي في الـ Staging
كهذا سيصبح الملف الذي في الـ Staging مطابق لنسخة الملف الذي في الـ HEAD المتواجد في الـ Local Repository
وهكذا تراجعنا عن التعديل واخرجناه من مرحلة الـ Staging
لنفقم برؤية هذا بشكل عملي
> git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: article_1.txt
no changes added to commit (use "git add" and/or "git commit -a")
لنفترض أننا وصلنا إلى هذه النقطة ثم قمنا بعمل git add بهذا الشكل
> git add article_1.txt
الآن سنقوم بعمل git status لنرى ما الذي حدث
> git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: article_1.txt
لاحظ أن الملف تم نقله إلى مرحلة الـ Staging
ونستطيع أن نقوم بعمل commit جديد في الـ Local Repository يضم التعديلات التي قمنا بها
عن طريق git commit
لكن نحن نريد ان نتعلم كيف نتراجع عن هذا التعديل لذا Git يساعدنا ويخبرنا كيف نفعل هذا
يقول لنا إن أردنا إخراج الملف فقط من مرحلة الـ Staging دون ان نتراجع عن التعديلات التي في الملف نستعمل git restore --staged article_1.txt
> git restore --staged article_1.txt
هكذا سيقوم Git بالذهاب إلى الـ HEAD المتواجد في الـ Local Repository واحضار نسخة الملف article_1.txt ويستبدلها بالملف الذي في الـ Staging
بالتالي نسخة الملف التي في الـ Staging ستكون مطابقة لنسخة الملف التي في الـ HEAD
بالتالي كأننا أخرجناه من حالة الـ Staging
لكن التعديلات التي في الملف مازالت موجودة
بمعنى أن نسخة الملف في الـ Working Directory مختلفة عن نسختها التي في الـ HEAD
وتذكر أن الـ HEAD يشير إلى آخر commit قمنا بعمله والذي يضم آخر التعديلات التي قمنا بتسجيلها داخل الـ Local Repository
يمكننا عمل git status ونتأكد
> git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: article_1.txt
no changes added to commit (use "git add" and/or "git commit -a")
أنظر رجعنا لحالتنا الأولى قبل قيامنا بعمل git add article_1.txt
بمعنى أن التعديلات التي في الملف مازالت موجودة في الـ Working Directory لكن نحن فقط أخرجنا الملف من مرحلة الـ Staging
لذا نستطيع أن نقول أن git restore --staged هو الأمر الذي يعكس ما يقوم به الأمر git add
ملحوظة: تذكرgit restoreيقوم باسترجاع الملف من الـStagingإلىWorking Directory
أماgit restore --stagedيقوم باسترجاع الملف من الـHEADالمتواجد فيLocal RepositoryإلىStaging
قبل أن نكمل لنقم بعمل git add و commit للملف article_1.txt
> git add article_1.txt
> git commit -m "edit article 1"
[main 6dc050b] edit article 1
1 file changed, 1 insertion(+)
git rm file-name
نستخدم git rm عندما نريد حذف ملف من المشروع كليًا أي من الـ Working Directory ومن الـ Staging
وما يفعله أنه يحذف الملف من الـ Working Directory ثم يقوم بعمل git add تلقائيًا للملف المحذوف دون أن تشعر
والـ git add غرضها هنا وضع الملف المحذوف في مرحلة الـ Staging لتأكيد على حذفه في الـ commit جديد
بالتالي سيتم إنشاء نسخة جديدة من المشروع يكون الملف محذوفًا فيه
ملحوظة: يمكننا القول أنgit rmهو في الحقيقة مزيج بينrmثمgit add
وبما أنها تحذف الملف من الـ Staging هكذا تم تحويل الملف إلى حالة Untracked بالتالي Git لن يتعرف عليه
لانه لم يعد Tracked File بالنسبة له
لكن في هذه الحالة الأمر لن يكون مهمًا لأن الملف لم يعد موجودًا في الـ Working Directory من الأساس
لنأخذ مثال عملي على ما قلناه
لنقم بإنشاء ملف جديد ثم نقوم بعمل git add و commit له
ثم نحاول حذفه من المشروع
> touch article_xyz.txt
> git add article_xyz.txt
> git commit -m "add xyz article"
[main c2d77c1] add xyz article
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 article_xyz.txt
> ls
article_1.txt article_xyz.txt
الآن أصبح لدينا مقالة جديدة تدعى article_xyz.txt
لكن للأسف الشديد هذه المقالة تم إنشاءها عن طريق الخطأ ونريد أن نحذفها
لذا سنستعمل الأمر الجميل git rm
> git rm article_xyz.txt
rm 'article_xyz.txt'
الآن هنا حصل أمرين:
- تم حذف الملف من الـ
Working Directory - تم وضع الملف المحذوف في مرحلة الـ
Stagingللتجهيزه لعملcommitجديد
لنقوم بعمل git status للتحقق من ما قلناه
> git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: article_xyz.txt
لاحظ أنه يقول لك Changes to be committed أي أن هذه التعديلات التي في الـ Staging جاهزة لعمل commit
وأهم شيء ستلاحظ أن الملف article_xyz.txt يتم الإشارة إليه بأنه محذوف بمعنى انه سيتم حذفه في النسخة التي سينشئها الـ commit
لاحظ أنه أيضًا يقول لك بكيفية التراجع عن الحذف عن طريق git restore --staged article_xyz.txt
وهذا الأمر كما أوضحنا سيتم إرجاع نسخة الملف من الـ HEAD إلى الـ Staging
هكذا سنستعيد الملف في الـ Staging وسيصبح Tracked كما كان
لكن الملف محذوف أيضًا من الـ Working Directory لذا لكي تسترجعه بشكل نهائي ستحتاج لتنفيذ git restore article_xyz.txt
وهكذا سيتبدل الملف المحذوف من الـ Staging ألى الـ Working Directory
وهكذا سنستعيد الملف ويعود المشروع إلى حالته الاصلية
يمكنك أختبار طريقة إرجاع الملف المحذوف بنفسك
نحن لا نريد أن نسترجع الملف المحذوف لذا سنقوم بعمل الـ commit ليتم إنشاء نسخة من المشروع يكون الملف محذوفًا فيه
> git commit -m "delete xyz article"
[main 937637d] delete xyz article
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 article_xyz.txt
git rm --cached file-name
هذا هو نفس الأمر السابق لكن مع زيادة --cached
وهو في الحقيقة يشبه الأمر السابق لكنه لا يقوم بحذف الملف من الـ Working Directory بل يكتفي بأن يحذفه فقط من الـ Staging
وطالما أن الملف حذف من الـ Staging فقط فسيتم تحويل الملف إلى Untracked بالتالي Git لن يتعرف عليه لانه لم يعد Tracked File بالنسبة للـ Git
وتذكر أن الملف لم يحذف من الـ Working Directory بل حذف فقط من الـ Staging
سنعطي نفس المثال السابق بأننا سننشيء ملف ما ثم نحاول حذف
> touch article_xyz_again.txt
> git add article_xyz_again.txt
> git commit -m "add xyz article again"
[main cbbc411] add xyz article again
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 article_xyz_again.txt
الآن أصبح لدينا مقالة جديدة تدعى article_xyz_again.txt
ونريد أن نحذفها عن طريق الأمر git rm --cached
> git rm --cached article_xyz_again.txt
rm 'article_xyz_again.txt'
الآن ما حصل هنا هو مثل ما حصل الأمر السابق لكن مع اختلاف:
أن الملف حذف فقط من الـ Staging وليس من الـ Working Directory
وبالتطبع تم وضع الملف المحذوف في مرحلة الـ Staging للتجهيزه لعمل commit جديد
لنقوم بعمل git status للتحقق من ما قلناه مجددًا
> git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: article_xyz_again.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
article_xyz_again.txt
حسنًا أريدك أن تركز جيدًا في ما سأشرحه الآن
الأمر git status يخبرنا بمعلومتين مهمتين
الأولى أن الملف الذي حذفناه تم وضعه في مرحلة الـ Staging مع الإشارة إليه بأنه محذوف بمعنى انه سيتم حذفه في النسخة التي سينشئها الـ commit
الثانية أن نفس الملف موجود بالفعل في الـ Working Directory لكنه Untracked أي أن Git ينظر اليه كملف جديد لا يعرف عنه شيء
وهذا بسبب أن الأمر git rm --cached لا يحذف الملف من الـ Working Directory بل يحذفه فقط الـ Staging
وطالما أن الملف حذف من الـ Staging فبالتبعية سيتم تحويل حالة الملف من Tracking إلى Untracking
الآن لدينا شيء مميز هنا وأريدك أن تركز معي، إذا أردنا التراجع عن الحذف ما الذي سنفعله ؟
ستقول لي هذا سهل، فقط سنستخدم git restore --staged article_xyz_again.txt لنخرجه من حالة الـ Staging كما تعلمنا
صحيح، لكن ماذا سيحدث عندما نقوم بعمل git add article_xyz_again.txt ؟
سيتم وضع الملف article_xyz_again.txt في مرحلة الـ Staging وجعله Tracked
حسنًا وثم ؟ فكر وركز هنا جيدًا، ستتفاجيء ان الملف لم يعد مطالب حذفه
والمشروع عاد كمان كان إلي حالته الأصلية
بمعنى أن تنفيذ الأمر git add article_xyz_again.txt كان مساويًا تماما للأمر it restore --staged article_xyz_again.txt في هذه الحالة بالتحديد
هل تستطيع التفكير بالسبب ؟
السبب بسيط وهو أن الأمر git rm --cached، حذف الملف من الـ Staging فقط لا غير وأبقى الملف كما هو في الـ Working Directory
وهذا الملف الآن الموجود في الـ Working Directory مازال مساويًا للنسخة الموجودة في الـ HEAD داخل الـ Local Repository
كل ما في الأمر أنه ليس في الـ Staging!
لذلك عندما نستعمل git add سيتم إضافة الملف من الـ Working Directory إلى الـ Staging
وعندما نستعمل git restore --staged يتم نقل الملف من الـ HEAD إلى الـ Staging
إذًا في كلتا الحالتين ستكون نسخة الملف في الـ Staging متساوية مع النسخة التي في الـ Working Directory ومتساوية مع النسخة الموجودة في الـ HEAD المتواجد داخل الـ Local Repository
هكذا طالما أن كل النسخ متساوية، فكل شيء عاد كما كان قبل حذف الملف
والملف سيرجع Tracked كمان كان لأنه في الـ Staging
لذا النتيجة ستكون ذاتها بأن اصبحت كل النسخ متساوية
أرجوا أن تكون الفكرة وصلت الأمر يحتاج فقط لفهم طبيعة عمل كلا الأمرين git add وgit restore --staged
لنعود للأمر git status
> git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: article_xyz_again.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
article_xyz_again.txt
ونقول أننا نريد عمل commit لإنشاء نسخة من المشروع يكون الملف محذوفً فيه
> git add article_xyz_again.txt
> git commit -m "delete xyz article again"
[main be7a504] delete xyz article again
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 article_xyz_again.txt
الآن تم إنشاء نسخة جديدة لا يتواجد فيها الملف article_xyz_again.txt
لكن تذكر أن ملف لازال موجودًا في الـ Working Directory وحالته Untracked
لنتأكد من هذا عن طريق git status
> git status
On branch main
Untracked files:
(use "git add <file>..." to include in what will be committed)
article_xyz_again.txt
nothing added to commit but untracked files present (use "git add" to track)
يمكنك أن تمسحه يدويًا الآن إن أردت أو أن تحتفظ به أو تضيف مجددًا، فلا يهم افعل ما تريده
أنا سأقوم بحذفه يدويًا لأنني لن احتاجه مجددًا
> rm article_xyz_again.txt
> ls
article_1.txt
git log
نستخدم git log عندما نرغب في مشاهدة تاريخ المشروع بالكامل وكل التعديلات التي تمت عليه من بداية المشروع حتى اللحظة الحالية
وكذلك لمعرفة من قام بإجراء التعديل ومتى قام بها
لذا عندما تريد رؤية جميع التغييرات والـ commit التي قمت بها في المشروع، فقط بضغطة زر تنفذ هذا الأمر البسيط git log
> git log
commit be7a50440aa044d331741b5af4758e23a190760d (HEAD -> main)
Author: AhmedEl-Tabarani <eltabaraniahmed@gmail.com>
Date: Fri Apr 12 03:17:02 2024 +0200
delete xyz article again
commit cbbc4119e47737ea5c96cd441b7bc69f51b16f1b
Author: AhmedEl-Tabarani <eltabaraniahmed@gmail.com>
Date: Fri Apr 12 01:51:45 2024 +0200
add xyz article again
commit 937637d020fbc80114f291c841d2f17f88f6178a
Author: AhmedEl-Tabarani <eltabaraniahmed@gmail.com>
Date: Fri Apr 12 01:02:54 2024 +0200
delete xyz article
commit c2d77c1cd3b94208816aefa916c8feb7f933f8ec
Author: AhmedEl-Tabarani <eltabaraniahmed@gmail.com>
Date: Thu Apr 11 23:55:25 2024 +0200
add xyz article
commit 6dc050b8d781d0247277fda29e8c330cd8b7f689
Author: AhmedEl-Tabarani <eltabaraniahmed@gmail.com>
Date: Thu Apr 11 05:50:45 2024 +0200
edit article 1
commit 4032898bcaf1dd2b5fbbaac2f15840e93097955f
Author: AhmedEl-Tabarani <eltabaraniahmed@gmail.com>
Date: Thu Apr 11 03:25:33 2024 +0200
add new article to the blog
وسيتم عرض لك جميع الـ commit التي كانت تخزن في الـ Local Repository
بالإضافة إلى عدة أمور منها الـ hash الخاص بالـ commit واسم الشخص الذي قام بالتعديل والوقت الذي تم فيه التعديل والرسالة التي كتبها مع الـ commit
فكما ترى لدينا العديد من الـ commit التي أنشأناها أثناء الشرح
لاختصار كمية المعلومات يمكننا ان ننفذ الأمر هكذا git log --oneline
> git log --oneline
be7a504 (HEAD -> main) delete xyz article again
cbbc411 add xyz article again
937637d delete xyz article
c2d77c1 add xyz article
6dc050b edit article 1
4032898 add new article to the blog
وكما ترى فأنه مفيد جدًا لرؤية آخر الـ commit التي اجريناها في المشروع
قد تجدني استخدم بعض الخيارات الاضافية معه كهذا git log --all --decorate --oneline --graph
خاتمة
كما تلاحظ، الآن أصبح لديك معرفة جيدة عن الأوامر الأساسية للـ Git وكيفية استخدامها
يجب أن تكون قادرًا الآن على إدارة مشروعاتك باستخدام Git وتنظيمها والقيام بالتعديلات والتحديثات بكل سهولة
بالطبع أنا لم اشرح جميع وظائف كل أمر، أنا فقط شرحت لك الفكرة والاستخدام العام لكل أمر
لكن اذا تعمقت ستجد ان كل أمر يحتوي على تفاصيل اعمق ودهاليز كثيرة
وأظن أنني اديت وظيفيتي في توصيل الهدف والاستخدام العام وهذا يكفي كبداية لتبدأ انت بجمع واستكشاف هذه الدهاليز والتفاصيل اثناء تقدمك وتعاملك
في المقالة التالية سنتكلم عن أوامر أكثر مثل git revert و git reset و git checkout و git stash
وسنفهم ما هو الـ HEAD وكيف نتحكم به
ويمكنكم قراءتها من هنا تكملة أوامر الـ Git والتحكم بالـ HEAD
ثم في مقالة أخرى سنتكلم عن الـ Branch في الـ Git
وأنها تعد من أهم المزايا التي يقدمها الـ Git
حيث أنها تساعدنا عن إنشاء عدة نسخ من المشروع، وكل نسخة تستطيع أن تطور فيها وتعدل وتفعل ما تريده دون أن تأثر على نسخة المشروع الأساسية
أو تقسم العمل ضمن الفريق حيث يمكن لكل عضو العمل على نسخته من الكود في فرع مختلف بشكل مستقل عن باقي الفريق
ويمكنكم قراءتها من هنا Git Branches آلة السفر عبر الأبعاد
ثم في المقالة التالية سنتكلم الـ Remote Repository وسنشرح مفاهيم وأوامر جديدة تتعلق بهذا العالم الآخر
ويمكنكم قراءتها من هنا التعامل مع Remote Repository وموقع GitHub