-
1. شروع به کار
- 1.1 دربارهٔ کنترل نسخه
- 1.2 تاریخچهٔ کوتاهی از گیت
- 1.3 گیت چیست؟
- 1.4 خط فرمان
- 1.5 نصب گیت
- 1.6 اولین راهاندازی گیت
- 1.7 کمک گرفتن
- 1.8 خلاصه
-
2. مقدمات گیت
- 2.1 دستیابی به یک مخزن گیت
- 2.2 ثبت تغییرات در مخزن
- 2.3 دیدن تاریخچهٔ کامیتها
- 2.4 بازگردانی کارها
- 2.5 کار با ریموتها
- 2.6 برچسبگذاری
- 2.7 نامهای مستعار در گیت
- 2.8 خلاصه
-
3. شاخهسازی در گیت
- 3.1 شاخهها در یک کلمه
- 3.2 شاخهسازی و ادغام مقدماتی
- 3.3 مدیریت شاخه
- 3.4 روند کاری شاخهسازی
- 3.5 شاخههای ریموت
- 3.6 ریبیسکردن
- 3.7 خلاصه
-
4. گیت روی سرور
- 4.1 پروتکلها
- 4.2 راهاندازی گیت در سرور
- 4.3 ساختن کلید عمومی SSH
- 4.4 نصب و راهاندازی سرور
- 4.5 دیمن گیت
- 4.6 HTTP هوشمند
- 4.7 گیتوب
- 4.8 گیتلب
- 4.9 گزینههای شخصی ثالث میزبانی شده
- 4.10 خلاصه
-
5. گیت توزیعشده
- 5.1 روندهای کاری توزیعشده
- 5.2 مشارکت در یک پروژه
- 5.3 نگهداری یک پروژه
- 5.4 خلاصه
-
6. GitHub
-
7. Git Tools
- 7.1 Revision Selection
- 7.2 Interactive Staging
- 7.3 Stashing and Cleaning
- 7.4 Signing Your Work
- 7.5 Searching
- 7.6 Rewriting History
- 7.7 Reset Demystified
- 7.8 Advanced Merging
- 7.9 Rerere
- 7.10 Debugging with Git
- 7.11 Submodules
- 7.12 Bundling
- 7.13 Replace
- 7.14 Credential Storage
- 7.15 Summary
-
8. Customizing Git
- 8.1 Git Configuration
- 8.2 Git Attributes
- 8.3 Git Hooks
- 8.4 An Example Git-Enforced Policy
- 8.5 Summary
-
9. Git and Other Systems
- 9.1 Git as a Client
- 9.2 Migrating to Git
- 9.3 Summary
-
10. Git Internals
- 10.1 Plumbing and Porcelain
- 10.2 Git Objects
- 10.3 Git References
- 10.4 Packfiles
- 10.5 The Refspec
- 10.6 Transfer Protocols
- 10.7 Maintenance and Data Recovery
- 10.8 Environment Variables
- 10.9 Summary
-
A1. پیوست A: Git in Other Environments
- A1.1 Graphical Interfaces
- A1.2 Git in Visual Studio
- A1.3 Git in Visual Studio Code
- A1.4 Git in Eclipse
- A1.5 Git in IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.6 Git in Sublime Text
- A1.7 Git in Bash
- A1.8 Git in Zsh
- A1.9 Git in PowerShell
- A1.10 Summary
-
A2. پیوست B: Embedding Git in your Applications
- A2.1 Command-line Git
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. پیوست C: Git Commands
- A3.1 Setup and Config
- A3.2 Getting and Creating Projects
- A3.3 Basic Snapshotting
- A3.4 Branching and Merging
- A3.5 Sharing and Updating Projects
- A3.6 Inspection and Comparison
- A3.7 Debugging
- A3.8 Patching
- A3.9 Email
- A3.10 External Systems
- A3.11 Administration
- A3.12 Plumbing Commands
3.1 شاخهسازی در گیت - شاخهها در یک کلمه
تقریباً همهٔ VCSها نوعی پشتیبانی از شاخهسازی دارند. شاخه یا شعبهسازی (Branching) به معنی این است که شما از مسیر اصلی توسعه جدا شده و به ادامهٔ کار، بدون خرابی به بار آوردن در مسیر اصلی بپردازید. در بسیاری از VCSها این فرآیندی کموبیش پرهزینه است. اغلب شما را مجبور میکند که کپی جدیدی از پوشه سورس کدتان بگیرید که در پروژههای عظیم وقت زیادی را میگیرد.
برخی مدل شاخهسازی گیت را «خفنترین ویژگی» گیت میداند و به طور قطع این ویژگی جایگاه خاصی به گیت در جامعه VCS داده است. چرا این ویژگی اینچنین خاص است؟ طریقه شاخهسازی در گیت بسیار سبکوزن است به گونهای که آنرا تقریباً بلادرنگ میکند، همچنین رفتوآمد بین شاخهها هم معمولاً به همان اندازه سریع است. بیتشابه به اکثر دیگر VCSها، گیت روند کاری را به شاخهشدن و مرج شدن سوق میدهد، حتی به اندازهای که چند بار در روز این کار انجام شود. فهم درست و خبره شدن در این قابلیت به شما ابزار یکتا و قدرتمندی میدهد و میتواند به کلی نحوه توسعهدادن کارتان را تغییر دهد.
شاخهها در یک کلمه
برای اینکه به راستی نحوهٔ شاخهسازی گیت را درک کنید، باید یک قدم به عقب برگردیم و نحوهٔ ثبت اطلاعات گیت را مطالعه کنیم.
همانطور که از شروع به کار به یاد دارید، گیت دادهها را به عنوان دستهای از تغییرات یا تفاوتهایی بین فایلها ذخیره نمیکند؛ بلکه اطلاعات را به عنوان مجموعهای از اسنپشاتها ذخیره میکند.
وقتی یک کامیت میسازید، گیت یک آبجکت کامیت که شامل یک نشانگر به اسنپشات دربرگیرندهٔ اطلاعات صحنهٔ شماست را ذخیره میکند. این آبجکت همچنین شامل نام نویسنده و آدرس ایمیل او، پیغامی که وارد کردهاید و یک نشانگر به کامیت یا کامیتهایی که مستقیماً قبل این کامیت (والد یا والدین) آمدهاند است: صفر والد برای کامیت اولیه، یک والد برای یک کامیت معمولی و چند والد برای یک کامیت مرج حاصل یک یا چند برنچ.
برای ملموس کردن این موضوع، فرض را بر این بگذاریم که پوشهای حاوی سه فایل داریم و شما همهٔ آنها را استیج و کامیت میکنید. استیج کردن فایلهای برای هر کدام از آنها یک چکسام (هش SHA-1 که درشروع به کار ذکر کردیم) محاسبه میکند، آن نسخه از فایل را در مخزن گیت ذخیره میکند، (گیت از این فایلهای با نام بلاب یاد میکند) و آن چکسام را به استیج اضافه میکند:
$ git add README test.rb LICENSE
$ git commit -m 'Initial commit'
وقتی کامیتی را با اجرای git commit
میسازید، گیت همهٔ زیرپوشهها (در مثال فقط روت پروژه) را چکسام میکند و آنها را به عنوان یک آبجکت درخت در مخزن گیت ذخیره میکند.
سپس گیت یک کامیت آبجکت که متادیتا و نشانگری که به روت درخت پروژه دارد میسازد تا بتواند اسنپشات پروژه را هنگامی که نیاز بود بازسازی کند.
مخزن گیت شما حالا پنج آبجکت دارد: سه بلاب (هر کدام نماینده محتوای یکی از سه فایل هستند)، یک درخت که محتویات پوشه را لیست میکند و تعیین میکند که چه فایل نامهایی در چه بلابهایی ذخیره شدهاند و یک کامیت با نشانگری به روت آن درخت و تمام متادیتای خود کامیت.
اگر تغییری ایجاد کنید و دوباره کامیت بگیرید، کامیت بعدی نشانگری را به کامیتی که دقیقاً قبل از آن آمده در خود ذخیره میکند.
یک برنچ گیت یک نشانگر سبکوزن قابل انتقال به یکی از این کامیتهاست.
نام پیشفرض برنچ در گیت master
است.
همچنان که کامیت میسازید، یک برنچ master
برایتان ساخته میشود که به آخرین کامیتی که ساختهاید اشاره میکند.
هر بار که کامیت میکنید نشانگر برنچ master
به طور خودکار به جلو حرکت میکند.
یادداشت
|
برنچ «master» در گیت برنچ خاصی نیست.
این برنچ دقیقاً مشابه هر برنچ دیگری است.
تنها دلیلی که تقریباً همهٔ مخزنها یک برنچ با این نام دارند این است که دستور |
ساختن یک شاخه جدید
وقتی یک برنچ جدید میسازید چه اتفاقی میافتد؟
انجام این کار یک نشانگر جدید برای شما میسازد تا آنرا به این سو و آن سو انتقال دهید.
فرض بر این بگذاریم که میخواهید برنچ جدیدی با نام testing
بسازید.
شما این کار را با دستور git branch
انجام میدهید:
$ git branch testing
این کار یک نشانگر جدید به کامیتی که روی آن هستید میسازد.
چگونه گیت میداند که روی چه برنچی کار میکنید؟
گیت نشانگر خاصی به نام HEAD
(هد) را در خود دارد.
به خاطر داشته باشید این مفهوم تفاوت زیادی با مفهوم HEAD
در دیگر VCSها، مانند سابورژن یا CVS، دارد که ممکن است از پیشتر به یاد داشته باشید.
در گیت، هد نشانگری است که به برنچ محلی که روی آن هستید اشاره میکند.
در مثالی که روی آن کار میکنیم شما هنوز روی master
هستید.
دستور git branch
فقط یک برنچ جدید ساخت — به برنچ جدید نقل مکان نکرد.
به سادگی هر چه تمام شما میتوانید با اجرای دستور git log
، که به شما نشان میدهد چه برنچی به کجا اشاره دارد، این موضوع را بررسی کنید.
این آپشن --decorate
خوانده میشود.
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) Add feature #32 - ability to add new formats to the central interface
34ac2 Fix bug #1328 - stack overflow under certain conditions
98ca9 Initial commit
شما میتوانید برنچهای master
و testing
را که دقیقاً کنار کامیت f30ab
هستند ببینید.
تعویض شاخهها
برای تعویض یا جابهجایی به یک برنچ از پیش ساخته شده دستور git checkout
را اجرا میکنید.
حال بیایید به برنچ جدید testing
برویم:
$ git checkout testing
این کار HEAD
را جابهجا میکند تا به برنچ testing
اشاره کند.
تأثیر این کار در چه بود؟ خب، بیایید یک کامیت دیگر انجام دهیم:
$ vim test.rb
$ git commit -a -m 'made a change'
این جالب است چرا که الآن برنچ testing
به جلو رفت در حالی که برنچ master
هنوز به کامیتی، که سابقاً روی آن git checkout
که برای تعویض برنچها استفاده شد، اشاره میکند.
بیایید دوباره به برنچ master
بازگردیم:
$ git checkout master
یادداشت
|
git log همیشه، همهٔ برنچها را نمایش نمیدهد.اگر الآن برنچ مذکور غیب نشده است؛ صرفاً گیت گمان نمیکند که شما علاقهای به دانستن اطلاعات آن برنچ دارید و سعی میکند مطالبی که به نظرش برای شما مفید است را به شما نشان دهد.
به بیان دیگر، در حالت پیشفرض، برای نمایش تاریخچهٔ کامیتهای برنچ مورد نظر باید به صراحت آن را نام ببرید: |
آن دستور دو کار انجام داد.
نشانگر هد را بازگرداند تا به برنچ master
اشاره کند و فایلهایی که در پوشه کاری شما بودند را به اسنپشاتی که master
به آن اشاره میکرد بازگردانی کرد.
این همچنین به این معنا است که تغییراتی که از این نقطه به بعد اعمال کنید از نسخههای قدیمیتر پروژه جدا خواهد ماند.
در سادهترین تعریف، کاری که در برنچ testing
کردید را خنثی میکند تا بتوانید راه دیگری را در پیش بگیرید.
یادداشت
|
تعویض برنچ فایلهای درون پوشه کاری را تغییر میدهد
بسیار مهم است که به خاطر داشته باشید که تعویض برنچ در گیت فایلهایی که در پوشه کاری دارید را تغییر میدهد. اگر به برنچ قدیمیتری انتقال پیدا کنید، پوشه کاری شما به آن صورتی بازگردانی خواهد شد که آخرین بار هنگام ایجاد کامیت روی آن برنچ بوده است. اگر گیت نتواند این بازگردانی را به صورت بینقص انجام دهد، نمیگذارد تعویض برنچ انجام شود. |
بیایید چند تغییر اعمال کنیم و دوباره کامیت بگیریم:
$ vim test.rb
$ git commit -a -m 'made other changes'
اکنون تاریخچه پروژه شما دوشاخه شده است (به تاریخچه دوشاخه شده مراجعه کنید).
شما یک برنچ ساختید و به آن انتقال پیدا کردید، کمی روی آن کار کردید و سپس به برنچ اصلی خود بازگشتید و آنجا کمی کار متفاوت انجام دادید.
هر دوی آن تغییرات به صورت ایزوله در برنچهای خودشان موجوداند: شما میتوانید بین برنچها جابهجا شوید و هرگاه آماده بودید آنها را با هم مرج کنید.
و جالبتر اینکه همهٔ این کارها را صرفاً با دستورهای branch
، checkout
و commit
انجام دادید.
علاوه بر آن، با دستور git log
میتوانید این اطلاعات را ببینید.
اگر git log --oneline --decorate --graph --all
را اجرا کنید، برنامه تاریخچهٔ کامیتهای شما را نمایش میدهد، نشان میدهد که نشانگرهای برنچهایتان کجاست و چگونه تاریخچهٔ شما دو شاخه شده است.
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) Made other changes
| * 87ab2 (testing) Made a change
|/
* f30ab Add feature #32 - ability to add new formats to the central interface
* 34ac2 Fix bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project
از این جهت که برنچ در گیت صرفاً یک فایل سادهٔ محتوی یک چکسام SHA-1 چهل حرفی کامیتی است که به آن اشاره میکند، ساختن و از بین بردن برنچها کم هزینه است. ساختن یک برنچ جدید به سادگی و سرعت نوشتن ۴۱ بایت اطلاعات درون یک فایل است (۴۰ حرف و یک خط جدید).
این قضیه بسیار متفاوت با نحوهٔ برنچسازی بیشتر ابزارهای VCS قدیمی است که شامل کپی کردن تمام فایلهای پروژه به یک پوشه ثانوی میباشد. این میتواند چندین ثانیه یا حتی دقیقه، بسته به سایز پروژه، طول بکشد؛ درحالی که در گیت این فرآیند همیشه آنی است. همچنین به علت اینکه هنگامی که کامیت میکنیم والد را هم در کامیت ثبت میکنیم، پیدا کردن یک پایهٔ ادغام برای مرج کردن به صورت خودکار برای ما انجام میشود و به طور کل انجام آن بسیار آسان است. این مزایا توسعهدهندگان را به ساختن و استفاده بیشتر از برنچها مشتاق میکند.
بیایید به اینکه چرا شما نیز باید این کار را کنید نگاهی بیاندازیم.
یادداشت
|
ساختن یک برنچ جدید و انتقال به آن در آن واحد
خیلی اوقات پیش میآید که یک برنچ جدید بسازید و بخواهید در آن واحد به آن انتقال یابید — این کار در یک عملیات با |