الـ Git Remotes، وما علاقة الـ GitHub بالـ Git ؟

السلام عليكم ورحمة الله وبركاته

وقت القراءة: ≈ 15 دقيقة

المقدمة

نستكمل شرحنا عن الـ Git وخصوصًا الجزء الخاص بتعامله مع أي Remote Repository
في المقالات السابقة تكلمنا عن الـ Git بشكل عام وأهم أوامره ومميزاته وكنا نطبق كل شيء بشكل Local أي على جهازك الشخصي
دون أي اتصال خارجي بأي شكل من الأشكال

يمكنكم قراءة المقالة الخاصة بالأساسيات من هنا أساسيات Git
والمقالة الخاصة بمفهوم الـ Branch من هنا الـ Git Branch، آله السفر عبر الأبعاد

وفي هذه المقالة سنتعامل مع الـ Remote Repository ونرى الأوامر الجديدة والمميزات التي يقدمها الـ Git
لتساعدنا على ربط الـ Local Repository الخاص بنا مع أي Remote Repository أوأكثر بكل سلاسة

وكيف نسحب ونرفع التعديلات التي لدينا في الـ Local Repository إلى الـ Remote Repository والعكس
سواء فقط لحفظ هذه التعديلات التي قمنا بها في مكان ما على الانترنت
أو ليراه باقي أعضاء الفريق التي تعمل معه وكل شخص يتابع التعديلات في التي يقوم بها كل عضو

Repository

قلنا أننا لدينا شيء يدعى Repository وهو مكان يستخدمه الـ Git ليحتفظ ويتابع التعديلات التي تحدث
ويمكن أن نقسمهما إلى Local Repository و Remote Repository

Local Repository

ويطلق عليه عدة مسميات مثل Git Repository أو Git Directory أو Git History
والذي يستخدمه الـ Git ليحتفظ بكل شيء ويتابع كل التعديلات الموجودة في الـ Working Directory الخاص بك على جهازك

Remote Repository

ويسمى أيضًا بالـ Upstream Repository
هو كالـ Local Repository لكنه نسخة يتم استضافتها في مكان ما على الإنترنت مثل GitHub أو GitLab أو غيرهما

بالتالي سيكون لدينا نسخة مركزية من المشروع مرفوعة ومرئية لجميع أعضاء الفريق وهو الـ Remote Repository
وكل عضو يستطيع بسهولة أن يتابع آخر التعديلات التي قام بها الأعضاء الآخرون وأيضًا يرفع تعديلاته للجميع

فتخيل أنك ضمن فريق وكل عضو لديه نسخته من المشروع وهو الـ Local Repository الخاص به
ثم قام أحد الأعضاء بتعديلات على نسخته ثم يقوم برفعها على الـ Remote Repository ليتشاركها مع الجميع
بالتالي أصبح كل الفريق يتابع آخر التعديلات التي قام بها كل عضو

وأيضًا هذه المواقع تسهل العمل مع فريق من أماكن مختلفة وتقدم مميزات كثيرة تساعد على تحقيق اقصى استفادة ممكنة في العمل ضمن فريق

السؤال الأزلي: ما الفرق بين الـ GitHub والـ Git

الـ Git هو أداة تستخدمها في جهازك الشخصية لإدارة نسختك من المشروع
ويتحكم وينظم ويسجل كل شيء يحدث فيها في الـ Local Repository

بينما الـ GitHub أو GitLab أو Bitbucket أو غيرهم فهم منصات تقوم باستضافة نسخة رئيسية من المشروع وتسمى الـ Remote Repository
بالتالي سيكون هناك نسخة مركزية متاحة للجميع الناس أو للفريق الخاص بك
والكل حينها يستطيع مشاركة إضافاته وتعديلاته في مكان واحد مشترك

ويقدموا أيضًا خدمات كثيرة تساعد الفرق والشركات على تنظيم مشروعاتهم الخاصة

وببساطة هي منصات ومواقع خدماتية بحتة تقدم لك استضافة لمشروعك وتساعدك على اداراته ضمن فريق

أهم أوامر الـ Git في التعامل مع الـ Remote Repository

كما العادة سنقوم بعرض مثال ثم نقوم بشرح أهم الأوامر من خلال هذا المثال
سنفترض أننا دخلنا إلى شركة ما وهذه الشركة لديها مشروع يتم استضافته على GitHub

لنفترض أن الرابط الخاص بالـ Remote Repository الخاص بمشروع الشركة هو
https://github.com/CompanyName/project-remote-repository.git

ونحن الآن نريد أن نستنسخه ونضعه في الجهاز الخاص بنا لنبدأ العمل على المشروع

git clone

تستخدم git clone لنسخ وتحميل نسخة من الـ Remote Repository على جهازك الشخصي ويصبح Local Repository بالنسبة لك
وثم يكون الـ Local Repository مرتبط بهذا الـ Remote Repository
بحيث يتم إنشاء حلقة تواصل بينهما لسحب ورفع الإضافات والتعديلات

طريقة استخدامه ستكون بسيطة كهذا git clone remote-repository-url folder-name
وبالطبع remote-repository-url سيكون هو الرابط الخاص بالـ Remote Repository و folder-name هو اسم المجلد الذي سيتم نسخه فيه والذي سيحتوي على الـ Local Repository

نحن في هذا المثال ومن أجل التوضيح سنسميه project-local-repository
واذا لم تحدد اسم للـ Local Repository سيتم استخدام اسم المشروع كاسم افتراضي له وسيكون project-remote-repository على الأرجح

> git clone https://github.com/CompanyName/project-remote-repository.git project-local-repository
Cloning into 'project-local-repository'...
done.

الآن تم إنشاء مجلد يدعى project-local-repository يمكننا فتحه ورؤية محتوياه

> cd project-local-repository

> ls --all
./  ../  .git/  article_1.txt

سترى أن المشروع يحتوي على ملف واحد فقط وهو article_1.txt
وأصبح لدينا نسخة من المشروع فيه لدينا .git والذي سيمثل كل شيء بالنسبة للـ Git كالـ Local Repository والـ Staging والـ Stash و ...إلخ

وأصبح هناك حلقة وصل بيننا وبين الـ Remote Repository

لنرى ماذا سيقول لنا الـ git status

> git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

سنراه يقول لنا أننا على الـ main وهو متوافق مع origin/main

ما هو الـ origin ؟

الـ origin هو اسم لـ remote الذي يشير إلى الـ Remote Repository الذي ارتبطنا به
وهو يحتوي على الـ main والـ HEAD الخاصة بهذا الـ Remote Repository ويشار إليهم بـ origin/HEAD و origin/main

والـ origin هو اسم رمزي أو افتراضي ويمكن أن تغيره إن أردت

ويمكنك عن طريق الـ git log رؤية مكان الـ origin/main والـ origin/HEAD

لنرى الـ git log

> git log --oneline --all
7a5aa61 (HEAD -> main, origin/main, origin/HEAD) add article number 1

سترى أن المشروع به commit واحد فقط ستجد أن الـ main الخاصة بالـ Local Repository والـ origin/main الخاصة بالـ Remote Repository يتطابقان

و ستجد أن الـ origin/HEAD والـ HEAD يقفان على نفس الـ commit

ملحوظة: الـ origin يشاور على آخر التعديلات في الـ Remote Repository بحسب آخر المعلومات التي حصل عليها الـ Local Repository
بالتالي فيمكن أن يكون الـ origin يملك معلومات قديمة عن الـ Remote Repository لأنه لا يحدث معلوماته بشكل تلقائي

git remote

أولًا كلمة remote نقصد بها الـ Remote Repository الذي نرتبط به
ونحن عندما ننفذ git clone يتم انشاء remote يدعى origin وهذا يشير إلى الـ Remote Repository

تستخدم git remote لعرض كل الـ Remote Repository المرتبطة بالـ Local Repository الخاصة بك

> git remote
origin

وكما ترى لدينا remote واحد فقط وهو الـ origin
ولكي تتأكد وتعرف رابط الـ Remote Repository الذي يشير إليه الـ origin نضع -v

> git remote -v
origin https://github.com/CompanyName/project-remote-repository.git (fetch)
origin https://github.com/CompanyName/project-remote-repository.git (push)

وهنا سيعطيك كل الـ remote التي لديك بجانب رابط الـ Remote Repository التي تشير إليه
وأيضًا العمليات المسموح لنا بأن نقوم بها
وهنا كما ترى مسموح لنا فقط بالقيام بـ fetch لجلب التعديلات منه و push لرفع التعديلات إليه وسنرى هذا بالتفصيل

وأجل يمكن للـ Local Repository الخاص بك أن يكون مرتبط بأكثر من Remote Repository
سواء بنُسخ مختلفة من نفس المشروع مرفوعة في حسابات مختلفة على الـ GitHub والـ GitLab وغيرهما
وحينها سيكون لديك remote مختلف مع كل Remote Repository مختلف ترتبط به

أو لديك نُسخ مرفوعة على مواقع الاستضافة التي تقوم بعمل deploy و host لمشروعك
وحينها سيتم إنشاء remote آخر يكون مربوط مع الـ Remote Repository الخاص بموقع الاستضافة المعين

git remote add remote-name remote-url

إذا كان لديك مشروع بالفعل كنت تعمل عليه وهو الـ Local Repository الخاص بك
وهذا المشروع لا يرتبط ولا يملك أي Remote Repository بعد
لأنه مجرد مشروع تعمل عليه بشكل خاص على جهازك الشخصي

ثم قررت أنك تريد أن ترفعه على GitHub وتضيف remote له لتكون هناك نسخة مركزية تكون هي الـ Remote Repository
حينها سنقوم بإضافة remote بشكل يدوي عن طريق تنفيذ الأمر التالي git remote add remote-name remote-url

ويفضل أن تختار origin كاسم لهذا الـ remote لأنه الاسم الشائع والمتعارف عليه
لكن بالطبع يمكنك أن تتمرد وتختار اسم عشوائي مثل hamada-el-gamed

ثم ستقوم بوضع الرابط الذي سيعطيه الـ GitHub لك

هذا في حالة أنك لديك Local Repository بالفعل وتريد أن تربطه مع Remote Repository
أما لو هناك Remote Repository وتريد أن تستنسخه إلى Local Repository لديك فنستخدم git clone كما فعلنا سابقًا

git fetch remote-name branch-name

نستخدم git fetch لكي نحدث الـ origin ونسحب آخر الإضافات والتعديلات التي حدثت في الـ Remote Repository
والتي ليست لديك في الـ Local Repository بعد

لكن لا يقوم بعمل merge لها في الـ HEAD

حسنًا لنفترض أن شخص ما في الفريق قام برفع بعض التعديلات على الـ Remote Repository على الـ GitHub
وليكن أنه قام بإنشاء ملف جديد يسمى article_2.txt

وهذه المقالة الثانية ليست مسجلة في الـ Local Repository بالطبع

> ls
article_1.txt

وأنت تريد أن تسحب تلك التعديلات عندك ماذا تفعل ؟

أولًا لنرى الـ git log والـ git status

> git log --oneline --all
7a5aa61 (HEAD -> main, origin/main, origin/HEAD) add article number 1

> git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

الـ Git لا يعرف ما الذي يحدث في الـ Remote Repository حاليًا
لذا فهو يقول لك أنك متوافق مع ما هو موجود في الـ origin على حسب علمه

لكننا نعرف أن هناك تعديلات و commit تم وضعه على الـ Remote Repository ونحن لا نراها
لأن الـ origin كما قلنا لا يحدث معلوماته بشكل تلقائي
بل يجب عليك ان تحدثها بشكل يدوي عن طريق git fetch

هكذا يتم تحديث المعلومات التي لدى الـ Local Repository في الـ origin
وسيتم سحب أي commit جديد متواجد في الـ Remote Repository وسيقوم بوضعه في الـ origin/main داخل الـ Local Repository

> git fetch origin main
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 284 bytes | 0 bytes/s, done.
From https://github.com/CompanyName/project-remote-repository.git
   7a5aa61..b4a383f  main       -> origin/main

ستلاحظ أنه يخبرنا في النهاية أنه وجد commit موجود في الـ Remote Repository وليس موجودًا في الـ Local Repository

بالتالي قام بسحبه ووضعه في الـ origin/main دون دمجه في الـ main
أي أن git fetch سحب التعديلات في الـ main الخاصة بالـ origin وليست في الـ main الخاص بنا
لنتأكد أن لا شيء تم وضعه في الـ Working Directory

> ls
article_1.txt

لدينا المقالة الأولى كما هي لكن المقالة الثانية لم تظهر بعد
لنرى الـ git log ونرى ما الذي تغير فيه

> git log --all --oneline
b4a383f (origin/main, origin/HEAD) create article number 2
7a5aa61 (HEAD -> main) add article number 1

سترى أن الـ HEAD مازال كما هو يشاور على الـ main الخاصة بنا
لكن ستلاحظ أن هناك commit جديد ظهر وهو يسبق الـ HEAD
وسترى أن origin/HEAD و origin/main يشيران ويقفان عليه

وهذا يدل على أن هذا الـ commit الجديد قادم من الـ origin وبالتحديد من الفرع main الخاص بالـ origin
والـ HEAD الخاص بالـ origin يقف عليه حاليًا
لكن الـ HEAD بنا والفرع الـ main الخاص بنا لا يشيران عليه حاليًا

لنقم بعمل git status لنرى المزيد من المعلومات

> git status
On branch main
Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)

nothing to commit, working tree clean

سترى أنه يخبرنا أننا الآن نقف على الـ main الخاصة بالـ Local Repository
والـ main متأخر على الـ origin/main الخاصة بالـ Remote Repository بـ commit واحد فقط
وهذا ما رأيناه فعلا في الـ git log حيث ان الفرق بين الـ HEAD و origin/HEAD هو commit واحد بالفعل

ويقول لك أنك يمكنك استخدام git merge أو git pull لدمج تلك التعديلات إلى الـ main الفرع الرئيسي الخاص بالـ Local Repository

نحن سنستخدم git merge حاليًا

> git merge origin main
Updating 7a5aa61..b4a383f
Fast-forward
 article_2.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 article_2.txt

قمنا بتنفيذ git merge وحددنا أننا نريد ان ندمج المحتويات الموجودة في main الخاصة بالـ origin

لاحظ انه كتب لنا أن عملية الدمج هذه نوعها Fast-forward وهو كما فلنا قام بتحريك الـ HEAD وجعله يساوي الـ commit الذي يقف عليه الـ origin/HEAD بدون أن يقوم بعمل أي commit جديد

الآن لنرى محتويات الـ Working Directory

> ls
article_1.txt  article_2.txt

سترى ان المقالة الجديدة article_2.txt التي كانت في الـ origin اصبحت موجودة عندنا بنجاح

لنرى الـ git log الآن

> git log --all --oneline
b4a383f (HEAD -> main, origin/main, origin/HEAD) create article number 2
7a5aa61 add article number 1

سترى أن الـ HEAD تم دمجه بنجاح مع الـ origin/HEAD وأصبح يشاور على نفس الـ commit

لنرى الـ git status

> git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

سترى أن كل شيء على ما يرام حاليًا ونسختنا الآن مطابقة لما يوجد في الـ origin

git pull remote-name branch-name

يقوم بعمل git fetch ثم git merge في الـ main في آن واحد
بمعنى انه يقوم بتجديد الـ origin كما كان يفعل git fetch تمامًا
ثم يقوم بدمجه في الـ main مباشرةً بتنفيذ git merge وكل هذا في خطوة واحدة فقط

فلو افترضنا اننا في المثال السابق استعملنا git pull كان سيقوم بجلب كل التعديلات الموجودة في الـ Remote Repository ثم يدمجها فورًا في الـ Local Repository

> git pull origin main
From https://github.com/CompanyName/project-remote-repository.git
 * branch            main       -> FETCH_HEAD
Updating 7a5aa61..b4a383f
Fast-forward
 article_2.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 article_2.txt

لاحظ انه قام بعمل fetch للتعديلات ثم merge في خطوة واحدة

git push remote-name branch-name

نستخدم git push لنقوم برفع التعديلات التي في الـ Local Repository إلى الـ Remote Repository
وهو الوجه المعاكس للـ git pull

لنفترض أنك كُلفت بعمل بعض التعديلات على المقالة الثانية article_2.txt
لذا فأنت قمت بهذه التعديلات

> git status
On branch main
Your branch is up to date with 'origin/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_2.txt

no changes added to commit (use "git add" and/or "git commit -a")

وقمت بعمل add و commit لهذه التعديلات

> git add article_2.txt

> git commit -m "edit article 2"
[main 2053411] edit article 2
 1 file changed, 1 insertion(+), 1 deletion(-)

الآن ماذا حدث ؟ أصبحنا نملك commit في الـ Local Repository وليس موجودًا في الـ Remote Repository

لنرى الـ git log لنتأكد من هذا

> git log --all --oneline
2053411 (HEAD -> main) edit article 2
b4a383f (origin/main, origin/HEAD) create article number 2
7a5aa61 add article number 1

الآن الـ HEAD الخاص بنا هو الذي يسبق الـ origin/HEAD
لأننا انشأنا commit على الـ Local Repository والـ origin لا يعرف عنه شيء
بالتالي فهذا الـ commit ليس موجودًا في الـ Remote Repository

لنرى ماذا سيقول لنا الـ git status الآن

> git status
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

يقول أن كل شيء على ما يرام لكن الـ main الخاص بنا يسبق الـ origin/main بـ commit واحد فقط وهذا ما رأيناه في الـ git log فعلًا

ستراه هنا يقول لك أن تستخدم git push لكي تقوم برفع التعديلات التي قمت بها إلى الـ Remote Repository

حاليًا لدينا مشكلة وهي أن أعضاء الفريق الذين يعملون معك على نفس المشروع لن يروا ما قمت بتعديله لأنه على الـ Local Repository الخاص بك فقط
ولذا يجب عليك أن ترفع هذا الـ commit الذي انشأته إلى الـ Remote Repository
ليستطيع باقي أعضاء الفريق سحبه ويروا هذه التعديلات التي قمت بها في الـ Local Repository الخاصة بهم

هنا سنستخدم git push

> git push origin main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 16 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 291 bytes | 145.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/CompanyName/project-remote-repository.git
   b4a383f..2053411  main -> main

الآن قمنا برفع كل commit جديد لدينا من الـ Local Repository إلى الـ Remote Repository بنجاح
وإن نظرنا إلى الـ git log والـ git status الآن ستراهما يؤكدان ما فعلناه

> git log --oneline --all
2053411 (HEAD -> main, origin/main, origin/HEAD) edit article 2
b4a383f create article number 2
7a5aa61 add article number 1

> git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

وسترى أن الـ git push قام أيضًا بعمل دمج للـ origin/main مع الـ main في الـ Local Repository

نصيحة قبل أن ترفع شيء على الـ Remote Repository

حسنًا ما فعلناه للتو هو أننا قمنا بعمل تعديلات بشكل مباشر في الـ branch الـ main
وهذا في بيئات العمل يكون هو الفرع الرئيسي وفي غالب الأمر يكون هو خاص بالـ Production وبه الكود المستقر الخاص بالمشروع
لذا لا يفضل أن تقوم بالتعديل عليه بشكل مباشر

لذا يفضل دائمًا عندما تقوم بالعمل على شيء ما أن تقوم بإنشاء branch خاص بك مشتق من الفرع الذي تريد أن تعدل فيه
ويفضل أن تختار اسم جيد للفرع يكون اسم معبر عن العمل الذي ستقوم به كـ fix-issue-2024 أو add-new-article وهكذا
بالطبع في غالب الأمر المسميات تتفق أنت وأعضاء فريقك عليها

ثم عندما تنتهي من العمل على الوظيفة التي كلفت بها تقوم برفع هذا الـ branch الذي انشأته إلى Remote Repository بشكل مستقل
ليقوم الشخص المسؤول عن الـ Remote Repository بمراجعة ما قمت به ثم يختبر ويتأكد من كل شيء
ثم يقوم بدمج ما قمت به إلى الـ main الخاص بالـ Remote Repository أو بدمجه على فرع آخر كـ experiment أو testing و development بحسب الفرع التي كنت تريد التعديل عليه
الأمر يعود إلى كيفية تنظيم سير المشروع واختباره ليصل إلى مرحلة الاستقرار ليكون جاهزًا للـ Production ودمجه في الـ main

ملحوظة: وهذه مجرد أمور تختلف من شركة لشركة ومن فريق لفريق ليديره سير العمل وتنظيمه باستخدام Git و GitHub

إنشاء branch على الـ Local Repository ورفعه إلى الـ Remote Repository

لنحاول تطبيق ما قلناه الآن سنقوم بعمل تعديل ما، لكن في branch مستقل عن الـ main ونرفع هذا الفرع الذي انشأناه إلي الـ Remote Repository

لنفترض أنه تم تكليفك بكتابة المقالة الثالثة

أو شيء نقوم بعمل git pull لنتأكد أننا لدينا آخر التعديلات التي على الـ Remote Repository
ولكي لا يحدث أي merge conflict فيما بعد

> git pull origin main
From https://github.com/CompanyName/project-remote-repository.git
 * branch            main       -> FETCH_HEAD
Already up to date.

الآن بعد ما تأكدنا أننا نملك آخر التعديلات، نقوم بإنشاء الفرع الخاص بنا لنبدأ العمل في كتابة المقالة الثالثة

> git branch article-3

> git switch article-3
Switched to branch 'article-3'

الآن انشأنا الفرع وسميناه article-3 ثم انتقلنا إليه عن طريق الـ git switch
الآن نقوم بتنفيذ وعمل المقالة الثالثة
وعندما ننتهي نقوم بعمل git status لنتأكد من كل شيء قمنا بتعديله

> git status
On branch article-3
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        article_3.txt

nothing added to commit but untracked files present (use "git add" to track)

نحن حاليًا في article-3 وقمنا بالانتهاء من المقالة الثالثة لذا سنقوم بعمل git add وgit commit

> git add article_3.txt

> git commit -m "finish article number 3"
[article-3 ed32ec2] finish article number 3
 1 file changed, 1 insertion(+)
 create mode 100644 article_3.txt

الآن لنرى الـ git log ونتأكد أن كل شيء جاهز

> git log --oneline --all
ed32ec2 (HEAD -> article-3) finish article number 3
2053411 (origin/main, origin/HEAD, main) edit article 2
b4a383f create article number 2
7a5aa61 add article number 1

الـ HEAD يقف على article-3 وهو commit انشأناه للتو وتأكدنا من كل شيء
والآن نحن جاهزون لرفع الـ branch إلى الـ Remote Repository عن طريق git push

> git push origin article-3
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 16 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 339 bytes | 339.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/CompanyName/project-remote-repository.git
 * [new branch]      article-3 -> article-3

نحن الآن رفعنا فقط الـ branch الخاص بنا article-3 إلى origin أي إلى الـ Remote Repository
لكن origin لا يملك فرع يسمى article-3 لذا سيتم انشاءه أثناء عملية الـ git push

كيف سيكون شكل الـ log الخاص بالـ Remote Repository ؟

الآن دعونا نذهب إلى الـ Remote Repository ونرى كيف سيكون شكل الـ git log فيه

> git log --oneline --all
ed32ec2 (article-3) finish article number 3
2053411 (HEAD -> main) edit article 2
b4a383f create article number 2
7a5aa61 add article number 1

هذا سيكون الـ log من وجه نظر الـ Remote Repository ستراه أصبح لديه article-3 والـ commit الذي كان لدينا في الـ Local Repository
الآن سيقوم شخص ما بمراجعة ما قمت به في الـ article-3 ثم يدمجه في الـ main إن وجد أن كل شيء على ما يرام

لصبح بهذا الشكل

> git log --oneline --all
ed32ec2 (HEAD -> main, article-3) finish article number 3
2053411 edit article 2
b4a383f create article number 2
7a5aa61 add article number 1

هذا ما حدث في الـ Remote Repository حاليًا
الآن لنرجع إلى الـ Local Repository لنرى الـ git looping الخاص بالـ Local Repository

> git log --oneline --all
ed32ec2 (HEAD -> article-3, origin/article-3) finish article number 3
2053411 (origin/main, origin/HEAD, main) edit article 2
b4a383f create article number 2
7a5aa61 add article number 1

ستراه كما هو كما تركناه في الـ Local Repository
لكن الآن تم تحديث الـ Remote Repository وتم دمج article-3 في الـ main
لكن كما تعرف أن الـ origin لا يحدث محتواه بشكل تلقائي بل بشكل يدوي عن طريق الـ git fetch
لذا علينا ان نسحب هذه التعديلات إلى الـ Local Repository الخاص بنا

أولًا سنتنقل إلى الـ main

> git switch main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

ستلاحظ أنه يقول أن الـ main مطابقة مع origin/main وهذا من وجه نظر الـ Local Repository
لأن الـ origin لا يدري على التغيرات التي تحدث في الـ Remote Repository كما وضحنا
لذا علينا أن نقوم بعمل git fetch ليكون على دراية بما يحدث
أو يمكننا عمل git pull بشكل مباشر ليقوم بعمل fetch و merge في آن واحد

دعونا نستخدم git pull هذه المرة

> git pull origin main
From https://github.com/CompanyName/project-remote-repository.git
 * branch            main       -> FETCH_HEAD
Updating 2053411..ed32ec2
Fast-forward
 article_3.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 article_3.txt

لاحظ انه قام بعمل fetch للتعديلات ثم merge في خطوة واحدة
الآن لنرى الـ git log الخاص بالـ Local Repository كيف أصبح

> git log --oneline --all
ed32ec2 (HEAD -> main, origin/main, origin/article-3, origin/HEAD, article-3) finish article number 3
2053411 edit article 2
b4a383f create article number 2
7a5aa61 add article number 1

لترى أن كل شيء في الـ Local Repository أصبح مطابق للـ Remote Repository
ويمكنك التأكد من هذا في أي وقت عن طريق git fetch و git log

خاتمة

لقد قمنا بشرح كيفية التعامل مع الـ Remote Repository في الـ Git بشكل عام

أحب أن اراجع أهم النقاط هنا: