٢، ٥، التعامل مع المستودعات البعيدة

حتى تستطيع التعاون في أي مشروع يستخدم جت، تحتاج معرفة كيف تدير مستودعاتك البعيدة. المستودعات البعيدة هي نُسخ من مشروعك، وهذه النسخ مستضافة على الشابكة (الإنترنت) أو على شبكة داخلية. يمكن أن يكون لديك عددٌ منها، وكل واحد منها غالبًا يسمح لك إما بالقراءة فحسب («القراءة فقط»)، وإما بالتحرير كذلك («القراءة والكتابة»). والتعاون مع الآخرين يشمل إدارة هذه المستودعات البعيدة ودفع البيانات إليها وجذبها منها عندما تحتاج إلى مشاركة العمل. وإدارة المستودعات البعيدة تشمل معرفة كيف تضيفها في مستودعك وكيف تزيلها وكيف تدير العديد من الفروع البعيدة وكيف تجعل الفروع البعيدة متعقَّبة أو غير متعقَّبة، وغير ذلك. سنتناول في هذا الفصل بعضًا من مهارات الإدارة هذه.

المستودعات البعيدة قد تكون على جهازك المحلي

من الممكن جدا أن تعمل مع مستودع «بعيد» (‪“remote”‬)، ولكنه في الحقيقة على جهازك الذي تستعمله نفسه. كلمة «بعيد» لا تعني بالضرورة أن المستودع في مكانٍ آخر على الشبكة المحلية أو على الشابكة (الإنترنت)، ولكنها تعني فقط أنه في مكان آخر. فالعمل مع مستودع بعيد مثل هذا ما زال يحتاج جميع عمليات الدفع والجذب والاستحضار المعتادة مثل أي مستودع بعيد آخر.

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

لسرد المستودعات البعيدة التي هيأتها، استعمل أمر البعداء git remote. فإنه يُظهر لك الاسم المختصر لكل بعيد في مستودعك. وإذا استنسخت مستودعًا، فإنك على الأقل سترى origin («الأصل»)، وهو الاسم الذي يعطيه جت للمستودع الذي استنسخت منه:

$ git clone https://github.com/schacon/ticgit
Cloning into 'ticgit'...
remote: Reusing existing pack: 1857, done.
remote: Total 1857 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1857/1857), 374.35 KiB | 268.00 KiB/s, done.
Resolving deltas: 100% (772/772), done.
Checking connectivity... done.
$ cd ticgit
$ git remote
origin

يمكنك أيضا استعمال الخيار -v («إطناب»)، ليُظهر لك الروابط التي خزنها جت للأسماء المختصرة للمستودعات البعيدة ليستعملها لقراءة ذلك المستودع البعيد ولتحريره:

$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)

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

$ cd grit
$ git remote -v
bakkdoor  https://github.com/bakkdoor/grit (fetch)
bakkdoor  https://github.com/bakkdoor/grit (push)
cho45     https://github.com/cho45/grit (fetch)
cho45     https://github.com/cho45/grit (push)
defunkt   https://github.com/defunkt/grit (fetch)
defunkt   https://github.com/defunkt/grit (push)
koke      git://github.com/koke/grit.git (fetch)
koke      git://github.com/koke/grit.git (push)
origin    git@github.com:mojombo/grit.git (fetch)
origin    git@github.com:mojombo/grit.git (push)

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

لاحظ أن هذه المستودعات البعيدة تستعمل موافيق (بروتوكولات) متنوعة؛ سنتحدث عن هذا في فصل تثبيت جت على خادوم.

إضافة مستودعات بعيدة

ذكرنا أن أمر الاستنساخ git clone يضيف لك الأصلَ البعيد origin آليًّا، ورأيت مثالين على ذلك. لنعرف الآن كيف نضيف مستودعًا بعيدًا بأمر صريح. لإضافة مستودع جت بعيد جديد وتسميته باسم مختصر للإشارة إليه به بسهولة فيما بعد، نفذ git remote add <shortname> <url>، أي الاسم المختصر ثم الرابط:

$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)
pb	https://github.com/paulboone/ticgit (fetch)
pb	https://github.com/paulboone/ticgit (push)

يمكنك الآن استعمال الاسم pb في سطر الأوامر، بدلًا من الرابط بكامله. مثلا إذا أردت استحضار جميع المعلومات التي لدي پول ولكن ليست لديك في مستودعك بعد، استعمل أمر الاستحضار معه، أي git fetch pb:

$ git fetch pb
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 43 (delta 10), reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
From https://github.com/paulboone/ticgit
 * [new branch]      master     -> pb/master
 * [new branch]      ticgit     -> pb/ticgit

الآن صار فرع master من مستودع پول متاحًا محليًّا (في مستودعك على جهازك) بالاسم pb/master؛ يمكنك دمجه في أحد فروعك، أو سحب إيداعه الأخير إلى فرع محلي إذا أردت تفقّده. سنشرح بالتفصيل ما هي الفروع وكيف نستعملها في باب التفريع في جت.

الاستحضار والجذب من مستودعاتك البعيدة

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

$ git fetch «البعيد»

يذهب هذا الأمر إلى المستودع البعيد ويجذب منه كل البيانات التي لديه وليست لديك بعد. بعد أن تفعل هذا، ستجد لديك إشارات لجميع الفروع التي لدى هذا البعيد، فيمكنك دمجها أو النظر فيها وقتما شئت.

إذا استنسخت مستودعًا، فإن أمر الاستنساخ يضيف آليًّا هذا المستودع البعيد بالاسم ‪“origin”‬. لذا فإن git fetch origin يستحضر أي عمل قد دُفع إلى هذا المستودع بعدما استنسخته (أو استحضرت منه) آخر مرة. مهمٌ ملاحظة أن أمر الاستحضار ينزّل فقط البيانات إلى مستودعك المحلي؛ لكنه لا يدمجها مع عملك ولا يغير في أي شيء تعمل عليه. عليك دمجها يدويًا مع عملك عندما تكون مستعدًا لذلك.

إذا كان الفرع الحالي مُعَدًّا ليتعقّب فرعًا بعيدًا (انظر الفصل الفرعي التالي وباب التفريع في جت للمزيد من المعلومات)، فأمر الجذب git pull يستحضر آليًّا هذا الفرع البعيد ثم يدمجه في الفرع الحالي. هذا قد يكون أسهل أو أريح لك. وأمر الاستنساخ بطبيعته يجعل لك الفرع المبدئي المحلي يتعقب الفرع المبدئي البعيد (master أو main أو أيًّا كان اسمه) في المستودع الذي استنسخت منه. يستحضر أمر الجذب البيانات من المستودع الذي استنسخت منه في الأصل عادةً ثم يحاول دمجها آليًّا في الفرع الذي تعمل فيه حاليًّا.

بَدءًا من النسخة 2.27 من جت، سيحذرك أمر الجذب git pull إن لم يكن متغير pull.rebase مهيأً. وسيبقى يحذرك حتى تعيّن له قيمة.

إن أردت سلوك جت المبدئي (التسريع متى أمكن، وإلا فإنشاء إيداع دمج)، فنفذ:
git config --global pull.rebase "false"

وإذا أردت إعادة التأسيس عند الجذب، فنفذ:
git config --global pull.rebase "true"

الدفع إلى مستودعاتك البعيدة

عندما يكون مشروعك في مرحلة تود مشاركتها، عليك دفعه إلى المنبع. الأمر الذي يفعل هذا يسير: git push <remote> <branch>، أي اسم المستودع البعيد ثم الفرع: فإذا أردت دفع فرع master الخاص بك إلى المستودع الأصل origin (غالبا يعيّن لك الاستنساخ هذين الاسمين آليًّا)، فتنفيذ هذا الأمر يدفع أي إيداعات صنعتها إلى الخادوم:

$ git push origin master

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

فحص مستودع بعيد

إذا أردت رؤية معلومات أكثر عن بعيد معين، فعليك بالأمر git remote show «البعيد». إذا نفذت هذا الأمر مع اسم مختصر معين، مثل origin، فسترى شيئًا مثل هذا:

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/schacon/ticgit
  Push  URL: https://github.com/schacon/ticgit
  HEAD branch: master
  Remote branches:
    master                               tracked
    dev-branch                           tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

إنه يسرد لك رابط المستودع البعيد إضافةً إلى معلومات تعقب الفروع. وللإفادة يخبرك كذلك بأنك إذا كنت في فرع master واستعملت أمر الجذب git pull فإنه تلقائيًّا سيدمج فرع master البعيد في الفرع المحلي بعد استحضاره. ويسرد لك كذلك جميع الإشارت البعيدة التي جذبها إليك.

هذا مثال صغير غالبًا ستقابله. ولكن عندما تستخدم جت بكثرة، فسيعطيك git remote show معلومات أكثر كثيرًا:

$ git remote show origin
* remote origin
  URL: https://github.com/my-org/complex-project
  Fetch URL: https://github.com/my-org/complex-project
  Push  URL: https://github.com/my-org/complex-project
  HEAD branch: master
  Remote branches:
    master                           tracked
    dev-branch                       tracked
    markdown-strip                   tracked
    issue-43                         new (next fetch will store in remotes/origin)
    issue-45                         new (next fetch will store in remotes/origin)
    refs/remotes/origin/issue-11     stale (use 'git remote prune' to remove)
  Local branches configured for 'git pull':
    dev-branch merges with remote dev-branch
    master     merges with remote master
  Local refs configured for 'git push':
    dev-branch               pushes to dev-branch               (up to date)
    markdown-strip           pushes to markdown-strip           (up to date)
    master                   pushes to master                   (up to date)

يُظهر لك هذا الأمر ما الفرع الذي يجذب جت إليه تلقائيًّا عندما تنفذ git push وأنت في فرع معين. ويُظهر لك كذلك ما فروع المستودع البعيد التي ليست لديك بعد، وما الفروع البعيدة التي لديك وأُزيلت من البعيد، وما الفروع المحلية التي تقبل الدمج التلقائي من فروعها المتعقِبة للبعيد عندما تنفذ git pull.

تغيير اسم بعيد أو حذفه

يمكنك استعمال git remote rename لتغيير الاسم المختصر لمستودع بعيد. مثلا، لتغيير اسم pb إلى paul، نفّذ:

$ git remote rename pb paul
$ git remote
origin
paul

مهم ملاحظة أن هذا يغيّر أسماء فروعك المتعقِبة للبعيد أيضا. فالذي كان يسمى pb/master صار paul/master.

وإذا أردت إزالة إشارة لمستودعٍ بعيد لسبب ما — نقلت المستودع، أو لم تعد تستخدم خادوم مرآة معين، أو مساهم لم يعد يساهم — استعمل أم‍ر إزالة البعيد git remote remove أو اختصاره git remote rm:

$ git remote remove paul
$ git remote
origin

وما إن تحذف الإشارة إلى بعيدٍ هكذا، فإن جميع الفروع المتعقِبة له وجميع إعدادات التهيئة المرتبطة به ستُحذف كذلك.