-
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.2 شاخهسازی در گیت - شاخهسازی و ادغام مقدماتی
شاخهسازی و ادغام مقدماتی
حال بیایید با هم به یک نمونه ساده از مرجکردن و برنچسازی با یک روند کاری که احتمالاً در دنیای واقعی از آن استفاده خواهید کرد بپردازیم. شما این مراحل را دنبال خواهید کرد:
-
کمی کار روی یک پروژه وبسایت کنید.
-
یک برنچ جدید برای یک یوزراستوری جدید که روی آن کار میکنید بسازید.
-
روی آن برنچ کمی کار کنید.
در این وهله شما تماسی دریافت میکنید که یک مورد بحرانی پیش آمده و باید یک راه حل سریع (هاتفیکس) برای آن آماده کنید. شما اینگونه عمل خواهید کرد:
-
به برنچ پروداکشن خود بروید.
-
یک برنچ برای اضافه کردن هاتفیکس به پروژه بسازید.
-
پس از اینکه تست شد برنچ هاتفیکس را مرج کنید و تغییرات را به برنچ پروداکشن پوش کنید.
-
به یوزراستوری قبلی که روی آن کار میکردید باز گردید و به ادامهٔ کار بپردازید.
شاخهسازی مقدماتی
در ابتدا فرض کنیم که شما روی پروژهای کار میکنید و از قبل تعدادی کامیت روی برنچ master
دارید.
شما تصمیم گرفتهاید که روی ایشو #53 در سیستم پیگیری-مشکلی (Issue-Tracking System) که کمپانی شما از آن استفاده میکند کار کنید.
برای ساختن یک برنچ جدید و تعویض برنچ در آن واحد میتوانید دستور git checkout
را با کلید -b
اجرا کنید:
$ git checkout -b iss53
Switched to a new branch "iss53"
این دستور کوتاه شده خطوط زیر است:
$ git branch iss53
$ git checkout iss53
شما روی سایت خود کار میکنید و چند کامیت میکنید.
انجام چنین کاری برنچ iss53
را به جلو منتقل میکند، به این دلیل که شما آنرا چکاوت کردهاید (یعنی HEAD
شما به آن اشاره دارد):
$ vim index.html
$ git commit -a -m 'Create new footer [issue 53]'
iss53
با کار شما به جلو رفته استحال تماسی به شما میگوید که مشکلی در وبسایت هست و شما باید درجا آنرا درست کنید.
با گیت، مجبور نمیشوید که فیکس خود را با تغییراتی که در iss53
دادهاید ارائه کنید و مجبور نیستید زحمتی در جهت بازگردانی آن تغییرات بکشید، پیش از اینکه بتوانید روی ارائه فیکس خود به نسخه پروداکشن کنید.
تمام کاری که نیاز است انجام دهید این است که به برنچ master
بازگردید.
اگرچه قبل از اینکه آن کار را انجام دهید باید دقت کنید که اگر پوشه کاری یا استیج شما تغییرات کامیتنشدهای دارد که باعث ایجاد تداخل (Conflict) در
برنچی که میخواهید به آن چکاوت کنید میشود، گیت به شما اجازهٔ تعویض برنچ نمیدهد.
همیشه بهتر است قبل از تعویض برنچ، پوشه کاری داشته باشید.
راههای متفاوتی برای انجام این تمیزکاری وجود دارد (من جمله استش (Stash) و امند کردن کامیت) که در Stashing and Cleaning به آن خواهیم پرداخت.
فعلاً بیاید فرض کنیم که همه تغییرات کامیت شدهاند، بنابراین میتوانید به برنچ master
خود انتقال پیدا کنید:
$ git checkout master
Switched to branch 'master'
تا اینجای کار پوشه کاری پروژهٔ شما دقیقاً مانند قبل از زمانی است که شروع به کار روی ایشو #53 کردید و میتوانید روی هاتفیکس خود تمرکز کنید. این نکته مهمی برای به خاطر سپردن است: هنگامی که برنچ را تعویض میکنید، گیت پوشه کاری شما را بازنشانی میکند تا دقیقاً به آن شکلی شود که آخرین بار روی آن برنچ کامیت کردید. گیت به طور خودکار فایلها را کم، زیاد یا ویرایش میکند تا مطمئن شود که کپی فعال شما عیناً مطابق آخرین کامیت روی برنچ است.
در ادامه شما باید به هاتفیکس خود بپردازید.
بیاید یک برنچ hotfix
بسازیم و تا زمان تمام شدنش روی آن کار کنیم:
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'Fix broken email address'
[hotfix 1fb7853] Fix broken email address
1 file changed, 2 insertions(+)
master
میتوانید تستهای خود را بگیرید، از اینکه هاتفیکس آنگونه که شما میخواهید هست اطمینان حاصل کنید و در آخر برنچ hotfix
را با برنچ master
مرج کنید تا روی
محیط پروداکشن پیادهسازی کنید. شما میتوانید این کار را با دستور git merge
انجام دهید:
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
شما متوجه عبارت «fast-forward» در آن مرج میشوید.
به این دلیل که کامیت C4
توسط برنچ hotfix
مورد اشاره قرار گرفته که دقیقاً جلوی کامیت C2
است که شما روی آن کار میکنید، گیت به سادگی نشانگر را به جلو هل میدهد.
به بیان دیگر وقتی سعی میکنید یک کامیت را با کامیت دیگری که میتوان از طریق یپمودن مسیر کامیت اول به آن رسید، مرج کنید،
گیت نشانگر را به جلو میکشد چون دوشاخگی در مسیر وجود ندارد که گیت بخواهد آنرا ادغام کند — به این کار «fast-forward» میگویند.
اکنون تغییرات شما در اسنپشات کامیتی است که برنچ master
به آن اشاره میکند و شما میتوانید فیکس خود را ارائه کنید.
master
به hotfix
فست-فوروارد شد.پس از اینکه فیکس فوق مهمتان ارائه شد، آمادهاید تا به کاری که پیش از اینکه به شما اطلاع داده شود بازگردید.
هرچند ابتدا شما برنچ hotfix
را پاک خواهید کرد، چرا که دیگر آنرا احتیاج ندارید — برنچ master
به همانجا اشاره دارد.
شما میتوانید با آپشن -d
دستور git branch
آنرا پاک کنید:
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
حال میتوانید به برنچ در حال تکمیل شدن قبلی که دربارهٔ ایشو #53 بود بازگردید و به کارکردن روی آن ادامه دهید:
$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'Finish the new footer [issue 53]'
[iss53 ad82d7a] Finish the new footer [issue 53]
1 file changed, 1 insertion(+)
iss53
ادامه پیدا میکنداهمیتی ندارد که کاری که روی برنچ hotfix
خود به انجام رسانیدهاید در فایلهای برنچ iss53
موجود نیست.
اگر احتیاج دارید تا آنرا اعمال کنید، میتوانید با اجرای git merge master
برنچ master
را در برنچ iss53
مرج کنید، یا میتوانید برای
تعبیهسازی تغییرات صبر کنید تا زمانی که تصمیم بگیرید که برنچ iss53
را به برنچ master
پول کنید.
ادغام مقدماتی
فرض کنید به این نتیجه رسیدهاید که کار روی ایشوی #53 تمام شده و آماده است تا با برنچ master
مرج شود.
برای اینکه این کار را انجام دهید، شما برنچ iss53
را درون برنچ master
میریزید و ادغام میکنید، بسیار شبیه به قبل، زمانی که برنچ hotfix
را مرج کردید.
تمام کاری که باید بکنید این است که برنچی که میخواهید تغییرات را به آن بریزید را چکاوت کنید و دستور git merge
را اجرا کنید:
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
این کمی متفاوت از مرج hotfix
که قبلاً انجام دادهاید به نظر میرسد.
در این مورد، تاریخچهٔ توسعهٔ شما از یک نقطه قدیمیتر به آنسو دوشاخه شده بود.
چرا که کامیتی که روی برنچ کاری شماست، در مسیر مستقیم برنچی که با آن ادغام میشود نیست و گیت باید در این رابطه کاری کند.
در این شرایط گیت یک مرج سه طرفه ساده، با استفاده از دو اسنپشاتی که نوک برنچها به آنها اشاره میکنند و یک والد مشترک از هر دو انجام میدهد.
به جای جلو بردن پوینتر برنچ به جلو، گیت یک اسنپشات جدید میسازد که حاصل این مرج سه طرفه است و به طور خودکار یک کامیت میسازد که به آن اسنپشات اشاره میکند. این کامیت به عنوان یک مرج کامیت، نوعی کامیت خاص که بیش از یک والد دارد، شناخته میشود.
حال که کار شما ادغام شده است و شما دیگر نیازی به برنچ iss53
ندارید.
شما میتوانید ایشو را در سیستم پیگیری-مشکلتان ببندید و برنچ را پاک کنید:
$ git branch -d iss53
تداخلات ادغام پایه
هر از گاهی این فرآیند به این آسانی انجام نمیپذیرد.
اگر یک بخش از یک فایل را در دو برنچی که مرج میکنید به دو نحو متفاوت ویرایش کردهاید، گیت نمیتواند به طور بینقص آنها را مرج کند.
اگر فیکس شما برای ایشو #53 همان بخشی را از یک فایل ویرایش کرده که در برنچ hotfix
هم ویرایش شده، شما یک تداخل (Conflict) مرج خواهید گرفت که چیزی شبیه زیر خواهد بود:
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
گیت به طور خودکار یک مرج کامیت جدید نساخته است.
فرآیند را متوقف کرده است تا شما تداخل را حل کنید.
هرگاه میخواهید ببینید که چه فایلهایی در یک تداخل مرج، مرجنشده باقی ماندهاند، میتوانید دستور git status
را اجرا کنید:
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
هر چیزی که تداخل مرج دارد و حل نشده باشد به عنوان «مرجنشده» (Unmerged) لیست میشود. گیت چند نشانگر استاندارد تفکیک-تداخل را به فایلهایی که در آنها تداخل هست اضافه میکند تا بتوانید آنها را به طور دستی باز کرده و تداخلها را حل کنید. فایل شما بخشی خواهد داشت که شبیه زیر خواهد بود:
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
این بدان معناست که نسخهای که در HEAD
وجود دارد (برنچ master
شما، چرا که این برنچ جایی است که آخرین بار پیش از اینکه دستور مرج را اجرا کنید چکاوت کردید) بخش بالایی
آن بلوک است (هر چیزی که بالای =======
قرار دارد)، در حالی که نسخهٔ درون برنچ iss53
مشابه نوشتههای بخش زیرین است.
برای حل تداخل، شما میتوانید یکی از دو طرف را انتخاب کرده یا محتوا را خودتان ادغام کنید.
به طور مثال ممکن است شما با جایگزین کردن کل آن بلوک با چنین محتوایی این تداخل را حل کنید:
<div id="footer">
please contact us at email.support@github.com
</div>
این راه حل کمی از هر بخش را در خود دارد و خطوط >>>>>>>
، =======
و <<<<<<<
هم کاملاً پاک شدهاند.
بعد از اینکه هر کدام از این بخشها را در هر فایل متداخل را ویرایش کردید، git add
را روی هر فایل اجرا کنید تا آنرا به عنوان حل شده علامتگذاری کنید.
در گیت، استیجکردن فایل آنرا به عنوان حل شده علامتگذاری میکند.
اگر میخواهید از ابزاری گرافیکی برای حل این مسائل استفاده کنید، میتوانید git mergetool
را اجرا کنید که
یک ابزار مرج بصری مناسب اجرا میکند و شما را در تداخلها همراهی میکند:
$ 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 (opendiff):
اگر میخواهید از ابزار مرجی به جز ابزار پیشفرض استفاده کنید (در این مثال گیت opendiff
را انتخاب کرده چرا که دستور روی یک مک اجرا شده)،
میتوانید لیست تمام ابزارهای پشتیبانی شده را در بالا پس از «one of the following tools» مشاهده کنید.
کافیست نام ابزاری که ترجیح میدهید استفاده کنید وارد کنید.
یادداشت
|
اگر به ابزار پیشرفتهتری برای حل تداخلهای خاص دارید، ما به بحث مرجکردن در Advanced Merging بیشتر میپردازیم. |
پس از اینکه ابزار مرج را بستید، گیت از شما دربارهٔ موفقیت آمیز بودن یا نبودن مرج میپرسد.
اگر به اسکریپت بگویید موفقیتآمیز بود، فایلها را استیج میکند تا آنها را برای شما به عنوان حل شده علامت زده باشد.
شما میتوانید git status
را دوباره اجرا کنید تا تصدیق کنید که تمام تداخلات حل شدهاند:
$ 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
اگر از این خروجی راضی هستید و تصدیق میکنید که هر چیزی که تداخل داشته استیج شده، میتوانید git commit
را تایپ کنید تا مرج کامیت را ثبت نهایی کنید.
پیغام پیشفرض کامیت چیزی شبیه زیر خواهد بود:
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
#
اگر فکر میکنید که برای دیگرانی که در آینده به این مرج کامیت نگاه میکنند مفیدتر خواهد بود، میتوانید این پیغام را با جزئیاتی درباره اینکه چگونه مرج را حل کردهاید بازنویسی کنید و اگر واضح نیست، توضیح دهید که چه تغییراتی اعمال کردهاید.