<?xml version="1.0"?>
<rss version="2.0"><channel><title>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: Git</title><link>https://academy.hsoub.com/programming/workflow/git/page/2/?d=2</link><description>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: Git</description><language>ar</language><item><title>[&#x641;&#x64A;&#x62F;&#x64A;&#x648;] &#x623;&#x633;&#x627;&#x633;&#x64A;&#x627;&#x62A; Git</title><link>https://academy.hsoub.com/programming/workflow/git/%D9%81%D9%8A%D8%AF%D9%8A%D9%88-%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-git-r658/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2019_02/1.png.37eda166a1d5c908c8b706dce0126dfa.png" /></p>

<p>
	<iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="394" src="https://www.youtube.com/embed/WVFXBMASu7I" width="700"></iframe>
</p>

<p>
	هل سمعت عن نظام إدارة الإصدارات Git وترغب بتعلم المزيد عنه؟ هل أنت مطور ترغب في استخدام GitHub وتجد التعامل معه صعبًا؟ هذا الفيديو أُعدّ خصيصًا لك.
</p>

<p>
	سنشرح مفاهيم Git وأساسياته، وسنطبق ذلك عمليًا. يمكنك أن تطلع على <a href="https://academy.hsoub.com/programming/workflow/git/" rel="">سلسلة المقالات التي وفرناها في أكاديمية حسوب عن Git</a>.
</p>
]]></description><guid isPermaLink="false">658</guid><pubDate>Tue, 05 Feb 2019 09:27:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x623;&#x633;&#x626;&#x644;&#x629; &#x627;&#x644;&#x639;&#x634;&#x631;&#x629; &#x627;&#x644;&#x623;&#x643;&#x62B;&#x631; &#x62A;&#x643;&#x631;&#x627;&#x631;&#x627; &#x62D;&#x648;&#x644; Git</title><link>https://academy.hsoub.com/programming/workflow/git/%D8%A7%D9%84%D8%A3%D8%B3%D8%A6%D9%84%D8%A9-%D8%A7%D9%84%D8%B9%D8%B4%D8%B1%D8%A9-%D8%A7%D9%84%D8%A3%D9%83%D8%AB%D8%B1-%D8%AA%D9%83%D8%B1%D8%A7%D8%B1%D8%A7-%D8%AD%D9%88%D9%84-git-r318/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_04/git-faq.png.512833524445da56dab945b01c7b44d4.png" /></p>

<p dir="rtl">
	سنتناول في هذا المقال الأسئلة العشرة الأكثر تكرارًا حول Git والحلول المتعلقة بها. ستساعد هذه الحلول في تجاوز بعض العقبات عند استخدام Git.
</p>

<p dir="rtl" style="text-align: center;">
	<img alt="git-faq.png" class="ipsImage ipsImage_thumbnailed" data-fileid="15426" data-unique="lsza8u7s1" src="https://academy.hsoub.com/uploads/monthly_2016_04/git-faq.png.6832bcccca08ede902166ca183fde516.png"></p>

<h2 dir="rtl">
	1. كيف أقوم بتحرير رسالة إيداع commit خاطئة في Git؟
</h2>

<p dir="rtl">
	وهو سؤال يطرح بكثرة من طرف كل من بدأ لتوّه باستخدام Git. لتحرير رسالة إيداع <span style="font-family:courier new,courier,monospace;">commit</span> خاطئة قمنا بكتابتها، نستخدم الأوامر التالية:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_7">
<span class="pln">git commit --amend </span></pre>

<p dir="rtl">
	سيقوم الأمر بفتح المحرّر الذي سيسمح بتغيير أحدث إيداع.
</p>

<p dir="rtl">
	إن أردنا تحرير رسالة الإيداع مباشرة عبر سطر الأوامر، يمكننا القيام بذلك باستخدام الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_9">
<span class="pln">git commit --amend -m "الرسالة الجديدة"</span></pre>

<h2 dir="rtl">
	2. كيف أتراجع عن آخر إيداع commit كاملا؟
</h2>

<p dir="rtl">
	للتراجع عن إيداع بعض الملفّات نقوم في البداية بإلغاء آخر إيداع باستخدام الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_11">
<span class="pln">git reset --hard HEAD~1</span></pre>

<p dir="rtl">
	سيقوم هذا الأمر بنقل مؤشر الرأس HEAD إلى الإيداع قبل الأخير. بعد ذلك، نقوم بعرض حالة جميع الملفات مرّة أخرى باستخدام الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_13">
<span class="pln">git status</span></pre>

<p dir="rtl">
	وأخيرًا، نضيف الملفات التي نودّ إضافتها إلى الإيداع باستخدام الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_7846_7">
<span class="pln">git add ...</span></pre>

<h2 dir="rtl">
	3. كيف أتراجع عن إضافة ملف git add؟
</h2>

<p dir="rtl">
	للتراجع عن إضافة بعض أو كل الملفّات إلى منطقة الإدراج بالأمر المذكور، نستخدم أحد الأوامر التالية:
</p>

<p dir="rtl">
	للتراجع عن ملف وحيد:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_17">
<span class="pln">git reset </span><span class="tag">&lt;FileName&gt;</span></pre>

<p dir="rtl">
	للتراجع عن جميع الملفّات:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_19">
<span class="pln">git reset</span></pre>

<h2 dir="rtl">
	4. كيف أحذف تفرع branch (محلي أو بعيد)؟
</h2>

<p dir="rtl">
	لحذف تفرّع محلّي، نستخدم الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_21">
<span class="pln">git branch -d yourLocalBranchName</span></pre>

<p dir="rtl">
	ولحذف تفرّع بعيد، نستخدم الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_23">
<span class="pln">git push origin --delete yourRemoteBranchName</span></pre>

<h2 dir="rtl">
	5. كيف أحذف ملفات محلية من التفرع الحالي
</h2>

<p dir="rtl">
	لحذف جميع الملفّات المحلّية التي لا نرغب بإيداعها أو الحفاظ عليها في مجلّد العمل، نستخدم الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_25">
<span class="pln">git clean -f</span></pre>

<p dir="rtl">
	أو:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_27">
<span class="pln">git reset --hard</span></pre>

<h2 dir="rtl">
	6. كيف أعيد تسمية تفرع محلي؟
</h2>

<p dir="rtl">
	لإعادة تسمية تفرّع محلّي، لدينا حالتان:
</p>

<p dir="rtl">
	إعادة تسمية لتفرّع الحالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_29">
<span class="pln">git branch -m newBranchName</span></pre>

<p dir="rtl">
	إعادة تسمية تفرّع آخر ليس التفرّع النّشط الحالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_31">
<span class="pln">git branch -m oldBranchName newBranchName</span></pre>

<h2 dir="rtl">
	7. كيف أنشئ تفرعا بعيدا remote Git branch؟
</h2>

<p dir="rtl">
	لإنشاء تفرّع بعيد، نقوم أوّلًا بإنشاء تفرّع محلّي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_33">
<span class="pln">git checkout -b newBranchName</span></pre>

<p dir="rtl">
	ومن ثم نقوم بدفع التفرّع الذي أنشأناه إلى الخادم البعيد:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_35">
<span class="pln">git push origin newBranchName</span></pre>

<h2 dir="rtl">
	8. كيف أغير الرابط الخاص بمستودع بعيد remote Git repository؟
</h2>

<p dir="rtl">
	لتغيير الرابط الخاص بمستودع بعيد (لنفترض أنه التفرّع <span style="font-family:courier new,courier,monospace;">origin</span>) نستخدم الأمر التالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_37">
<span class="pln">git remote set-url origin newURL</span></pre>

<h2 dir="rtl">
	9. كيف أغير اسم من قام بالإيداع؟
</h2>

<p dir="rtl">
	يمكن تغيير اسم من قام بالإيداع في سجلّ المُستودع باستخدام السكربت التالي <a href="https://help.github.com/articles/changing-author-info" rel="external nofollow">المأخوذ من مقالات موقع </a><a href="https://help.github.com/articles/changing-author-info" rel="external nofollow">github.com</a>:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_39">
<span class="pln">git filter-branch --env-filter '

an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITER_NAME"
cm="$GIT_COMMITTER_EMAIL"

if[ "$GIT_COMMITTER_EMAIL" = "your@email.to.match" ]
then
cn="New Committer Name"
cm="New Committer Email"
fi
if[ "$GIT_AUTHOR_EMAIL" = "your@email.to.match" ]
then
an="New Author Name"
am="New Author Email"
fi

export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_AUTHOR_EMAIL="$cm"'</span></pre>

<h2 dir="rtl">
	10. كيف أستنسخ مستودعا في مجلد معين؟
</h2>

<p dir="rtl">
	لاستنساخ مستودع في مجلّد معيّن، نحتاج إمّا:
</p>

<p dir="rtl">
	الانتقال بمسار سطر الأوامر إلى داخل ذلك المجلّد وتنفيذ الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_45">
<span class="pln">git clone </span><span class="tag">&lt;URL&gt;</span></pre>

<p dir="rtl">
	أو ننفّذ الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3789_47">
<span class="pln">git clone </span><span class="tag">&lt;URL&gt;</span><span class="pln"> </span><span class="tag">&lt;yourFolderName&gt;</span></pre>

<p dir="rtl">
	حيث أن <span style="font-family:courier new,courier,monospace;">yourFolderName</span> هو اسم/مسار المُجلّد المعني بالأمر.
</p>

<p dir="rtl">
	ترجمة -وبتصرّف- للمقال <a href="http://www.codingdefined.com/2014/07/top-10-frequently-asked-questions-on-git.html" rel="external nofollow">Top 10 frequently asked questions on Git</a> لصاحبه Hemant Joshi.
</p>
]]></description><guid isPermaLink="false">318</guid><pubDate>Wed, 20 Apr 2016 12:15:33 +0000</pubDate></item><item><title>&#x625;&#x639;&#x627;&#x62F;&#x629; &#x62A;&#x623;&#x633;&#x64A;&#x633; &#x627;&#x644;&#x62A;&#x641;&#x631;&#x64A;&#x639;&#x627;&#x62A; (Rebasing) &#x641;&#x64A; Git</title><link>https://academy.hsoub.com/programming/workflow/git/%D8%A5%D8%B9%D8%A7%D8%AF%D8%A9-%D8%AA%D8%A3%D8%B3%D9%8A%D8%B3-%D8%A7%D9%84%D8%AA%D9%81%D8%B1%D9%8A%D8%B9%D8%A7%D8%AA-rebasing-%D9%81%D9%8A-git-r289/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_03/git-rebasing.png.5fd24eeb88eee19f4a5287239dbf51b4.png" /></p>

<p>
	توجد طريقتان أساسيتان في Git لتضمين التعديلات من تفريع إلى آخر: <span style="font-family:courier new,courier,monospace;"><code>merge</code></span> و <code>rebase</code>. يشرح هذا المقال ماهية إعادة تأسيس التفريعات Rebasing، كيفيتها، الفائدة منها والحالات التي يجدر بك عدم استخدام إعادة التأسيس فيها.
</p>

<p style="text-align: center;">
	<img alt="git-rebasing.png.4ea0e0373d5ea9e5b6127e6" class="ipsImage ipsImage_thumbnailed" data-fileid="14228" data-unique="k0e3h1p8j" src="https://academy.hsoub.com/uploads/monthly_2016_03/git-rebasing.png.4ea0e0373d5ea9e5b6127e62f7329569.png"></p>

<h2 id="مبادئ-إعادة-التأسيس">
	مبادئ إعادة التأسيس
</h2>

<p>
	يمكن بالعودة إلى المثال في درس <a href="https://academy.hsoub.com/programming/workflow/git/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D9%81%D8%B1%D9%8A%D8%B9-branching-%D9%88%D8%A7%D9%84%D8%AF%D9%85%D8%AC-merging-%D9%81%D9%8A-git-r276/#%D8%A7%D9%84%D9%85%D8%A8%D8%A7%D8%AF%D8%A6-%D8%A7%D9%84%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-%D9%84%D8%AF%D9%85%D8%AC-%D8%A7%D9%84%D8%AA%D9%81%D8%B1%D9%8A%D8%B9%D8%A7%D8%AA">المبادئ الأساسية لدمج التفريعات</a> رؤية تمايز أعمالك بإضافة إيداعات إلى كلٍّ من التفريعين.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/01_rebasing.png.3533089d95857869caeebc91a59a533f.png"><img alt="01_rebasing.thumb.png.d8d3d809f54b40b530" class="ipsImage ipsImage_thumbnailed" data-fileid="13423" data-unique="gyrwzmr4c" src="https://academy.hsoub.com/uploads/monthly_2016_02/01_rebasing.thumb.png.d8d3d809f54b40b53074087ddf05666e.png"></a>
</p>

<p>
	استخدام أمر <code>git merge</code> هو أسهل طريقة، مثل ما رأينا سابقا، لتضمين تفريع في آخر. ينفّذ الأمرُ الدمجَ الثلاثي بين آخر لقطتين في كلّ تفريع (<code>C3</code> و<code>C4</code>) واللقطة المشتركة الأقرب (<code>C2</code>) منشئا بذلك لقطة (وإيداعا) جديدة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/02_rebasing.png.b335dec9364abb0ef2ff2cfc596e894d.png"><img alt="02_rebasing.thumb.png.0f84f6373bdf5073c5" class="ipsImage ipsImage_thumbnailed" data-fileid="13424" data-unique="iwkshksbd" src="https://academy.hsoub.com/uploads/monthly_2016_02/02_rebasing.thumb.png.0f84f6373bdf5073c5e8d66f0e4c8540.png"></a>
</p>

<p>
	إلا أنه توجد طريقة أخرى: يمكنك أخذ الترقيع Patch الذي أضافه الإيداع <code>C4</code> ثم تطبيقه على الإيداع <code>C3</code>. تسمى هذه العملية في Git بإعادة التأسيس. يتيح الأمر <code>rebase</code> أخذ جميع الإيداعات التي أضيفت إلى تفريع وتكرارها على تفريع آخر.
</p>

<p>
	يكون تطبيق هذا المبدأ على المثال في الصورة بتنفيذ الأمر على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2428_7">
<span class="pln">git checkout experiment
git rebase master
  First, rewinding head to replay your work on top of it...
  Applying: added staged command</span></pre>

<p>
	يعمل الأمر بالرجوع إلى الإيداع السابق المشترك بين التفريعين (التفريع الذي تعمل عليه الآن، والتفريع الذي تريد إعادة التأسيس عليه)، الحصول على التغييرات التي أدرجها كل إيداع على التفريع الحالي وتخزينها في ملف ظرفي، ضبط التفريع الحالي على آخر إيداع في التفريع الذي نريد إعادة التأسيس عليه ثم في الأخير تطبيق التعديلات بالترتيب.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/03_rebasing.png.95aeab79efb9ce0b46c361a5431fbe75.png"><img alt="03_rebasing.thumb.png.0407ae1e987aa1339c" class="ipsImage ipsImage_thumbnailed" data-fileid="13425" data-unique="n90w8tavb" src="https://academy.hsoub.com/uploads/monthly_2016_02/03_rebasing.thumb.png.0407ae1e987aa1339cef74cc0a10bfa2.png"></a>
</p>

<p>
	نستطيع بالوصول إلى هذه النقطة العودة إلى التفريع <code>master</code> وتنفيذ دمج بتقدم سريع:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2428_9">
<span class="pln">git checkout master
git merge experiment</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/04_rebasing.png.17446d3d3e3b66b4e3c6faf2bde3ef40.png"><img alt="04_rebasing.thumb.png.d6a80a7f679ed65000" class="ipsImage ipsImage_thumbnailed" data-fileid="13426" data-unique="okwxkn6hf" src="https://academy.hsoub.com/uploads/monthly_2016_02/04_rebasing.thumb.png.d6a80a7f679ed650000117ce64cea659.png"></a>
</p>

<p>
	يشير الإيداع <code>'C4</code> إلى نفس اللقطة التي يشير إليها الإيداع <code>C5</code> في مثال الدمج الذي تحدثنا عنه في البداية. لا يوجد فرق في المنتوج النهائي بين الاثنين؛ إلا أن إعادة التأسيس تجعل سجل التعديلات أكثر وضوحا. يبدو سجل الإيداعات في تفريع أعيد تأسيسه خطيًّا: تظهر الأعمال كما لو أنها حدثت بالتتالي، حتى لو كان الواقع أنها كانت بالتوازي.
</p>

<p>
	يُلجَأ عادة لتأسيس التفريعات للتأكد من أن الإيداعات تُطبَّق دون مشاكل على تفريع بعيد؛ مثلا عند المشاركة في مشروع لا تتولى صيانته. تعمل في هذه الحالة على تفريع ثم تعيد تأسيس التفريع على <code>origin/master</code> عندما تكون جاهزا لإرسال الترقيع إلى المشروع الرئيس. لن يحتاج مسؤول المشروع في هذه الحالة إلا إلى دمج سريع.
</p>

<p>
	انتبه إلى أن اللقطة التي يشير إليها التفريع هي نفسها، سواء كانت الأخيرة من إيداعات بعد إعادة تأسيس التفريع أو إيداع دمج. وجه الاختلاف هو فقط سجل التغييرات. تكرّر إعادة التأسيس التغييرات من خط عمل على آخر بالترتيب الذي حدثت به في حين يأخذ الدمج نقطتي النهاية ويدمجهما معا.
</p>

<h2 id="إعادات-تأسيس-متقدمة">
	إعادات تأسيس متقدمة
</h2>

<p>
	يتيح Git إمكانية تطبيق إعادة التأسيس على أمور أخرى غير التفريع المستهدف بإعادة التأسيس. نأخذ المثال الموضَّح في الصورة أدناه. أنشأت تفريعا جديدا باسم <code>server</code> (<a href="https://academy.hsoub.com/programming/workflow/git/%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D8%AA%D9%81%D8%B1%D9%8A%D8%B9%D8%A7%D8%AA-git-%D9%88%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85%D9%87%D8%A7-%D9%84%D8%AA%D8%AE%D8%B7%D9%8A%D8%B7-%D8%B3%D9%8A%D8%B1-%D8%A7%D9%84%D8%B9%D9%85%D9%84-r287#%D8%AA%D9%81%D8%B1%D9%8A%D8%B9%D8%A7%D8%AA-%D8%A7%D9%84%D9%85%D9%88%D8%A7%D8%B6%D9%8A%D8%B9">تفريع موضوع</a> Topic branch) لإضافة ميزات من جهة الخادوم إلى مشروعك وأضفت إيداعا إلى هذا التفريع؛ ثم أنشأت بعدها تفريعا جديدا لميزات تعمل في جانب العميل <code>client</code> وأضفت عليه إيداعات متتابعة. عدت في الأخير إلى تفريع <code>server</code> وأضفت إليه إيداعات أخرى.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/05_rebasing.png.d5776a3ef6dc30af13993a20139ac517.png"><img alt="05_rebasing.thumb.png.bd2e27cd4c5eeef826" class="ipsImage ipsImage_thumbnailed" data-fileid="13427" data-unique="yv55h8fbs" src="https://academy.hsoub.com/uploads/monthly_2016_02/05_rebasing.thumb.png.bd2e27cd4c5eeef826e83255dd4c6326.png"></a>
</p>

<p>
	نريد الآن دمج التغييرات في جانب العميل إلى التفريع الرئيس وفي نفس الوقت ترك التعديلات في جانب الخادوم لاختبارها أكثر. نستخدم خيار <code>onto--</code> مع أمر <code>git rebase</code> لأخذ الإيداعات الموجودة على التفريع <code>client</code> دون أن تكون موجودة على <code>server</code> (أي الإيداعات <code>C8</code> و<code>C9</code>):
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2428_13">
<span class="pln">git rebase --onto master server client</span></pre>

<p>
	يمكن تفسير الأمر السابق بـ”افحص تفريع <code>client</code>، اعثر على الإيداعات التالية للإيداع المشترك بينه والتفريع <code>server</code> ثم طبقها على التفريع <code>master</code>“. يبدو الأمر معقّدا إلا أن النتيجة مذهلة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/06_rebasing.png.439f786980bf348aa9be21cde6275cfd.png"><img alt="06_rebasing.thumb.png.472a503c4cc4cdeba0" class="ipsImage ipsImage_thumbnailed" data-fileid="13428" data-unique="kql49to2o" src="https://academy.hsoub.com/uploads/monthly_2016_02/06_rebasing.thumb.png.472a503c4cc4cdeba0fe8b15919ed95d.png"></a>
</p>

<p>
	يمكن بعدها تطبيق دمج سريع على التفريع الرئيس:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2428_15">
<span class="pln">git checkout master
git merge client</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/07_rebasing.png.25bb05cc555275d02ed939d444f300ed.png"><img alt="07_rebasing.thumb.png.9bf962b7f52b8aa9cb" class="ipsImage ipsImage_thumbnailed" data-fileid="13429" data-unique="fvnumko0h" src="https://academy.hsoub.com/uploads/monthly_2016_02/07_rebasing.thumb.png.9bf962b7f52b8aa9cbe4fdf4657765ba.png"></a>
</p>

<p>
	نرغب الآن في تضمين التفريع <code>server</code> أيضا. تمكننا إعادة تأسيس التفريع <code>server</code> على التفريع <code>master</code> دون الحاجة لفحصه أولا بتنفيذ الأمر <code>[git rebase [basebranch] [topicbranc</code>. يفحص الأمر تفريع الموضوع (أي التفريع <code>server</code> في هذه الحالة) تلقائيا ثم يؤسسه على التفريع القاعدي (<code>master</code>):
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2428_17">
<span class="pln">git rebase master server</span></pre>

<p>
	يُعيد الأمر تأسيس التفريع <code>server</code> على التفريع <code>master</code> على النحو الموضَّح في الصورة التالية.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/08_rebasing.png.110fca70e8d1c5b034553fa8b000d09a.png"><img alt="08_rebasing.thumb.png.ae2f0e49c6536f48dc" class="ipsImage ipsImage_thumbnailed" data-fileid="13430" data-unique="pop2o5tdx" src="https://academy.hsoub.com/uploads/monthly_2016_02/08_rebasing.thumb.png.ae2f0e49c6536f48dc734ad01fe6f0f9.png"></a>
</p>

<p>
	نطبق دمجا سريعا للتفريع القاعدي <code>master</code>:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2428_19">
<span class="pln">git checkout master
git merge server</span></pre>

<p>
	يمكن الآن حذف التفريعين <code>server</code> و<code>client</code> لأن جميع الأعمال فيهما أدمجت في التفريع الرئيس ولم تعد بحاجة إليها.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2428_21">
<span class="pln">git branch -d client
git branch -d server</span></pre>

<p>
	يبدو سجل التعديلات كما يظهر في الصورة أدناه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/09_rebasing.png.3a2f4806fa0ef60ba09f27511520cd74.png"><img alt="09_rebasing.thumb.png.86bf3f5fa148c06cfd" class="ipsImage ipsImage_thumbnailed" data-fileid="13431" data-unique="7zts524e4" src="https://academy.hsoub.com/uploads/monthly_2016_02/09_rebasing.thumb.png.86bf3f5fa148c06cfdd8d7b3886cbdd3.png"></a>
</p>

<h2 id="مشاكل-إعادة-التأسيس">
	مشاكل إعادة التأسيس
</h2>

<p>
	يمكن إجمال مخاطر إعادة تأسيس التفريعات في النصيحة التالية: لا تُعِد تأسيس إيداعات موجودة خارج مستودعك.
</p>

<p>
	تهجُر عندما تعيد تأسيس تفريع، إيداعاتٍ موجودةً وتبدلها بأخرى جديدة مشابهة إلا أنها مختلفة. تصبح الأمور صعبة وغير مرتبة عند استخدام إعادة التأسيس بما يخالف النصيحة أعلاه، مثلا عندما تدفع إيداعات إلى مستودع مشترك ثم يجلبها آخرون ويعملون عليها، ثم تعيد كتابة الإيداعات باستخدام أمر <code>git rebase</code> وتدفعها إلى المستودع مرة أخرى. سيحتاج مشاركوك في هذه الحالة لإعادة دمج أعمالهم ويمكن أن تحدث مشاكل عندما يريدون دفع أعمالهم بعدك.
</p>

<p>
	فلنأخذ مثالا لحالة يمكن أن تؤدي فيها إيداعات - أعيد تأسيسها ووُفِّرت للعموم - إلى مشاكل. نفترض أنك نسخت مستودعا من خادوم مركزي ثم أجريت أعمالا عليه. يبدو سجل الإيداعات على النحو الموضَّح في الصورة التالية.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/10_rebasing.png.e19ad56cb853a59933a4718ac32f34e9.png"><img alt="10_rebasing.thumb.png.041a6404cef6350521" class="ipsImage ipsImage_thumbnailed" data-fileid="13432" data-unique="ne8toz57a" src="https://academy.hsoub.com/uploads/monthly_2016_02/10_rebasing.thumb.png.041a6404cef63505213a5bc83dbe6aa2.png"></a>
</p>

<p>
	يعمل أحدهم في هذه الأثناء على إضافة تعديلات إلى المستودع من ضمنها دمج تفريع ثم يدفع النتيجة إلى الخادوم المركزي، تأتي أنت وتفتش عن الجديد على المستودع البعيد وتدمج التفريع البعيد الجديد إلى عملك؛ يصبح سجل الإيداعات على النحو التالي.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/11_rebasing.png.2da90772aed6661164f7e2eda7188775.png"><img alt="11_rebasing.thumb.png.76bfb6169ff92ada9a" class="ipsImage ipsImage_thumbnailed" data-fileid="13433" data-unique="tum3nqzt2" src="https://academy.hsoub.com/uploads/monthly_2016_02/11_rebasing.thumb.png.76bfb6169ff92ada9a1fd938065f5577.png"></a>
</p>

<p>
	يقرّر الشخص الذي دفع التفريع المدموج التراجع وإعادة تأسيس التفريع بدلا من ذلك؛ ينفذ أمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2916_7">
<span class="pln"> git push --force </span></pre>

<p>
	لتغيير سجل الإيداعات على الخادوم، ثم تأتي أنت للتفتيش عن جديد المستودع البعيد وتجلب الإيداعات الجديدة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/12_rebasing.png.10d1330cb5a4018cf689e3c78f9c65b0.png"><img alt="12_rebasing.thumb.png.5c73d893789e9aae01" class="ipsImage ipsImage_thumbnailed" data-fileid="13434" data-unique="our8r8jkd" src="https://academy.hsoub.com/uploads/monthly_2016_02/12_rebasing.thumb.png.5c73d893789e9aae01a82a06c42404f0.png"></a>
</p>

<p>
	أنتما الآن في ورطة: تنفيذك لأمر:
</p>

<p>
	 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2916_9">
<span class="pln">git pull </span></pre>

<p>
	سينشئ إيداعَ دمج يتضمّن سجلي التعديلات وسيبدو المستودع لديك كالتالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/13_rebasing.png.dc0a24fafb67d2e7ac6a25357e58444b.png"><img alt="13_rebasing.thumb.png.7903ef4657c6aa0a85" class="ipsImage ipsImage_thumbnailed" data-fileid="13435" data-unique="9c7u6pimf" src="https://academy.hsoub.com/uploads/monthly_2016_02/13_rebasing.thumb.png.7903ef4657c6aa0a85a7dd3bf0726f02.png"></a>
</p>

<p>
	سيظهر عند تنفيذ أمر <code>git log</code> على سجل التعديلات أعلاه إيداعان لديهما نفس الكاتب، التاريخ والرسالة؛ أمر مربك. علاوة على ذلك، يؤدي دفع بيانات بسجل التغيير هذا إلى الخادوم إلى إدخال كل هذه الإيداعات المعاد تأسيسها إلى الخادوم وهو ما سيربك الآخرين أكثر. من الآمَن في هذه الحالة افتراضُ أن المطوّر الآخر لا يريد أن يَبقى الإيداعان <code>C4</code> و<code>C6</code> في سجل الإيداعات؛ ولهذا السبب أعاد التأسيس أصلا.
</p>

<h3 id="إصلاح-ما-أفسدته-إعادة-التأسيس">
	إصلاح ما أفسدته إعادة التأسيس
</h3>

<p>
	يوفر Git آليات إضافية لحالات مثل التي رأيناها في الفقرة السابقة. التحدي في المواقف التي يدفع فيها أحد أعضاء الفريق تعديلات تغير تلك التي أعدت تأسيس عملك عليها هو التفريق بين عملك وبين ما أعيدت كتابته. يحسب Git، إضافة إلى مجموع التحقق (دالة SHA-1) الخاص بالإيداع مجموع تحقق خاص بالترقيع Patch الذي أضيف مع الإيداع؛ يسمّى مجموع التحقق هذا بمعرّف الترقيع Patch id.
</p>

<p>
	يمكن لـGit، عندما تجلب بيانات أعيدت كتابتها ثم تعيد التأسيس لها على الإيداعات الجديدة من الشريك، أن يتعرّف على الإيداعات الخاصة بك ثم يطبقها على التفريع الجديد.
</p>

<p>
	بدلا من تنفيذ أمر <code>git merge</code> بعد أن نفّذ الشريك أمر <code>git push --force</code> في المثال السابق (الحالة الموضَّحة في الصورة قبل الأخيرة) نفّذ الأمر <code>git rebase teamone/master</code> وسيقوم Git بالتالي:
</p>

<ul><li>
		تحديد الإيداعات الخاصة بتفريعك فقط (أي الإيداعات <code>C6</code>، <code>C4</code>، <code>C3</code>، <code>C2</code> و<code>C7</code>).
	</li>
	<li>
		التعرف على الإيداعات التي ليست إيداعات دمج (<code>C3</code>، <code>C2</code> و<code>C4</code>).
	</li>
	<li>
		تحديد الإيداعات التي لم تُعد كتابتها في التفريع الوجهة (التفريعان <code>C2</code> و<code>C3</code> فالإيداعان <code>C4</code> و<code>'C4</code> هما نفس الترقيع، أي أن تعديلاتهما هي نفسها).
	</li>
	<li>
		تطبيق هذه الإيداعات على التفريع <code>teamone/master</code>.
	</li>
</ul><p>
	ينتج عن الخطوات المتّبعة الوضعية التالية بدلا من تلك التي كنا سنجد فيها أنفسنا لو نفّذنا أمر <code>git pull</code>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/14_rebasing.png.cb43467800d8578d89471f0305e13555.png"><img alt="14_rebasing.thumb.png.69cbff3d89d3fe30e8" class="ipsImage ipsImage_thumbnailed" data-fileid="13436" data-unique="yy9euh9ii" src="https://academy.hsoub.com/uploads/monthly_2016_02/14_rebasing.thumb.png.69cbff3d89d3fe30e8200f3e37052962.png"></a>
</p>

<p>
	تعمل الطريقة أعلاه فقط إن كان الإيداعان <code>C4</code> و<code>'C4</code> الذين أضافهما شريكك متطابقين تقريبا؛ وإلا فإن أمر <code>rebase</code> لن يكون قادرا على معرفة أيهما المكرَّر وسيضيف إيداعا جديدا مشابها لـ<code>'C4</code> (يُحتمَل جدّا ألا يُطبَّق نظرا لأن التعديلات ستكون غالبا موجودة في مكان ما).
</p>

<p>
	يمكن تسهيل الأمر بتنفيذ <code>git pull --rebase</code> بدلا من <code>git pull</code> عادي؛ أو التأسيس يدويا بتنفيذ أمر <code>git fetch</code> تتبعه بـ <code>git rebase teamone/master</code> في هذه الحالة.
</p>

<p>
	توجد طريقة لجعل خيار <code>rebase--</code> مبدئيا عند تنفيذ أمر <code>git pull</code> وهي إعداد المعطى <code>pull.rebase</code> في الإعدادات ليأخذ القيمة <code>git config --global pull.rebase true</code>.
</p>

<p>
	ستجري الأمور بخير ما دمت تستخدم إعادة التأسيس بوصفها طريقة لتنسيق الإيداعات والعمل عليها قبل دفعها وما ظللت ملتزما بإعادة تأسيس الإيداعات التي لم تتوفر أبدا للعموم دون غيرها. في الجانب الآخر، تتعرّض للكثير من المخاطر بإعادة التأسيس على إيداعات سبق دفعها إلى مستودعات عمومية ويمكن أن يكون بعض شركائك أسسوا عملهم عليها. تأكد من تنفيذ جميع أعضاء الفريق لأمر <code>git pull --rebase</code> لمحاولة التقليل من المشاكل بعد إعادة تأسيس أحدهم على إيداعات جلبها من المستودع العمومي.
</p>

<h2 id="إعادة-التأسيس-أم-الدمج">
	إعادة التأسيس أم الدمج؟
</h2>

<p>
	ربما تتساءل الآن بعد الخوض في كلّ من إعادة التأسيس والدمج، أيهما أنسب؟ سنعود إلى الوراء قليلا قبل الإجابة على التساؤل لندقّق في معنى سجل المستودع.
</p>

<p>
	يمكن رؤية الموضوع على أساس أن سجل المستودع هو تسجيل لما حدث فيه، بمعنى أنه وثيقة تاريخية قيّمة بذاتها، ولا يجوز التلاعب بها. يعدّ تغيير السجلّ من وجهة النظر هذه خطأ كبيرا؛ فذلك يعني تزوير الوقائع. ماذا لو حدثت فوضى في المستودع بعد متتالية من الإيداعات؟ هذه هي الوقائع ويجب أن تظل مسجّلة تقول وجهة النظر هذه.
</p>

<p>
	توجد رؤية مغايرة للموضوع، تقول إن سجل الإيداعات هو رواية لكيفية بناء المشروع. يحتاج دليل صيانة البرنامج لنفس الحذر الذي يتطلبه نشر كتاب، فلا يجوز أن تنشر كتابا مازال في طور المسودة. يتبنى وجهة النظر هذه من يستخدمون أدوات مثل <code>git rebase</code>و<code>git filter-branch</code> لسرد القصة بأفضل طريقة للقراء المستقبليين.
</p>

<p>
	يتضح الآن أن سؤال أيها أستخدم، إعادة التأسيس أم الدمج؟ ليس بتلك السهولة. Git أداة قوية تسمح بفعل الكثير من الأشياء للسجّل وبه؛ إلا أن كلّ فريق مختلف وكذلك المشاريع. يعود الأمر إليك، بعد فهم طريقة عمل الاثنين، لاختيار ما يناسب الفريق الذي تعمل معه والمشروع الذي تعمل عليه.
</p>

<p>
	المبدأ العام للحصول على أفضل ما في الطريقتين هو إعادة تأسيس التعديلات المحلية التي لم تشارَك بعد قبل أن تدفعها من أجل تقديم القصة؛ والابتعاد تماما عن إعادة تأسيس أي شيء سبق دفعه إلى مستودع عمومي.
</p>

<h2 id="خاتمة">
	خاتمة
</h2>

<p>
	غطينا في هذه السلسلة <a href="https://academy.hsoub.com/programming/workflow/git/%D9%85%D9%82%D8%AF%D9%91%D9%85%D8%A9-%D8%B9%D9%86-%D8%A7%D9%84%D8%AA%D9%81%D8%B1%D9%8A%D8%B9-branching-%D9%81%D9%8A-git-r271/">أساسيات التفريع</a> والدمج في Git. يجدر بك أن تكون مرتاحا للعمل على إنشاء التفريعات الجديدة والانتقال للعمل عليها، <a href="https://academy.hsoub.com/programming/workflow/git/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D9%81%D8%B1%D9%8A%D8%B9-branching-%D9%88%D8%A7%D9%84%D8%AF%D9%85%D8%AC-merging-%D9%81%D9%8A-git-r276/">التبديل بين التفريعات ودمجها</a> ودمج التفريعات المحلية معا؛ بالإضافة إلى <a href="https://academy.hsoub.com/programming/workflow/git/%D8%A7%D9%84%D8%AA%D9%81%D8%B1%D9%8A%D8%B9%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B9%D9%8A%D8%AF%D8%A9-%D9%81%D9%8A-git-r288/">تشارك التفريعات</a> بدفعها إلى خادوم مشترك، العمل مع آخرين على تفريعات مشتركة وإعادة تأسيس تفريعاتك فبل أن تشاركها. الخطوة الموالية هي معرفة ما تحتاجه لتشغيل خادوم Git خاص بك لتشارك المستودعات.
</p>

<p>
	ترجمة -بتصرف- للفصل <a href="https://git-scm.com/book/en/v2/Git-Branching-Rebasing" rel="external nofollow">Git Branching - Rebasing</a> من كتاب <a href="http://git-scm.com/book/en/v2" rel="external nofollow" target="_blank">Pro Git</a> لصاحبه <a href="https://twitter.com/chacon" rel="external nofollow" target="_blank">Scott Chacon</a>.
</p>
]]></description><guid isPermaLink="false">289</guid><pubDate>Wed, 23 Mar 2016 13:38:35 +0000</pubDate></item><item><title>&#x627;&#x644;&#x62A;&#x639;&#x627;&#x645;&#x644; &#x645;&#x639; &#x627;&#x644;&#x62A;&#x641;&#x631;&#x64A;&#x639;&#x627;&#x62A; &#x627;&#x644;&#x628;&#x639;&#x64A;&#x62F;&#x629; (Remote Branches) &#x641;&#x64A; Git</title><link>https://academy.hsoub.com/programming/workflow/git/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D8%AA%D9%81%D8%B1%D9%8A%D8%B9%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B9%D9%8A%D8%AF%D8%A9-remote-branches-%D9%81%D9%8A-git-r288/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_03/git-remote-branches.png.2eaf10cabd8a2ecc0b0c231f39495776.png" /></p>

<p id="التفريعات-البعيدة">
	المراجع البعيدة في Git هي مؤشرات Pointers إلى المستودعات البعيدة بما تتضمنه من تفريعات، وسوم وغيرها.
</p>

<p style="text-align: center;">
	<img alt="git-remote-branches.png.67982674081e8dcc" class="ipsImage ipsImage_thumbnailed" data-fileid="14123" data-unique="0ys7y0zi5" src="https://academy.hsoub.com/uploads/monthly_2016_03/git-remote-branches.png.67982674081e8dcc86559e92f777679e.png"></p>

<p>
	يمكنك الحصول على لائحة كاملة بالمراجع البعيدة بتنفيذ الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_11">
<span class="pln">git ls-remote [remote]</span></pre>

<p>
	أو: 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_13">
<span class="pln">git remote show [remote]</span></pre>

<p>
	لعرض التفريعات البعيدة إضافة لمعلومات متفرقة. إلا أنه توجد طريقة أخرى أكثر شيوعا وهي الاستفادة من تفريعات التتبع عن بعد Remote-tracking branches
</p>

<p>
	تفريعات التتبع عن بعد هي مراجع لحالة التفريعات البعيدة. توجد هذه التفريعات محليا إلا أنه ليس بالإمكان تحريكها فهي تتحرك تلقائيا عندما تتبادل بيانات مع الخادوم البعيد. تعمل تفريعات التتبع عن بعد كإشارة مرجعية لتذكيرك بموضع تفريعات المستودعات البعيدة في آخر مرة اتصلت فيها بالخادوم.
</p>

<p>
	تأخذ تفريعات التتبع عن بعد الهيئة <code>(remote)/(branch)</code>. إن أردت مثلا رؤية الحالة التي كان عليها التفريع <code>master</code> على مستودع <code>origin</code> البعيد في آخر مرة اتصلت فيها به فستفحص Checkout التفريع <code>origin/master</code>. إن كنت تعمل عن بعد مع زملاء، ثم دفعوا Push تفريعا باسم <code>iss53</code> فيمكن أن يكون لديك تفريع محلي بنفس الاسم بينما يشير تفريع التتبع عن بعد إلى الإيداع على <code>origin/iss53</code>.
</p>

<p>
	قد يبدو الأمر معقّدا قليلا لذا سنأخذ مثالا. فلنفترض أن لديك خادوم Git على العنوان <code>git.ourcompany.com</code>. إن نسخت Clone مستودعا من الخادوم فإن أمر <code>git clone</code> سيسميه تلقائيا <code>origin</code>، يجلب جميع البيانات إلى المستودع المحلي، ينشئ مؤشرا إلى آخر إيداع في التفريع <code>master</code> ويسميه محليا بـ<code>origin/master</code>. يوفر Git أيضا تفريع <code>master</code> محليا يبدأ من نفس مبدأ التفريع <code>master</code> الخاص بـ<code>origin</code>.
</p>

<p>
	<strong>ملحوظة: <code>origin</code> ليس مستودعا ذا خصوصية.</strong>
</p>

<p>
	لا يمثل <code>origin</code> مستودعا ذا خصوصية تماما كما أن <code>master</code> ليس تفريعا ذا دلالة خاصة في Git. يسمّي Git التفريع َالمبدئي بـ<code>master</code> عند تنفيذ أمر <code>git init</code> كما يسمي أمر <code>git clone</code> المستودع البعيد مبدئيا بـ <code>origin</code>؛ لهذا السبب فقط يكثُر استخدام التسميتين.
</p>

<p>
	إن نفذت أمر <code>git clone</code> مع خيار <span style="font-family:courier new,courier,monospace;"><code>o-</code> </span>مثل:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_19">
<span class="pln"> git clone -o booyah </span></pre>

<p>
	فسيكون التفريع <code>booyah/master</code> هو التفريع المبدئي لديك.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/01_remote_branches.png.d9936b5908f0260c97878500f2c05200.png"><img alt="01_remote_branches.thumb.png.ee545c4c1f3" class="ipsImage ipsImage_thumbnailed" data-fileid="13308" data-unique="4czg4e6z8" src="https://academy.hsoub.com/uploads/monthly_2016_02/01_remote_branches.thumb.png.ee545c4c1f32875e2e9b6a315b8e8165.png"></a>
</p>

<p>
	إن عملت على التفريع <code>master</code> المحلي وأثناء عملك دفع أحدهم تغييرات إلى <code>git.ourcompany.com</code> وحدّث التفريع <code>master</code> على الخادوم فسيختلف سجل الإيداعات المحلي عن البعيد. في تلك الأثناء لن يتغير تفريع <code>origin/master</code> ما لم تدخل في تبادل بيانات مع الخادوم.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/02_remote_branches.png.df55fb9eda98963d49377ff41d4447fc.png"><img alt="02_remote_branches.thumb.png.793c743c91b" class="ipsImage ipsImage_thumbnailed" data-fileid="13309" data-unique="fh6lk7bh1" src="https://academy.hsoub.com/uploads/monthly_2016_02/02_remote_branches.thumb.png.793c743c91bce149a1763cba6674b868.png"></a>
</p>

<p>
	نفذ أمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_21">
<span class="pln"> git fetch origin </span></pre>

<p>
	لمزامنة تفريع التتبع عن بعد. يبحث الأمر عن خادوم المستودع <code>origin</code> (أي <code>git.ourcompany.com</code> )، يفتش عن البيانات الموجودة على الخادوم التي لا توجد محليا ثم يحدّث البيانات المحلية محرّكا المؤشر <code>origin/master</code> إلى موضعه الجديد.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/03_remote_branches.png.44284d4262cd862dc52dcd6f017a861e.png"><img alt="03_remote_branches.thumb.png.2d8cc20fb58" class="ipsImage ipsImage_thumbnailed" data-fileid="13310" data-unique="oggf133ug" src="https://academy.hsoub.com/uploads/monthly_2016_02/03_remote_branches.thumb.png.2d8cc20fb58958390c238af568c19930.png"></a>
</p>

<p>
	نأخذ مثالا لتوضيح كيف تبدو تفريعات التتبع عن بعد لخواديم بعيدة متعدّدة. نفترض أن لديك خادوم Git داخلي تستخدمه إحدى فرق العمل لأغراض التطوير والاختبار. عنوان هذا الخادوم هو <code>git.team1.ourcompany.com</code>. تمكن إضافة مرجع للخادوم البعيد هذا إلى المشروع الذي تعمل عليه حاليا بتنفيذ الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_17">
<span class="pln"> git remote add </span></pre>

<p>
	كما تطرقنا لذلك في درس <a href="http://academy.hsoub.com/programming/workflow/git/%D8%A7%D9%84%D8%B9%D9%85%D9%84-%D8%B9%D9%84%D9%89-%D8%A7%D9%84%D9%85%D8%B3%D8%AA%D9%88%D8%AF%D8%B9%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B9%D9%8A%D8%AF%D8%A9-%D9%81%D9%8A-git-r253/">العمل على المستودعات البعيدة في Git</a>. نضيف المستودع مع استخدام الاختصار <code>teamone</code>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/04_remote_branches.png.b53f46be9414bbbd084fb90b6a8a117e.png"><img alt="04_remote_branches.thumb.png.08c835bf412" class="ipsImage ipsImage_thumbnailed" data-fileid="13311" data-unique="tns4n5e9z" src="https://academy.hsoub.com/uploads/monthly_2016_02/04_remote_branches.thumb.png.08c835bf4121968fd62fafd3175821a1.png"></a>
</p>

<p>
	يمكنك الآن تنفيذ الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_15">
<span class="pln">git fetch teamone </span></pre>

<p>
	للبحث عن البيانات الموجودة على الخادوم الجديد دون أن تكون موجودة محليا. يوجد على الخادوم <code>teamone</code> جزء من العمل الموجود على الخادوم الأول؛ يعني هذا أن Git بعد تنفيذ الأمر السابق لن ينزل إيداعات جديدة لكنه سيكتفي بإنشاء تفريع تتبع عن بعد جديد ويسميه <code>teamone/master</code> يشير إلى آخر إيداع في التفريع <code>master</code> على الخادوم <code>teamone</code>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/05_remote_branches.png.75b34600911e5f951e4ddb078d5ddd08.png"><img alt="05_remote_branches.thumb.png.c389b9095b5" class="ipsImage ipsImage_thumbnailed" data-fileid="13312" data-unique="nbi4y98k9" src="https://academy.hsoub.com/uploads/monthly_2016_02/05_remote_branches.thumb.png.c389b9095b5e66aa911cbde5c12880ab.png"></a>
</p>

<h2 id="دفع-البيانات">
	دفع البيانات
</h2>

<p>
	عندما تريد مشاركة تفريع تعمل عليه مع آخرين فستحتاج لدفع البيانات إلى مستودع بعيد لديك صلاحية الكتابة عليه. لا يُزامن Git التفريعات المحلية تلقائيا مع التفريعات البعيدة، بل يجب أن تزامن التفريع الذي ترغب في مشاركته يدويا. تستخدم بهذه الطريقة تفريعات خاصة (محلية) للأعمال التي لا تريد مشاركتها بينما تدفع بيانات التفريعات التي تود مشاركتها إلى خادم مشترك.
</p>

<p>
	إن كان لديك تفريع باسم <code>serverfix</code> تريد التشارك بالعمل عليه مع آخرين فيمكنك دفع البيانات إليه بنفس طريقة دفع التفريع الأخرى بتنفيذ الأمر:
</p>

<pre class="ipsCode" id="ips_uid_3943_23">
 git push &lt;remote&gt; &lt;branch&gt;</pre>

<p>
	كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6609_9">
<span class="pln">git push origin serverfix
    Counting objects: 24, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (15/15), done.
    Writing objects: 100% (24/24), 1.91 KiB | 0 bytes/s, done.
    Total 24 (delta 2), reused 0 (delta 0)
    To https://github.com/schacon/simplegit
    * [new branch]      serverfix -&gt; serverfix</span></pre>

<p>
	يأخذ Git تلقائيا محتوى التفريع <code>serverfix</code> إلى <span style="font-family:courier new,courier,monospace;"><code>refs/heads/serverfix:refs/heads/serverfix</code></span> وهو ما يعني أخذ بيانات التفريع المحلي <code>serverfix</code> ودفعها لتحديث بيانات التفريع البعيد <code>serverfix</code>. سنعرج للحديث عن <code>refs/heads/</code> عندما نتحدث عن أمور داخلية في Git، يمكن الآن تجاوزها.
</p>

<p>
	يمكن أيضا تنفيذ الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_25">
<span class="pln">push origin serverfix:serverfix </span></pre>

<p>
	الذي يؤدي نفس المهمة. يُفسَّر الأمر بـ "خذ التفريع <code>serverfix</code> المحلي واجعله هو تفريع <code>serverfix</code> البعيد". يمكن استخدام هذه الطريقة لدفع بيانات تفريع محلي إلى تفريع بعيد يختلف عنه في الاسم. أما إن كنت ترغب في تغيير اسم التفريع في المستودع البعيد فيمكنك تنفيذ الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_27">
<span class="pln"> git push origin serverfix:awesomebranch </span></pre>

<p>
	لدفع بيانات تفريع <code>serverfix</code> المحلي إلى التفريع <code>awesomebranch</code> على الخادوم البعيد.
</p>

<h3>
	لا تعد كتابة كلمة السر في كل مرة!
</h3>

<p>
	يطلُب Git عند دفع البيانات إلى مستودع يستخدم روابط مؤمنة بيانات الاستيثاق (اسم المستخدم وكلمة السر) ويظهر محثّ Prompt في سطر الأوامر لتلقي هذه البيانات. تستطيع استخدام تخبئة اعتمادات Credential cache لتفادي إدخال اسم المستخدم وكلمة السر في كل مرة تدفع فيها البيانات. الطريقة الأسهل لإعدادها هي تنفيذ أمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_31">
<span class="pln">git config --global credential.helper cache</span></pre>

<p>
	يحصُل مشاركوك في المستودع عند تنفيذ أمر <code>git fetch</code> مستقبلا على مرجع لمكان نسخة التفريع <code>serverfix</code> الموجودة على الخادوم:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6609_11">
<span class="pln">git fetch origin
    remote: Counting objects: 7, done.
    remote: Compressing objects: 100% (2/2), done.
    remote: Total 3 (delta 0), reused 3 (delta 0)
    Unpacking objects: 100% (3/3), done.
    From https://github.com/schacon/simplegit
    * [new branch]      serverfix    -&gt; origin/serverfix</span></pre>

<p>
	من المهم الانتباه إلى أن تفريعات التتبع عن بعد التي تنتج عن تنفيذ أمر <code>git fetch</code> لا تعطيك تلقائيا نسخة يمكن تحريرها من هذه التفريعات. يعني هذا بعبارة أخرى أن الأمر أعلاه لا ينشئ تفريع <code>serverfix</code> جديدا بل مؤشرا باسم <code>origin/serverfix</code> لا يمكن تعديله.
</p>

<p>
	نفذ أمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_33">
<span class="pln">git merge origin/serverfix </span></pre>

<p>
	لدمج التفريع البعيد في التفريع الحالي لديك. إن كنت تريد تفريع <code>serverfix</code> خاصا بك للعمل عليه فيمكنك تأسيسه على تفريع التتبع عن بعد:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6609_13">
<span class="pln">git checkout -b serverfix origin/serverfix
    Branch serverfix set up to track remote branch serverfix from origin.
    Switched to a new branch 'serverfix'</span></pre>

<p>
	يعطيك الأمر أعلاه تفريعا محليا يبدأ من حيث يوجد <code>origin/serverfix</code> ويمكنك العمل عليه.
</p>

<h2 id="تفريعات-التتبع-tracking-branches">
	تفريعات التتبع Tracking branches
</h2>

<p>
	يؤدي فحصُ تفريع محلي من تفريع تتبع عن بعد تلقائيا إلى إنشاء ما يُسمّى تفريع تتبع. تفريعات التتبع هي تفريعات محلية ذات علاقة مباشرة مع مستودع بعيد (يُسمَّى التفريع البعيد بالتفريع العلوي Upstream branch). إذا كنت تعمل على تفريع تتبع ثم نفذت أمر <code>git pull</code> فإن Git سيعرف تلقائيا من أين سيجلب البيانات والتفريعَ الذي يجب دمجها فيه.
</p>

<p>
	ينتج عادة عن نسخ مستودع إنشاء تفريع <code>master</code> لتتبع <code>origin/master</code>. يمكنك إن أردت إعداد تفريعات تتبع أخرى؛ أو التخلي عن تتبع التفريع <code>master</code> الذي أُعدّ تلقائيا أثناء نسخ المستودع. أقرب مثال لإنشاء تفريعات تتبع هو تنفيذ الأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_35">
<span class="pln">git checkout -b [branch] [remotename]/[branch]</span></pre>

<p>
	هذا الأمر شائع لدرجة أن Git لديه اختصار للأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6609_15">
<span class="pln">git checkout --track origin/serverfix
    Branch serverfix set up to track remote branch serverfix from origin.
    Switched to a new branch 'serverfix'</span></pre>

<p>
	في الواقع، الأمر شائع لدرجة وجود اختصار للاختصار أعلاه! ينشئ Git عند تنفيذ أمر <code>git checkout</code> تفريع تتبع إذا توفر الشرطان: (أ) التفريع غير موجود سلفا، (ب) يوافق اسم التفريع بالضبط تفريعا بعيدا وحيدا:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6609_17">
<span class="pln">git checkout serverfix
    Branch serverfix set up to track remote branch serverfix from origin.
    Switched to a new branch 'serverfix'</span></pre>

<p>
	تتاح أيضا إمكانية إعداد تفريع محلي باسم مختلف عن التفريع البعيد باستخدام النسخة الأولى من الأمر مع ذكر اسم التفريع المحلي على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6609_19">
<span class="pln">git checkout -b sf origin/serverfix
    Branch sf set up to track remote branch serverfix from origin.
    Switched to a new branch 'sf'</span></pre>

<p>
	بهذا يجلب تنفيذ الأمر <code>git pull</code> على التفريع <code>sf</code> البيانات تلقائيا من <code>origin/serverfix</code>.
</p>

<p>
	استخدم خيار <code>u-</code> أو <code>set-upstream--</code> إذا كنت تريد إعداد تفريع محلي تعمل عليه لتتبع تفريع بعيد أو تغيير التفريع العلوي الذي يتتبّعه التفريع المحلي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6609_21">
<span class="pln">git branch -u origin/serverfix
    Branch serverfix set up to track remote branch serverfix from origin.</span></pre>

<p>
	<strong>ملحوظة: اختصار التفريع العلوي.</strong>
</p>

<p>
	تستطيع بعد إعداد تفريع تتبع استخدام الاختصار <code>{upstream}@</code> أو <code>{u}@</code> للإشارة إلى التفريع العلوي المرتبط به. نفترض أنك تعمل على التفريع <code>master</code> الذي يتتبع التفريع <code>origin/master</code>؛ يمكنك في هذه الحالة تنفيذ الأمر المختصر <code>{git merge @{u</code> بدلا من <code>git merge origin/master</code>.
</p>

<p>
	استخدم خيار <code>vv-</code> مع أمر <code>git branch</code> لعرض تفريعات التتبع التي أعددتها. يسرد الأمر قائمة بالتفريعات المحلية مع معلومات أكثر عن كل تفريع بما فيها التفريعات العلوية وهل تفريع التتبع يتقدم على التفريع العلوي أم يتأخر عنه أم الاثنان معا.
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6609_23">
<span class="pln">git branch -vv
    iss53     7e424c3 [origin/iss53: ahead 2] forgot the brackets
    master    1ae2a45 [origin/master] deploying index fix
    * serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
    testing   5ea463a trying something new</span></pre>

<p>
	تشير نتيجة الأمر في المثال أعلاه إلى أن التفريع <code>iss53</code> يتتبّع التفريع <code>origin/iss53</code>، وأنه يتقدم عليه بإيداعين (<code>ahead 2</code>)؛ بمعنى أنه يوجد إيداعان محليان لم يدفعا بعدُ إلى الخادوم. يظهر أن التفريع <code>master</code> يتتبّع التفريع <code>origin/master</code> وأنه محدَّث. نرى في السطر الموالي أن <code>serverfix</code> يتتبّع <code>server-fix-good</code> على الخادوم <code>teamone</code> وأنه يتقدم عليه بـ<code>3</code> ويتأخر عنه ب<code>1</code>؛ أي أنه يوجد إيداع واحد على الخادوم لم يُدمج محليَّا بعد، كما توجد ثلاثة إيداعات محلية لم تُدفع إلى الخادوم. يظهر في السطر الأخير أن التفريع <code>testing</code> لا يتتبّع أي تفريع بعيد.
</p>

<p>
	يجب الانتباه إلى أن هذه الأعداد تحيل إلى البيانات المخبَّأة منذ آخر مرة بُحث فيها عن بيانات على كل خادوم؛ فالأمر أعلاه لا يدخل في اتصال مع الخواديم بل يخبرك فقط بالمعلومات الموجودة محليا. إن كنت تريد بيانات حديثة كليًّا فيجب البحث عنها أولا على الخواديم جميعا بتنفيذ الأمر <code>git fetch</code> عليها. يمكن مثلا تحديث البيانات من جميع الخواديم كالتالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_37">
<span class="pln">git fetch --all; git branch -vv</span></pre>

<h2 id="جلب-البيانات">
	جلب البيانات
</h2>

<p>
	ينزّل أمر <code>git fetch</code> كل التغييرات الموجودة على الخادوم التي لا توجد عندك محليا؛ ولكنها لا تغير مجلد العمل بتاتا، بل تكتفي بتنزيل البيانات وترك مهمة دمجها لك. إلا أنه يوجد أمر <code>git pull</code> الذي ينزّل البيانات ويدمجها في مجلد العمل لديك؛ ينتج عن تنفيذ أمر <code>git pull</code> غالبا تنفيذ أمر <code>git fetch</code> متبوعا مباشرةً بأمر <code>git merge</code>. يؤدي تنفيذ <code>git pull</code> على تفريع تتبع مُعدّ مثل ما وضحنا في الفقرة السابقة، إما بإعداده صراحة أو عن طريق أمر <code>git clone</code> أو <code>git checkout</code>، يؤدي إلى البحث في المستودع العلوي المناسب عن البيانات الجديدة ثم دمجها فورا في تفريع التتبع المحلي. من الأفضل عموما استخدام أمري:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_39">
<span class="pln">git fetch </span></pre>

<p>
	و 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3943_41">
<span class="pln">git merge </span></pre>

<p>
	بالتتابع إذ أن أمر <code>git pull</code> قد يكون مربكا.
</p>

<h2 id="حذف-التفريعات-البعيدة">
	حذف التفريعات البعيدة
</h2>

<p>
	لنفترض أنك أنهيت العمل على تفريع بعيد (أكملت أنت ومشاركوك العمل على ميزة وأُدمجت في التفريع الرئيس الذي توجد به الشفرة المستقرة مهما كان اسمه، <code>master</code> أو أي شيء آخر)؛ يمكنك حذف هذا التفريع باستخدام الخيار <code>delete--</code> في أمر <code>git push</code>. نفذ الأمر التالي إذا أردت حذف التفريع <code>serverfix</code> من الخادوم:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_6609_7">
<span class="pln">git push origin --delete serverfix
    To https://github.com/schacon/simplegit
    - [deleted]         serverfix</span></pre>

<p>
	يتلخص عمل الأمر في حذف مؤشر التفريع من الخادوم. يحتفظ خادوم Git عادة ببقية البيانات لمدة إلى أن تتم عملية جمع النفايات Garbage collection؛ تتيح هذه الطرقة إمكانية إرجاع التفريع إن كان حذفه عرضيا.
</p>

<p>
	ترجمة -بتصرف- للفصل <a href="https://git-scm.com/book/en/v2/Git-Branching-Remote-Branches" rel="external nofollow">Git Branching - Remote Branches</a> من كتاب <a href="http://git-scm.com/book/en/v2" rel="external nofollow" target="_blank">Pro Git</a> لصاحبه <a href="https://twitter.com/chacon" rel="external nofollow" target="_blank">Scott Chacon</a>.
</p>
]]></description><guid isPermaLink="false">288</guid><pubDate>Thu, 17 Mar 2016 22:16:24 +0000</pubDate></item><item><title>&#x625;&#x62F;&#x627;&#x631;&#x629; &#x627;&#x644;&#x62A;&#x641;&#x631;&#x64A;&#x639;&#x627;&#x62A; (branches) &#x641;&#x64A; Git &#x648;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645;&#x647;&#x627; &#x644;&#x62A;&#x62E;&#x637;&#x64A;&#x637; &#x633;&#x64A;&#x631; &#x627;&#x644;&#x639;&#x645;&#x644;</title><link>https://academy.hsoub.com/programming/workflow/git/%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D8%AA%D9%81%D8%B1%D9%8A%D8%B9%D8%A7%D8%AA-branches-%D9%81%D9%8A-git-%D9%88%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85%D9%87%D8%A7-%D9%84%D8%AA%D8%AE%D8%B7%D9%8A%D8%B7-%D8%B3%D9%8A%D8%B1-%D8%A7%D9%84%D8%B9%D9%85%D9%84-r287/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_03/git-branch-workflow.png.074d09996f12b4a32b9e6b6606532362.png" /></p>

<p>
	تعرفنا في الدرسين السابقين على <a href="https://academy.hsoub.com/programming/workflow/git/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%B9%D9%86-%D8%A7%D9%84%D8%AA%D9%81%D8%B1%D9%8A%D8%B9-branching-%D9%81%D9%8A-git-r271/">كيفية إنشاء التفريعات (Branches) في Git</a> و <a href="https://academy.hsoub.com/programming/workflow/git/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D9%81%D8%B1%D9%8A%D8%B9-branching-%D9%88%D8%A7%D9%84%D8%AF%D9%85%D8%AC-merging-%D9%81%D9%8A-git-r276/">كيفية دمجها وحذفها</a>. سنرى في هذا الدرس أدوات لإدارة التفريعات وخططا لتسيير أعمال التطوير باستخدام التفريعات في Git.
</p>

<p style="text-align: center;">
	<img alt="git-branch-workflow.png.5ad7e9817a3c0de2" class="ipsImage ipsImage_thumbnailed" data-fileid="14124" data-unique="gepjisk5b" src="https://academy.hsoub.com/uploads/monthly_2016_03/git-branch-workflow.png.5ad7e9817a3c0de29536a1d0923c9ccb.png"></p>

<h2 id="إدارة-التفريعات">
	إدارة التفريعات
</h2>

<p>
	لا ينحصر عمل أمر <code>git branch</code> على إنشاء التفريعات وحذفها، بل يتعدّى ذلك. إن نفّذت الأمر من دون خيارات فستحصُل على قائمة بالتفريعات الحالية:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5010_7">
<span class="pln">git branch
    iss53
    * master
    testing</span></pre>

<p>
	لاحظ علامة <code>*</code> أمام تفريع <code>master</code>: تعني هذه العلامة أن التفريع <code>master</code> هو آخر تفريع انتقلت إليه، أي أن المؤشّر <code>HEAD</code> يشير الآن إلى هذا التفريع). يعني هذا أيضا أنك إن أضفت إيداعا الآن فإن تفريع <code>master</code> سيتقدّم إلى الأمام.
</p>

<p>
	استخدم خيار <code>v-</code> لعرض آخر إيداع على كل تفريع:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5010_9">
<span class="pln">git branch -v
    iss53   93b412c fix javascript issue
    * master  7a98805 Merge branch 'iss53'
    testing 782fd34 add scott to the author list in the readmes</span></pre>

<p>
	يمكن أيضا استخدام الخيارين <code>merged--</code> و <code>no-merged--</code> لترشيح نتيجة الأمر والإبقاء فقط على التفريعات التي دُمجت أم لا في التفريع الذي توجد عليه الآن:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5010_11">
<span class="pln">git branch --merged
    iss53
    * master</span></pre>

<p>
	يظهر التفريع <code>iss53</code> لأنك دمجته سابقا في التفريع الحالي <code>master</code>. في الحالة العامة يمكن حذف التفريعات التي لا تظهر أمامها علامة <code>*</code> في نتيجة الأمر أعلاه إذ يدل ذلك على أن محتواها دُمج سابقا في تفريع آخر (الحالي) وبالتالي فلن تخسر شيئا بحذفها.
</p>

<p>
	استخدم الخيار <code>no-merged--</code> لعرض التفريعات التي تحوي أعمالا لم تُدمج بعد:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5010_13">
<span class="pln">git branch --no-merged
    testing</span></pre>

<p>
	تُظهر نتيجة الأمر السابق التفريع الآخر الذي يوجد به محتوى لم يُدمَج بعد. إن جربت حذف هذا التفريع بالأمر:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5976_9">
<span class="pln">git branch -d </span></pre>

<p>
	فلن ينجح:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5010_15">
<span class="pln">git branch -d testing
    error: The branch 'testing' is not fully merged.
    If you are sure you want to delete it, run 'git branch -D testing'.</span></pre>

<p>
	تظهر رسالة خطأ لتعلمك بوجود محتوى على التفريع <code>testing</code> لم يُدمج بعد. إن أردت رغم ذلك حذف التفريع وبالتالي فقدان المحتوى فيمكنك فرض الحذف باستخدام الخيار <code>D-</code> كما تشير بذلك رسالة المساعدة في نتيجة الأمر السابق.
</p>

<h2 id="تسيير-العمل-باستخدام-التفريعات">
	تسيير العمل باستخدام التفريعات
</h2>

<p>
	تعرفنا على أساسيات التفريع والدمج ولكن كيف يمكننا استخدامها في تسيير عمليات التطوير؟ سنغطي في هذه الفقرة طريقتين يكثر استخدامهما لتسيير الأعمال بالاعتماد على مبادئ التفريع.
</p>

<h3 id="التفريعات-طويلة-الأمد">
	التفريعات طويلة الأمد
</h3>

<p>
	تسهّل قاعدة الدمج الثلاثي من إمكانية دمج تفريع في آخر أكثر من مرة في فترة زمنية طويلة. يعني هذا أنه بالإمكان الإبقاء دائما على تفريعات مفتوحة لاستخدامها في أطوار مختلفة من دورة تطوير البرنامج ودمج بعضها في أخرى من حين لآخر.
</p>

<p>
	يختار كثير من مستخدمي Git هذه المقاربة القائمة على الحفاظ على الشفرة البرمجية المستقرة - التي صُدّرت لبيئة الإنتاج أو في طريقها إلى ذلك - في التفريع الرئيس. يوجد بالتوازي مع التفريع الرئيس تفريع آخر باسم <code>develop</code> أو <code>next</code> للعمل عليه أو لاختبار الاستقرار. ليس بالضرورة أن يكون هذا التفريع مستقرا دائما، ولكنه حالما يصل إلى حالة استقرار يُدمج في التفريع الرئيس. يُستخدَم التفريع الموازي لتُدمج فيه التفريعات قصيرة الأمد (تفريع لميزة محدّدة) عندما تكون جاهزة والتأكد من استقرار العمل وخلوه من العلل بعد إضافة الميزة الجديدة قبل أن يُدمج في التفريع الرئيس.
</p>

<p>
	تُفهم هذه المقاربة بالنظر إلى موقع مؤشر التفريع على الخط الزمني للإيداعات. توجد الإيداعات المستقرة في نقطة أقدم على الخط الزمني، بينما توجد إيداعات التفريعات الجديدة في موقع أحدث.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/01_commits_time_line.png.5aeee2f53c19eebfc885c0aa8775d58e.png"><img alt="01_commits_time_line.thumb.png.fd454c9e5" class="ipsImage ipsImage_thumbnailed" data-fileid="13184" data-unique="y1fmxrbws" src="https://academy.hsoub.com/uploads/monthly_2016_02/01_commits_time_line.thumb.png.fd454c9e5020564d470af743b7be20ca.png"></a><br><strong>رؤية خطية للتفريع حسب تقدم الاستقرار</strong>
</p>

<p>
	طريقة أخرى لفهم المقاربة هي النظر إلى التفريعات على أنها مدرَّجات. تنتقل مجموعة إيداعات إلى درجة أعلى (أكثر استقرارا) بعد أن تُختبر.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/02_commits_workflow.png.d9f0ff32e3aaf3f838d40ec5856f9f11.png"><img alt="02_commits_workflow.thumb.png.70fcaa693e" class="ipsImage ipsImage_thumbnailed" data-fileid="13185" data-unique="ktobs8594" src="https://academy.hsoub.com/uploads/monthly_2016_02/02_commits_workflow.thumb.png.70fcaa693e10b8723c265436027c5cf7.png"></a><br><strong>تدرج الإيداعات حسب درجة الاستقرار</strong>
</p>

<p>
	يمكن استخدام مستويات استقرار متعددة. يوجد في بعض المشاريع تفريع باسم <code>proposed</code> (مُقترَح) أو <code>pu</code> (اختصار لـproposed updates أي تحديثات مقترحة) لتضمين التفريعات التي لم تجهز بعد للدمج في تفريع <code>next</code> أو <code>master</code>.
</p>

<p>
	الفكرة هي أن تكون التفريعات على مستويات مختلفة من الاستقرار؛ وعندما تصل إلى مستوى استقرار أعلى تُدمج في التفريع الموالي. ليس من الضروري أن تكون لديك تفريعات متعدّدة ولكن ذلك يساعد غالبا خصوصا في المشروعات المعقّدة أو الكبيرة.
</p>

<h3 id="تفريعات-المواضيع">
	تفريعات المواضيع
</h3>

<p>
	تفيد تفريعات المواضيع، وهي تفريعات قصيرة الأمد تُنشأ لميزة أو عمل محدّد مرتبط بالمشروع، مهما كان حجمه. ليس شائعا استخدام هذه الطريقة في التفريع في نظم إدارة النسخ الأخرى لثقل آليات التفريع والدمج فيها؛ على العكس من Git الذي تُستخدم فيه هذه الطريقة كثيرا.
</p>

<p>
	رأينا مثالا على طريقة التفريع هذه عندما أنشأنا التفريعين <code>iss53</code> و <code>hotfix</code> في <a href="https://academy.hsoub.com/programming/workflow/git/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D9%81%D8%B1%D9%8A%D8%B9-branching-%D9%88%D8%A7%D9%84%D8%AF%D9%85%D8%AC-merging-%D9%81%D9%8A-git-r276/">درس أساسيات التفريع والدمج</a>: أضفنا بضع إيداعات إلى التفريعين ثم حذفناهما مباشرة بعد دمجهما في التفريع الرئيس. تتيح هذه الطريقة سهولة تغيير السياق تماما وبسرعة؛ نظرا لكون العمل مقسَّمًا حسب مواضيع فإن كل تفريع يحتفظ فقط بالتغييرات المتعلقة بموضوعه. يمكن إبقاء التغييرات في التفريع لدقائق، أيام أو أشهر ثم دمجها عندما تكون جاهزة بغض النظر عن ترتيب إنشاء تفريعات المواضيع أو ترتيب العمل عليها.
</p>

<p>
	فلنفترض المثال التالي: كنت تعمل على التفريع الرئيس (<code>master</code>) ، أنشأت تفريعا جديدا لعلة اكتشفتها (<code>iss91</code>) واستمريت في العمل عليها لبعض الوقت ثم أنشأت تفريعا جديدا من التفريع <code>iss91</code> لتجربة طريقة أخرى في حل العلة (<code>iss91v2</code>)؛ ثم عدت للعمل على التفريع الرئيس وعملت عليه لبعض الوقت ثم أنشأت تفريعا جديدا لتجربة فكرة لست متأكدا من نجاحها (التفريع <code>dumbidea</code>). يبدو سجل التفريع لهذا المثال على النحو التالي
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/03_topic_branches.png.65d7f79cf14b4d086eaa0b26c21240da.png"><img alt="03_topic_branches.thumb.png.8c5ad3481505" class="ipsImage ipsImage_thumbnailed" data-fileid="13186" data-unique="785uqgpfa" src="https://academy.hsoub.com/uploads/monthly_2016_02/03_topic_branches.thumb.png.8c5ad34815058c78418b336e2f650503.png"></a>
</p>

<p>
	فلنفرض أن الحل الثاني للعلة (التفريع <code>iss91v2</code>) هو الأفضل، وأن الفكرة الجديدة نالت إعجاب زملائك في العمل. يمكن الآن التخلي عن التفريع <code>iss91</code> (مما يعني خسارة الإيداعين <code>C5</code> و<code>C6</code>) ثم دمج التفريعين المتبقيين في التفريع الرئيس. يصبح سجل الإيداعات على النحو التالي
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/04_topic_branches.png.64e6f65bbbeeb23663ff7026cd3fd45d.png"><img alt="04_topic_branches.thumb.png.083ff4bcedad" class="ipsImage ipsImage_thumbnailed" data-fileid="13187" data-unique="rrarj0r6f" src="https://academy.hsoub.com/uploads/monthly_2016_02/04_topic_branches.thumb.png.083ff4bcedad40b30f1633438dc6ed88.png"></a>
</p>

<p>
	من المهم تذكر أن جميع هذه التفريعات محلية. كل التغييرات التي تفعلها عند إنشاء تفريعات جديدة أو دمج تفريعات موجودة تتم في مستودع Git دون حدوث أي تواصل مع خادوم بعيد. توجد خطط أخرى لتسيير العمل عند التعامل مع المستودعات البعيدة سنعرض لها في مقال لاحق.
</p>

<p>
	ترجمة -بتصرف- للفصل <a href="https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows" rel="external nofollow">Git Branching - Branching Workflows</a> من كتاب <a href="http://git-scm.com/book/en/v2" rel="external nofollow" target="_blank">Pro Git</a> لصاحبه <a href="https://twitter.com/chacon" rel="external nofollow" target="_blank">Scott Chacon</a>.
</p>
]]></description><guid isPermaLink="false">287</guid><pubDate>Thu, 17 Mar 2016 22:09:17 +0000</pubDate></item><item><title>&#x623;&#x633;&#x627;&#x633;&#x64A;&#x627;&#x62A; &#x627;&#x644;&#x62A;&#x641;&#x631;&#x64A;&#x639; (Branching) &#x648;&#x627;&#x644;&#x62F;&#x645;&#x62C; (Merging) &#x641;&#x64A; Git</title><link>https://academy.hsoub.com/programming/workflow/git/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D9%84%D8%AA%D9%81%D8%B1%D9%8A%D8%B9-branching-%D9%88%D8%A7%D9%84%D8%AF%D9%85%D8%AC-merging-%D9%81%D9%8A-git-r276/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_03/git-branching-merging.png.e2327b3c812aa391b9fc34e4ebaee53e.png" /></p>

<p>
	يعرض هذا المقال أساسيات التفريع والدمج في Git. نبدأ بمثال سهل لسيناريو يحدث كثيرا أثناء تطوير البرمجيات ونرى كيفية تطبيقه على التفريع والدمج.
</p>

<p style="text-align: center;">
	<img alt="git-branching-merging.png.300fb59d8e1e94" class="ipsImage ipsImage_thumbnailed" data-fileid="13884" data-unique="cqsdrels1" src="https://academy.hsoub.com/uploads/monthly_2016_03/git-branching-merging.png.300fb59d8e1e94bc2afd19c777f329c8.png"></p>

<p>
	لنفترض حدوث الخطوات التالية:
</p>

<ul><li>
		كنت تعمل على موقع ويب وأنجزت الجزء الأهم وهو الآن مفتوح للزوار.
	</li>
	<li>
		أنشأت تفريعا جديدا وبدأت العمل على ميزات ستضيفها لاحقا للموقع.
	</li>
</ul><p>
	عند هذه النقطة وردك اتصال يخبرك عن مشكل في الموقع. المشكل خطير ويحتاج حلا سريعا.
</p>

<ul><li>
		تنتقل لنسخة الموقع الموجودة على بيئة الإنتاج (إصدار الموقع المفتوح للزوار). أي أنك انتقلت للتفريع الذي أطلقت منه الموقع (وليكن التفريع <code>master</code>).
	</li>
	<li>
		تنشئ تفريعا جديدا انطلاقا من تفريع الإنتاج بهدف إصلاح الخلل (الترقيع).
	</li>
	<li>
		تعمل على التفريع الجديد وتختبر التعديلات حتى تتأكد من جاهزيتك لإضافتها إلى بيئة الإنتاج.
	</li>
	<li>
		تدمج تفريع الترقيع مع تفريع الإنتاج وتدفع التغييرات إلى الموقع.
	</li>
	<li>
		أصلحت المشكل وبإمكانك الآن العودة إلى تفريع تحسين الميزات الذي كنت تعمل عليه قبل ورود الاتصال.
	</li>
</ul><h2 id="المبادئ-الأساسية-للتفريع">
	المبادئ الأساسية للتفريع
</h2>

<p>
	نفرض أنك تعمل على مشروع سبق أن أضفت إليه إيداعين.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/01_basic_branching.png.4594815c8bcc3f3c19d2ba11c4494cbc.png"><img alt="01_basic_branching.thumb.png.5cc577e12c9" class="ipsImage ipsImage_thumbnailed" data-fileid="12688" data-unique="818a4u4n4" src="https://academy.hsoub.com/uploads/monthly_2016_02/01_basic_branching.thumb.png.5cc577e12c96f38caea51dd969c3f198.png"></a><br><strong>سجل إيداعات مستقيم</strong>
</p>

<p>
	قررت أنك ستعمل على إضافة الميزة رقم 53. تنشئ لهذا الغرض تفريعا جديدا. لإنشاء تفريع والانتقال للعمل عليه في نفس الوقت نستخدم الأمر <code>git checkout</code> مع الخيار <span style="font-family:courier new,courier,monospace;"><code>b-</code></span>:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_7">
<span class="pln">git checkout -b iss53
Switched to a new branch "iss53"</span></pre>

<p>
	هذا الأمر هو اختصار للأمرين:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_9">
<span class="pln">git branch iss53
git checkout iss53</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/02_basic_branching.png.49fa0ce0a705ecb709c510eea4e55cc0.png"><img alt="02_basic_branching.thumb.png.dcec227ac42" class="ipsImage ipsImage_thumbnailed" data-fileid="12689" data-unique="62ouwgkl8" src="https://academy.hsoub.com/uploads/monthly_2016_02/02_basic_branching.thumb.png.dcec227ac42c5e567af4067ce44bebd1.png"></a><br><strong>إنشاء مؤشر تفريع جديد</strong>
</p>

<p>
	تنفيذ أمر <code>git checkout</code> يعني نقل المؤشر <code>HEAD</code> ليحيل إلى التفريع <code>iss53</code>.
</p>

<p>
	استمريت في العمل على موقعك، وتنفيذ إيداعات:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_11">
<span class="pln">vim index.html
git commit -a -m 'added a new footer [issue 53]'</span></pre>

<p>
	وهو ما يجعل التفريع <code>iss53</code> يتقدم بتتالي الإيداعات:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/03_basic_branching.png.650f2fe51177ef543617e3f20025ed74.png"><img alt="03_basic_branching.thumb.png.bf39b4e3a5e" class="ipsImage ipsImage_thumbnailed" data-fileid="12690" data-unique="oizisd5qk" src="https://academy.hsoub.com/uploads/monthly_2016_02/03_basic_branching.thumb.png.bf39b4e3a5e31a812549f40b3cc964c6.png"></a><br><strong>تقدّم التفريع iss53 بتوالي الإيداعات</strong>
</p>

<p>
	يأتي الآن الاتصال الذي ينبئ بوجود مشكل في الموقع؛ ويجب التغلب على هذا المشكل في أقرب وقت. لا تحتاج مع Git لنشر الترقيع العاجل مع ترقيع الميزة 53؛ كما أنك لا تحتاج لبذل الكثير من الجهد للتراجع عن التعديلات التي أضفتها أثناء عملك على الميزة 53 حتى تعود إلى حالة الموقع الموجود الآن أمام الزوار. كل ما عليك فعله هو العودة إلى التفريع الرئيس <code>master</code> وترك التفريع <code>iss53</code> لحين الفراغ من العمل العاجل.
</p>

<p>
	انتبه إلى أن Git لن يسمح لك بالانتقال إلى تفريع جديد إن كان مجلد العمل أو منطقة الإدراج يحوي تغييرات تتعارض مع التفريع الذي تريد الانتقال إليه. توجد طرق للالتفاف حول هذا الأمر، وهي ادّخار الإيداعات Stashing وتصحيحها Amending وهو ما سنتطرّق إليه لاحقا عند الحديث عن الادّخار والتنظيف Cleaning. سنفترض في الوقت الحالي أن جميع التعديلات أودعت وبإمكننا الانتقال إلى التفريع الرئيس:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_13">
<span class="pln">git checkout master
Switched to branch 'master'</span></pre>

<p>
	يكون مجلد العمل في المشروع بالوصول إلى هذه النقطة مماثلا تماما لما كان عليه قبل بدء العمل على الميزة 53، ويمكنك الآن التركيز على العلة العاجلة. من المهم تذكر هذا الأمر: يعيد Git عند الانتقال إلى تفريع، مجلد العمل إلى ما كان عليه بعد آخر مرة نفّذت فيها إيداعا على هذا التفريع. فيضيف ملفات وينقل أخرى أو يغيرها تلقائيا للتأكد من أن نسخة مجلد العمل مطابقة لما كان عليه بعد آخر عملية إيداع على التفريع.
</p>

<p>
	لدينا ترقيع عاجل يجب إصداره. ننشئ تفريعا خاصا <code>hotfix</code> للعمل على إصدار ترقيع في أقرب وقت:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_15">
<span class="pln">git checkout -b hotfix
Switched to a new branch 'hotfix'
vim index.html
git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
1 file changed, 2 insertions(+)</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/04_basic_branching.png.b3ea8bb58f0e368b21783a1a824b389d.png"><img alt="04_basic_branching.thumb.png.05e5154d400" class="ipsImage ipsImage_thumbnailed" data-fileid="12691" data-unique="e9l8dbria" src="https://academy.hsoub.com/uploads/monthly_2016_02/04_basic_branching.thumb.png.05e5154d40029b9cb7fbda1b7651985b.png"></a><br><strong>إنشاء تفريع <code>hotfix</code> انطلاقا من التفريع <code>master</code></strong>
</p>

<p>
	يمكن الآن اختبار التعديلات والتأكد من أن الترقيع يؤدي العمل المطلوب ثم بعد ذلك ندمج التفريع <code>hotfix</code> (باستخدام أمر <code>git merge</code>) مع التفريع الرئيس لنشره على بيئة الإنتاج. ننفذ الأوامر التالية لهذا الغرض:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_17">
<span class="pln">git checkout master
git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)</span></pre>

<p>
	لاحظ جملة <code>fast-forward</code> (تقدّم سريع) بعد تنفيذ أمر الدمج. يعود السبب في ذلك إلى أن الإيداع الذي يشير إليه التفريع الذي دمجت فيه يوجد ضمن سوابق الإيداع الذي دمجته. بعبارة أخرى؛ عندما تريد دمج إيداع “أ” مع إيداع “ب” يوجد من بين سوابق الإيداع المدموج ("أ") فإن Git يسهّل الأمر بتقديم مؤشر التفريع “ب” ليحيل إلى الإيداع “أ”؛ يفعل Git هذا الأمر بسبب عدم وجود إيداعات متنافرة بين التفريعين لدمجها. بمعنى أنه في حالتنا لم يطرأ أي إيداع على التفريع <code>master</code> منذ إنشاء التفريع <code>hotfix</code>. نقول في هذه الحالة إن Git أجرى تقدما سريعا <code>fast-forward</code>.
</p>

<p>
	توجد التعديلات الآن في اللقطة التي يشير إليها التفريع <code>master</code> ويمكن نشر الترقيع ليصبح متاحا للعموم.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/05_basic_branching.png.4410b7da4e85a0d12a16ab4140de58d9.png"><img alt="05_basic_branching.thumb.png.849ecaa059c" class="ipsImage ipsImage_thumbnailed" data-fileid="12692" data-unique="u4b2d5c7o" src="https://academy.hsoub.com/uploads/monthly_2016_02/05_basic_branching.thumb.png.849ecaa059cdbcf70c609d0b7b5a0bc9.png"></a><br><strong>التقدم السريع للتفريع <code>master</code> إلى التفريع <code>hotfix</code></strong>
</p>

<p>
	أنت جاهز بعد نشر الترقيع العاجل للعودة إلى العمل الذي انقطعت عنه. لكن يجب أولا حذفُ تفريع <code>hotfix</code> الذي لم تعد تحتاج إليه؛ تفريع <code>master</code> يشير الآن إلى نفس الإيداع. يمكن حذف التفريع <code>hotfix</code> باستخدام أمر <code>git branch</code> مع خيار <span style="font-family:courier new,courier,monospace;"><code>d-</code></span>:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_19">
<span class="pln">git branch -d hotfix
Deleted branch hotfix (3a0874c).</span></pre>

<p>
	يمكن العودة إلى التفريع <code>iss53</code> واستكمال العمل على الميزة 53:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_21">
<span class="pln">git checkout iss53
Switched to branch "iss53"
vim index.html
git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/06_basic_branching.png.af67a1bcc0e09075d358468dd3f5f7cb.png"><img alt="06_basic_branching.thumb.png.d0539e311c0" class="ipsImage ipsImage_thumbnailed" data-fileid="12693" data-unique="jr9u6qlub" src="https://academy.hsoub.com/uploads/monthly_2016_02/06_basic_branching.thumb.png.d0539e311c066c136424901ae9e79dde.png"></a><br><strong>استكمال العمل على الميزة 53</strong>
</p>

<p>
	يجب الانتباه هنا إلى أن العمل المضاف إلى التفريع <code>hotfix</code> غير موجود في ملفات التفريع <code>iss53</code>. يوجد لديك خياران لإضافة تعديلات <code>hotfix</code>؛ إما دمج التفريع الرئيس في تفريع <code>iss53</code> أو الانتظار حتى تكمل العمل على التفريع <code>iss53</code> ثم تدمجه في التفريع الرئيس.
</p>

<h2 id="المبادئ-الأساسية-لدمج-التفريعات">
	المبادئ الأساسية لدمج التفريعات
</h2>

<p>
	أكملت العمل على الميزة 53 وأنت جاهز لدمجها في التفريع الرئيس. يجري دمج التفريع <code>iss53</code> في التفريع الرئيس بنفس الطريقة التي دمجنا بها التفريع <code>hotfix</code> في التفريع الرئيس: الانتقال إلى التفريع الرئيس بالأمر <code>git checkout</code> ثم تنفيذ أمر الدمج:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_23">
<span class="pln">git checkout master
Switched to branch 'master'
git merge iss53
Merge made by the 'recursive' strategy.
index.html |    1 +
1 file changed, 1 insertion(+)</span></pre>

<p>
	يوجد اختلاف بين الدمج في هذه الحالة ودمج التفريع <code>hotfix</code> السابق. مصدر الاختلاف هو حدوث إيداعات على كل من التفريعين بالتوازي؛ الإيداع الذي يشير إليه التفريع الرئيس الآن ليس هو الإيداع الذي كان يشير إليه عند إنشاء التفريع <code>iss53</code>. يعني هذا أن على Git اتخاذ طريقة مغايرة للتقدم السريع آنفة الذكر. ينفذ Git في هذه الحالة ما يعرف بالدمج الثلاثي Three-way merge فيستخدم اللقطتين المشار إليهما في الصورة أدناه والإيداع المشترك بين الفرعين.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/07_basic_branching.png.61dff084d987676866887e8d4d568046.png"><img alt="07_basic_branching.thumb.png.cb4d3f8cfda" class="ipsImage ipsImage_thumbnailed" data-fileid="12696" data-unique="epccaknde" src="https://academy.hsoub.com/uploads/monthly_2016_02/07_basic_branching.thumb.png.cb4d3f8cfda8985cd9b78896009a4077.png"></a><br><strong>3 لقطات مستخدمة في الدمج</strong>
</p>

<p>
	ينشئ Git، بدلا من تقديم المؤشر إلى آخر إيداع في التفريع <code>iss53</code> مثل ما فعل مع التفريع <code>hotfix</code>، ينشئ لقطة جديدة ناتجة عن الدمج الثلاثي، وينشئ تلقائيا إيداعا جديدا يشير إلى اللقطة الجديدة. يُسمّى هذا الإيداع بإيداع الدمج Merge commit، ويتميز بكونه جزءا من متتاليتي إيداعات (أي أن له سابقين).
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/08_basic_branching.png.705d3219bfea877fb605d0301869bb8a.png"><img alt="08_basic_branching.thumb.png.2ffe172376c" class="ipsImage ipsImage_thumbnailed" data-fileid="12695" data-unique="tkiapifv3" src="https://academy.hsoub.com/uploads/monthly_2016_02/08_basic_branching.thumb.png.2ffe172376c5707d1544bfb6b4856268.png"></a><br><strong>إيداع دمج</strong>
</p>

<p>
	تجدر الإشارة هنا إلى أن Git يحدّد الإيداع الأفضل من بين الإيداعات السابقة لاستخدامه قاعدة للدمج. يختلف الأمر عن نظم إدارة نسخ أخرى مثل CVS وSubversion (قبل الإصدار 1.5) يُطلب فيها من المطور تحديد أفضل قاعدة إيداعات للدمج وفقا لها؛ وهو ما يجعل دمج التفريعات في Git أسهل كثيرا من النظم الأخرى.
</p>

<p>
	لم نعد نحتاج الآن، بعد دمج الميزة في التفريع الرئيس، للتفريعة 53. يمكن إغلاق التذكرة Ticket في نظام إدارة التذاكر لديك وحذف التفريع:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_25">
<span class="pln">git branch -d iss53</span></pre>

<h3 id="التعارض-في-عمليات-الدمج">
	التعارض في عمليات الدمج
</h3>

<p>
	لا تجري الأمور دائما بنفس السهولة المذكورة في الفقرة السابقة. إن غيّرت نفس الأجزاء من نفس الملف في فرعين تريد دمجهما فلن يكون بمقدور Git دمجهما بطريقة صحيحة. مثلا، إن عدّل العمل على الميزة 53 والترقيع في التفريع <code>hotfix</code> نفس الجزء من نفس الملف فسيظهر لديك تعارض Conflict في الدمج كما في المثال أدناه:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_27">
<span class="pln">git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.</span></pre>

<p>
	لم ينشئ Git في المثال أعلاه إيداعا للدمج؛ بل أوقف عملية الدمج إلى أن تحل مشكلة التعارض. إن أردت رؤية الملفات التي لم تطلها عملية الدمج بعد فيمكنك تنفيذ الأمر <code>git status</code>:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_29">
<span class="pln">git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")

Unmerged paths:
(use "git add </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to mark resolution)

    both modified:      index.html

no changes added to commit (use "git add" and/or "git commit -a")</span></pre>

<p>
	تظهر جميع الملفات التي يوجد بها تعارض يمنع دمجها تحت بند <code>Unmerged</code> (غير مدموج). يضيف Git علامات قياسية لحل التعارض إلى الملفات المعنية ليمكن للمطور فتحها ومن ثم حلّ التعارضات. يحوي الملف فقرة تشبه ما يلي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_31">
<span class="pln">&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD:index.html
</span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"footer"</span><span class="tag">&gt;</span><span class="pln">contact : email.support@github.com</span><span class="tag">&lt;/div&gt;</span><span class="pln">
=======
</span><span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"footer"</span><span class="tag">&gt;</span><span class="pln">
please contact us at support@github.com
</span><span class="tag">&lt;/div&gt;</span><span class="pln">
&gt;&gt;&gt;&gt;&gt;&gt;&gt; iss53:index.html</span></pre>

<p>
	يعني هذا أن النسخة التي يحيل إليها المؤشر <code>HEAD</code> هي تلك الموجودة في الأعلى (كل ما يوجد فوق الخط <code>======</code>)؛ بينما يظهر محتوى الملف الموجود في التفريع <code>iss53</code> في الأسفل. للتذكير، يحيل المؤشر <code>HEAD</code> إلى التفريع الرئيس الآن، ويعود السبب في ذلك إلى أننا انتقلنا إليه بتنفيذ الأمر <code>git checkout</code> قبل محاولة الدمج.
</p>

<p>
	يجب اختيار محتوى أحد الملفين أو دمجهما يدويا. يمكن على سبيل المثال تغيير كامل الجزء المعلّم (يبدأ بـ<code>&lt;&lt;&lt;&lt;&lt;&lt;&lt;</code> وينتهي بـ <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt;</code>) ووضع محتوى جديد مكانه:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_33">
<span class="tag">&lt;div</span><span class="pln"> </span><span class="atn">id</span><span class="pun">=</span><span class="atv">"footer"</span><span class="tag">&gt;</span><span class="pln">
please contact us at email.support@github.com
</span><span class="tag">&lt;/div&gt;</span></pre>

<p>
	يحوي هذا الحل جزءًا من كل فقرة، ويُلاحظ أن الأسطر <code>&gt;&gt;&gt;&gt;&gt;&gt;&gt;</code>، <code>&lt;&lt;&lt;&lt;&lt;&lt;&lt;</code> و <code>=======</code> اختفت بالكامل. نفذ أمر <span style="font-family:courier new,courier,monospace;"><code>git add</code> </span>على كل ملف بعد التخلص من التعارض. إضافة ملف به تعارض إلى منطقة الإدراج في Git يعني أن التعارض في الملف حُلّ.
</p>

<p>
	نفّذ أمر <span style="font-family:courier new,courier,monospace;"><code>git mergetool</code></span> إن أردت استخدام أداة رسومية لحل التعارضات. يُظهِر الأمر الأداة الرسومية المناسبة لحل التعارضات:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_35">
<span class="pln">git mergetool

This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html

Normal merge conflict for 'index.html':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (meld):</span></pre>

<p>
	اضغط زر <code>Enter</code> للبدء في استخدام الأداة الافتراضية (في المثال أعلاه يظهر اسم الأداة <code>meld</code> بين قوسين لأن المستخدم يشغّل نظام لينكس). إن أردت استخدام أداة مغايرة فيمكنك الاختيار بين الأدوات المدعومة التي يسردها أمر <code>git mergetool</code> مباشرة بعد جملة <code>one of the following tools</code> ثم كتابة اسم الأداة والضغط على زر <code>Enter</code>.
</p>

<p>
	يسألك Git بعد الخروج من الأداة ما إذا كان الدمج ناجحا. فإن أجبت بنعم (زر <code>y</code> على لوحة المفاتيح) فإنه يعلمّ الملفات للإشارة لتجاوز التعارض ويضيفها بالتالي إلى منطقة الإدراج. يمكن تنفيذ أمر <code>git status</code>مرة أخرى للتأكد من أن جميع التعارضات حُلّت:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_37">
<span class="pln">git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)

Changes to be committed:

    modified:   index.html</span></pre>

<p>
	ثم تنفيذ أمر الإيداع <code>git commit</code> لاستكمال الدمج، بعد التأكد من أن جميع الملفات التي يوجد بها تعارض أضيفت إلى منطقة الإدراج. تبدو رسالة الإيداع المبدئية على النحو التالي (عند تنفيذ أمر <code>git commit</code> بعد دمج الملفات المتعارضة):
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_1295_39">
<span class="pln">Merge branch 'iss53'

Conflicts:
    index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
#   .git/MERGE_HEAD
# and try again.


# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
#   modified:   index.html
#</span></pre>

<p>
	يمكنك تعديل الرسالة لإضافة تفصيلات عن كيفية حل التعارض إن كنت ترى أن ذلك سيفيد الآخرين عند النظر في هذا الدمج في المستقبل. لماذا فعلت ما فعلت، خصوصا إن لم يكن بديهيا.
</p>

<p>
	ترجمة -بتصرف- للفصل <a href="https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging" rel="external nofollow">Git Branching - Basic Branching and Merging</a> من كتاب <a href="http://git-scm.com/book/en/v2" rel="external nofollow" target="_blank">Pro Git</a> لصاحبه <a href="https://twitter.com/chacon" rel="external nofollow" target="_blank">Scott Chacon</a>.
</p>
]]></description><guid isPermaLink="false">276</guid><pubDate>Fri, 11 Mar 2016 00:07:41 +0000</pubDate></item><item><title>&#x645;&#x642;&#x62F;&#x645;&#x629; &#x639;&#x646; &#x627;&#x644;&#x62A;&#x641;&#x631;&#x64A;&#x639; (Branching) &#x641;&#x64A; Git</title><link>https://academy.hsoub.com/programming/workflow/git/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%B9%D9%86-%D8%A7%D9%84%D8%AA%D9%81%D8%B1%D9%8A%D8%B9-branching-%D9%81%D9%8A-git-r271/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_03/git-branching.png.49307448c529c30d80b62de6671256d1.png" /></p>

<p>
	يدعم Git على غرار غالبية أنظمة إدارة النسخ التفريع Branching.
</p>

<p style="text-align: center;">
	<img alt="git-branching.png.9207636d12d0a3f8291a73" class="ipsImage ipsImage_thumbnailed" data-fileid="13713" data-unique="nt0w9pdm1" src="https://academy.hsoub.com/uploads/monthly_2016_03/git-branching.png.9207636d12d0a3f8291a73a982a620d0.png"></p>

<p>
	يُقصَد بالتفريع الانتقال للعمل على خط تطوير مغاير لخط التطوير الرئيس والاستمرار في العمل على هذا الخط دون تداخل مع الخط الرئيس. يتطلّب التفريع في كثير من أنظمة إدارة النسخ إنشاء نسخة جديدة من مجلد الشفرة المصدرية، وهو أمر مكلّف ويأخذ الكثير من الوقت في المشاريع الكبيرة.
</p>

<h2 id="أساسيات-التفريع">
	أساسيات التفريع
</h2>

<p>
	نحتاج لفهم آلية التفريع للعودة قليلا إلى الوراء ومراجعة الكيفية التي يخزّن بها Git بياناته. ذكرنا في درس <a href="https://academy.hsoub.com/programming/workflow/git/%D9%85%D8%A8%D8%A7%D8%AF%D8%A6-git-%D8%A7%D9%84%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-r256/">مبادئ Git الأساسية</a> أن البرنامج لا يخزّن البيانات على هيئة مجموعة فروق أو تغييرات؛ لكنه بدلا من ذلك يخزّن متتالية من اللقطات Snapshots.
</p>

<p>
	ما يحدُث عند إيداع البيانات هو أن Git يخزّن كائن إيداع Commit object يحوي مؤشرا على لقطة للمحتوى الذي أدرجته. يوجد بهذا الكائن أيضا اسمُ كاتب الإيداع Author وبريده الإلكتروني، الرسالة التي أضفتها مع الإيداع ومؤشرات Pointers على الإيداع أو الإيداعات التي تأتي مباشرة قبل الإيداع الذي يمثّله الكائن المذكور (الإيداع أو الإيداعات السابقة): لا سابق بالنسبة لأول إيداع، سابق واحد لإيداع عاديّ وإيداعات سابقة متعدّدة لإيداع ناتج عن دمج Merge تفريعين أو أكثر.
</p>

<p>
	سنفرض أن لدينا ثلاثة ملفات، أضفناها جميعا إلى منطقة الإدراج ثم نفّذنا أمر الإيداع. ينشئ الإدراج جمع تحقق Checksum لكلّ ملف، يخزّن نسخة الملف في مستودع Git (يسمّي Git هذه النسخ بالكتل Blobs) ثم يضيف جموع التحقق إلى منطقة الإدراج:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2976_7">
<span class="pln">git add README test.rb LICENSE
git commit -m 'The initial commit of my project'</span></pre>

<p>
	ينشئ Git عند تنفيذ أمر <code>commit</code> جمع تحقق لكل مجلّد فرعي (المجلّد الجذر فقط في المثال الحالي) ويخزّن كائنات الشجرة في مستودع Git؛ ثم ينشئ بعد ذلك كائن إيداع لديه بيانات وصفية Metadata ومؤشرًا يحيل إلى شجرة جذر المشروع مما يسمح له بإنشاء لقطة من المجلد عند الحاجة.
</p>

<p>
	يحوي مستودع Git الآن خمسة كائنات: كتلة واحدة لمحتوى كلٍّ من الملفات الثلاثة، شجرة واحدة تسرُد لائحة بمحتوى المجلّد وتحدّد الكتل التي تخزِّن أسماء الملفات وكائن إيداع يوجد فيه مؤشر إلى جذر الشجرة إضافة لكلّ البيانات الوصفية الخاصة بالإيداع.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/01_commits_and_tree.png.4e9e4f8c36711c8211e37c1793d21649.png"><img alt="01_commits_and_tree.thumb.png.de574b7405" class="ipsImage ipsImage_thumbnailed" data-fileid="12540" data-unique="z8jknris5" src="https://academy.hsoub.com/uploads/monthly_2016_02/01_commits_and_tree.thumb.png.de574b740550f9b13e4b3b4f9be4d328.png"></a><br><strong>شجرة البيانات الخاصة بالإيداع</strong>
</p>

<p>
	إن أجريت تعديلات ثم نفذت أمر <code><span style="font-family:courier new,courier,monospace;">commit</span> </code>من جديد فإن الإيداع الجديد سيخزّن مؤشرا على الإيداع الذي سبقه.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/02_commits_parents.png.bc873ff5d9cc8f509eeece186a92eb0b.png"><img alt="02_commits_parents.thumb.png.62fe04b207e" class="ipsImage ipsImage_thumbnailed" data-fileid="12541" data-unique="9roa8jr55" src="https://academy.hsoub.com/uploads/monthly_2016_02/02_commits_parents.thumb.png.62fe04b207e1607cef45c87faea860d9.png"></a><br><strong>إيداع والإيداعات السابقة عليه</strong>
</p>

<p>
	تفريع Git ليس سوى مؤشر على واحد من هذه الإيداعات؛ يتميز هذا المؤشر بكونه قابلا للنقل. يدعى التفريع المبدئي في Git بـ<code>master</code>. ينشئ Git عند بدء الإيداعات تفريعا يؤشِّر على آخر إيداع؛ وفي كلّ مرة تضيف إيداعا جديدا ينتقل المؤشر تلقائيا إليه.
</p>

<p>
	<strong>ملحوظة: </strong>تفريع <code>master</code> ليس تفريعًا خاصًّا فهو مماثل لأي تفريع آخر في Git. يعود السبب في كون كلّ مستودعات Git تقريبا تحوي تفريعًا بهذا الاسم إلى أنّ أمر <code>git init</code> ينشئ مبدئيا تفريعا بهذا الاسم، والكثيرون لا يكلّفون أنفسهم عناء تغييره.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/03_branch_history.png.6b18229fd23bb8f9cdd5fd96fe7ad957.png"><img alt="03_branch_history.thumb.png.d6ba0f269e11" class="ipsImage ipsImage_thumbnailed" data-fileid="12542" data-unique="0gpu6rlms" src="https://academy.hsoub.com/uploads/monthly_2016_02/03_branch_history.thumb.png.d6ba0f269e11a19a4867d05fe8824c6c.png"></a><br><strong>تفريع وسجل الإيداعات الخاصة به</strong>
</p>

<h2 id="إنشاء-تفريع-جديد-في-git">
	إنشاء تفريع جديد في Git
</h2>

<p>
	مالذي يحدث بالضبط عندما تنشئ تفريعا جديدا؟ يعني هذا أنك تنشئ مؤشرا جديدا للتنقل به. فلنفترض أننا أنشأنا تفريعا جديدا باسم <code>testing</code> باستخدام أمر <code>git branch</code> التالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2976_9">
<span class="pln">git branch testing</span></pre>

<p>
	ينشئ الأمر مؤشرا جديدا يحيل إلى نفس الإيداع الذي توجد عليه. أي أن لدينا مؤشرين يحيلان إلى نفس المتتالية من الإيداعات.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/04_two_branches.png.169a1f048c925b8baf0d7875eb0d3497.png"><img alt="04_two_branches.thumb.png.3e306d0e9b1c07" class="ipsImage ipsImage_thumbnailed" data-fileid="12543" data-unique="kybfzsi6c" src="https://academy.hsoub.com/uploads/monthly_2016_02/04_two_branches.thumb.png.3e306d0e9b1c075d45da118a3546e502.png"></a><br><strong>تفريعان يشيران إلى نفس متتالية الإيداعات</strong>
</p>

<p>
	كيف يعرف Git التفريع الذي توجد عليه الآن؟ يحتفظ Git لهذا الغرض بمؤشر خاص يُسمّى <code>HEAD</code> (المقدّمة). ينبغي الانتباه إلى أن <code>HEAD</code> في Git مختلف تماما عنه في أنظمة إدارة نسخ أخرى مثل Subversion و CVS. يحيل <code>HEAD</code> إلى التفريع المحلي الذي تعمل عليه الآن. في المثال أعلاه فنحن لا زلنا على التفريع <code>master</code> حتى بعد إنشاء تفريع <code>testing</code> الجديد؛ فأمر <code>git branch</code> ينشئ تفريعا جديدا ولكنّه لا ينقُل إلى التفريع الجديد.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/05_head_master.png.de7bddb2a14c6c35bbe2df4730549c9d.png"><img alt="05_head_master.thumb.png.1fd914ecf3c9745" class="ipsImage ipsImage_thumbnailed" data-fileid="12544" data-unique="7y41elxz6" src="https://academy.hsoub.com/uploads/monthly_2016_02/05_head_master.thumb.png.1fd914ecf3c9745f2786ff6c94f9dea6.png"></a><br><strong>مؤشر HEAD يشير إلى تفريع master</strong>
</p>

<p>
	تسهُل رؤية هذا الأمر بتنفيذ أمر <code>git log</code> الذي يعرض عند تحديد الخيار <code>decorate--</code> الإيداعات التي تحيل إليها مؤشرات التفريعات:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2976_11">
<span class="pln">git log --oneline --decorate
f30ab (HEAD  -&gt; master, testing) add feature #32 - ability to add new formats to the central interface
34ac2 Fixed bug #1328 - stack overflow under certain conditions
98ca9 The initial commit of my project</span></pre>

<p>
	يظهر اسما التفريعين <code>master</code> و<code>testing</code> بجانب الإيداع <code>f30ab</code>.
</p>

<h2 id="التبديل-بين-التفريعات">
	التبديل بين التفريعات
</h2>

<p>
	يُستخدم أمر <code>git checkout</code> للانتقال إلى تفريع وبدء العمل عليه. ننفذ الأمر التالي للانتقال إلى التفريع <code>testing</code> الذي أنشأناه للتو:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_9130_7">
<span class="pln">git checkout testing</span></pre>

<p>
	ينقل أمر <code>git checkout</code> أعلاه مؤشرَ <code>HEAD</code> إلى تفريع <code>testing</code>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/06_head_testing.png.4ed27b6525d518365a75993afd1b73e2.png"><img alt="06_head_testing.thumb.png.44f889b9e029c1" class="ipsImage ipsImage_thumbnailed" data-fileid="12545" data-unique="rwvz5k9on" src="https://academy.hsoub.com/uploads/monthly_2016_02/06_head_testing.thumb.png.44f889b9e029c1d7099df520daf4397d.png"></a><br><strong>يشير HEAD الآن إلى تفريع testing</strong>
</p>

<p>
	ما دلالة نقل مؤشّر <code>HEAD</code>؟ سنضيف إيداعا جديدا وسنرى: 
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2976_13">
<span class="pln">vim test.rb
git commit -a -m 'made a change'</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/07_advance_testing.png.7c21e618a80e604db067096e0bf69e39.png"><img alt="07_advance_testing.thumb.png.57d8809ff37" class="ipsImage ipsImage_thumbnailed" data-fileid="12546" data-unique="jla5c9lah" src="https://academy.hsoub.com/uploads/monthly_2016_02/07_advance_testing.thumb.png.57d8809ff37c8a7518c0d24372a52233.png"></a><br><strong>يتقدم مؤشر <code>HEAD</code> إلى الإيداع الأخير في التفريع</strong>
</p>

<p>
	ينتقل مؤشر <code>HEAD</code> بتنفيذ الأمر <code>commit</code>. أي أن تفريع <code>testing</code> تقدم بإيداع بينما لا زال تفريع <code>master</code> على ما كان عليه عند تنفيذ أمر الانتقال <code>git checkout</code>. نعود إلى التفريع الرئيس <code>master</code> بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2976_15">
<span class="pln">git checkout master</span></pre>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/08_checkout_master.png.ed6ec243dd58bd3a4fbcd46e08db25f8.png"><img alt="08_checkout_master.thumb.png.bab60e8625b" class="ipsImage ipsImage_thumbnailed" data-fileid="12547" data-unique="wxjg6mx8c" src="https://academy.hsoub.com/uploads/monthly_2016_02/08_checkout_master.thumb.png.bab60e8625bdae047e8fa538a505efad.png"></a><br><strong>ينتقل مؤشر <code>HEAD</code> إلى التفريع الرئيس</strong>
</p>

<p>
	ينقل الأمر السابق مؤشر <code>HEAD</code> ليحيل إلى التفريع الرئيس ثم يرجع الملفات الموجودة في مجلد العمل إلى اللقطة التي يشير إليها التفريع <code>master</code>. يعني هذا أيضا أن التعديلات من الآن فصاعدا ستكون على نسخة قديمة من المشروع. يبدو الأمر كما لو أنك تراجعت عن التعديلات التي أجريتها بعد الانتقال إلى تفريع <code>testing</code>؛ وبدأت في تغييرات جديدة.
</p>

<p>
	<strong>ملحوظة: الانتقال إلى تفريع يغيّر ملفات مجلد العمل.</strong>
</p>

<p>
	ينبغي الانتباه إلى أن الانتقال إلى تفريع يؤدي إلى تغير الملفات الموجودة في مجلد العمل. إن انتقلت إلى تفريع قديم فسيعود محتوى مجلد العمل إلى ما كان عليه بعد آخر إيداع على هذا التفريع. إن لم يستطع Gitفعل ذلك فلن يسمح لك بتاتا بالانتقال إلى التفريع الجديد
</p>

<blockquote>
	<p>
		نعدّل على أحد الملفات ثم نضيف إيداعا جديدا:
	</p>
</blockquote>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2976_17">
<span class="pln">vim test.rb
git commit -a -m 'made other changes'</span></pre>

<p>
	للتذكير نحن نعمل على التفريع <code>master</code>. بالإيداع أعلاه يبدأ سجلّ التفريعين بالتباعد كما هو موضح في الشكل أدناه. أنشأنا تفريعا جديدا وانتقلنا للعمل عليه، أجرينا بضعة تغييرات ثم عدنا من جديد للعمل على التفريع الرئيس. كل من هذه التغييرات معزول عن الآخر في تفريع مختلف: يمكن العمل على تفريع، ثم الانتقال إلى تفريع آخر والعمل عليه ثم العودة إلى التفريع الأول والعمل عليه أيضا؛ وعندما تكون جاهزا يمكن أن تدمج الاثنين. يؤدّى كل هذا العمل بسهولة بالأوامر <code>checkout </code>،<code>branch</code> و<code>commit</code>.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_02/09_advance_master.png.9501787864eedc5625ed1afe6315feba.png"><img alt="09_advance_master.thumb.png.c35c4ecf1a3e" class="ipsImage ipsImage_thumbnailed" data-fileid="12548" data-unique="16yjvovdc" src="https://academy.hsoub.com/uploads/monthly_2016_02/09_advance_master.thumb.png.c35c4ecf1a3e8d4d8951709791b180de.png"></a><br><strong>تباعد التفريعات عن بعضها</strong>
</p>

<p>
	يمكن استخدام الأمر التالي لعرض سجل التغييرات على شكل مخطّط يوضّح إلى أين تحيل مؤشرات التفريعات وكيف تباعدت عن بعضها:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2976_19">
<span class="pln">git log --oneline --decorate --graph --all</span></pre>

<p>
	مثال على النتيجة:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2976_21">
<span class="pln">* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project</span></pre>

<p>
	يسهُل إنشاء تفريعات ومحوها في Git، إذ لا يتطلّب ذلك سوى إنشاء ملفّ من مجموع تحقق ذي 40 محرفا يمثّل الإيداع الذي يحيل إليه مؤشّر التفريع. يختلف Git عن نظم إدارة نسخ أخرى يتطلب التفريع فيها نسخ جميع ملفات المشروع إلى مجلد ثان ممّا يدوم ثواني عدّة وأحيانا دقائق حسب حجم المشروع؛ بينما يكاد يكون الأمر في Git لحظيا. زيادة على ذلك فإن تخزين سوابق الإيداع تجعل من العثور على قاعدة مناسبة لدمج تفريعين أسهل وفي كثير من الأحيان تلقائيا. تشجّع هذه الميزة التي سنتطرّق إليها في المقال التالي المطوّرين على إنشاء التفريعات واستخدامها أكثر.
</p>

<p>
	ترجمة -بتصرف- للفصل <a href="https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell" rel="external nofollow">Git Branching - Branches in a Nutshell</a> من كتاب <a href="http://git-scm.com/book/en/v2" rel="external nofollow" target="_blank">Pro Git</a> لصاحبه <a href="https://twitter.com/chacon" rel="external nofollow" target="_blank">Scott Chacon</a>.
</p>
]]></description><guid isPermaLink="false">271</guid><pubDate>Mon, 07 Mar 2016 21:44:11 +0000</pubDate></item><item><title>&#x645;&#x628;&#x627;&#x62F;&#x626; &#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x627;&#x644;&#x627;&#x62E;&#x62A;&#x635;&#x627;&#x631;&#x627;&#x62A; (Aliases) &#x641;&#x64A; Git</title><link>https://academy.hsoub.com/programming/workflow/git/%D9%85%D8%A8%D8%A7%D8%AF%D8%A6-%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D8%A7%D8%AE%D8%AA%D8%B5%D8%A7%D8%B1%D8%A7%D8%AA-aliases-%D9%81%D9%8A-git-r262/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_02/56cca1c2aae48_git-aliases(1).png.b65aede5ba517890dde5ff6c75867895.png" /></p>

<p>
	يتيح Git طريقة سهلة لجعل كتابة الأوامر وتجربة استخدام Git عموما أيسر وأقرب للتعود عليها، وهي الاختصارات Aliases.
</p>

<p style="text-align: center;">
	<img alt="56cca1c4619af_git-aliases(1).png.9385da5" class="ipsImage ipsImage_thumbnailed" data-fileid="13468" data-unique="rw9feyjvi" src="https://academy.hsoub.com/uploads/monthly_2016_02/56cca1c4619af_git-aliases(1).png.9385da5b03be5e2070d4ebd4dccbeeb6.png"></p>

<p>
	لا يُكمِل Git تلقائيا الأوامر أثناء كتابتها؛ إن كنت ترغب في ألا تكتب الأوامر كاملة في كل مرة فيمكنك إعداد اختصار لكل أمر باستخدام <code>git config</code>؛ في ما يلي أمثلة على بعض هذه الأوامر:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status</pre>

<p>
	يعني تنفيذُ الأوامر أعلاه أنك لن تحتاج لكتابة أمر <code>git commit</code> كاملا من أجل إيداع ملفاتك، بل تكتفي بالاختصار <code>git ci</code>. نفس الشيء ينطبق على <code>git checkout</code> التي أصبح ممكنا إبدالها بـ<code>git co</code>. ستلاحظ أثناء استخدامك لـGit أن أوامر محدّدة تتكرّر أكثر من غيرها؛ لا تتردد في إنشاء اختصارات لها على النحو المذكور أعلاه.
</p>

<p>
	يمكن أيضا استخدام الاختصارات لإنشاء أوامر ترى أنها يجب أن تكون موجودة. مثلا؛ لتسهيل نزع ملف من منطقة الإدراج يمكن إنشاء اختصار باسم <span style="font-family:courier new,courier,monospace;"><code>unstage</code></span> بدلا من الأمر الكامل <code>-- reset HEAD</code>:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git config --global alias.unstage 'reset HEAD --'</pre>

<p>
	لدينا الآن تكافؤ في عمل الأمرين التاليين، مع سهولة أكثر في استخدام الأول منهما (الاختصار):
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git unstage fileA
git reset HEAD -- fileA</pre>

<p>
	من الشائع بين مستخدمي Git إضافةُ اختصار باسم <code>last</code> لعرض آخر إيداع:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git config --global alias.last 'log -1 HEAD'</pre>

<p>
	فيصبح عرض آخر إصدار أسهل:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git last
commit 66938dae3329c7aebe598c2246a8e6af90d04646
Author: Josh Goebel &amp;lt;dreamer3@example.com&amp;gt;
Date:   Tue Aug 26 19:48:51 2008 +0800

    test for current head

    Signed-off-by: Scott Chacon &amp;lt;schacon@example.com&amp;gt;</pre>

<p>
	يبدِل Git الاختصار بالأمر الذي حددته أثناء إنشائها، الأمر بهذه السهولة.
</p>

<p>
	قد تودّ تنفيذ أمر خارجي بدلا من واحد من أوامر Git؛ يعرَّف الاختصار في هذه الحالة بوضع علامة تعجّب <code>!</code> أمامه. يفيد استخدام الاختصارات بهذه الطريقة كثيرا إن كنت تطور أدوات خاصة للتعامل مع مستودعات Git.
</p>

<p>
	مثال على إنشاء اختصار لأداة <code>gitk</code> (متصفح مستودعات بواجهة رسومية):
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git config --global alias.visual '!gitk'</pre>

<p>
	ترجمة -بتصرف- للفصل <a href="http://git-scm.com/book/en/v2/Git-Basics-Git-Aliases" rel="external nofollow">Git Basics - Git Aliases</a> من كتاب <a href="http://git-scm.com/book/en/v2" rel="external nofollow" target="_blank">Pro Git</a> لصاحبه <a href="https://twitter.com/chacon" rel="external nofollow" target="_blank">Scott Chacon</a>.
</p>
]]></description><guid isPermaLink="false">262</guid><pubDate>Tue, 01 Mar 2016 21:25:00 +0000</pubDate></item><item><title>&#x623;&#x633;&#x627;&#x633;&#x64A;&#x627;&#x62A; &#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x627;&#x644;&#x648;&#x633;&#x648;&#x645; (Tags) &#x641;&#x64A; Git</title><link>https://academy.hsoub.com/programming/workflow/git/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D9%88%D8%B3%D9%88%D9%85-tags-%D9%81%D9%8A-git-r261/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_02/git-tags.png.9ec54453d974ef5ed34806e761857ee4.png" /></p>

<p>
	يتيح Git مثل الكثير من أنظمة إدارة النسخ <abbr title="Version Control Systems | أنظمة التحكم بالنُّسخ"><abbr title="Version Control Systems | أنظمة التحكم بالنُّسخ">VCS</abbr></abbr>، إمكانية تعليم مواضع معينة خلال مرحلة التطوير على أنها مهمة باستخدام وسوم Tags.
</p>

<p style="text-align: center;">
	<img alt="git-tags.png" class="ipsImage ipsImage_thumbnailed" data-fileid="13465" data-unique="6u5womj2y" src="https://academy.hsoub.com/uploads/monthly_2016_02/git-tags.png.a1b7308b9b76284daa901b8030c2cd8a.png"></p>

<p>
	يستخدم المطورون كثيرا هذه الميزة لتحديد مواضع إطلاق الإصدارات (الإصدار 1.0؛ 1.1 وهكذا). سنرى في هذا المقال كيفية عرض الوسوم المستخدمة في المستودع، كيفية إنشاء وسوم جديدة وما هي أنواع الوسوم.
</p>

<h2 id="عرض-الوسوم">
	عرض الوسوم
</h2>

<p>
	يعرض الأمر التالي قائمة بالوسوم الموجودة في المستودع:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git tag</pre>

<p>
	النتيجة:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
v0.1
v1.3</pre>

<p>
	يعرض الأمر أعلاه الوسوم حسب الترتيب الأبجدي.
</p>

<p>
	يمكن أيضا البحث عن الوسوم التي تتبع نمطا معيّنا. يحوي مستودع الشفرة المصدرية لـGit على سبيل المثال أكثر من 500 وسم؛ إن كنت ترغب في إظهار الوسوم التي تتعلق بالإصدار <code>1.8.5</code> فقط دون غيره فالأمر التالي يؤدي المهمة:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git tag -l "v1.8.5*"</pre>

<p>
	مثال على النتيجة:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
v1.8.5
v1.8.5-rc0
v1.8.5-rc1
v1.8.5-rc2
v1.8.5-rc3
v1.8.5.1
v1.8.5.2
v1.8.5.3
v1.8.5.4
v1.8.5.5</pre>

<h2 id="إنشاء-الوسوم">
	إنشاء الوسوم
</h2>

<p>
	يستخدم Git نوعين من الوسوم: الخفيفة Lightweight والمشروحة Annotated.
</p>

<p>
	يشبه الوسم الخفيف فرعا لا تدخل عليه تغييرات، إذ أنه ليس إلا مؤشر على إيداع محدّد.
</p>

<p>
	الوسوم المشروحة على العكس من ذلك تخزّن بوصفها كائنات داخل قاعدة بيانات Git ويُنشأ لها مجموع تحقق، تحتوي على اسم من أضاف الوسم، بريده الإلكتروني والتاريخ. كما أن لديها رسالة وسم، ويمكن أن توثَّق ويُتحقَّق منها بواسطة GnuPG (برنامج تعمية تابع لمشروع GNU). يُنصَح باستخدام الوسوم المشروحة من أجل الحصول على كل هذه المعلومات، لكن إن كنت تريد وسما ظرفيا أو لا تريد لسبب ما حفظ البيانات المذكورة آنفا فإن الوسوم الخفيفة متاحة لهذا الغرض.
</p>

<h3 id="الوسوم-المشروحة">
	الوسوم المشروحة
</h3>

<p>
	كل ما عليك فعله لإنشاء وسم مشروح هو إضافة خيار <code>a-</code> إلى أمر <code>git tag</code> على النحو التالي:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git tag -a v1.4 -m "my version 1.4"
git tag
v0.1
v1.3
v1.4</pre>

<p>
	يحدّد الخيار <code>m-</code> رسالة الوسم التي تخزَّن معه. إن لم تحدّد رسالة فسيظهر محرّر بعد تنفيذ الأمر لإضافتها.
</p>

<p>
	يمكن عرض الوسم مع الإيداع الموسوم به باستخدام الأمر <code>git show</code>:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git show v1.4
tag v1.4
Tagger: Ben Straub &amp;lt;ben@straub.cc&amp;gt;
Date:   Sat May 3 20:19:12 2014 -0700

my version 1.4

commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon &amp;lt;schacon@gee-mail.com&amp;gt;
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number</pre>

<p>
	يعرض الأمر بيانات الواسِم (صاحب الوسم)، تاريخ وسم الإيداع ورسالة الوسم قبل أن يظهر بيانات الإيداع.
</p>

<h3 id="الوسوم-الخفيفة">
	الوسوم الخفيفة
</h3>

<p>
	الطريقة الأخرى لوسم الإيداعات هي استخدام الوسوم الخفيفة. لا تُخزّن أي معلومات إضافية بالنسبة لهذه الوسوم، ما عدا مجموع التحقق من الإيداع.
</p>

<p>
	استخدم أمر <code>git tag</code> دون ذكر خيار لإنشاء وسم خفيف:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git tag v1.4-lw
git tag
v0.1
v1.3
v1.4
v1.4-lw
v1.5</pre>

<p>
	إن نفذت أمر <code>git show</code> على الوسم الخفيف فلن تظهر سوى بيانات الإيداع:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git show v1.4-lw
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon &amp;lt;schacon@gee-mail.com&amp;gt;
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number</pre>

<h2 id="الوسم-المتأخر">
	الوسم المتأخر
</h2>

<p>
	يوفّر Git إمكانية وسم الإيداعات حتى بعد أن تكون تجاوزتها. فلنفترض أن سجلّ الإيداعات لديك يبدو كالتالي:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git log --pretty=oneline

15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
4682c3261057305bdd616e23b64b0857d832627b added a todo file
166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme</pre>

<p>
	نفترض الآن أنك نسيت إضافة الوسم <code>v1.2</code> على الإيداع ذي الرسالة <code>updated rakefile</code>. لا زال بإمكانك وسم الإيداع؛ لوسم هذا الإيداع حدّد مجموع التحقق منه (أو جزءًا من مجموع التحقق) في نهاية الأمر كالتالي:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git tag -a v1.2 9fceb02</pre>

<p>
	يمكنك التحقق من وسم الإيداع:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git tag
v0.1
v1.2
v1.3
v1.4
v1.4-lw
v1.5

git show v1.2
tag v1.2
Tagger: Scott Chacon &amp;lt;schacon@gee-mail.com&amp;gt;
Date:   Mon Feb 9 15:32:16 2009 -0800

version 1.2
commit 9fceb02d0ae598e95dc970b74767f19372d61af8
Author: Magnus Chacon &amp;lt;mchacon@gee-mail.com&amp;gt;
Date:   Sun Apr 27 20:43:35 2008 -0700

    updated rakefile
...</pre>

<h2 id="مشاركة-الوسوم">
	مشاركة الوسوم
</h2>

<p>
	لا ينقُل أمر <code>git push</code> مبدئيا الوسوم إلى الخواديم البعيدة. ستحتاج للتصريح بأنك تريد نقل الوسوم التي أنشأتها:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git push origin v1.5
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 2.05 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
* [new tag]         v1.5 -&amp;gt; v1.5</pre>

<p>
	إن كانت لديك الكثير من الوسوم وتريد دفعها معا فخيار <code>tags--</code> بدلا من اسم الوسم يؤدي المهمة:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 160 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
* [new tag]         v1.4 -&amp;gt; v1.4
* [new tag]         v1.4-lw -&amp;gt; v1.4-lw</pre>

<p>
	سيحصُل المساهمون الآخرون بهذه الطريقة على الوسوم التي أضفتها عندما ينسخون المستودع أو يجلبون البيانات منه.
</p>

<h2 id="نقل-ملفات-وسم-إلى-مجلد-العمل">
	نقل ملفات وسم إلى مجلد العمل
</h2>

<p>
	إن كنت تريد وضع إصدار يستخدم وسما من المستودع في مجلد العمل فيمكنك إنشاء فرع جديد انطلاقا من الوسم باستخدام أمر <code>git checkout</code> كما يلي:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git checkout -b version2 v2.0.0
Switched to a new branch 'version2'</pre>

<p>
	تحدّد الوسوم، على عكس الفروع، نقطة زمنية ثابتة من المستودع. من هذا المنطلق لا يتطور الوسم بتغير ملفاته لذا ينبغي الانتباه إلى أن الفرع <code>version2</code> لن يكون موافقا للوسم <code>v2.0.0</code> بعد إضافة إيداع إليه؛ إذ أن الفرع تقدم إلى الأمام بالتعديلات الجديدة التي أضافها الإيداع.
</p>

<p>
	ترجمة -وبتصرّف- للفصل <a href="https://git-scm.com/book/en/v2/Git-Basics-Tagging" rel="external nofollow">Git Basics - Tagging</a> من كتاب <a href="http://git-scm.com/book/en/v2" rel="external nofollow" target="_blank">Pro Git</a> لصاحبه <a href="https://twitter.com/chacon" rel="external nofollow" target="_blank">Scott Chacon</a>.
</p>
]]></description><guid isPermaLink="false">261</guid><pubDate>Sun, 28 Feb 2016 21:01:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x639;&#x645;&#x644; &#x639;&#x644;&#x649; &#x627;&#x644;&#x645;&#x633;&#x62A;&#x648;&#x62F;&#x639;&#x627;&#x62A; &#x627;&#x644;&#x628;&#x639;&#x64A;&#x62F;&#x629; (Remote repositories) &#x641;&#x64A; Git</title><link>https://academy.hsoub.com/programming/workflow/git/%D8%A7%D9%84%D8%B9%D9%85%D9%84-%D8%B9%D9%84%D9%89-%D8%A7%D9%84%D9%85%D8%B3%D8%AA%D9%88%D8%AF%D8%B9%D8%A7%D8%AA-%D8%A7%D9%84%D8%A8%D8%B9%D9%8A%D8%AF%D8%A9-remote-repositories-%D9%81%D9%8A-git-r253/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_02/git-working-with-remotes.png.8510dd15fbba7e84078982c07e171849.png" /></p>

<p>
	يجب أن تعرف كيف تدير المستودعات البعيدة لتكون قادرا على التعاون في مشروع يستخدم Git.
</p>

<p style="text-align: center;">
	<img alt="git-working-with-remotes.png" class="ipsImage ipsImage_thumbnailed" data-fileid="13464" data-unique="1rs0ye6ar" src="https://academy.hsoub.com/uploads/monthly_2016_02/git-working-with-remotes.png.720ad40298d0d3c43464a4be8ec59c83.png"></p>

<p>
	المستودعات البعيدة هي نسخ من المشروع مضافة على خادوم غير جهازك المحلي. يمكن أن يكون لديك أكثر من مستودع بعيد، وهو إما أن يكون للقراءة فقط Read-only أو للقراءة والكتابة. يستدعي التعاون مع الآخرين إدارةَ المستودعات ودفع Push البيانات إليها أو جلبها منها Pull لمشاركة مساهماتك مع بقية الفريق. تتضمن إدارة المستودعات البعيدة معرفة كيفية إضافتها، حذفها عندما تصبح غير صالحة، إدارة الفروع Branches البعيدة ومتابعتها Tracking إضافةً لأمور أخرى. يعرِض هذا المقال لمهارات أساسية لإدارة المستودعات البعيدة.
</p>

<h2 id="عرض-المستودعات-البعيدة">
	عرض المستودعات البعيدة
</h2>

<p>
	يعرِض الأمر <code>git remote</code> الخواديم البعيدة المضبوطة لديك. ينتج عن تنفيذ الأمر إظهار لائحة بأسماء مختصرة لكل خادوم بعيد ضبطته. إن كنت نسخت مستودعا فسترى على الأقل الاسم المختصر <code>origin</code>، وهو الاسم المختصر الافتراضي الذي يعطيه Git للخادوم الذي نسخت منه المستودع. يستخدَم الاسم المختصر مرجعا للدلالة على المستودع بدلا من كتابة مساره كاملا.
</p>

<p>
	في المثال التالي ننسخ المستودع <code>ticgit</code> ثم نلج إلى مجلد المستودع وننفذ أمر <code>git remote</code>:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
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</pre>

<p>
	لاحظ الاسم المختصر <code>origin</code>.
</p>

<p>
	يمكن أيضا استخدام الخيار <code>v-</code> الذي يُظهر مسارات URL التي خزنها Git للاستخدام عند القراءة من المستودع أو الكتابة فيه:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git remote -v
origin  https://github.com/schacon/ticgit (fetch)
origin  https://github.com/schacon/ticgit (push)</pre>

<p>
	إن كان لديك أكثر من مستودع بعيد فسيسرُدها الأمر جميعا. على سبيل المثال، إن كان لمستودع واحد خواديم بعيدة متعدّدة للعمل مع متعاونين مختلفين فستكون نتيجة تنفيذ الأمر كالتالي:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
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)</pre>

<p>
	يعني هذا أن بإمكاننا جلب مساهمات أي واحد من هؤلاء المتعاونين بسهولة.
</p>

<h2 id="إضافة-مستودعات-بعيدة">
	إضافة مستودعات بعيدة
</h2>

<p>
	ذكرنا في الفقرات السابقة كيفية إضافة مستودعات بعيدة باختصار؛ في الفقرات التالية سنفصِّل في الكيفية. استخدم الأمر التالي لإضافة مستودع جديد باسم مختصر يمكنك جعله مرجعا للمستودع:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git remote add [shortname] [url]</pre>

<p>
	مثلا:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
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)</pre>

<p>
	يمكنك الآن استخدام الاسم <code>pb</code> بدلا من العنوان الكامل في سطر الأوامر. استخدم الأمر التالي لإحضار جميع البيانات الموجودة في المستودع البعيد الذي أضفته أعلاه والتي لا توجد لديك محليًّا:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
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     -&amp;gt; pb/master
* [new branch]      ticgit     -&amp;gt; pb/ticgit</pre>

<p>
	يمكن الآن الوصول إلى الفرع الرئيس من المستودع عبر <code>pb/master</code> .
</p>

<h2 id="جلب-مستودعات-بعيدة-ودفع-البيانات-إليها">
	جلب مستودعات بعيدة ودفع البيانات إليها
</h2>

<p>
	يمكن جلب بيانات مستودع بعيد بتنفيذ الأمر:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git fetch [remote-name]</pre>

<p>
	يذهب Git بعد تنفيذ الأمر أعلاه إلى المستودع البعيد وينزل جميع بياناته التي لا توجد لديك حتى الآن. تحصُل بعد تنفيذ الأمر على مراجع (أسماء مختصرة) لجميع الفروع يمكن بعد ذلك دمجها أو فحصها في أي وقت.
</p>

<p>
	يضيف أمر النسخ <code>git clone</code> الاسم المختصر <code>origin</code> للمستودع البعيد تلقائيا. يجلب أمر <code>git fetch origin</code> أي بيانات جديدة دُفِعت إلى الخادوم بعد نسخ المستودع (أو بعد آخر جلب منه). من المهم ملاحظة أن <code>git fetch</code> تضيف البيانات إلى المستودع المحلي، ولا تدمجها تلقائيا مع أي من أعمالك؛ كما أنها لا تعدل على ما تعمل عليه. يعني هذا أن عليك دمجها يدويا عندما تكون جاهزا.
</p>

<p>
	إن كان لديك فرع معدّ لتتبع مستودع بعيد فيمكنك استخدام <code>git pull</code> لجلب البيانات من المستودع البعيد ودمجها مع الفرع الحالي. يُعِد أمر <code>git clone</code> تلقائيا الفرع الرئيس المحلي لتتبع الفرع الرئيس على الخادوم البعيد الذي نُسخ المستودع منه. يجلب أمر <code>git pull</code> البيانات من الخادوم الذي نُسخ أصلا منه المستودع ويحاول تلقائيا دمجها إلى الشفرة البرمجية التي تعمل عليها حاليا.
</p>

<h2 id="دفع-البيانات-إلى-المستودع-البعيد">
	دفع البيانات إلى المستودع البعيد
</h2>

<p>
	يجب دفع المشروع إلى الخادوم عندما يكون جاهزا لتشاركه مع الآخرين، بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git push [remote-name] [branch-name]</pre>

<p>
	حيث <code>[remote-name]</code> يمثل الفرع على الخادوم البعيد و<code>[branch-name]</code> على الخادوم المحلي، مع التذكير أن نسخ المستودع يضبط الاسمين تلقائيا كما أشرنا أعلاه.
</p>

<p>
	عندما تريد دفع الفرع الرئيس إلى الخادوم الأصلي فيمكنك تنفيذ الأمر التالي لدفع الإيداعات التي أنجزتها إلى الخادوم:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git push origin master</pre>

<p>
	يعمل الأمر السابق فقط إن كنت نسخت المستودع من خادوم لديك صلاحيات الكتابة عليه، مع شرط ألا يكون أي شخص آخر دفع بيانات جديدة للمستودع البعيد بعد آخر عملية جلب قمت بها. إذا نسخت المستودع أنت وشخص آخر في نفس الوقت ثم أضاف هو إيداعات جديدة بدفعها إلى المستودع ثم أتيت لدفع بياناتك فإن المستودع لن يقبلها. يجب عليك في هذه الحالة جلب إيداعات الشخص الآخر أولا إلى جهازك المحلي ثم تضمينها لديك في المشروع ثم دفعه من جديد.
</p>

<h2 id="فحص-مستودع-بعيد">
	فحص مستودع بعيد
</h2>

<p>
	إن أردت الحصول على معلومات أكثر تفصيلا عن مستودع بعيد فالأمر التالي يؤدي هذه المهمة:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git remote show [remote-name]</pre>

<p>
	إن نفذت الأمر مع اسم مختصر مثل <code>origin</code> فستحصل على نتيجة شبيهة بالتالي:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
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)</pre>

<p>
	يظهر في نتيجة الأمر مسار المستودع البعيد إضافة إلى معلومات خاصة بفرع التتبع. يخبرك الأمر أيضا أنك إن نفذت الأمر <code>git pull</code> على الفرع الرئيس <span style="font-family:courier new,courier,monospace;"><code>master</code></span> فسيدمجه تلقائيا في الفرع الرئيس في المستودع البعيد بعد أن يجلب جميع المراجع البعيدة؛ كما أنه يسرد قائمة بجميع المراجع البعيدة التي جلبها.
</p>

<p>
	إن كنت تستخدم Git كثيرا فستظهر معلومات أكثر تفصيلا من المثال غير المعقد أعلاه:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
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)</pre>

<p>
	يعرض الأمر الفروع التي ستُدفَع إليها البيانات تلقائيا عند تنفيذ الأمر <code>git push</code> على فروع معيَّنة. كما يُظهر أيضا الفروع الموجودة على الخادوم التي لا توجد لديك حتى الآن، الفروع التي حذفت من الخادوم ولكنها لا زالت لديك محليًّا والفروع المختلفة التي دُمجت تلقائيا عند تنفيذ الأمر <code>git pull</code>.
</p>

<h2 id="حذف-المستودعات-البعيدة-وإعادة-تسميتها">
	حذف المستودعات البعيدة وإعادة تسميتها
</h2>

<p>
	يتيح الأمر<span style="font-family:courier new,courier,monospace;"> <code>git remote rename</code></span> إمكانية تغيير الاسم المختصر الخاص بالمستودع البعيد. إن أردت مثلا تغيير <code>pb</code> إلى <code>paul</code> فيجب تنفيذ الأمر على النحو التالي:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git remote rename pb paul
git remote
origin
paul</pre>

<p>
	ينتج عن الأمر أيضا التعديل على أسماء الفروع أيضا، مثلا <code>pb/master</code> تصبح <code>paul/master</code> عند تعديل الاسم المختصر من <code>pb</code> إلى <code>paul</code>.
</p>

<p>
	استخدم الأمر <code>git remote rm</code> لحذف مستودع بعيد :
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git remote rm paul
git remote
origin</pre>

<p>
	ترجمة -وبتصرف- للفصل <a href="https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes" rel="external nofollow">Git Basics - Working with Remotes</a> من كتاب <a href="http://git-scm.com/book/en/v2" rel="external nofollow" target="_blank">Pro Git</a> لصاحبه <a href="https://twitter.com/chacon" rel="external nofollow" target="_blank">Scott Chacon</a>.
</p>
]]></description><guid isPermaLink="false">253</guid><pubDate>Fri, 26 Feb 2016 20:37:00 +0000</pubDate></item><item><title>&#x639;&#x631;&#x636; &#x633;&#x62C;&#x644; &#x627;&#x644;&#x625;&#x64A;&#x62F;&#x627;&#x639;&#x627;&#x62A; (commits log) &#x641;&#x64A; Git</title><link>https://academy.hsoub.com/programming/workflow/git/%D8%B9%D8%B1%D8%B6-%D8%B3%D8%AC%D9%84-%D8%A7%D9%84%D8%A5%D9%8A%D8%AF%D8%A7%D8%B9%D8%A7%D8%AA-commits-log-%D9%81%D9%8A-git-r245/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_02/git-commits-logs.png.07ebea8271f90d3ffeb723698a622746.png" /></p>

<p>
	قد تود بعد القيام بعمليات إيداع عدّة، أو بعد استنساخ Cloning مستودع Repository يحوي سجلا للإداعات، النظر إلى ماضي الإيداعات لرؤية مالذي كان يحصُل. أمر <code>git log</code> أيسر طريقة وأكثرها فعالية لهذا الغرض.
</p>

<p style="text-align: center;">
	<img alt="git-commits-logs.png.faf28054c9396306306" class="ipsImage ipsImage_thumbnailed" data-fileid="13461" data-unique="6n2nf8zmk" src="https://academy.hsoub.com/uploads/monthly_2016_02/git-commits-logs.png.faf28054c93963063067ebf1e4f92c86.png"></p>

<p>
	تستخدم الأمثلة المقدّمة هنا مشروع <code>simplegit-progit</code> الذي يمكن الحصول عليه بتنفيذ الأمر التالي:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git clone https://github.com/schacon/simplegit-progit</pre>

<p>
	نفذ أمر <code>git log</code> بعد الدخول إلى مجلد المشروع:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git log</pre>

<p>
	ستحصل على مخرجات على النحو التالي:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon &amp;lt;schacon@gee-mail.com&amp;gt;
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon &amp;lt;schacon@gee-mail.com&amp;gt;
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon &amp;lt;schacon@gee-mail.com&amp;gt;
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit</pre>

<p>
	يسرُد أمر <code>git log</code> - إن استخدِم دون خيارات - الإيداعات التي حدثت حسب ترتيب زمني عكسي، أي الإيداع الأحدث أولا. تمكن ملاحظة أنه مع كل إيداع يظهر مجموع التدقيق Checksum الخاص به، اسم من كاتب الإيداع وعنوانها البريدي، تاريخ الإيداع ورسالة الإيداع.
</p>

<p>
	توجد الكثير من الخيارات للاستخدام مع أمر <code>git log</code> من أجل إظهار ما تريده بالضبط. سنعرِض هنا لأكثرها شعبية.
</p>

<ul><li>
		<p>
			يعرض خيار <span style="font-family:courier new,courier,monospace;"><code>p-</code></span> عند استخدامه مع أمر <code>git log</code> الفروقات ضمن كل إيداع. تمكن إضافة عدد لتحديد المخرجات. يعرض المثال التالي آخر إيداعيْن مع إظهار الفروق:
		</p>
	</li>
</ul><pre class="html ipsCode prettyprint" data-pbcklang="html" data-pbcktabsize="4">
git log -p -2</pre>

<p>
	النتيجة:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon &amp;lt;schacon@gee-mail.com&amp;gt;
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

diff --git a/Rakefile b/Rakefile
index a874b73..8f94139 100644
--- a/Rakefile
+++ b/Rakefile
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
spec = Gem::Specification.new do |s|
    s.platform  =   Gem::Platform::RUBY
    s.name      =   "simplegit"
-    s.version   =   "0.1.0"
+    s.version   =   "0.1.1"
    s.author    =   "Scott Chacon"
    s.email     =   "schacon@gee-mail.com"
    s.summary   =   "A simple gem for using Git in Ruby code."

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon &amp;lt;schacon@gee-mail.com&amp;gt;
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index a0a60ae..47c6340 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -18,8 +18,3 @@ class SimpleGit
    end

end
-
-if $0 == __FILE__
-  git = SimpleGit.new
-  puts git.show
-end
\ No newline at end of file</pre>

<p>
	يعرض الخيار <code>p-</code> نفس المعلومات التي يعرضها الأمر بدون خيارات، مع إضافة الفروق بالنسبة لكل مُخرَج (إيداع). يفيد هذا الأمر كثيرا عند مراجعة الشفرة البرمجية أو للتصفح السريع لما جرى خلال سلسلة من عمليات الإيداع التي أجراها أحد أعضاء الفريق مثلا.
</p>

<ul><li>
		يمكن أيضا استخدام خيارات للتلخيص مع الأمر <code>git log</code>. إن أردت مثلا إحصاءات ملخَّصة لكلّ إيداع فيمكنك استخدام خيار <code>stat--</code>:
	</li>
</ul><pre class="html ipsCode prettyprint" data-pbcklang="html" data-pbcktabsize="4">
git log --stat</pre>

<p>
	النتيجة:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon &amp;lt;schacon@gee-mail.com&amp;gt;
Date:   Mon Mar 17 21:52:11 2008 -0700

changed the version number

Rakefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon &amp;lt;schacon@gee-mail.com&amp;gt;
Date:   Sat Mar 15 16:40:33 2008 -0700

removed unnecessary test

lib/simplegit.rb | 5 -----
1 file changed, 5 deletions(-)

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon &amp;lt;schacon@gee-mail.com&amp;gt;
Date:   Sat Mar 15 10:31:28 2008 -0700

first commit

README           |  6 ++++++
Rakefile         | 23 +++++++++++++++++++++++
lib/simplegit.rb | 25 +++++++++++++++++++++++++
3 files changed, 54 insertions(+)
</pre>

<p>
	يظهر خيار <code>stat--</code> تحت كل إيداع قائمة بالملفات التي عُدلت في الإيداع، عددها وعدد الأسطر التي أُضيفت أو حُذفت. يضيف الخيار أيضا ملخصًا للتعديلات تحت كل إيداع.
</p>

<ul><li>
		<p>
			إن أردت تغيير الصيغة التي تظهر بها مخرجات السجل فيمكنك استخدام الخيار <code>pretty--</code>. توجد صيغ معدّة سلفا للاستخدام؛ عند إعطاء القيمة <code>oneline</code> لخيار <code>pretty--</code> فإن كل إيداع يظهر في سطر واحد، وهو ما سيكون مفيدا إن كانت لديك الكثير من الإيداعات للنظر فيه.
		</p>
	</li>
</ul><pre class="html ipsCode prettyprint" data-pbcklang="html" data-pbcktabsize="4">
git log --pretty=oneline</pre>

<p>
	النتيجة:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
ca82a6dff817ec66f44342007202690a93763949 changed the version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit
</pre>

<p>
	تعدّ قيمة <code>format</code> من أكثر قيم <code>pretty--</code> أهمية. تعطي هذه القيمة عند استخدامها مع الخيار إمكانية تحديد صيغة مخصَّصة لمخرجات السجلات. يساعد هذا الأمر كثيرا إن كنت تريد تهيئة المخرجات لتحليلها آليا:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git log --pretty=format:"%h - %an, %ar : %s"</pre>

<p>
	مثال على النتيجة:
</p>

<pre class="html ipsCode prettyprint" data-pbcklang="html" data-pbcktabsize="4">
ca82a6d - Scott Chacon, 6 years ago : changed the version number
085bb3b - Scott Chacon, 6 years ago : removed unnecessary test
a11bef0 - Scott Chacon, 6 years ago : first commit
</pre>

<p>
	توجد في الجدول أدناه قائمة بالخيارات التي يمكن استخدامها لتهيئة مخرجات <span style="font-family:courier new,courier,monospace;">format</span>.
</p>
<style type="text/css">
table{border: 1px solid black; border-collapse: collapse;}
td, th{border: 1px solid black; padding: 5px 15px;}
th{background-color: #ecf0f1;}</style><center>
	<table><tbody><tr><th>
					الخيار
				</th>
				<th>
					الوصف
				</th>
			</tr><tr><td>
					H%           
				</td>
				<td>
					مجموع التدقيق
				</td>
			</tr><tr><td>
					h%
				</td>
				<td>
					الصيغة المختصرة لمجموع التدقيق
				</td>
			</tr><tr><td>
					T%
				</td>
				<td>
					مجموع التدقيق لكامل الشجرة Tree
				</td>
			</tr><tr><td>
					t%
				</td>
				<td>
					مجموع التدقيق المختصَر للشجرة
				</td>
			</tr><tr><td>
					P%
				</td>
				<td>
					مجموعات التدقيق للعنصر الأب
				</td>
			</tr><tr><td>
					an%
				</td>
				<td>
					اسم كاتب الإيداع
				</td>
			</tr><tr><td>
					ae%
				</td>
				<td>
					البريد الإلكتروني لكاتب الإيداع
				</td>
			</tr><tr><td>
					ad%
				</td>
				<td>
					تاريخ إنشاء الإيداع (Author date)
				</td>
			</tr><tr><td>
					ar%
				</td>
				<td>
					التاريخ النسبي لإنشاء الإيداع (قبل كذا من الزمن)
				</td>
			</tr><tr><td>
					cn%
				</td>
				<td>
					اسم صاحب الإيداع Commiter
				</td>
			</tr><tr><td>
					ce%
				</td>
				<td>
					البريد الإلكتروني لصاحب الإيداع
				</td>
			</tr><tr><td>
					cd%
				</td>
				<td>
					تاريخ الإيداع
				</td>
			</tr><tr><td>
					cr%
				</td>
				<td>
					التاريخ النسبي للإيداع
				</td>
			</tr><tr><td>
					s%
				</td>
				<td>
					الموضوع
				</td>
			</tr></tbody></table></center>

<p style="text-align: right;">
	<strong style="line-height: 1.6;">ملحوظة:</strong><span style="line-height: 1.6;"> ربما تتساءل عن الفرق بين كاتب الإيداع وصاحب الإيداع؛ كاتب الإيداع هو الشخص الذي كتب العمل بينما صاحب الإيداع هو آخر شخص أضاف العمل إلى المستودع. نفرض مثلا أنك أرسلت ترقيعا لمشروع برمجي، ثم أضافه أحد مطوري المشروع إلى المستودع. يُعزَى لكل منكما في السجل؛ أنت بوصفك كاتب الترقيع وهو بوصفه صاحب الإيداع.</span>
</p>

<ul><li>
		يفيد خيارا <code>oneline</code> و <code>format</code> كثيرًا عند استخدامهما مع خيار <code>graph--</code> الذي يعرض مخطط ASCII لسجل التفرع Branch والدمج Merge.
	</li>
</ul><pre class="html ipsCode prettyprint" data-pbcklang="html" data-pbcktabsize="4">
git log --pretty=format:"%h %s" --graph</pre>

<p>
	مثال على النتيجة:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
* 2d3acf9 ignore errors from SIGCHLD on trap
*  5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Added a method for getting the current branch.
* | 30e367c timeout code and tests
* | 5a09431 add timeout protection to grit
* | e1193f8 support for heads with slashes in them
|/
* d6016bc require time for xmlschema
*  11d191e Merge branch 'defunkt' into local
</pre>

<p style="text-align: right;">
	يفيد خيار <code>graph--</code> كثيرا عند استخدام التفريع والدمج في مستودعات git.
</p>

<p style="text-align: right;">
	توجد الكثير من الخيارات الأخرى للعمل مع أمر <code>git log</code>. يسرد الجدول التالي قائمة بخيارات تعمل مع <code>git log</code> إضافة لخيارات تهيئة أخرى قد تجدها مفيدة.
</p>

<center>
	<table><tbody><tr><th>
					الخيار
				</th>
				<th>
					<p>
						الوصف
					</p>
				</th>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">p-</span>
				</td>
				<td>
					إظهار الترقيع المصاحب لكل إيداع
				</td>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">stat--</span>
				</td>
				<td>
					إظهار إحصاءات الملفات المعدّل عليها في كل إيداع
				</td>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">shortstat--</span>
				</td>
				<td>
					<p>
						قصر النتائج الظاهر من نتيجة <span style="font-family:courier new,courier,monospace;">stat--</span> على الأسطر المعدّل عليها،
					</p>

					<p>
						المضافة أو المحذوفة
					</p>
				</td>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">name-only--</span>
				</td>
				<td>
					عرض قائمة بالملفات المعدّل عليها بعد معلومات الإيداع
				</td>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">name-status--</span>
				</td>
				<td>
					عرض قائمة بالملفات التي أضيفت إليها معلومات، عدلت معلوماتها أو حذفت
				</td>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">abbrev-commit--</span>
				</td>
				<td>
					<p>
						عرض المحارف الأولى من مجموع التحقق من الإيداع،
					</p>

					<p>
						بدلا من كامل المجموع (40 محرفا)
					</p>
				</td>
			</tr><tr><td>
					relative-date--
				</td>
				<td>
					عرض التواريخ بصيغة نسبية ("قبل يومين" مثلا) بدلا من الصيغة الكاملة
				</td>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">graph--</span>
				</td>
				<td>
					عرض مخطّط ASCII لسجل التفريع والدمج بجانب مخرجات أمر log
				</td>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">pretty--</span>
				</td>
				<td>
					<p>
						عرض الإيداعات بصيغة بديلة، يمكن للخيار أن يأخذ إحدى القيم
					</p>

					<p>
						<code>oneline </code>،<code>short </code>،<code>fuller </code>،<code>full</code>، أو <code>format</code>
					</p>
				</td>
			</tr></tbody></table></center>

<h2 id="تحديد-مخرجات-أمر-git-log">
	تحديد مخرجات أمر git log
</h2>

<p>
	يقبل أمر <code>git log</code> خيارات لتحديد المخرجات الظاهرة في نتيجة الأمر، فلا يُعرَض سوى عدد محدّد منها. رأينا أعلاه خيار <code>2-</code> الذي يعرض فقط الإيداعين الأخيرين. يمكن استخدام الخيار <code>n-</code> حيث <code>n</code> عدد طبيعي لإظهار العدد الموافق من الإيداعات (آخر 5 أو 10 إيداعات مثلا).
</p>

<p>
	عمليا، قد لا تستخدم هذه الخيارات كثيرا؛ عكسَ خيارات التحديد المتعلقة بالزمن مثل <code>since--</code> أو <code>until--</code> التي يكثر استخدامها. مثلا يسرد الأمر التالي قائمة بالإيداعات التي أضيفت خلال الأسبوعين الأخيرين:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git log --since=2.weeks</pre>

<p>
	يمكن استخدام <code>since--</code> مع الكثير من الصيغ؛ تحديد التاريخ <code>15-01-2016</code> مثلا، أو تاريخ نسبي (قبل 3 سنوات ويوم و3 دقائق):
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
3 years 1 day 3 minutes ago</pre>

<p>
	يمكنك أيضا ترشيح المخرجات لتطابق معايير بحث تحدّدها. يسمح خيار <code>author--</code> بالترشيح حسب كاتب الإيداع، في ما يتيح خيار <code>grep--</code> البحث حسب كلمات مفتاحية ضمن رسائل الإيداع (إن كنت ترغب باستخدام خياري <code>author--</code> و<code>grep--</code> معا فيجب أن تضيف <code>all-match--</code> إلى الأمر).
</p>

<p>
	يعد خيار <code>S-</code> من الخيارات المفيدة كثيرا، حيث يسمح بالبحث عن الإيداعات التي أضافت أو حذفت سلسلة محارف معيّنة. إن أردت على سبيل المثال البحث عن آخر إيداع أضاف أو حذف دالة باسم <code>function_name</code> فيمكن استخدام الأمر التالي:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git log -Sfunction_name</pre>

<p>
	توجد أيضا إمكانية قصر نتائج أمر <code>git log</code> على الإيداعات التي أجرت تغييرات على ملفات أو مجلدات معينة بذكر مسار الملفات أو المجلدات. يجب أن تكون المسارات هي آخر عنصر في أمر <code>git log</code> ويُنصح أن تسبقها شرطتان <code>--</code> لفصلها عن بقية الخيارات.
</p>

<p>
	يعرض الجدول التالي أهم الخيارات المستخدمة في تحديد مخرجات الأمر <code>git log</code>.
</p>

<center>
	<table><tbody><tr><th>
					الخيار                           
				</th>
				<th>
					الوصف                                                                                     
				</th>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">n-</span>
				</td>
				<td>
					تحديد عدد الإيداعات المراد عرضها
				</td>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">since, --after--</span>
				</td>
				<td>
					عرض الإيداعات التي أضيفت بعد التاريخ المحدد
				</td>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">until, --before--</span>
				</td>
				<td>
					عرض الإيداعات التي أضيفت قبل التاريخ المحدد
				</td>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">author--</span>
				</td>
				<td>
					<p>
						عرض الإيداعات التي يوافق حقل الكاتب فيها
					</p>

					<p>
						سلسلة المحارف المعيّنة
					</p>
				</td>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">committer--</span>
				</td>
				<td>
					<p>
						عرض الإيداعات التي يوافق حقل صاحب الإيداع فيها
					</p>

					<p>
						سلسلة المحارف المعيّنة
					</p>
				</td>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">grep--</span>
				</td>
				<td>
					<p>
						عرض الإيداعات التي تحوي الرسائل المصاحبة لها
					</p>

					<p>
						سلسلة المحارف المذكورة
					</p>
				</td>
			</tr><tr><td>
					<span style="font-family:courier new,courier,monospace;">S-</span>
				</td>
				<td>
					<p>
						عرض الإيداعات التي أضافت أو حذفت
					</p>

					<p>
						سلسلة المحارف المعيَّنة
					</p>
				</td>
			</tr></tbody></table></center>

<p>
	يعرض الأمر التالي الإيداعات التي كتبها gitster في الشفرة المصدرية لـGit والتي لم تُدمَج Merge في شهر أكتوبر 2008:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \
--before="2008-11-01" --no-merges -- t/
</pre>

<p>
	مثال على النتيجة:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
5610e3b - Fix testcase failure when extended attributes are in use
acd3b9e - Enhance hold_lock_file_for_{update,append}() API
f563754 - demonstrate breakage of detached checkout with symbolic link HEAD
d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths
51a94af - Fix "checkout --track -b newbranch" on detached HEAD
b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch
</pre>

<p>
	من بين 40 ألف إيداع في سجل الشفرة المصدرية لـGit أظهر الأمر الإيداعات الستة التي توافق المعايير المذكورة أعلاه.
</p>

<p>
	ترجمة -وبتصرّف- للفصل <a href="http://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History" rel="external nofollow">Git Basics - Viewing the Commit History</a> من كتاب <a href="http://git-scm.com/book/en/v2" rel="external nofollow" target="_blank">Pro Git</a> لصاحبه <a href="https://twitter.com/chacon" rel="external nofollow" target="_blank">Scott Chacon</a>.
</p>
]]></description><guid isPermaLink="false">245</guid><pubDate>Thu, 25 Feb 2016 09:19:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x62A;&#x631;&#x627;&#x62C;&#x639; &#x639;&#x646; &#x627;&#x644;&#x62A;&#x639;&#x62F;&#x64A;&#x644;&#x627;&#x62A; &#x641;&#x64A; Git</title><link>https://academy.hsoub.com/programming/workflow/git/%D8%A7%D9%84%D8%AA%D8%B1%D8%A7%D8%AC%D8%B9-%D8%B9%D9%86-%D8%A7%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84%D8%A7%D8%AA-%D9%81%D9%8A-git-r252/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_02/git-undoing-things.png.3bd7c51b210e15d2f305b8dd3e1da60e.png" /></p>

<p>
	يتناول هذا المقال الأدوات الأساسية للتراجع عن التعديلات في Git. ينبغي دائما الحذر عند التعامل مع أوامر التراجع، إذ أن التراجع من الأمور القليلة في Git التي قد تجعلك تخسر العمل إن أجريتها بطريقة خاطئة.
</p>

<p style="text-align: center;">
	<img alt="git-undoing-things.png" class="ipsImage ipsImage_thumbnailed" data-fileid="13462" data-unique="rf44xj3i1" src="https://academy.hsoub.com/uploads/monthly_2016_02/git-undoing-things.png.7c5342433897539076ea0a5d14b0ee17.png"></p>

<p>
	يكثر استخدام التراجع عند الإيداع قبل أن تكون جاهزا لذلك؛ مثلا بنسيان ملفات أو رسائل الإيداع. في هذه الحالة يمكنك إعادة الإيداع باستخدام الخيار <code>amend--</code>:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git commit --amend</pre>

<p>
	يأخذ الأمر أعلاه محتويات منطقة الإدراج Staging area ويستخدمها في الإيداع. إن لم تحدث أية تغييرات منذ آخر عملية إيداع (عند تنفيذ الأمر مثلا مباشرة بعد تطبيق الإيداع السابق) فسيكون بإمكانك التعديل على رسالة الإيداع الأخيرة التي ستظهر في المحرّر. بهذه الطريقة تكون عدلت على رسالة الإيداع السابق دون أن تضيف إيداعا جديدا.
</p>

<p>
	بنفس الطريقة، تمكن إضافة ملف منسي إلى الإيداع. نفترض أنك مثلا بعد إرسال الإيداع فطنت إلى نسيان ملف باسم <code>forgotten_file</code> كان يجب أن يكون فيه؛ في هذه الحالة تستخدم نفس الأمر كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git commit -m 'initial commit'
git add forgotten_file
git commit --amend</pre>

<p>
	أرسلنا الإيداع في الأمر الأول، ثم أضفنا في الأمر الثاني ملفا جديدا إلى منطقة الإدراج واستخدمنا خيار <code>amend--</code> مع <code>git commit</code>. نحصُل في النهاية على إيداع واحد يحل محل الأول ويوجد فيه الملف المنسي.
</p>

<h2 id="التراجع-عن-إضافة-الملفات-إلى-منطقة-الإدراج">
	التراجع عن إضافة الملفات إلى منطقة الإدراج
</h2>

<p>
	سنتطرق في الفقرتين التاليتين إلى كيفية التراجع عن التعديلات على منطقة الإدراج ومجلد العمل. من الجميل أن الأمر الذي يريك حالة هاتين المنطقتين يذكرك بكيفية التراجع عن التعديلات عليهما. لنفترض مثلا أنك عدلت على ملفين وتريد إيداعهما منفصلين (إيداع لكل ملف)، ولكنك نفذت الأمر <code><span style="font-family:courier new,courier,monospace;">* git</span> add</code> بالخطأ، وأضفتهما في نفس الوقت إلى منطقة الإدراج. كيف يمكنك نزع الاثنين من منطقة الإدراج؟ أمر <code>git status</code> يذكرك بالكيفية:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git add *
git status
On branch master
Changes to be committed:
(use "git reset HEAD &amp;lt;file&amp;gt;..." to unstage)

    renamed:    README.md -&amp;gt; README
    modified:   CONTRIBUTING.md</pre>

<p>
	مباشرة تحت عبارة <code>Changes to be committed</code> (التعديلات المهيّأة للإيداع) يوجد التذكير الذي يقول "استخدام <code>reset HEAD...</code> للتراجع عن إضافة ملف إلى منطقة الإدراج". إن قررنا اتباع النصيحة والتراجع عن إضافة ملف (وليكن <code>CONTRIBUTING.md</code>) إلى منطقة الإدراج:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git reset HEAD CONTRIBUTING.md</pre>

<p>
	نحصل على الرسالة التالية:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
Unstaged changes after reset:
M     CONTRIBUTING.md</pre>

<p>
	وعند التحقق الآن من الحالة:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git status</pre>

<p>
	نحصل على النتيجة التالية:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
On branch master
Changes to be committed:
(use "git reset HEAD &amp;lt;file&amp;gt;..." to unstage)

    renamed:    README.md -&amp;gt; README

Changes not staged for commit:
(use "git add &amp;lt;file&amp;gt;..." to update what will be committed)
(use "git checkout -- &amp;lt;file&amp;gt;..." to discard changes in working directory)

    modified:   CONTRIBUTING.md</pre>

<p>
	عدلنا على الملف <code>CONTRIBUTING.md</code> إلا أنه الآن خارج منطقة الإدراج.
</p>

<p>
	<strong>ملحوظة:</strong> استخدام أمر <code>git reset</code> يمكن أن يكون خطرا عند استخدام الخيار <code>hard--</code> إلا أنه ليس كذلك إن استخدم دون خيارات، في هذه الحالة يتعامل مع منطقة الإدراج فقط.
</p>

<h2 id="التراجع-عن-تعديل-ملفات">
	التراجع عن تعديل ملفات
</h2>

<p>
	ما ذا لو قررت أنك لا تريد الاحتفاظ بالتعديلات التي أجريتها على الملف <code>CONTRIBUTING.md</code>؟ كيف يمكن التراجع عن التعديلات بسهولة، إعادته إلى ما كان عليه قبل آخر إيداع مثلا؟ يخبرك أمر <code>git status</code> بكيفية ذلك، مثل ما فعل مع إضافة الملفات إلى منطقة الإدراج. في مخرجات المثال أعلاه تبدو منطقة الإدراج على النحو التالي:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
Changes not staged for commit:
(use "git add &amp;lt;file&amp;gt;..." to update what will be committed)
(use "git checkout -- &amp;lt;file&amp;gt;..." to discard changes in working directory)

    modified:   CONTRIBUTING.md</pre>

<p>
	تخبرك الرسالة "<code>..."use "git checkout"</code> بكيفية إلغاء التعديلات على ملفات مجلد العمل. نطبق التعليمات:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git checkout -- CONTRIBUTING.md</pre>

<p>
	ثم نتحقق من تأثير الأمر:
</p>

<pre class="ipsCode prettyprint" data-pbcklang="" data-pbcktabsize="">
git status
On branch master
Changes to be committed:
(use "git reset HEAD &amp;lt;file&amp;gt;..." to unstage)

    renamed:    README.md -&amp;gt; README</pre>

<p>
	تمكن ملاحظة أن التعديلات ألغيت.
</p>

<p>
	<strong>هام:</strong> من المهم فهمُ أن أمر <code>git checkout</code> خطير جدا. يلغي الأمر أي تعديل أجريته بلا رجعة، ولن يمكنك إعادته. استخدم هذا الأمر فقط عندما تكون متأكدا من أنك لم تعد ترغب في التعديلات.
</p>

<p>
	تذكر أن كل ما أودِع Commited في Git يمكن غالبا إرجاعه؛ حتى الإيداعات الموجودة على فروع Branches محذوفة أو تلك التي عدل عليها باستخدام خيار <code>amend--</code>. إلا أن البيانات التي لم تودع تُفقَد -على الأرجح- بغير رجعة.
</p>

<p>
	ترجمة -وبتصرّف- للفصل <a href="https://git-scm.com/book/en/v2/Git-Basics-Undoing-Things" rel="external nofollow">Git Basics - Undoing Things</a> من كتاب <a href="http://git-scm.com/book/en/v2" rel="external nofollow" target="_blank">Pro Git</a> لصاحبه <a href="https://twitter.com/chacon" rel="external nofollow" target="_blank">Scott Chacon</a>.
</p>
]]></description><guid isPermaLink="false">252</guid><pubDate>Tue, 23 Feb 2016 20:13:00 +0000</pubDate></item><item><title>&#x623;&#x633;&#x627;&#x633;&#x64A;&#x627;&#x62A; &#x633;&#x64A;&#x631; &#x639;&#x645;&#x644; &#x646;&#x638;&#x627;&#x645; &#x627;&#x644;&#x62A;&#x62D;&#x643;&#x645; &#x641;&#x64A; &#x627;&#x644;&#x646;&#x633;&#x62E; git</title><link>https://academy.hsoub.com/programming/workflow/git/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A7%D8%AA-%D8%B3%D9%8A%D8%B1-%D8%B9%D9%85%D9%84-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%AD%D9%83%D9%85-%D9%81%D9%8A-%D8%A7%D9%84%D9%86%D8%B3%D8%AE-git-r267/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_02/git-essentials.png.32f226daeff73c48bdaab2c612530fb9.png" /></p>

<div>
	<p>
		سنقوم في هذا الدرس بتغطية الأوامر الأساسية التي لا يُمكنك الاستغناء عنها إن أردت أن تستخدم Git بكفاءة عالية والتي ستقضي وقتك على Git في استخدامها.
	</p>

	<p style="text-align: center;">
		<img alt="git-essentials.png.40f1c64480b1e11a18bb5" class="ipsImage ipsImage_thumbnailed" data-fileid="13439" data-unique="mvdzmwxp4" src="https://academy.hsoub.com/uploads/monthly_2016_02/git-essentials.png.40f1c64480b1e11a18bb5ad1e23f6a8d.png"></p>

	<p>
		يُفترض بك بعد إنهاء قراءة هذا الدرس أن تصبح قادرًا على إعداد وتهيئة مُستودع، الشروع في وإيقاف تتبع التغييرات في ملفات مُعينة، إرسال التغييرات إلى منطقة الإدراج وإيداعها. سنشرح لك أيضا كيف ستقوم بتجاهل ملفات مُعينة أو التي تتبع أنماطا خاصة، فيما ستتحدث الدروس التي تلي هذا عن كيفية التراجع عن أخطاء قُمت بها بشكل سريع وسهل، كيفية تصفح تاريخ المشروع والاطلاع على كافة التعديلات التي حدثت ما بين كل إيداعين، وكيف تقوم بدفع التغييرات إلى مُستودع في خادوم بعيد أو سحب البيانات منه.
	</p>
</div>

<div>
	<h2 id="الحصول-على-م-ستودع-وحفظ-التغييرات-فيه:5bc8635476404749f76287ef866562d6">
		الحصول على مستودع وحفظ التغييرات فيه
	</h2>

	<p>
		يُمكنك الحصول على مُستودع Git بطريقتين مُختلفتين. تتمثل الأولى في إنشاء مُستودع لمشروع أو مُجلد مُعد سلفا، وتتم الثانية عبر استنساخ مُستودع موجود على خادوم بعيد.
	</p>

	<h3 id="إنشاء-م-ستودع-جديد-لمشروع-راهن:5bc8635476404749f76287ef866562d6">
		إنشاء مستودع جديد لمشروع موجود مسبقا
	</h3>

	<p>
		إن أردت الشروع في تتبع إصدارات وتغييرات مشروع راهن فكل ما عليك القيام به هو الذهاب إلى مُجلد المشروع (بسطر الأوامر طبعا) ومن ثم تنفيذ الأمر التالي:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_17">
<span class="pln">$ git init</span></pre>

	<p>
		سيقوم هذا الأمر بإنشاء مُجلد فرعي داخل مُجلد المشروع يحمل الاسم <span style="font-family:courier new,courier,monospace;">git.</span> والذي سيحتوي جميع ملفات المُستودع الأساسية التي ستشكل هيكل المستودع. بطبيعة الحال لن يتم تتبع أية تغييرات بُمجرد تنفيذ هذا الأمر لوحده.
	</p>

	<p>
		إن أردت الشروع في إدارة نسخ الملفات الراهنة (يعني لن تبدأ بمُجلد فارغ) فإنه يجب عليك أولا الشروع في تتبع هذه الملفات والقيام بأول عملية إيداع. يُمكن القيام بذلك عبر تنفيذ بضعة أوامر<span style="font-family:courier new,courier,monospace;"> git add</span> التي ستحدد فيها أسماء هذه الملفات ثم تُتبعها بأمر للإيداع:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_19">
<span class="pln">$ git add README
$ git commit -m "initial project version"</span></pre>

	<p>
		بعد تنفيذك لهذه الأوامر (سنشرح ما تقوم به هذه الأوامر بعد قليل) سيكون لديك مُستودع Git يقوم بتتبع التغييرات التي ستطرأ على مجموعة ملفات، إضافة إلى إيداع أولي.
	</p>

	<h3 id="نسخ-م-ستودع-راهن:5bc8635476404749f76287ef866562d6">
		نسخ مستودع موجود مسبقا
	</h3>

	<p>
		إن أردت استنساخ مُستودع Git راهن -وليكن مُستودعا لمشروع ترغب في المُساهمة فيه- فإن الأمر الذي ستحتاجه للقيام بذلك هو <span style="font-family:courier new,courier,monospace;">git clone</span>. إن كانت لديك دراية مُسبقة بباقي أنظمة إدارة النُسخ مثل Subversion فإنك ستلحظ بأن الأمر الذي نستعمله هنا هو <span style="font-family:courier new,courier,monospace;">clone</span> وليس <span style="font-family:courier new,courier,monospace;">checkout</span>، حيث أن ما سيستقبله Git هو نُسخة من جميع البيانات (أو تقريبا) الموجودة على الخادوم. يعني بأنك ستحصل على كل نسخة من كل الملفات منذ أن تم الشروع في تتبع المُستودع الموجود على الخادوم لدى تنفيذ الأمر <span style="font-family:courier new,courier,monospace;">git clone</span>. بعبارة أخرى، لو تعرض القرص الصلب لخادومك لعطب ما فإنه بإمكانك استعادة المشروع الذي كنت تعمل عليه كما كان (أو تقريبا) بفضل النُسخ الموجودة في جميع الأجهزة التي تعمل على نفس المشروع.
	</p>

	<p>
		يتم استنساخ المُستودعات باستخدام الأمر التالي:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_21">
<span class="pln">git clone [url]</span></pre>

	<p>
		حيث يتم استبدال  بعُنوان المُستودع المُراد استنساخه. فعلى سبيل المثال لو أردت استنساخ مُستودع "<a href="http://www.arabicgit.com/simple-guide/" rel="external nofollow">الدليل البسيط لاستخدام Git</a>" فسيكون الأمر على النحو التالي:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_23">
<span class="pln">git clone git://github.com/arabicgit/simple-guide.git</span></pre>

	<p>
		سيتم إنشاء مُجلد يحمل الاسم<span style="font-family:courier new,courier,monospace;"> simple-guide</span> يتم إنشاء مُجلد <span style="font-family:courier new,courier,monospace;">git. </span>بداخله، ومن ثم سيتم استنساخ جميع البيانات الموجودة في مستودع الدليل على Github التي يُمكن الشروع في العمل عليها.
	</p>

	<p>
		إن أردت أن يتم استنساخ المُستودع داخل مُجلد باسم مُخالف فيُمكن تحديد اسم المُجلد الذي ترغب فيه (وليكن MyGuide) في أمر الاستنساخ على النحو التالي:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_2681_7">
<span class="pln">git clone git://github.com/arabicgit/simple-guide.git MyGuide</span></pre>

	<p>
		يدعم Git عدة بروتوكولات للتحويل. استعملنا في المثال السابق بروتوكول <span style="font-family:courier new,courier,monospace;">git://</span>، لكنه بإمكانك أيضا استخدام <span style="font-family:courier new,courier,monospace;">(http(s:// </span>أو <span style="font-family:courier new,courier,monospace;">user@server:/path.git</span> والتي تعتمد على بروتوكول <abbr title="Secure Shell | القشرة (أو الصَدَفة) الآمنة">SSH</abbr><a href="%7Boption%7D" rel="external">. </a>
	</p>

	<h2 id="تسجيل-التغييرات-الحاصلة-في-الم-ستودع:5bc8635476404749f76287ef866562d6">
		تسجيل التغييرات الحاصلة في المستودع
	</h2>

	<p>
		الآن وبعد أن حصلت على مُستودع يقبل تتبع التغييرات الحاصلة على ملفاته، إضافة إلى جُملة من الملفات التي ستعمل عليها، ستحتاج بطبيعة الحال إلى إحداث تغييرات عليها ومن ثم إيداع تلك التغييرات في كل مرة يصل فيها مشروعك إلى مرحلة ترغب في تسجيلها.
	</p>

	<p>
		تذكر بأن الملفات تكون في إحدى الحالتين التاليتين: مُتتبع tracked أو غير مُتتبع untracked. الملفات المُتتبعة هي التي سبق وأن سجلت حضورا في اللقطة snapshot السابقة.
	</p>

	<p>
		يُمكن لهذه الملفات أن تكون في حالات ثلاثة:
	</p>

	<ul><li>
			مُعدّلة
		</li>
		<li>
			غير مُعدلة
		</li>
		<li>
			مُدرجة staged (أي موجودة في منطقة الإدراج).
		</li>
	</ul><p>
		أما الملفات غير المُتتبعة فهي ما سوى ذلك، ويشمل ذلك أي ملف في مجلد العمل لم يكن موجودًا في اللقطة السابقة وغير موجود في منطقة الإدراج. لدى قيامك باستنساخ مُستودع فإن جميع ملفاته ستكون مُتتبّعة وغير مُعدّلة لأنه -وبكل بساطة- قمت لتوك بسحبها ولم تحدث أية تغييرات عليها.
	</p>

	<p>
		بمُجرد أن تدخل تغييرات على أحد الملفات فسيعتبره Git ملفا مُعدّلا، حيث أن هذه الملفات قد طرأت عليها تغييرات منذ آخر إيداع. ما هي الخُطوة القادمة في هذه الحالة؟ ستقوم أولا بإدراج هذه التغييرات stage (أي وضع الملفات المعنية بالأمر في منطقة الإدراج) ومن ثم تقوم بإيداع تلك التغييرات <span style="font-family:courier new,courier,monospace;">commit</span>، وستكرر هذه العملية طيلة استخدامك لـ Git، مثلما هو مُوضح في الصورة التالية:
	</p>

	<p style="text-align: center;">
		<img alt="file-status-lifecycle.png.e1595f8e682098" class="ipsImage ipsImage_thumbnailed" data-fileid="13422" data-unique="pjd1t2inx" src="https://academy.hsoub.com/uploads/monthly_2016_02/file-status-lifecycle.png.e1595f8e682098555e6a6dcb1cc38c64.png"></p>

	<h2 id="التحقق-من-حالة-ملفاتك:5bc8635476404749f76287ef866562d6">
		التحقق من حالة ملفاتك
	</h2>

	<p>
		للتحقق من حالة ملفات مستودعك ستحتاج إلى استخدام الأمر<span style="font-family:courier new,courier,monospace;"> git status</span>. إن قمت بتنفيذ هذا الأمر مُباشرة بعد قيامك باستنساخ مُستودع فإنه يُفترض بهذه النتيجة أن تظهر:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_5290_12">
<span class="pln">$ git status
On branch master
nothing to commit, working directory clean</span></pre>

	<p>
		وهو ما يعني بأنك أمام مُجلد عمل نظيف. بعبارة أخرى لم يتم إحداث تغييرات على أي ملف مُتتبَّع. في هذه الحالة أيضا لا يُظهر Git أي ملفات غير مُتتبعة، لأنه لو كان الأمر غير كذلك فسيقوم حتما بإعلامك بالأمر. يُخبرك هذا الأمر بالفرع <span style="font-family:courier new,courier,monospace;">branch</span> الذي تتواجد فيه، ومثلما هو ظاهر من النتيجة السابقة فإننا حاليا في الفرع الرئيسي <span style="font-family:courier new,courier,monospace;">master</span> وهو الفرع الذي يتم استعماله بشكل قياسي.
	</p>

	<p>
		لنفرض الآن بأنك قُمت بإضافة ملف جديد إلى مشروعك، ولنفرض بأنه ملف <span style="font-family:courier new,courier,monospace;">README</span>. إذا لم يكن هذه الملف موجودا من قبل داخل هذا المُستودع ولدى قيامك بتنفيذ الأمر<span style="font-family:courier new,courier,monospace;"> git status</span> فإن اسم هذا الملف سيظهر في قسم الملفات غير المُتتبعة على النحو التالي:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_29">
<span class="pln">$ vim README
$ git status
On branch master
Untracked files:
(use "git add </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to include in what will be committed)

README

nothing added to commit but untracked files present (use "git add" to track)</span></pre>

	<p>
		عدم التتبع عنها يعني بأن git قد عرف بأن الملف لم يكن في اللقطة السابقة لمشروعك (أي آخر إيداع)، لكنه لن يشرع في تتبعه بشكل آلي ما لم تقم أنت بطلب ذلك بشكل صريح، وستجد بأن ذلك مُفيد جدا خاصة لما تعمل على مشروع يُنتج الكثير من الملفات المُوقتة التي لا ترغب في تتبعها.
	</p>

	<h2 id="تتبع-الملف-الجديد:5bc8635476404749f76287ef866562d6">
		تتبع الملف الجديد
	</h2>

	<p>
		الآن وللشروع في تتبع الملف الجديد فإننا سنحتاج إلى الأمر <span style="font-family:courier new,courier,monospace;">git add</span> على النحو التالي:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_31">
<span class="pln">$ git add README</span></pre>

	<p>
		وإذا قمت بتنفيذ الأمر <span style="font-family:courier new,courier,monospace;">git status</span> من جديد فإن الملف سيظهر مُتتبعا ومُدرجا:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_33">
<span class="pln">$ git status
On branch master
Changes to be committed:
(use "git reset HEAD </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to unstage)

new file: README</span></pre>

	<p>
		بإمكانك معرفة أن الملف في منطقة الإدراج لأنه يظهر في قسم التغييرات التي سيتم إيداعها "Changes to be committed". إذا قمت بإدراج الملف في هذه المرحلة فإن حالة الملف لدى تنفيذك للأمر <span style="font-family:courier new,courier,monospace;">git add </span>هي التي ستتم إضافتها إلى اللقطة. يُمكنك تحديد مسار ملف أو مُجلد لدى تنفيذك لأمر<span style="font-family:courier new,courier,monospace;"> git add</span>، ولدى تحديد مُجلد فإنه ستتم إضافة جميع مُحتوياته.
	</p>

	<h2 id="إدراج-الملفات-الم-عد-لة:5bc8635476404749f76287ef866562d6">
		إدراج الملفات المعدلة
	</h2>

	<p>
		لنقم الآن بتعديل ملف سبق وأن شرعنا في تتبع التغيرات الطارئة عليه. لو أدخلنا تغييرات على الملف <span style="font-family:courier new,courier,monospace;">benchmark.rb</span> ومن ثم نفذنا الأمر<span style="font-family:courier new,courier,monospace;"> </span><span style="font-family:courier new,courier,monospace;">status</span> من جديد لحصلنا على نتيجة مُماثلة لهذه النتيجة:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_35">
<span class="pln">$ git status
On branch master
Changes to be committed:
(use "git reset HEAD </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to unstage)

new file: README

Changes not staged for commit:
(use "git add </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to update what will be committed)
(use "git checkout -- </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to discard changes in working directory)

modified: benchmarks.rb</span></pre>

	<p>
		أين يظهر ملف <span style="font-family:courier new,courier,monospace;">benchmark.db </span>تحت قسم "Changes not staged for commit" (تعديلات لم يتم إدراجها لإيداعها).ومثلما هو ظاهر من هذا الوصف فأننا قمنا بإدخال تعديلات على ملف مُتتبع ولم يتم إدراج تلك التغييرات بعد. ولإدراج هذه التغييرات يكفي أن نُنفذ الأمر<span style="font-family:courier new,courier,monospace;"> git add</span> الذي لديه عدة استخدامات كالشروع في تتبع الملفات مثلما سبق وأن شاهدناه، إدراج الملفات وللقيام بأمور أخرى كتعليم ملفات الدمج المُتضاربة merge-conflicted files كمحلولة.
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_37">
<span class="pln">$ git add benchmarks.rb
$ git status
On branch master
Changes to be committed:
&gt; (use "git reset HEAD </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to unstage)

new file: README
modified: benchmarks.rb</span></pre>

	<p>
		مثلما نلاحظه الآن، تم إدراج كلا الملفين وسيتم أخذ التغييرات الطارئة عليهما في الحسبان في عملية الإيداع القادمة. لكن لنفرض بأنك تذكرت تغييرا آخرًا تود إدخاله على ملف قبل أن تقوم بعملية الإيداع، وعليه فإنك ستقوم بالتعديل عليه قبل إيداعه. لكن لو قمت الآن بتنفيذ أمر<span style="font-family:courier new,courier,monospace;"> git status</span> من جديد فستظهر هذه النتيجة:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_39">
<span class="pln">$ vim benchmarks.rb
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to unstage)

new file: README
modified: benchmarks.rb

Changes not staged for commit:
(use "git add </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to update what will be committed)
(use "git checkout -- </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to discard changes in working directory)

modified: benchmarks.rb</span></pre>

	<p>
		غريب؟ أليس كذلك؟ يظهر ملف <span style="font-family:courier new,courier,monospace;">benchmark.rb</span> على أساس أنه مُدرج وغير مُدرج في آن واحد. هل هذا ممكن؟ نعم هذا مُمكن حيث يقوم git بإدراج الملف في حالته التي كان عليها لدى تنفيذ الأمر<span style="font-family:courier new,courier,monospace;"> git add</span> وبالتالي لو قمت بالإيداع الآن فإنه سيتم إيداع ملف<span style="font-family:courier new,courier,monospace;"> benchmark.rb</span> في حالته التي كان عليها لدى تنفيذ الأمر<span style="font-family:courier new,courier,monospace;"> git add</span> وليس على الحال التي هو عليها الآن، وبالتالي فإنه يجب تنفيذ الأمر <span style="font-family:courier new,courier,monospace;">git add</span> لإدراج تلك التغييرات في كل مرة تقوم بإدخال التعديلات على الملف:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_41">
<span class="pln">$ git add benchmarks.rb
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to unstage)

new file: README
modified: benchmarks.rb</span></pre>

	<h2 id="تجاهل-ملفات:5bc8635476404749f76287ef866562d6">
		تجاهل ملفات
	</h2>

	<p>
		عادة ما تكون لديك في المشروع الذي تعمل عليه جُملة أو صنف من الملفات التي لا ترغب من Git أن يقوم بإضافتها بشكل آلي أو حتى في إظهارها كملفات غير مُتتبعة، وعادة ما تكون هذه الملفات تلك التي يتم توليدها بشكل آلي مثل ملفات log أو الملفات التي تنتج عن نظام البناء الخاص بك build system. في مثل هذه الحالات فإن الحل يكمن في استخدام ملف <span style="font-family:courier new,courier,monospace;">gitignore.</span> الذي يحتوي أنماط أسماء هذه الملفات غير المرغوب فيها:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_45">
<span class="pln">$ cat .gitignore
*.[oa]
*~</span></pre>

	<p>
		يطلب السطر الأول في الملف (ولا أعني بذلك الأمر <span style="font-family:courier new,courier,monospace;">cat</span>) من Git أن يتجاهل جميع الملفات التي تنتهي بـ o. أو a. (الكائنات وملفات الأرشيف التي يُحتمل أن تنتج عن عملية بناء شفرتك البرمجية). أما السطر الثاني فيطلب من Git أن يتجاهل جميع الملفات التي تنتهي أسماؤها بمحرف ~ والتي تستخدمها بعض محررات النصوص كمُحرر Emacs لحفظ الملفات المؤقتة. بإمكانك أيضا أن تُضمن في هذا الملف ملفات log ،tmp أو مجلد <span style="font-family:courier new,courier,monospace;"><abbr title="Process IDentifier | معرّف العملية أو البرنامج">pid</abbr></span> والتوثيق التي يتم توليده بشكل آلي وما إلى ذلك. الشروع في إعداد ملف <span style="font-family:courier new,courier,monospace;">gitignore.</span> قبل الشروع في العمل على المشروع من شأنه أن يُجنبك إيداع ملفات لا ترغب أن تظهر في مستودعك لاحقا.
	</p>

	<p>
		القواعد العامة التي تتبعها أنماط أسماء الملفات المُضمنة في ملف<span style="font-family:courier new,courier,monospace;"> gitignore.</span>  هي على النحو التالي:
	</p>

	<ul><li>
			يتم تجاهل الأسطر الفارغة والأسطر التي تبدأ بمحرف <strong>#</strong><a href="%7Boption%7D" rel="external"> </a>
		</li>
		<li>
			يتم أخذ الأنماط المبسطة للتعابير القياسية Standard glob patterns في الحسبان
		</li>
		<li>
			بإمكانك إنهاء النمط بـ <strong>/</strong> للدلالة على المجلدات.
		</li>
		<li>
			بإمكانك عكس النمط بتسبيقه بعلامة تعجب<strong> !</strong><a href="%7Boption%7D" rel="external"> </a>
		</li>
	</ul><p>
		الأنماط المبسطة للتعابير القياسية Standard glob patterns هي نسخة مُبسطة من التعابير القياسية التي يُمكن استخدامها على سطر الأوامر. فـ <strong>*</strong> تدل على 0 أو أكثر من محرف، و <strong>[abc]</strong> تتوافق مع أي حرف ضمن هذه القائمة (في هذه الحالة: a ،b و c). أما علامة الاستفهام فتتوافق مع محرف واحد. أما لو استخدمنا هذه الصيغة <strong>[0-9]</strong> فإنها ستوافق أي محرف يقع ما بين 0 و 9.
	</p>

	<p>
		إليكم مثالا آخر عن ملف <span style="font-family:courier new,courier,monospace;">gitignore.</span>:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_47">
<span class="pln"># a comment - this is ignored
# no .a files
*.a
# but do track lib.a, even though you're ignoring .a files above
!lib.a
# only ignore the root TODO file, not subdir/TODO
/TODO
# ignore all files in the build/ directory
build/
# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt
# ignore all .txt files in the doc/ directory
doc/**/*.txt
النمط **/ مُتوفر بداية من الإصدار 1.8.2</span></pre>

	<h2>
		إظهار التغييرات المدرجة وغير المدرجة
	</h2>

	<p>
		إذا كانت النتيجة التي يُظهرها الأمر<span style="font-family:courier new,courier,monospace;"> git status</span> غير دقيقة بالنسبة إليك أو إن كنت ترغب في معرفة التغييرات التي حصلت بدقة وليس مجرد معرفة قائمة الملفات التي تم تغييرها فإنه بإمكانك الاستعانة بالأمر <span style="font-family:courier new,courier,monospace;">git diff</span> للقيام بذلك. لسنا هنا بصدد تفصيل الأمر <span style="font-family:courier new,courier,monospace;">git diff </span>(سنقوم بذلك في مقال لاحق) لكنك ستحتاجه للإجابة على سؤالين مُحددين: ما الذي قُمت بالتعديل عليه ولم تقم بإدراجها بعد، وما الذي قمت بإدراجه لكن لم تقم بإيداعه بعد. بالرغم من أنه بإمكان<span style="font-family:courier new,courier,monospace;"> git status</span> الإجابة على هذين السؤالين، إلا أن الأمر  <span style="font-family:courier new,courier,monospace;">git diff </span>كفيل بالإجابة عنها بشكل أدق، حيث سيخبرك عن أي سطر تمت إضافته وعن أي سطر تمت إزالته.
	</p>

	<p>
		لنفرض بأنك قمت بتحرير وإيداع ملف <span style="font-family:courier new,courier,monospace;">README</span> من جديد ومن ثم قمت بتحرير ملف <span style="font-family:courier new,courier,monospace;">benchmarks.rb</span> من دون إدراجه. لو قمت بتنفيذ الأمر <span style="font-family:courier new,courier,monospace;">status</span> فإنك ستحصل على نتيجة مُشابه للنتيجة التالية:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_49">
<span class="pln">$ git status
On branch master
Changes to be committed:
(use "git reset HEAD </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to unstage)

new file: README

Changes not staged for commit:
(use "git add </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to update what will be committed)
(use "git checkout -- </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to discard changes in working directory)

modified: benchmarks.rb</span></pre>

	<p>
		لكن لو رغبت في معرفة التغييرات التي حصلت والتي لم يتم إدراجها فاستعن بالأمر <span style="font-family:courier new,courier,monospace;">git diff:</span>
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_51">
<span class="pln">$ git diff
diff --git a/benchmarks.rb b/benchmarks.rb
index 3cb747f..da65585 100644
--- a/benchmarks.rb
+++ b/benchmarks.rb
@@ -36,6 +36,10 @@ def main
@commit.parents[0].parents[0].parents[0]
end

+ run_code(x, 'commits 1') do
+ git.commits.size
+ end
+
run_code(x, 'commits 2') do
log = git.commits('master', 15)
log.size</span></pre>

	<p>
		يقوم هذا الأمر بمقارنة مُحتوى مُجلد العمل بما هو موجود في منطقة الإدراج، وبالتالي فإن النتيجة ستُخبرك بالتغييرات التي قُمت بها والتي لم تقم بإدراجها بعد.
	</p>

	<p>
		أما إذا أردت رؤية التغييرات المُدرجة التي سيتم أخذها في الحسبان في الإيداع القادم فما عليك سوى استخدام الأمر <span style="font-family:courier new,courier,monospace;">git diff --cached</span> (في الإصدار 1.6.1 والإصدارات التي تليه أصبح بالإمكان استخدام الأمر<span style="font-family:courier new,courier,monospace;"> git diff --staged</span> بدلا عنه، حيث يُعتبر هذا الأمر أسهل للتذكر من سابقه). يقوم هذا الأمر بمقارنة مُحتوى منطقة الإدراج بآخر إيداع قمت به:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_53">
<span class="pln">$ git diff --cached
diff --git a/README b/README
new file mode 100644
index 0000000..03902a1
--- /dev/null
+++ b/README2
@@ -0,0 +1,5 @@
+grit
+ by Tom Preston-Werner, Chris Wanstrath
+ http://github.com/mojombo/grit
+
+Grit is a Ruby library for extracting information from a Git repository</span></pre>

	<p>
		تجدر الإشارة إلى أن الأمر  <span style="font-family:courier new,courier,monospace;">git diff </span>بدون أية معاملات إضافية لا يقوم بإظهار كل التغييرات التي قُمت بها منذ آخر إيداع، حيث تكتفي بإظهار التغييرات التي لم يتم إدراجها. هذا الأمر قد يكون مُربكا بعض الشيء بحكم أنه لو قمت بإدراج جميع التغييرات التي قمت بها فإن أمر <span style="font-family:courier new,courier,monospace;">git diff </span>لن يُظهر أية نتيجة.
	</p>

	<p>
		مثال آخر، لو قمت بإدراج الملف<span style="font-family:courier new,courier,monospace;"> benchmarks.rb</span> ومن ثم قمت بالتعديل عليه فإنه بإمكانك استخدام الأمر <span style="font-family:courier new,courier,monospace;">git diff </span>لرؤية التغييرات التي تمت على الملف والتي تم إدراجها وتلك التغييرات التي لم يتم إدراجها أيضا:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_55">
<span class="pln">$ git add benchmarks.rb
$ echo '# test line' &gt;&gt; benchmarks.rb
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to unstage)

modified: benchmarks.rb

Changes not staged for commit:
(use "git add </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to update what will be committed)
(use "git checkout -- </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to discard changes in working directory)

modified: benchmarks.rb</span></pre>

	<p>
		الآن يُمكنك استخدام الأمر <span style="font-family:courier new,courier,monospace;">git diff </span>لمعرفة ما الذي لم يتم إدراجه بعد:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_57">
<span class="pln">$ git diff
diff --git a/benchmarks.rb b/benchmarks.rb
index e445e28..86b2f7c 100644
--- a/benchmarks.rb
+++ b/benchmarks.rb
@@ -127,3 +127,4 @@ end
main()

##pp Grit::GitRuby.cache_client.stats
+# test line</span></pre>

	<p>
		والأمر <span style="font-family:courier new,courier,monospace;">git diff --cached</span><span style="font-family:georgia,serif;"> </span>لمعرفة ما الذي قُمت بإدراجه إلى حد الآن:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_59">
<span class="pln">$ git diff --cached
diff --git a/benchmarks.rb b/benchmarks.rb
index 3cb747f..e445e28 100644
--- a/benchmarks.rb
+++ b/benchmarks.rb
@@ -36,6 +36,10 @@ def main
@commit.parents[0].parents[0].parents[0]
end

+ run_code(x, 'commits 1') do
+ git.commits.size
+ end
+
run_code(x, 'commits 2') do
log = git.commits('master', 15)
log.size</span></pre>

	<h2 id="إيداع-التغييرات:5bc8635476404749f76287ef866562d6">
		إيداع التغييرات
	</h2>

	<p>
		الآن وبعد أن قمت بإعداد منطقة الإدراج على النحو الذي ترغب فيه، بإمكانك الآن القيام بإيداع التغييرات التي قمت بها. تذكر دائما بأن أي تغيير لم تم بإيداعه -أي ملف قمت بإنشائه أو التعديل عليه والذي لم تقم بإضافته بتنفيذ الأمر<span style="font-family:courier new,courier,monospace;"> git add </span>عليه منذ إنشائه أو منذ آخر تحديث عليه- لن يتم أخذه بالحسبان في الإيداع القادم، بل سينظر إليه النظام كملف تم تعديله. في هذه الحالة، ولدى تنفيذك للأمر<span style="font-family:courier new,courier,monospace;"> git status</span> آخر مرة فإنك لاحظت بأنه تم إدراج جميع التغييرات وبالتالي فإنك جاهز لإيداع التغييرات. يتم ذلك باستخدام الأمر <span style="font-family:courier new,courier,monospace;">git commit</span> على النحو التالي:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_61">
<span class="pln">git commit</span></pre>

	<p>
		تنفيذ هذا الأمر سيقوم بفتح مُحرر النصوص المُفضل لديك (والذي يتم تحديده عبر قيمة مُتغيرالنظام <span style="font-family:courier new,courier,monospace;">EDITOR$ </span>والذي يُمكن أن يكون vim ،emacs أو أي مُحرر نصوص آخر، كما أنه يُمكنك تحديد عبر الأمر<span style="font-family:courier new,courier,monospace;"> git config --global core.editor</span> مثلما سبق وأن تطرقنا إليه في درس <a href="https://academy.hsoub.com/programming/workflow/git/%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-git-%D9%84%D9%84%D9%85%D8%B1%D8%A9-%D8%A7%D9%84%D8%A3%D9%88%D9%84%D9%89-r260/">إعداد Git للمرة الأولى</a>.
	</p>

	<p>
		سيقوم المُحرر بإظهار النص التالي (المثال التالي مأخوذ من مُحرر النصوص Vim):
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_63">
<span class="pln"># Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# new file: README
# modified: benchmarks.rb
#
~
~
~
".git/COMMIT_EDITMSG" 10L, 283C</span></pre>

	<p>
		مثلما نلاحظه هنا فإن نص/رسالة الإيداع القياسية تحتوي مُخرجة الأمر <span style="font-family:courier new,courier,monospace;">git status</span> على هيئة تعليق، إضافة إلى سطر فارغ يسبق ذلك. بإمكانك حذف هذا التعليق وكتابة النص الذي ترغب فيه، كما أنه بإمكانك الإبقاء عنها لتتذكر الملفات التي تم تعديلها في هذا الإيداع ( للحصول على تذكير أدق يُمكنك تمرير المُعامل <span style="font-family:courier new,courier,monospace;">v-</span> لأمر <span style="font-family:courier new,courier,monospace;">git commit</span> سابق الذكر، وستحصل حينها على تفاصيل التغييرات التي حدثت على الملفات لما يتم فتح المُحرر المفضل لديك).
	</p>

	<p>
		لدى إغلاقك لمحرر النصوص سيقوم Git بإنشاء الإيداع ويقوم بإرفاق ذلك النص/الرسالة به مع التخلص من التعليقات وتفاصيل التغييرات التي أدخلت على الملفات.
	</p>

	<p>
		يُمكنك أيضا كتابة نص الإيداع مُباشرة مُرفقا بأمر الإيداع وذلك بتسبيقه بـ <span style="font-family:courier new,courier,monospace;">m-</span> على النحو التالي:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_67">
<span class="pln">$ git commit -m "Story 182: Fix benchmarks for speed"
[master 463dc4f] Story 182: Fix benchmarks for speed
2 files changed, 3 insertions(+)
create mode 100644 README</span></pre>

	<p>
		كما تلاحظ فإنك قمت بعمل أول عملية إيداع لك وحصلت على بعض المعلومات حوله، كاسم الفرع الذي ينتمي إليه (master) وما هي قيمة هاش SHA-1 الخاصة به 463dc4f، عدد الملفات التي تم تحديثها، إضافة إلى عدد الأسطر التي تمت إضافتها أو حذفها.
	</p>

	<p>
		يجب التذكير بأن عملية الإيداع تقوم بأخذ صورة عن البيانات التي تم إدراجها وأي تغييرات لم تقم بإرسالها إلى منطقة الإدراج لن يتم أخذها بالحسبان، وعليه يجب إضافتها من جديد إلى منطقة الإدراج قبل إيداعها من جديد. كل مرة تقوم فيها بعملية إيداع فإنك تأخذ صورة عن حالة مشروعك في اللحظة التي تم التقاط تلك الصورة فيها وبإمكانك الرجوع إلى تلك الحالة لاحقا إن رغبت في ذلك.
	</p>

	<h2 id="تجاوز-منطقة-الإدراج:5bc8635476404749f76287ef866562d6">
		تجاوز منطقة الإدراج
	</h2>

	<p>
		بالرغم من أن منطقة الإدراج في غاية الأهمية لتمكيننا من "بناء" إيداعات على الشكل الذي نرغب فيه، إلا أنها تُعتبر في بعض المرات مرحلة إضافية لا نرغب فيها. إذا رغبت في تجاوز منطقة الإدراج ما بين الحين والآخر فإن Git يسمح لك بالقيام بذلك، حيث يكفي إضافة خيار <span style="font-family:courier new,courier,monospace;">a- </span>إلى أمر <span style="font-family:courier new,courier,monospace;">git commit</span> ليقوم git بإضافة جميع الملفات التي كنت تتبعها سابقا قبل عملية الإيداع الحالية (يعني يقوم باختصار أمر <span style="font-family:courier new,courier,monospace;">git add</span>).
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_69">
<span class="pln">$ git status
On branch master
Changes not staged for commit:
(use "git add </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to update what will be committed)
(use "git checkout -- </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to discard changes in working directory)

modified: benchmarks.rb

no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -a -m 'added new benchmarks'
[master 83e38c7] added new benchmarks
1 files changed, 5 insertions(+)</span></pre>

	<p>
		لاحظ كيف أننا لم نحتج إلى تنفيذ الأمر <span style="font-family:courier new,courier,monospace;">git add</span> على الملف<span style="font-family:courier new,courier,monospace;"> benchmarks.rb </span>في هذه الحالة قبل أن تقوم بعملية الإيداع.
	</p>

	<h2 id="حذف-الملفات:5bc8635476404749f76287ef866562d6">
		حذف الملفات
	</h2>

	<p>
		لحذف ملف من مشروع Git فإنه يجب عليك أن تحذفه من قائمة الملفات المُتتبّعة (أو بالأحرى من قائمة الملفات المُدرجة) قبل أن تقوم بعملية إيداع. يُمكّن أمر <span style="font-family:courier new,courier,monospace;">git rm </span>من القيام بذلك ويقوم بحذف الملف من مُجلد العمل مما سيُجنّب ظهوره في قائمة الملفات غير المُتتبعة.
	</p>

	<p>
		إذا قمت بحذف الملف يدويا من المشروع فإن اسمه سيظهر في قائمة التغييرات التي لم يتم إدراجها لما تقوم بتنفيذ الأمر <span style="font-family:courier new,courier,monospace;">git status</span>:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_87">
<span class="pln">$ rm grit.gemspec
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to update what will be committed)
(use "git checkout -- </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to discard changes in working directory)

deleted: grit.gemspec

no changes added to commit (use "git add" and/or "git commit -a")</span></pre>

	<p>
		ومن ثم إذا قمت بتنفيذ الأمر <span style="font-family:courier new,courier,monospace;">git rm </span>فإنه سيتم "إدراج" الملف للحذف:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_73">
<span class="pln">$ git rm grit.gemspec
rm 'grit.gemspec'
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to unstage)

deleted: grit.gemspec</span></pre>

	<p>
		وفي المرة القادمة التي تقوم فيها بالإيداع فإن الملف سيختفي كُليّة. إذا كنت قد عدّلت على الملف وقمت بإضافته إلى الفهرس index فإنه يجب فرض إزالته عبر تمرير الخيار -f. يتم الاستعانة بذلك لتجنب حذف بيانات لم يتم تسجيلها في سجلات Git عن طريق الخطأ (وبالتالي لن يُصبح بالإمكان استرجاعها).
	</p>

	<p>
		أمر آخر قد ترغب في القيام به والمُتعلق بحذف الملف من git مع إبقائه في مُجلد العمل الخاص بك. بعبارة أخرى قد تكون أضفت ملفا مُعينا عن طريق الخطأ ولكن لا ترغب في مواصلة تتبعه عبر git، وعادة ما يكون الأمر مُتعلقا بملفات نسيت إضافتها إلى <span style="font-family:courier new,courier,monospace;">gitignore. </span>كملفات log كبيرة الحجم أو ملفات <span style="font-family:courier new,courier,monospace;">a.</span> الناتجة عن ترجمة المشروع. كل ما تحتاج إلى القيام به هو إضافة خيار <span style="font-family:courier new,courier,monospace;">cached-- </span>على الشكل التالي:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_83">
<span class="pln">$ git rm --cached readme.txt</span></pre>

	<p>
		بإمكان تمرير أسماء ملفات، مُجلدات أو حتى أنماطا مُبسطة للتعابير القياسية file-glob patterns لأمر <span style="font-family:courier new,courier,monospace;">git rm</span>. يعني يُمكن القيام مثلا بالتالي:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_85">
<span class="pln">$ git rm log/\*.log</span></pre>

	<p>
		لاحظ وجود محرف \ الذي يسبق * والذي يُعتبر ضروريا لأن git يستعمل نظامه الخاص لتفسير هذه الأنماط إضافة إلى النظام الخاص بسطر الأوامر الذي تستخدمه. أما على نظام Windows فإنك لن تحتاج إلى إضافته. يقوم هذا الأمر بحذف جميع الملفات التي تملك المُلحق <span style="font-family:courier new,courier,monospace;">log.</span> في مُجلد <span style="font-family:courier new,courier,monospace;">log/</span>.
	</p>

	<p>
		بإمكانك أيضا تنفيذ الأمر التالي لحذف جميع الملفات التي تنتهي أسماؤها بـ ~:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_89">
<span class="pln">$ git rm \*~</span></pre>

	<h2 id="نقل-الملفات:5bc8635476404749f76287ef866562d6">
		نقل الملفات
	</h2>

	<p>
		على عكس ما هو مُتداول عليه باقي أنظمة إدارة الإصدارات فإن Git لا يقوم بتتبع حركة الملفات بشكل مُباشر. إن قمت بتغيير اسم ملف مثلا فإن git لا يحتفظ بأية بيانات حول الأمر، إلا أن النظام يملك مقدارا مُعينا من "الذكاء" يسمح له باستنتاج ذلك لاحقا. سنقوم بالتطرق لتتبع حركة الملفات في مقال لاحق.
	</p>

	<p>
		قد يبدو الأمر غامضا نوعا ما خاصة وأن git يملك الأمر <span style="font-family:courier new,courier,monospace;">mv</span>. إن أردت إعادة تسمية ملف فإنه يُمكن القيام بذلك على النحو التالي:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_91">
<span class="pln">$ git mv file_from file_to</span></pre>

	<p>
		وسيتم ذلك على النحو المُتوقّع، حيث يظهر ذلك واضحا على النحو التالي:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_93">
<span class="pln">$ git mv README README.txt
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD </span><span class="tag">&lt;file&gt;</span><span class="pln">..." to unstage)

renamed: README -&gt; README.txt</span></pre>

	<p>
		في المقابل، الأمر السابق مُماثل في نتيجته للتالي:
	</p>

	<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3875_95">
<span class="pln">$ mv README README.txt
$ git rm README
$ git add README.txt</span></pre>

	<p>
		حيث سيعرف git بأنك تقوم بإعادة تسمية الملف، وبالتالي لا يهم الآلية التي تتبعها للقيام بذلك. الاختلاف الوحيد ما بين الطريقتين هو أن <span style="font-family:courier new,courier,monospace;">mv</span> عبارة عن أمر واحد بدل الأوامر الثلاثة في الطريقة الثانية. الأهم من ذلك يُمكن الاستعانة بأية طريقة ترغب فيها لإعادة تسمية الملفات، كل ما يهمك أن تقوم بتنفيذ أوامر <span style="font-family:courier new,courier,monospace;">add/rm</span> اللازمة قبل أن تقوم بعملية الإيداع.
	</p>

	<p>
		ترجمة -وبتصرف- للفصلين: <a href="http://git-scm.com/book/en/v2/Git-Basics-Getting-a-Git-Repository" rel="external nofollow">Git Basics – Getting a Git Repository</a> و <a href="http://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository" rel="external nofollow">Git Basics – Recording Changes to the Repository</a> من كتاب <a href="http://git-scm.com/book/en/v2" rel="external nofollow">Pro Git</a> لصاحبه <a href="https://twitter.com/chacon" rel="external nofollow">Scott Chacon</a>.
	</p>
</div>
]]></description><guid isPermaLink="false">267</guid><pubDate>Tue, 23 Feb 2016 12:22:00 +0000</pubDate></item><item><title>&#x643;&#x64A;&#x641; &#x62A;&#x633;&#x627;&#x647;&#x645; &#x641;&#x64A; &#x645;&#x634;&#x627;&#x631;&#x64A;&#x639; &#x645;&#x641;&#x62A;&#x648;&#x62D;&#x629; &#x627;&#x644;&#x645;&#x635;&#x62F;&#x631; &#x639;&#x644;&#x649; Github</title><link>https://academy.hsoub.com/programming/workflow/git/%D9%83%D9%8A%D9%81-%D8%AA%D8%B3%D8%A7%D9%87%D9%85-%D9%81%D9%8A-%D9%85%D8%B4%D8%A7%D8%B1%D9%8A%D8%B9-%D9%85%D9%81%D8%AA%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1-%D8%B9%D9%84%D9%89-github-r265/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_01/github-social-coding.png.52eb043608fefa78e9b6ef6c6adc9bf1.png" /></p>

<div><p>وأخيرا اقتنعت بفلسفة المصادر المفتوحة، أو أنك أخيرا وجدت الوقت للمُساهمة في أحدها، وربما ما دفعك إلى الأمر هو استفادتك من مشروع مفتوح المصدر وأردت أن ترد الجميل بالمساهمة فيه بدورك، لكن لا تدري كيف تقوم بذلك؟ الأمر بسيط، كل ما تحتاجه هو جهاز محلي يكون Git مُنصبا عليه، حساب على Github وبعض الوقت، ومن ثم اتباع بضع خُطوات بسيطة.</p></div><div><p dir="RTL" style="text-align: center;"><a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_01/github-social-coding.png.053d1d7e6d9381b414241068a4133043.png"><img data-fileid="12089" class="ipsImage ipsImage_thumbnailed" alt="github-social-coding.thumb.png.0f701c8c3" src="https://academy.hsoub.com/uploads/monthly_2016_01/github-social-coding.thumb.png.0f701c8c31b863b12950e080c807af45.png"></a></p><p dir="RTL">تجدر الإشارة إلى أنك لا تحتاج إلى أن تكون مُبرمجا للمُساهمة في المشاريع مفتوحة المصدر، يُمكنك المُساهمة في إنشاء أو تحسين توثيق المشروع، حيث يُعتبر التوثيق الجيد أحد أهم عوامل نجاح المشاريع مفتوحة المصدر، وانتشار بعضها على حساب الآخر.</p><p dir="RTL">لنفرض أن المشروع الذي تود المُساهمة فيه هو <a rel="external nofollow" href="https://github.com/arabicgit/simple-guide">"git – الدّليل البسيط"</a>.</p><p dir="RTL"><strong>1. قم باستنساخ المشروع</strong> إلى حسابك الخاص وذلك بالنقر على زر <strong>Fork</strong> الموجود في الزاوية العُلوية اليُمنى لصفحة المشروع. هذه العملية من شأنها أن تُنشئ نُسخة مُطابقة للمُستودع الأصلي على حسابك على Github.</p><p dir="RTL" style="text-align: center;"><a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_01/contributing-open-source-projects-github-01.png.e520cbe7a807e2b5b84a5d27c9241281.png"><img data-fileid="12084" class="ipsImage ipsImage_thumbnailed" alt="contributing-open-source-projects-github" src="https://academy.hsoub.com/uploads/monthly_2016_01/contributing-open-source-projects-github-01.thumb.png.dba3a333f429b9c81c96874158a5a9db.png"></a></p><p dir="RTL"><strong>2. بعد ذلك قم باستنساخ هذا المُستودع الجديد على جهازك المحلي</strong>. ادخل إلى المجلد الذي تود استنساخ المُجلد فيه (<span style="font-family:courier new,courier,monospace;">cd path/to/folder</span>) وقم بتنفيذ الأمر <span style="font-family:courier new,courier,monospace;">git clone</span> متبوعا بعُنوان المُستودع. ستجد العُنوان أسفل القائمة اليُمنى في صفحة المُستودع. بالنسبة لي سيكون الأمر على النحو التالي:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">git clone https://github.com/djug/simple-guide.git</pre><p dir="RTL" style="text-align: center;"><a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_01/contributing-open-source-projects-github-02.png.6d432faf989952d1a4b3c32dd9fec373.png"><img data-fileid="12085" class="ipsImage ipsImage_thumbnailed" alt="contributing-open-source-projects-github" src="https://academy.hsoub.com/uploads/monthly_2016_01/contributing-open-source-projects-github-02.thumb.png.2ee36cffad17831a83a04a4395acf38f.png"></a></p><p dir="RTL"><strong>3. الآن وبعد أن حصلت على هذه النُسخة، قم بإدخال التعديلات التي ترغب فيها واحفظ تلك التعديلات.</strong></p><p dir="RTL">قبل أن نقوم بإيداع تلك التعديلات، يُنصح دائما التحقق من حالة المُستودع، وإن تم أخذ التعديلات بالحسبان أو إن قمنا بتعديل ملف لم نكن نرغب في تعديله، حيث يكفي أن ننفذ الأمر<span style="font-family:courier new,courier,monospace;"> git status</span> لمعرفة حالة المُستودع (النسخة المحلية):</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">git status 
  On branch master 
  Your branch is up-to-date with 'origin/master'. 
  Changes not staged for commit: 
  (use "git add &lt;file&gt;..." to update what will be committed) 
  (use "git checkout -- &lt;file&gt;..." to discard changes in working directory) 
  modified: index.ar.html</pre><p dir="RTL"><strong>4. تبدو الأمور طبيعية. لنقم بإرسال التغييرات إلى منطقة الإدراج:</strong></p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">git add .</pre><p dir="RTL">ومن ثم إيداعها (<span style="font-family:courier new,courier,monospace;">commit</span>):</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">git commit -m "Your commit Message Here"</pre><p dir="RTL">بطبيعة الحال ستحتاج إلى وضع وصف مُناسب للتغييرات التي قمت بها. بإمكانك أيضا تنفيذ الأمر <span style="font-family:courier new,courier,monospace;">commit</span> لوحده من دون أية رسائل:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">git commit</pre><p dir="RTL">وسيقوم git بفتح مُحرر النصوص المُفضل لديك لكتابة الوصف (في حال ما إذا قمت بتحديد اسم هذا المُحرر في إعدادات git).</p><p dir="RTL">سنحتاج الآن إلى إرسال هذه التغييرات إلى المُستودع (<strong>الشخصي</strong> وليس مُستودع المشروع الذي نشارك فيه) على Github عبر تنفيذ الأمر:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">git push origin master</pre><p dir="RTL">سيطلب منك Git اسم المُستخدم الخاص بك على Github وكلمة السر، وبمُجرد أن يتم التحقق منهما سيتم دفع التغييرات إلى مُستودعك الخاص.</p><p dir="RTL">5. الآن لو عدنا إلى صفحة المُستودع الشخصي على Github سيظهر لنا تاريخ آخر تحديث للملفات المُعدلة ووصف له. وكل ما نحتاج إلى فعله الآن هو إرسال "طلب سحب" pull request -أي سحب التغيرات- إلى المُستودع الأصلي للمشروع وذلك بالنقر على الزر الأخضر الذي يظهر في الزاوية العُلوية اليُمنى للمُستودع</p><p dir="RTL" style="text-align: center;"><a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_01/contributing-open-source-projects-github-03.png.5a11eec44bf92c7643ff865cb2cc7a9e.png"><img data-fileid="12086" class="ipsImage ipsImage_thumbnailed" alt="contributing-open-source-projects-github" src="https://academy.hsoub.com/uploads/monthly_2016_01/contributing-open-source-projects-github-03.thumb.png.6c872479d3fc0ec35b2e293d055db9f0.png"></a></p><p dir="RTL">ستظهر لك صفحة لتلخص من جديد التغييرات التي تمت</p><p dir="RTL"><strong>6. الخطوة الأخيرة هي النقر على زر Create Pull request</strong>، إضافة أية تعليقات ترغب فيها على الطلب، ومن ثم النقر على زر <strong>Send pull request</strong>:</p><p dir="RTL" style="text-align: center;"><a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_01/contributing-open-source-projects-github-04.png.e2dcc50219c64d770a528f9e6ba619cb.png"><img data-fileid="12087" class="ipsImage ipsImage_thumbnailed" alt="contributing-open-source-projects-github" src="https://academy.hsoub.com/uploads/monthly_2016_01/contributing-open-source-projects-github-04.thumb.png.ee04cf485c663e3454c65624a9846bef.png"></a></p><p dir="RTL">ستصل صاحب المشروع رسالة بخصوص التغييرات التي قمت بها، وفي حال قبولها سيصلك إشعار بها وستظهر تغييراتك على المستودع الأصلي:</p><p dir="RTL" style="text-align: center;"><a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_01/contributing-open-source-projects-github-05.png.17d40f888214646e51133c5cadffb21b.png"><img data-fileid="12088" class="ipsImage ipsImage_thumbnailed" alt="contributing-open-source-projects-github" src="https://academy.hsoub.com/uploads/monthly_2016_01/contributing-open-source-projects-github-05.thumb.png.da6c74f8200e8cdcbfbc3ba364e46e12.png"></a></p><p dir="RTL">هذا كل ما في الأمر. أنت الآن بطريق… أقصد مُشارك في مشاريع مفتوحة المصدر بشكل رسمي.</p><h2 dir="RTL">نصائح عامة لدى المساهمة في المشاريع</h2><ul><li>اجعل نص الإيداع <span style="font-family:courier new,courier,monospace;">commit</span> معبّرا أو ملخصا للتغيرات التي قمت بها، لا تجعله مبهما أو عاما.</li><li>افصل طلبات السحب "<span style="font-family:courier new,courier,monospace;">pull request</span>" حسب الغرض، أو اجعل لكل تغير تقترحه في branch لوحده حسب الغرض، مثال: لا ترسل طلب سحب يحتوي تغيرات مرئية في الـ html و css وفيه أيضا ترجمة النصوص إلى العربية، هكذا تصعب المهمة على من يقوم بعملية الدمج في حال كان يريد قبول الترجمة لكنه غير راض عن التغيرات التي طرأت في الـ html/css. في هذه الحالة سيكون من الأنسب:<ul><li>طلب سحب للتغيرات المرئية لوحده.</li><li>طلب سحب آخر للملفات الترجمة إلى العربية.</li></ul></li><li>في حال كانت مساهمتك تحل علة ما تم التبليغ عنها في قسم الـ issues في مستودع المشروع على github، أو لها علاقة به، فإنه يمكنك الإشارة إلى تلك العلة في نص الإيداع فقط بوضع رقم العلة مسبوقا بعلامة #، مثال:</li></ul><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">git commit -m "fix for some bug (issue #23)"</pre><p style="margin-right: 40px;">ستلاحظ عند زيارة واجهة Github أن الرقم 23# في نص الإيداع، قد أصبح رابطا يحول مباشرة إلى صفحة تلك العلة.</p><ul><li>في حال قمت بعمل Fork وساهمت في المشروع، وأردت مرة أخرى أن تساهم في ذاك المشروع مجددا، فلا تنس أن تجعل مستودعك الشخصي من ذاك المشروع محدّثا، يعني اجلب التغيرات الجديدة التي طرأت على المستودع الأصلي، قبل المساهمة مجددا وعمل أي commit أو pull request، هذا يخفض من نسبة التعارض conflicts، ويسهّل عليك وعلى القائمين على المشروع عمليات الدمج، قد تكون التغيرات التي قمت بها، قد قام بها آخر، أو ربما تم حذف الملف الذي تعمل عليه أصلا من المشروع الأصلي، فيضيع جهدك هباءا منثورا.</li><li>من المحبذ أيضا، استعمال صيغة الأمر في نص الإيداع، مثال، استعمل "<strong>add something to file x</strong>" عوض "<strong>adding|added something to file x</strong>".</li></ul></div>
]]></description><guid isPermaLink="false">265</guid><pubDate>Fri, 29 Jan 2016 18:27:29 +0000</pubDate></item><item><title>&#x625;&#x639;&#x62F;&#x627;&#x62F; Git &#x644;&#x644;&#x645;&#x631;&#x629; &#x627;&#x644;&#x623;&#x648;&#x644;&#x649;</title><link>https://academy.hsoub.com/programming/workflow/git/%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF-git-%D9%84%D9%84%D9%85%D8%B1%D8%A9-%D8%A7%D9%84%D8%A3%D9%88%D9%84%D9%89-r260/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_01/first-time-git-setup.png.5b18b693d29c096e804ea9cff3e59c9c.png" /></p>

<div><p style="text-align: center;"><a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_01/first-time-git-setup.png.d750a550dda00cf314ad53266733c17d.png"><img data-fileid="12039" class="ipsImage ipsImage_thumbnailed" alt="first-time-git-setup.thumb.png.21c73d5a8" src="https://academy.hsoub.com/uploads/monthly_2016_01/first-time-git-setup.thumb.png.21c73d5a8aaecf168b06e237ef6fa5e7.png"></a></p><p>يأتي Git مُرفقا بأداة تُدعى<span style="font-family:courier new,courier,monospace;"> git config</span> والتي تسمح لك بقراءة إعدادات النظام وتغييرها والتحكم في كامل جوانب عمل Git. يتم حفظ هذه الإعدادات في الأماكن الثلاثة التالية:</p></div><div><ul><li><span style="font-family:courier new,courier,monospace;">etc/gitconfig/</span>: يحتوي هذا الملف على الإعدادات الخاصة بجميع المُستخدمين على نفس النظام/الجهاز أيّا كان المُستودع الذي يعملون عليه. في حال ما إذا قمت بتمرير خيار <span style="font-family:courier new,courier,monospace;">system--</span> إلى أمر <span style="font-family:courier new,courier,monospace;">git config</span> فسيكون بإمكانك قراءة وتعديل الإعدادات الموجودة في هذا الملف.</li><li><span style="font-family:courier new,courier,monospace;">gitconfig./~</span>: هذا الملف خاص بإعدادات المُستخدم الحالي فقط. بإمكانك قراءة الإعدادات من هذا الملف أو التعديل عليها عبر تمرير خيار <span style="font-family:courier new,courier,monospace;">global--</span> إلى الأمر<span style="font-family:courier new,courier,monospace;"> git config</span>.</li><li><span style="font-family:courier new,courier,monospace;">git/config.</span>: هذا الملف المتواجد داخل كل مُستودع يحتوي الإعدادات الخاصة بالمستودع الذي يحتويه فقط. في حال ما إذا قمت بحفظ الإعدادات في مُستوى مُعين فإنه سيتم تجاهل إعدادات المُستوى الذي يعلوه. بعبارة أخرى، سيتم أخذ إعدادات ملف <span style="font-family:courier new,courier,monospace;">git/config<span style="line-height: 22.4px; text-align: right;">.</span></span> بالحسبان لو وُجدت وتجاهل إعدادات ملف <span style="font-family:courier new,courier,monospace;">etc/gitconfig/</span>.</li></ul><p dir="RTL">على أنظمة Windows يقوم Git بالبحث عن ملف <span style="font-family:courier new,courier,monospace;">gitconfig.</span> داخل مُجلد <span style="font-family:courier new,courier,monospace;">HOME<span style="line-height: 22.4px;">$</span></span> أي داخل مُجلد <span style="font-family:courier new,courier,monospace;">C:\Documents and Settings\$USER</span> أو  <span style="font-family:courier new,courier,monospace;">C:\Users\$USER</span> حسب إصدار نظام التشغيل المُستخدم. كما أنه يبحث أيضا عن ملف<span style="font-family:courier new,courier,monospace;"> etc/gitconfig<span style="line-height: 22.4px;">/</span></span> والذي يكون داخل المُجلد الذي قررت تنصيب Git فيه.</p><h2 dir="RTL">هويتك على Git</h2><p dir="RTL">من بين الأمور التي يجب عليك القيام بها بمُجرد تنصيبك لنظام Git هو تحديد هويتك عليه ونقصد بذلك اسمك وعنوان بريدك الإلكتروني. هذه الخُطوة مُهمة لأن Git سيقوم بربط أي عملية تقوم بها بهذه الهوية، كما أن كل عملية إيداع ستقوم بها ستحمل هذه البيانات معها.</p><p dir="RTL">يتم تحديد هوية المُستخدم عبر الأمرين التاليين:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com</pre><p dir="RTL">من جديد، لن تحتاج إلى القيام بها الأمر سوى مرة واحد في حال ما إذا قمت بتمرير الخيار <span style="font-family:courier new,courier,monospace;">global--</span> للأمرين السابقين لأنه في هذه الحالة سيقوم Git باستخدام هذه الهوية مع جميع العمليات التي تتم على النظام/الجهاز الحالي. إذا رغبت في استخدام هوية مُختلفة مع مشاريع مُعينة فما عليك سوى تنفيذ الأمرين السابقين من دون تمرير الخيار<span style="font-family: 'courier new', courier, monospace; line-height: 22.4px;">global--</span>.</p><h2 dir="RTL">محرر النصوص الافتراضي</h2><p dir="RTL">الآن وبعد أن حددت هويتك على Git حان الأوان لاختيار مُحرر النصوص الذي ستستعمله لما يطلب منك Git كتابة رسالة أو تعليق على العمليات التي تقوم بها. في حال لم تقم باختيار مُحرر نصوص خاص فإن Git سيقوم باستخدام مُحرر النصوص الافتراضي لنظام التشغيل الخاص بك والذي عادة ما يكون Vi أو Vim. إن رغبت في استخدام مُحرر نصوص آخر وليكن Emacs فما عليك سوى تنفيذ الأمر التالي:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">$ git config --global core.editor emacs</pre><h2 dir="RTL">أداة Diff Tool</h2><p dir="RTL">خاصية أخرى تحتاج إلى إعداداها هي أداة diff tool والتي سيتم استخدامها لحل المشاكل المُتعلقة بعمليات الدمج. في حال ما إذا أردت استخدام <span style="font-family:courier new,courier,monospace;">vimdiff</span> مثلا فما عليك سوى تنفيذ الأمر التالي:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">$ git config --global merge.tool vimdiff</pre><p dir="RTL">يستطيع Git التعامل مع جُملة من الأدوات بشكل قياسي وهي كالتالي:</p><ul dir="rtl"><li>kdiff3</li><li>tkdiff</li><li>meld</li><li>xxdiff</li><li>emerge</li><li>vimdiff</li><li>gvimdiff</li><li>ecmerge</li><li>opendiff</li></ul><h2 dir="RTL">التحقق من الإعدادات</h2><p dir="RTL">إذا رغبت في التحقق من الإعدادات التي قمت بها فما عليك سوى تنفيذ الأمر:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint"> git config --list </pre><p dir="RTL">والذي يقوم بعرض النتائج على الشكل التالي:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">$ git config --list

user.name=Scott Chacon
user.email=schacon@gmail.com
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
...</pre><p dir="RTL">في حال ما إذا ظهرت قيم مُختلفة لنفس الخيار فهذا راجع إلى قراءة Git للإعدادات من أماكن مُختلفة ( /etc/gitconfigو ~/.gitconfig على سبيل المثال). في هذه الحالة فإن Git سيأخذ بالحسبان آخر قيمة في هذه القائمة.</p><p dir="RTL">بإمكانك أيضا التحقق من الإعدادات بشكل فردي على باستخدام الأمر git config {key} مع استبدال ما يجب استبداله في الأمر:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">$ git config user.name
Scott Chacon</pre><h2 dir="RTL">الحصول على المساعدة</h2><p dir="RTL">إن احتجت إلى أية مساعدة لدى استخدامك لنظام Git فيُمكنك الاستعانة بأحد الأوامر الثلاثة التالية للحصول على طريقة استخدام أي من أوامر Git:</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">$ git help
$ git --help
$ man git</pre><p dir="RTL">على النحو التالي (للحصول على شرح لأمر <span style="font-family:courier new,courier,monospace;">config</span>):</p><pre data-pbcklang="html" data-pbcktabsize="4" class="html ipsCode prettyprint">$ git help config</pre><p dir="RTL">هذه الأوامر مُفيدة جدا خاصة وأنها مُتوفرة دون الحاجة إلى اتصال إنترنت. إن كانت المصادر التي في حوزتك غير كافية وكنت تحتاج إلى مُساعدة شخصية ومباشرة فُيمكن زيارة قناتي git<span style="line-height: 22.4px;">#</span> و github<span style="line-height: 22.4px;">#</span> على خادوم Freenode IRC (على العنوان <span style="font-family:courier new,courier,monospace;">irc.freenode.net</span>)، ستجد فيهما مجموعة كبيرة من خبراء Git والذين لديهم الرغبة في مساعدة من يطلبون المُساعدة.</p><h1 dir="RTL">خلاصة</h1><p dir="RTL">بعد قراءتك لهذا المقال والمقالات السابقة التي نشرناها هنا فسيكون لديك فهم لأساسيات Git وفهم الاختلافات الموجودة بينه وبين باقي أنظمة إدارة النُسخ. سيكون لديك أيضا نظام Git جاهز للعمل على جهازك وإعدادات تضمن تضمين بياناتك الشخصية في كل عملية ستقوم بها. حان الآن الأوان للشروع في استخدام Git.</p><p dir="RTL">ترجمة -وبتصرف- للفصل <a rel="external nofollow" href="http://git-scm.com/book/en/Getting-Started-First-Time-Git-Setup">First-Time Git Setup</a> من كتاب <a rel="external nofollow" target="_blank" href="http://git-scm.com/book">Pro Git</a> لصاحبه <a rel="external nofollow" target="_blank" href="https://twitter.com/chacon">Scott Chacon</a>.</p></div>
]]></description><guid isPermaLink="false">260</guid><pubDate>Wed, 27 Jan 2016 19:42:03 +0000</pubDate></item><item><title>&#x645;&#x628;&#x627;&#x62F;&#x626; Git &#x627;&#x644;&#x623;&#x633;&#x627;&#x633;&#x64A;&#x629;</title><link>https://academy.hsoub.com/programming/workflow/git/%D9%85%D8%A8%D8%A7%D8%AF%D8%A6-git-%D8%A7%D9%84%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D8%A9-r256/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_01/git-basics.png.124e0776b09296f87062fcb2bb6d828b.png" /></p>

<p dir="RTL">
	كما سبق ذكره فإن أحد أهم الاختلافات ما بين Git وأنظمة إدارة النُسخ هو الطريقة التي ينظر ويتعامل فيها Git مع البيانات.
</p>

<p dir="RTL" style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_01/git-basics.png.3fd25c78d92f56f8e37a5cb016c7f872.png" data-fileid="11850" rel=""><img alt="git-basics.thumb.png.5eefe7ead2e4367c175" class="ipsImage ipsImage_thumbnailed" data-fileid="11850" src="https://academy.hsoub.com/uploads/monthly_2016_01/git-basics.thumb.png.5eefe7ead2e4367c175a332dcb8934ed.png"></a>
</p>

<p dir="RTL">
	مبدئيا تقوم أغلب أنظمة إدارة النُسخ بحفظ البيانات على شكل قائمة من التغيرات التي طرأت على الملفات. هذه الأنظمة (CVS, Subversion، Perforce، Bazaar وهلم جرا) تنظر إلى البيانات التي تقوم بإدارتها على أساس أنها ملفات إضافة إلى التغييرات الحاصلة في كل ملف مع مرور الوقت، مثلما هو مُوضح في الشكل 1.
</p>

<p dir="RTL" style="text-align: center;">
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="24621" data-unique="1bxaklx7r" src="https://academy.hsoub.com/uploads/monthly_2017_08/Figure-1-4.png.17b0af103fe679cb9699d662ce48891a.png" alt="Figure-1-4.png"></p>

<p dir="RTL" style="text-align: center;">
	<strong>الشكل 1: تقوم مُعظم الأنظمة بحفظ البيانات على هيئة الاختلافات الطارئة عليها مُقارنة بنسخة أولية من الملف.</strong>
</p>

<p dir="RTL">
	لا يتعامل Git مع البيانات على هذا النحو، بل يعتبر البيانات مجموعة من اللقطات Snapshots لنظام ملفات مُصغر. كل مرة تقوم فيها بإيداع البيانات (commit) أو تحفظ حالة مشروعك باستخدام Git، فإن ما يقوم به النظام هو التقاط صورة لما هي عليه الملفات في تلك اللحظة ويحفظها. ولجعل هذه الآلية فعالة فإنه لا يتم حفظ صور أخرى لنفس الملف ما إذا لم يتم إحداث تغييرات على الملف، بل يتم فقط الربط على الصورة السابقة. ينظر Git إلى البيانات التي يحفظها مثلما هو مُبين في الشكل 2.
</p>

<p dir="RTL" style="text-align: center;">
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="24622" data-unique="31w89b7f4" src="https://academy.hsoub.com/uploads/monthly_2017_08/Figure-1-5.png.c8fd548ad232c4ffe779b2da0db91842.png" alt="Figure-1-5.png"></p>

<p dir="RTL" style="text-align: center;">
	<strong>الشكل 2: يلتقط Git صورا على المشروع مع مرور الوقت.</strong>
</p>

<p dir="RTL">
	يُعتبر هذه الاختلاف في مبدأ العمل جوهريا، حيث يُعيد Git بشكل جذري تعريف كامل المفاهيم المُتعلقة بإدارة النُسخ التي توارثتها باقي الأنظمة عن الأنظمة التي سبقتها. هذا الاختلاف في مبدأ العمل يجعل Git أقرب ما يكون من نظام ملفات مُصغر منه إلى أنظمة إدارة النُسخ التقليدية، وهو ما مكّن من بناء أدوات في غاية القوة اعتمادا عليه. سنقوم باستعراض الفوائد المُترتبة عن مبدأ عمل Git المُختلف عن باقي الأنظمة لدى الحديث عن تفريعات Git في مقال لاحق.
</p>

<h2 dir="RTL">
	أغلب العمليات تتم بشكل محلي
</h2>

<p dir="RTL">
	أغلب العمليات التي يقوم بها Git تحتاج فقط إلى ملفات محلية ليتم تنفيذها وذلك من دون الحاجة إلى أية بيانات من خواديم بعيدة. هذه الخاصية تُعطي الانطباع بأن Git سريع جدا مُقارنة بغيره من أنظمة إدارة النُسخ نظرا لكون كامل ملفات وتاريخ المشروع الذي تعمل عليه مُتوفرة بشكل محلي على خلاف باقي الأنظمة التي تحتاج إلى الاتصال بأجهزة وخواديم أخرى.
</p>

<p dir="RTL">
	فعلى سبيل المثال فحتى ولو احتجت إلى إلقاء نظرة على تاريخ المشروع أو مقارنة نسخ قديمة منه فإنك لن تحتاج إلى الاتصال بخادوم بعيد للقيام بذلك حيث يقوم Git بقراءته والاحتفاظ به كاملا على جهازك المحلي.
</p>

<p dir="RTL">
	هذه الخاصية تسمح لك أيضا بمواصلة العمل على مشروعك حتى ولو لم يكن لديك اتصال إنترنت، حيث يُمكنك إيداع البيانات commit في انتظار أن يكون بمقدورك الاتصال بالإنترنت من جديد. على باقي أنظمة إدارة الإصدارات، مواصلة العمل لدى انقطاع الإنترنت هو إما أمر مُستحيل أو معقد جدا. على نظام Perforce لا يُمكن القيام بأي شيء ما لم تكن مُتصلا بالخادوم الذي يدار عليه المشروع، أما Subversion وCVS فيسمحان لك بتحرير الملفات لكن لا يُمكن إدراج التغييرات ما لم تكن متصلا بخادوم مشروعك. قد لا تبدو هذه الخاصية مُهمة جدا لكن تأثيرها كبير.
</p>

<h2 dir="RTL">
	المحافظة على سلامة الملفات
</h2>

<p dir="RTL">
	يتم التحقق من الملفات عبر عمليات checksum قبل حفظها، ومن ثم يتم استخدام ناتج هذه العملية (Cheksum) كمُعرف للملفات، يعني ذلك بأنه يستحيل تغيير مُحتوى ملف أو مُجلد من دون أن يعلم Git بذلك. هذه الخاصية هي إحدى الخواص التي بُني عليها Git والتي يعتمد عليها في الطبقات السُفلى من النظام، كما أنها جزء لا يتجزأ من المبادئ الأساسية التي بُني عليها. بفضل هذه الخاصية فإنه من غير المُمكن أن تفقد أية بيانات لدى نقلها أو أن يُصاب ملف ما بالعطب من دون أن يكون هناك لدى Git علم مُسبق بالأمر.
</p>

<p dir="RTL">
	يُطلق على الآلية التي يعتمد عليها Git للتحقق من الملفات اسم SHA-1 hash، تنتج عنها سلسلة نصية مُتكونة من 40 محرف ستعشري (الأرقام من 0 إلى 9 والحروف من a إلى f) ويتم حسابها اعتمادا على مُحتوى الملف أو المُجلد. سلاسل SHA-1 hash تكون مُشابهة للسلسلة التالية:
</p>

<p dir="RTL" style="text-align: center;">
	<strong>24b9da6552252987aa493b52f8696cd6d3b00373</strong>
</p>

<p dir="RTL">
	لدى استخدامك لنظام Git ستشاهد هذه السلاسل في كل مكان بحكم أنه يتم استخدامها كثيرا حيث أن Git يحفظ كل شيء اعتمادًا على Hash مُحتوى كل ملف وليس اعتمادًا على أسمائها.
</p>

<h2 dir="RTL">
	لا يقوم Git عادة سوى بإضافة بيانات
</h2>

<p dir="RTL">
	أغلب العمليات التي تقوم بها على Git تقوم بإضافة بيانات إضافية إلى قاعدة بيانات Git. من الصعب جدا أن تجعل النظام يقوم بعمليات لا يُمكن التراجع عنها أو حذف بيانات لا يُمكن استرجاعها. لدى استخدام باقي أنظمة إدارة النسخ فإنه من المُمكن أن تخسر أو تعبث ببيانات لم تقم بإدراجها بعد، لكن لدى القيام بعملية إدراج فإنه من الصعب جدا أن تفقدها خاصة ما إذا كنت تقوم بدفع البيانات إلى مستودع موجود على خادوم بعيد.
</p>

<p dir="RTL">
	هذا الأمر يجعل استخدام Git مُمتعا في حد ذاته، حيث أنه بإمكاننا القيام بأية تجارب نودها على مشاريعنا دون أن نعرض بياناتها للخطر.
</p>

<h2 dir="RTL">
	الحالات الثلاث للبيانات على Git
</h2>

<p dir="RTL">
	إن قرأت ما سبق ذكره على عجل، فيجب أن تركز جيدا في هذه الفقرة حيث أننا سنناقش المبدأ الأساسي الذي لا يُمكن لك استخدام Git ما لم تستوعبه جيدا. لدى استخدام Git فإن الملفات تملك إحدى الحالات الثلاث التالية: مرحلة الإيداع (ملفات تم إيداعها committed)، مرحلة التعديل (ملفات أجريت تعديلات عليها modified) ومرحلة الإدراج (ملفات تم إدراجها staged).
</p>

<p dir="RTL">
	المقصود بالإيداع commit هو أن حفظ البيانات بشكل آمن في قاعدة البيانات المحلية. الملفات التي تم تعديلها هي التي تم إدخال تغييرات عليها لكنه لم يتم حفظ تلك التغييرات إلى قاعدة البيانات المحلية بعد. أما الإدراج فهو تعليم الملفات التي تم تعديلها في حالتها الحالية ليتم تضمينها في الإيداع القادم.
</p>

<p dir="RTL">
	هذه الحالات الثلاث تُقسم مشاريع Git إلى 3 أقسام: مُجلد Git، مُجلد العمل، ومنطقة الإدراج.
</p>

<p dir="RTL" style="text-align: center;">
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="24623" data-unique="h9ivc08xx" src="https://academy.hsoub.com/uploads/monthly_2017_08/Figure-1-6_ar.png.f5ac487a6e3dfa012751ef9a46b3adc4.png" alt="Figure-1-6_ar.png"></p>

<p dir="RTL" style="text-align: center;">
	<strong>الشكل 3: مُجلد Git، مُجلد العمل ومنطقة الإدراج</strong>
</p>

<p dir="RTL">
	مُجلد Git هو المكان الذي يقوم النظام فيه بتخزين البيانات الوصفية metadata وقاعدة بيانات مشروعك، ويُعتبر الجزء الأهم من Git حيث أنه المُجلد الذي يتم نسخه لدى القيام بعملية استنساخ المُستودعات الموجودة على أجهزة أخرى.
</p>

<p dir="RTL">
	مُجلد العمل عبارة عن إصدار المشروع الحالي والذي يحتوي ملفات تم استخراجها من قاعدة بيانات Git ووضعها تحت تصرفك لإدخال التعديلات التي ترغب فيها عليها.
</p>

<p dir="RTL">
	منطقة الإدراج عبارة عن ملف واحد يتم الاحتفاظ به عادة داخل مُجلد Git والذي يحفظ معلومات حول المُحتوى الذي سيتم إرساله في الإيداع القادم. عادة ما تتم الإشارة إليه باسم الفهرس index لكن استخدام مُصطلح “منطقة الإدراج” staging area أصبح الأكثر شيوعا.
</p>

<p dir="RTL">
	سير عمل مشاريع Git يتم عادة على النحو التالي:
</p>

<ol>
<li>
		التعديل على الملفات الموجودة في مُجلد العمل.
	</li>
	<li>
		إضافة الملفات إلى منطقة الإدراج
	</li>
	<li>
		إيداع الملفات commit، أي التقاط صورة عن الملفات الموجودة في منطقة الإيداع وحفظها بشكل دائم داخل مُجلد Git.
	</li>
</ol>
<p dir="RTL">
	لتلخيص الأمر: إذا كان الملف موجودا داخل مُجلد Git فهذا يعني بأنه تم إيداعه committed. إذا تم إدخال تغييرات عليه وتم وضعه في منطقة الإيداع فهذا ملف مُدرج staged. أما إذا تم إحداث تغييرات عليه ولم يتم نقله إلى منطقة الإدراج فيُعتبر مُعدّلا. في مقال قادم سنتحدث بشكل أوسع حول الحالات الثلاث هذه وكيفية الاستفادة منها بشكل جيد، إضافة إلى كيفية تجاوز منطقة الإدراج بشكل كامل.
</p>

<p dir="RTL">
	ترجمة -وبتصرف- لـ <a href="http://git-scm.com/book/en/Getting-Started-Git-Basics" rel="external nofollow">Git Basics</a> من كتاب <a href="http://git-scm.com/book" rel="external nofollow">Pro Git</a> لصاحبه <a href="https://twitter.com/chacon" rel="external nofollow" target="_blank">Scott Chacon</a>.
</p>
]]></description><guid isPermaLink="false">256</guid><pubDate>Mon, 25 Jan 2016 20:16:00 +0000</pubDate></item><item><title>&#x645;&#x62F;&#x62E;&#x644; &#x625;&#x644;&#x649; &#x623;&#x646;&#x638;&#x645;&#x629; &#x625;&#x62F;&#x627;&#x631;&#x629; &#x627;&#x644;&#x646;&#x633;&#x62E; VCS</title><link>https://academy.hsoub.com/programming/workflow/git/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D8%A7%D9%84%D9%86%D8%B3%D8%AE-vcs-r248/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_01/into-version-control-system.png.d3fa0a0ce08e42b17ab71373f1345252.png" /></p>

<div>
	<p>
		<strong>ما هو نظام التحكّم في النسخ Git، ولماذا حرّي بك أن توليه اهتماما؟</strong>
	</p>

	<p style="text-align: center;">
		<a class="ipsAttachLink ipsAttachLink_image" data-fileid="11677" href="https://academy.hsoub.com/uploads/monthly_2016_01/into-version-control-system.png.a11eca191869f925c7dbcc78517fa34b.png" rel=""><img alt="into-version-control-system.thumb.png.b4" class="ipsImage ipsImage_thumbnailed" data-fileid="11677" src="https://academy.hsoub.com/uploads/monthly_2016_01/into-version-control-system.thumb.png.b4d27cf96f671f257b290dac51343fe1.png"></a>
	</p>
</div>

<div>
	<p dir="rtl">
		إن التحكّم في النّسخ، هو نظام يسجل التغيرات التي تحدث عبر الزمن على ملف أو مجموعة ملفات بحيث يمكنك الرجوع إلى مرحلة معينة (إصدار) لاحقًا. عمليا، يمكنك أن تقوم بهذا على جُل أنواع ملفات الحاسوب. إذا كنت تعمل كمصمم رسوميات أو ويب، مبرمج أو ما شابه وتريد طريقة لمتابعة جميع الإصدارات والتعديلات التي تجريها على صورة أو قالب ما (الأمر الذي سيعجبك بالتأكيد)، فإنه من الحكمة استعمال نظام إدارة الإصدارات <abbr title="Version Control Systems | أنظمة التحكم بالنُّسخ">VCS</abbr>. حيث يمكّنك من إرجاع الملفات إلى حالٍ كانت عليه سابقًا، أو إرجاع مشروع بأكمله، يمكنك أيضًا مقارنة التغيرات الحاصلة مع مرور الزمن، أو معرفة من قام بآخر تعديل قد يكون سبب خطأ ما، من أشَارَ إلى خطْبٍ  ما ومتى، وغيرهم المزيد. استخدامك لنظام إدارة الإصدارات يعني أيضًا أنه إذا قمت بعبث وتبعثرت أشياء، أو خسرت ملفات المشروع لسبب ما، يمكنك استرجاعها إلى حالها بسهولة. بل وبأدنى مشقة منك.
	</p>

	<h2 id="أنظمة-إدارة-إصدارات-المصدر-المحلية:32fe66f03885b8c71435f59e997e570a">
		أنظمة إدارة إصدارات المصدر المحلية
	</h2>

	<p dir="rtl">
		الطريقة المثلى لدى كثير من الناس في التحكّم النسخ، هي نَسخ الملفات في مجلد مغاير (قد يكون مُعّلما بالزمن، في حالة كان الشخص حذِقا). هذا النهج منتشر بكثرة لبساطته، لكنه وبشكل مفرط، مَدعاة للغلط. فمن السهل نسيان أيٌ من المجلدات أنت فيها فتكتب عن غير قصد في الملف الخطأ، أو تنسخ فوق ملفات لم تكن تعنيها. للتعامل مع هذا المشكل، عمل المبرمجون قديما على تطوير VCSs مزودة بقاعدة بيانات بسيطة تحفظ جميع التغيرات التي تطرأ على الملفات التي هي تحت إدارة المراجعة (انظر الصورة).
	</p>

	<p style="text-align: center;">
		<a class="ipsAttachLink ipsAttachLink_image" data-fileid="25094" href="https://academy.hsoub.com/uploads/monthly_2017_09/1local.png.3a624e890d23b08aa2a9c576ba26c0c1.png" rel=""><img alt="1local.png" class="ipsImage ipsImage_thumbnailed" data-fileid="25094" data-unique="kkvcpd5ge" src="https://academy.hsoub.com/uploads/monthly_2017_09/1local.thumb.png.a9c8212d1b4666122a62b1be0be73b67.png"></a>
	</p>

	<p dir="rtl">
		إحدى أدوات <abbr title="Version Control Systems | أنظمة التحكم بالنُّسخ">VCS</abbr> الأكثر شعبية كان نظاما تدعى rcs والتي لا تزال تُوّزع مع العديد من حواسيب اليوم. حتى نظام OS X المشهور يحوي أمر rcs عند تنصيبك لأدوات المطور، تعمل هذه الأداة أساسا بحفظ مجموع الرقع (أي الاختلافات الحاصلة بين الملفات) بين كل عملية تغيير واحدة ومثيلتها في هيئة خاصة على القرص الصلب، يمكنها بهذا إعادة إنشاء أي ملف بنفس الهيئة التي كان عليها في نقطة ما من الزمن عن طريق دمج الرقع.
	</p>

	<h2 id="أنظمة-إدارة-إصدارات-المصدر-المركزية:32fe66f03885b8c71435f59e997e570a">
		أنظمة إدارة إصدارات المصدر المركزية
	</h2>

	<p dir="rtl">
		المشكل الكبير التالي الذي واجه المستخدمين هو حاجتهم إلى التعاون مع مُبرمجين آخرين على أنظمة تشغيل أخرى. ولحل هذا المُشكل تم تطوير أنظمة لإدارة إصدارات المصدر مركزية (CVCSs). تستخدم هذه الأنظمة، مثل كل من CVS ،Subversion أو Perforce خادوما واحدا يحتوي كل الملفات التي نقوم بإدارة إصداراتها، إضافة إلى مجموعة من العملاء الذين يقومون باسترجاع الملفات من هذا الخادوم المركزي. ظلت هذه الأنظمة لسنوات عديدة المعيار القياسي لأنظمة إدارة إصدارات المصدر.
	</p>

	<p dir="rtl">
		توفر هذه الأنظمة مزايا عديدة خاصة إذا ما قارناها بأنظمة إدارة الإصدارات المحلية، فعلى سبيل المثال يُمكن للجميع –إلى حد مُعين من الدقة- معرفة ما الذي يقوم به الجميع على المشروع، كما أن للمدراء القدرة على التحكم بشكل دقيق فيما يُمكن لأي مشارك أن يقوم به. دون أن ننسى أنه من الأسهل التعامل مع نظام إدارة إصدارات مركزي مقارنة مع إدارة قواعد بيانات على جهاز كل مشارك. في المقابل، تأتي هذه الأنظمة مرفقة ببعض العيوب والتي قد يكون أخطرها هو اعتماد النظام على نقطة مركزية وحيدة، فإن تعطل الخادوم لساعة من الزمن، فإنه من غير المُمكن لأي كان أن يتشارك التحديثات التي تمت خلال تلك الفترة. أما لو تعرض القرص الصلب على الخادوم لعطب، فإنه -ما لم يتم أخذ نسخ احتياط قبل حصول ذلك- فإن احتمال فقدان المشروع بكامل تاريخه أمر وارد جدا، باستثناء النسخ المحلية المتواجدة على أجهزة المتعاونين في المشروع.
	</p>

	<h2 dir="rtl">
		أنظمة إدارة الإصدارات الموزعة
	</h2>

	<p dir="rtl">
		ولمثل هذه الأوضاع ظهرت أنظمة إدارة الإصدارات المُوزعة (DVCSs). في مثل هذه الأنظمة كـ Git ،Mercurial ،Bazaar أو Darcs فإن ما يقوم به المستخدمون ليس مُجرد التحقق من آخر إصدار للملفات، لكن يقومون بإخذ نسخ كاملة عن المستودعات التي يعملون عليها. وعليه، فإن تعرض الخادوم لأي خلل فإنه يُمكن مواصلة العمل عبر نسخ المستودع الموجود على أي من أجهزة المستخدمين بحكم أن أي عملية تحقق يقوم بها المستخدم هي عبارة عن عملية نسخ احتياطي كامل لكامل بيانات المشروع (انظر الصورة التالية).
	</p>

	<p dir="rtl" style="text-align: center;">
		<a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2017_09/59cf74d403908_3distributed(1).png.aa5594307b30784a64fa436cccb9cb87.png" data-fileid="25096" rel=""><img class="ipsImage ipsImage_thumbnailed" data-fileid="25096" data-unique="t9nnhpv1u" src="https://academy.hsoub.com/uploads/monthly_2017_09/59cf74d4361fd_3distributed(1).thumb.png.3b58e39917defab3b3851f465587fa7c.png" alt="3distributed (1).png"></a>
	</p>

	<p dir="rtl">
		وعلاوة على ذلك، فإن العديد من هذه الأنظمة المُوزعة تتعامل بشكل جيد مع المشاريع التي تملك عدة مستودعات تعمل عليها مجموعات مختلفة من المستخدمين بطرق مختلفة وضمن نفس المشروع. هذا الأمر يسمح باعتماد مهام لسير العمل لم يكن بالإمكان اعتمادها على الأنظمة المركزية مثل النماذج الهرمية.
	</p>

	<p dir="rtl">
		ترجمة -وبتصرف- لـ <a href="http://git-scm.com/book/en/Getting-Started-About-Version-Control" rel="external nofollow">About Version Control</a>  من كتاب <a href="http://git-scm.com/book" rel="external nofollow">Pro Git</a> لصاحبه <a href="https://twitter.com/chacon" rel="external nofollow">Scott Chacon</a>.
	</p>
</div>
]]></description><guid isPermaLink="false">248</guid><pubDate>Thu, 21 Jan 2016 20:32:00 +0000</pubDate></item><item><title>&#x645;&#x62F;&#x62E;&#x644; &#x625;&#x644;&#x649; &#x646;&#x638;&#x627;&#x645; &#x627;&#x644;&#x62A;&#x62D;&#x643;&#x645; &#x641;&#x64A; &#x627;&#x644;&#x646;&#x633;&#x62E; Git</title><link>https://academy.hsoub.com/programming/workflow/git/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D9%86%D8%B8%D8%A7%D9%85-%D8%A7%D9%84%D8%AA%D8%AD%D9%83%D9%85-%D9%81%D9%8A-%D8%A7%D9%84%D9%86%D8%B3%D8%AE-git-r240/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2016_01/git-intro.png.24de8532882b77a0c4788b0bc581f45d.png" /></p>

<p>ما هو Git، ولماذا كل هذا الاهتمام المتزايد به؟ هل أحتاج فعلا إلى استعماله؟ هل سأصبح مُبرمجا من الدرجة الثانية لو لم تكن لدي أدنى فكرة حول ماهية Git؟  كيف لي أن أستعمله لأزيد مردوديتي البرمجية؟ هل سأصبح [ضع أي وصف هنا] لو استعملت Git؟</p><p>هذا المقال سيحاول الإجابة على بعض هذه الأسئلة، يُشوقك للبحث عن إجابات لأخرى، أو يدفعك لقراءة المقال إلى آخره لترى إن كانت هناك أية إجابة على السؤال الأخير.</p><p style="text-align: center;"><a href="https://academy.hsoub.com/uploads/monthly_2016_01/git-intro.png.1dbce9940355bdfbdbf592cf30cab489.png" class="ipsAttachLink ipsAttachLink_image"><img data-fileid="11853" src="https://academy.hsoub.com/uploads/monthly_2016_01/git-intro.thumb.png.f3273f170e7b0602df8f7633c6ce4ded.png" class="ipsImage ipsImage_thumbnailed" alt="git-intro.thumb.png.f3273f170e7b0602df8f"></a></p><p>فلنبدأ ببساطة وبكلام يفهمه الجميع، … ما هو Git؟</p><ul><li>هل هو لغة برمجة؟ – لا</li><li>هل هو قاعدة بيانات؟ – لا</li><li>هل هو نظام تشغيل؟ – لا</li></ul><p>(جميع هذه الأسئلة وردتني شخصيا)</p><p><strong>إذا ماهو Git؟ وما وظيفته بالتحديد؟</strong></p><p>لفهم ماهيته، علينا أولا فهم المشكلة التي أدّت إلى وجوده، فخذ هذا كمثال بسيط، وأسقطه على نفسك لتفهم المشكلة.</p><h2 id="المشكلة:a83f70c9d70986ba56d90c0e4331bb15">المشكلة</h2><p>أنت مبرمج أو مطور ويب، تعمل على مشروع ما، سهرت الليالي فرحًا، لقد حققت تقدما وإنجازا في مشروعك، مرّت بضعة أيام أو بضعة أسابيع، فإذ بك تجد نفسك في مشكلة، كتبت شفرة برمجية عاثت في مشروعك فسادًا، وليتك تستطيع الرجوع للوراء، أو وصلت إلى مرحلة أين يشتغل فيها المشروع بشكل جيد، لكنك تخاف أن تُفسد الخطوة التالية عليه، ﻷنك لست متأكدا أن الميزة القادمة التي ستبرمجها في المشروع ستتكامل معه ولن تقلبه رأسا على عقب، حسنا، أنت شخص ذكي (ربما أنت بلال؟)، لن تقع في فخ كهذا!</p><p>تبدأ بإنشاء مجلد يحوي المشروع في حالته الحالية، وإن كنت حَذِقا زيادة، ستعطي المجلد اسما بتاريخ اليوم وتوقيته، وتعمل على نسخة أخرى منه في مجلد آخر، وهكذا تفعل في كل مرة يتكرر المشكل، وبهذا يسهل عليك الرجوع إلى حالة المشروع السابقة في حال سارت الأمور علي عكس ما كنت تُخطط له مستقبلا.</p><p style="text-align: center;"><a class="ipsAttachLink ipsAttachLink_image" href="https://academy.hsoub.com/uploads/monthly_2016_01/Screenshot_from_2016-01-17_21-41-13.png.5019cede29d6f29840ec86950d9ff5de.png"><img data-fileid="11492" class="ipsImage ipsImage_thumbnailed" alt="Screenshot_from_2016-01-17_21-41-13.thum" src="https://academy.hsoub.com/uploads/monthly_2016_01/Screenshot_from_2016-01-17_21-41-13.thumb.png.f9d72e356290b68d4bcda67b3562cf91.png"></a></p><p>مرّ مزيد من الوقت، كَبُر المشروع، أصبحتَ مرّة تتكاسل عن إنشاء مجلد جديد ﻷنه ليس لديك وقت لهذا، ومرّة تريد الرجوع إلى حالة سابقة للمشروع لاسترجاع جزء من الشفرة البرمجية في الملف الفلاني كانت تعمل بشكل أفضل،<strong> </strong>دقيقة، <strong>متى كان هذا؟ أين وضعت ذاك المجلد؟</strong> ما كل هذه المجلدات الكثيرة! <strong>أيّها هي المجلد الذي أحتاجه؟</strong> حسنا لقد وجدته، أين كانت تلك الشفرة البرمجية حينذاك <strong>وفي أي ملف؟!</strong> ضاعت الدقائق والساعات، وضاع الجهد والسّهر.</p><p>مرّ مزيد من الوقت، لقد كبُر المشروع أكثر، بل وزادت أهميته ومسؤوليته، انضم إلى مشروعك أشخاص آخرون، أصدقاؤك المبرمجون يتعاونون معك لتطويره، أو زملاؤك في العمل يتشاركون فيه، أنتم فريق رائع وذكي، لقد وجدتم طريقة لتشارك الشفرة البرمجية، تتراسلونها عبر البريد، أو ترفعونها على خادوم شركتكم البعيد، أو تضعونها على خادومكم الخاص بكل تأكيد، أو ربما ترفعونها على إحدى خدمات التخزين مثل Dropbox.</p><p>مهلا، فُلان أضاف شيئا في المشروع، في نفس الوقت أضفت أنت أيضا شيئا فيه، <strong>كيف أدمج نسخته مع النسخة التي لدي؟!</strong> مشكلة، لقد كتبنا شفرة في نفس الموضع، لتقوم بنفس العمل، <strong>فأي الشفرتين أفضل؟</strong></p><p>قد تحرّيت الوضع وتبين أن لكلا الشفرتين مزايا وعيوب، <strong>فكيف أدمج مزايا الشفرتين في واحدة؟</strong> في نفس الوقت أرسل زيد وسعيد شفرتيهما، أنت مدير المشروع وعلى مسؤوليتك دمج التغيرات التي يُرسلها الفريق، لقد أرفق زيد رسالة وقال يمكنك أن تبدل الملف الفلاني بالملف الذي أرسلته ولا تخف، وقال أنه أفضل من الملف الذي أرسله سعيد، صدّقت زيدًا وتخطيت سعيدا، وتسرعت في استبدال الملف وأنت سعيد، وإذا بالملف يُفسد عليك كامل المشروع، ولا تملك نسخة منه  بالحالة التي كان عليها لا من قريب ولا من بعيد،… زيدٌ ذاك له منّي أشد وعيد!</p><p>وضاعت دقائق وساعات أخرى.</p><h2 id="الحل:a83f70c9d70986ba56d90c0e4331bb15">الحل</h2><p>لست وحدك في هذا المشكل، فلقد عانى منه المبرمجون قديما، وعملوا على حلّه بتطوير أدوات تتولى أو تسهّل عليهم حفظ التغيرات التي يجرونها عبر الزمن على ملفات الشفرة البرمجية، وتسجيلها (أي التغيّرات) في قاعدة بيانات تحفظ <strong>الفروقات</strong> بين نُسَخ الشفرة البرمجية <strong>عبر الزمن</strong>، بحيث يمكن الرجوع إلى نسخة معينة، في مرحلة معينة من الشفرة البرمجية، <strong>تماما كما كانت عليه وقت حفظها</strong>. ليس هذا وحسب، حيث يمكن للأداة أن تدمج التغيرات التي أجراها أكثر من شخص بعضها ببعض، وتُعلمك بوجود تضاربات بين شفرة فلان وعلان في الملف الفلاني من سطر كذا إلى سطر كذا.</p><p>بل وتطورت هذه الأدوات أكثر، وأصبحت تتولى مهمة رفع التغيرات التي أجريتها إلى خادوم بعيد (عبر إنشاء ما يُعرف بالمستودع أو Repository على الخادوم)، أو جلب التغيرات التي أجراها الآخرون من خادوم بعيد (من المستودع)، بل وحتى أكثر من خادوم في نفس الوقت، ثم مساعدتك في عرض الفروقات Diffs بين النُّسخ، ودمج أحدث التغيرات في نسخة واحدة.</p><p>سمّوا هذه الأدوات بعدة مسمّيات تصب كلّها في نفس المعنى، من ذلك:</p><ul><li>نظام التحكم في النسخ، بالانجليزية: Version Control System أو اختصارًا: <abbr title="Version Control Systems | أنظمة التحكم بالنُّسخ">VCS</abbr>، وهذا المُسمّى أشهرهم.</li><li>نظام التحكم بالمصدر، بالانجليزية: Source Control.</li><li>نظام التحكم بالمراجعات، بالانجليزية: Revision Control.</li><li>إدارة الشفرة المصدرية، بالانجليزية: Source Code Management وتختصر إلى: SCM.</li></ul><p>كلها مسمّيات يُقصد بها الأداة التي تقوم بتسجيل التغيرات التي تحدث عبر الزمن على ملف أو مجموعة ملفات بحيث يمكن الرجوع إلى مرحلة معينة (نسخة، أو إصدار) لاحقًا. ماهي التغيرات التي حصلت، ما هي التعارضات الموجودة بين نسختين لنفس الملف، من قام بكتابة الشفرة الفلانية، ومن سبب مشكلا ما، ومن عمل على حل المشكل الفلاني. وغير ذلك المزيد.</p><p>من بين تلك الأدوات، نعرض أشهرها عبر الزمن، وهي:</p><ul><li><strong>rcs</strong> وقد كانت من بين أشهر الأدوات. حتى نظام  OS X المشهور يحتوي على أمر rcs عند تنصيبك لأدوات المطور، تعمل هذه الأداة أساسا على حفظ مجموع الرُّقع (أي الاختلافات الحاصلة بين الملفات)  بين كل عملية تغيير  ومثيلتها في هيئة خاصة على القرص الصلب، يمكنها بهذا إعادة إنشاء أي ملف بنفس الهيئة التي كان عليها في نقطة ما من الزمن عن طريق دمج الرقع، لكنها أداة بدائية في حال كان يعمل على المشروع أكثر من شخص.</li><li><strong>أنظمة التحكم بالنُّسخ المركزية</strong>، أو Centralized Version Control Systems وتعرف اختصارا بـ CVCSs، جاءت لتحل المشكل الكبير التالي الذي واجه المستخدمين، وهو حاجتهم إلى التعاون مع مُبرمجين آخرين على أنظمة تشغيل أخرى. تستخدم هذه الأنظمة، مثل كل من CVS، Subversion أو Perforce خادوما واحدا يحتوي كل الملفات التي نقوم بالتحكّم في نُسَخها، إضافة إلى مجموعة من العملاء الذين يقومون باسترجاع الملفات من هذا الخادوم المركزي. ظلت هذه الأنظمة لسنوات عديدة المعيار القياسي لأنظمة التحكم في النّسخ <abbr title="Version Control Systems | أنظمة التحكم بالنُّسخ">VCS</abbr>.</li><li><strong>أنظمة التحكم في النّسخ المُوزعة</strong> أو Distributed Version Control Systems و تعرف اختصارًا بـ DVCSs. في مثل هذه الأنظمة كـ Git، Mercurial، Bazaar أو Darcs فإن ما يقوم به المستخدمون ليس مُجرد التحقق من آخر نسخة من الملفات، لكن يقومون أيضا بأخذ نُسَخٍ كاملة عن المستودعات التي يعملون عليها. وعليه، فإن، وفي حال ما إذا تعرّض الخادوم لأي خلل، فإنه يُمكن مواصلة العمل عبر نَسْخ المستودع الموجود على أي من أجهزة المستخدمين بحكم أن أي عملية التحقق التي يقوم بها المستخدم هي عبارة عن عملية نسخ احتياطي لكامل بيانات المشروع.</li></ul><p><strong>كل هذه تدخل تحت مسمّى <abbr title="Version Control Systems | أنظمة التحكم بالنُّسخ">VCS</abbr>.</strong></p><p><strong>أما Git</strong>، فيعتبر نقلة نوعية في عالم <abbr title="Version Control Systems | أنظمة التحكم بالنُّسخ">VCS</abbr> بشكل عام، ﻷنه جاء بإدارة التفرعات (branches) المتوازية وإعادة دمجها مع بعض، وهو الأمر الذي كان يُعدّ كابوسا في الأدوات القديمة مثل CVS. وللأمانة، فإن Git ليس أول نظام جاء بهذه الفكرة، بل سبقه إليها bitkeeper لكنه لم يكن برنامجا مجانيا ولا حرّا، وبالتالي فإن Git أوّل نظام حر ومجاني يأتي بإدارة التفرعات المتوازية (mercurial أيضا جاء بها وهو حر مجاني، وقد تم تطويرهما أصلا ليكونا بديلا لـbitkeeper).</p><p><strong>إذا، إجابة على السؤال الأول، ماهو Git؟ </strong>باختصار هو:</p><p>نظام التحكم في النسخ الموزّع غير المركزي، وهي جملة يُفترض أنه يمكنك فهمها الآن.</p><h2 id="أسئلة-شائعة:a83f70c9d70986ba56d90c0e4331bb15">أسئلة شائعة:</h2><h3>هل تعلّم Git صعب؟ وهل يحتاج أن يكون لدي خلفية برمجية؟</h3><p>لا، ليس صعبا، وليس غاية في حد ذاته، فهو فقط أداةٌ وسيلة، تعلمّها يأتي بالتمرّس، فقط بضعة أوامر ستتعود عليها وتصبح بداهة مع مرور الزمن، ولن تحتاج إلى أي خلفية برمجية. عليك البدء في إدخاله في سير عملك، واعلم أنك ستربح الوقت به ولن تضيعه.</p><h3>قلت أوامر؟؟ أنا أخاف من الطرفية، هل له واجهات رسومية؟!</h3><p>نعم، له عدة واجهات رسومية على مختلف أنظمة التشغيل، لكنه من غير المحبذ للمبتدئ أن يبدأ بها، بل من المستحسن أن يصبر مع الطرفية ليفهم آلية عمله جيدا، ثم له أن ينتقل لما يصل لمرحلة متقدمة، ولو أن حتى المتقدمين لا يزالون يفضلون الطرفية.</p><h3>هل يعمل على Linux فقط؟ هل له نسخة Windows؟</h3><p>يعمل على جميع الأنظمة المعروفة، سواء Linux ،Mac أو Windows بل حتى على أنظمة أخرى، ويعمل بنفس الكيفية وبنفس الأوامر، الشي الوحيد الذي يختلف نوعا ما هو طريقة التنصيب.</p><h3>هل يمكن التحكم بنُسخ الملفات غير البرمجية؟ كأنواع الملفات الأخرى؟</h3><p>نعم، يمكن الإستفادة من Git في التحكم بنُسخ الملفات على اختلاف أنواعها، فإن كنت مثلا مصمما، أو كاتبا، أو مهندسا معماريا أو ما شابه، فإنه يمكن إدارة نسخ الملفات التي تعمل عليها بنفس الطريقة. لكن الملفات التنفيذية أو غير النصية يصعب معرفة ما تغير فيها عبر الزمن وعرض الفروقات فيها أو بينها، نظرًا لطبيعتها (binary).</p><h3>هل يجب وجود خادوم بعيد للعمل بـ Git؟</h3><p>لا، بتاتا، يمكن إنشاء المستودعات على حاسوبك، وإبقائه عندك ولن تحتاج ﻷي خادوم بعيد.</p><h3>كيف يُنطق Git؟</h3><p>ينطق چيت، بنفس الجيم التي ينطقون بها في مصر.</p><center><audio controls=""><br><source type="audio/ogg" src="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=11212"></source><br><source type="audio/mpeg" src="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=11211"></source><br>متصفحك لا يدعم تشغيل ملفات الصوت.</audio></center><h3>من طور Git؟</h3><p>نفسه من بدأ بتطوير نواة Linux، وهو <a rel="external nofollow" href="https://ar.wikipedia.org/wiki/%D9%84%D9%8A%D9%86%D9%88%D8%B3_%D8%AA%D9%88%D8%B1%D9%81%D8%A7%D9%84%D8%AF%D8%B3">Linus Torvalds</a>.</p><h3>ما معنى كلمة Git؟</h3><p>تعني شخصا غبيا أو لنقل أحمقا، وهي كلمة عامية بريطانية، وهو ما قد يشعر به المرء لما يكتشف أنه ضيع سنوات دون استعماله.</p><p> </p><p>آمل أن أكون قد وُفقت في شرح ماهية Git بشكل خاص و <abbr title="Version Control Systems | أنظمة التحكم بالنُّسخ">VCS</abbr> بشكل عام.</p><p>إذا كان لديكم أية أسئلة إضافية أو اقتراحات، فاطرحوها بالتعليقات وسيتم تحديث الموضوع.</p>
]]></description><guid isPermaLink="false">240</guid><pubDate>Fri, 15 Jan 2016 10:17:00 +0000</pubDate></item></channel></rss>
