-
1. شروع به کار (getting started)
-
2. مقدمات گیت (git basics chapter)
- 2.1 گرفتن یک مخزن گیت (Getting a Git Repository)
- 2.2 ثبت تغییرات در مخزن (Recording Changes to the Repository)
- 2.3 مشاهده تاریخچه کامیتها (Viewing the Commit History)
- 2.4 بازگرداندن تغییرات (Undoing Things)
- 2.5 کار کردن با ریموت ها (Working with Remotes)
- 2.6 تگ کردن (Tagging)
- 2.7 نام مستعار گیت (Git Aliases)
- 2.8 خلاصه (summary)
-
3. انشعابگیری در گیت (Git Branching)
-
4. گیت روی سرور (Git on the server)
- 4.1 پروتکلها (The Protocols)
- 4.2 راهاندازی گیت روی یک سرور (Getting Git on a Server)
- 4.3 ایجاد کلید عمومی SSH شما (Generating Your SSH Public Key)
- 4.4 نصب و راهاندازی سرور (Setting up server)
- 4.5 سرویسدهنده گیت (Git Daemon)
- 4.6 HTTP هوشمند (Smart HTTP)
- 4.7 گیتوب (GitWeb)
- 4.8 گیتلب (GitLab)
- 4.9 گزینههای میزبانی شخص ثالث (Third Party Hosted Options)
- 4.10 خلاصه (Summary)
-
5. گیت توزیعشده (Distributed git)
-
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. سفارشیسازی Git (Customizing Git)
-
9. گیت و سیستمهای دیگر (Git and Other Systems)
-
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 در ویژوال استودیو (Git in Visual Studio)
- A1.3 Git در Visual Studio Code (Git in Visual Studio Code)
- A1.4 Git در IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine (Git in IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine)
- A1.5 Git در Sublime Text (Git in Sublime Text)
- A1.6 گیت در بش (Git in Bash)
- A1.7 Git در Zsh (Git in Zsh)
- A1.8 Git در PowerShell (Git in PowerShell)
- A1.9 خلاصه (Summary)
-
A2. پیوست B: گنجاندن گیت در برنامههای شما (Embedding Git in your Applications)
-
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)
7.6 ابزارهای گیت (Git Tools) - بازنویسی تاریخچه (Rewriting History)
بازنویسی تاریخچه (Rewriting History)
بارها هنگام کار با گیت ممکن است بخواهید تاریخچهی کامیتهای محلی خود را بازبینی کنید. یکی از ویژگیهای عالی گیت این است که به شما اجازه میدهد تصمیمات را در آخرین لحظه ممکن بگیرید. میتوانید تصمیم بگیرید که کدام فایلها در کدام کامیت قرار بگیرند درست قبل از اینکه کامیت کنید با استفاده از فضای استیجینگ، میتوانید با دستور git stash
مشخص کنید که هنوز قصد ندارید روی چیزی کار کنید، و میتوانید کامیتهایی که قبلاً انجام شدهاند را بازنویسی کنید تا طوری به نظر برسد که به شکل متفاوتی انجام شدهاند. این کار میتواند شامل تغییر ترتیب کامیتها، تغییر پیامها یا اصلاح فایلها در یک کامیت، ادغام یا تقسیم کامیتها، یا حذف کامل کامیتها باشد — همه اینها قبل از اینکه کار خود را با دیگران به اشتراک بگذارید.
در این بخش، خواهید دید چگونه این کارها را انجام دهید تا تاریخچهی کامیتهای شما پیش از به اشتراک گذاری با دیگران، به شکل دلخواه شما درآید.
یادداشت
|
Don’t push your work until you’re happy with it
یکی از اصول اساسی گیت این است که چون بخش زیادی از کار به صورت محلی در کلون شما انجام میشود، آزادی زیادی برای بازنویسی تاریخچه محلی خود دارید. اما وقتی کار خود را پوش میکنید، داستان کاملاً متفاوت است و باید کارهای پوش شده را نهایی فرض کنید مگر اینکه دلیل موجهی برای تغییر آن داشته باشید. به طور خلاصه، بهتر است از پوش کردن کارهای خود تا زمانی که از آن راضی هستید و آمادهی به اشتراک گذاری با بقیه هستید، خودداری کنید. |
تغییر آخرین کامیت (Changing the Last Commit)
تغییر آخرین کامیت شما احتمالاً رایجترین نوع بازنویسی تاریخچه است که انجام میدهید. معمولاً دو کار اصلی روی آخرین کامیت انجام میدهید: یا صرفاً پیام کامیت را تغییر میدهید، یا محتوای واقعی کامیت را با افزودن، حذف یا اصلاح فایلها تغییر میدهید.
اگر فقط میخواهید پیام آخرین کامیت را اصلاح کنید، کار ساده است:
$ git commit --amend
دستور بالا پیام کامیت قبلی را در یک ویرایشگر باز میکند که میتوانید تغییرات مورد نظر را اعمال کنید، آن را ذخیره کرده و خارج شوید. وقتی ویرایشگر را ذخیره و ببندید، یک کامیت جدید با پیام اصلاح شده ایجاد میشود و جایگزین آخرین کامیت شما میشود.
اگر بخواهید محتوای واقعی آخرین کامیت را تغییر دهید، فرآیند اساساً مشابه است — ابتدا تغییراتی که فراموش کردهاید را انجام دهید، آنها را استیج کنید، سپس دستور git commit --amend
کامیت قبلی را با کامیت جدید و اصلاح شده جایگزین میکند.
با این روش باید مراقب باشید چون اصلاح کامیت باعث تغییر SHA-1 آن میشود. این مثل یک ریبیس خیلی کوچک است — اگر کامیت آخر را قبلاً پوش کردهاید، آن را اصلاح نکنید.
نکته
|
An amended commit may (or may not) need an amended commit message
وقتی کامیت را اصلاح میکنید، هم فرصت تغییر پیام و هم محتوای کامیت را دارید. اگر محتوای کامیت را به طور قابل توجهی تغییر میدهید، بهتر است پیام کامیت را هم بهروز کنید تا این تغییرات را منعکس کند. اما اگر اصلاحات شما خیلی جزئی است (مثلاً رفع یک اشتباه تایپی ساده یا افزودن فایلی که فراموش کرده بودید استیج کنید) و پیام قبلی کامیت مناسب است، میتوانید فقط تغییرات را اعمال و استیج کنید و بدون باز کردن ویرایشگر به این شکل ادامه دهید:
|
تغییر پیام چندین کامیت (Changing Multiple Commit Messages)
برای اصلاح کامیتی که در تاریخچهی شما عقبتر است، باید از ابزارهای پیچیدهتری استفاده کنید. گیت ابزار مستقیمی برای ویرایش تاریخچه ندارد، اما میتوانید از ابزار ریبیس برای ریبیس کردن سریای از کامیتها روی HEAD که قبلاً بر اساس آن بودند استفاده کنید به جای اینکه آنها را روی یک نقطهی دیگر منتقل کنید. با ابزار ریبیس تعاملی میتوانید بعد از هر کامیتی که میخواهید اصلاح کنید متوقف شده و پیام را تغییر دهید، فایل اضافه کنید یا هر کار دیگری انجام دهید.
میتوانید ریبیس را به صورت تعاملی با افزودن گزینه -i
به دستور git rebase
اجرا کنید. باید مشخص کنید تا چه اندازه عقب میخواهید تاریخچه را بازنویسی کنید با تعیین کامیتی که میخواهید ریبیس روی آن انجام شود.
مثلاً اگر میخواهید پیام سه کامیت آخر یا هر یک از پیامهای آنها را تغییر دهید، باید والد آخرین کامیتی که میخواهید ویرایش کنید را به عنوان آرگومان به git rebase -i
بدهید که معمولاً HEAD~2^
یا HEAD~3
است. به خاطر سپردن ~3
آسانتر است چون قصد دارید سه کامیت آخر را ویرایش کنید، اما به یاد داشته باشید که در واقع دارید والد کامیتی که میخواهید ویرایش کنید را تعیین میکنید که چهار کامیت قبل است:
$ git rebase -i HEAD~3
دوباره به خاطر داشته باشید که این یک دستور بازپایهگذاری (rebasing) است — هر کامیتی در بازهی HEAD~3..HEAD
که پیام آن تغییر کرده باشد و همهی فرزندان آن بازنویسی خواهند شد.
هیچ کامیتی که قبلاً به سرور مرکزی فرستادهاید را وارد نکنید — انجام این کار باعث سردرگمی سایر توسعهدهندگان میشود، چون نسخهی جایگزینی از همان تغییر ارائه میدهد.
اجرای این دستور فهرستی از کامیتها را در ویرایشگر متن شما نمایش میدهد که چیزی شبیه این است:
pick f7f3f6d Change my name a bit
pick 310154e Update README formatting and add blame
pick a5f4a0d Add cat-file
# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
مهم است بدانید که این کامیتها به ترتیب معکوس نسبت به آنچه معمولاً با دستور log
میبینید، فهرست شدهاند.
اگر دستور log
را اجرا کنید، چیزی شبیه این میبینید:
$ git log --pretty=format:"%h %s" HEAD~3..HEAD
a5f4a0d Add cat-file
310154e Update README formatting and add blame
f7f3f6d Change my name a bit
توجه کنید که ترتیب کامیتها معکوس است.
بازپایهگذاری تعاملی (interactive rebase) اسکریپتی به شما میدهد که قرار است اجرا شود.
این اسکریپت از کامیتی که در خط فرمان مشخص کردهاید (HEAD~3
) شروع میکند و تغییرات هر یک از این کامیتها را از بالا به پایین بازپخش میکند.
کامیتهای قدیمیتر در بالا قرار دارند، نه جدیدترها، چون اولین کامیتی است که بازپخش میشود.
شما باید اسکریپت را طوری ویرایش کنید که در کامیتی که میخواهید ویرایش کنید، متوقف شود. برای این کار، کلمهی “pick” را به “edit” تغییر دهید برای هر کامیتی که میخواهید اسکریپت بعد از آن متوقف شود. مثلاً، برای تغییر پیام فقط کامیت سوم، فایل را به شکل زیر تغییر میدهید:
edit f7f3f6d Change my name a bit
pick 310154e Update README formatting and add blame
pick a5f4a0d Add cat-file
وقتی فایل را ذخیره و از ویرایشگر خارج میشوید، گیت شما را به آخرین کامیت در آن فهرست برمیگرداند و پیام زیر را در خط فرمان نشان میدهد:
$ git rebase -i HEAD~3
Stopped at f7f3f6d... Change my name a bit
You can amend the commit now, with
git commit --amend
Once you're satisfied with your changes, run
git rebase --continue
این دستورالعملها دقیقاً به شما میگویند چه کاری انجام دهید. بنویسید:
$ git commit --amend
Change the commit message, and exit the editor. Then, run:
$ git rebase --continue
این دستور دو کامیت دیگر را بهطور خودکار اعمال میکند و کار شما تمام میشود.
اگر pick
را در چند خط به edit
تغییر دهید، میتوانید این مراحل را برای هر کامیتی که به edit
تغییر دادهاید تکرار کنید.
هر بار گیت متوقف میشود، اجازه میدهد کامیت را اصلاح کنید و وقتی تمام کردید ادامه میدهد.
مرتبسازی مجدد کامیتها (Reordering Commits)
میتوانید از بازپایهگذاری تعاملی برای مرتبکردن دوباره یا حذف کامل کامیتها هم استفاده کنید. اگر میخواهید کامیت “Add cat-file” را حذف کنید و ترتیب دو کامیت دیگر را تغییر دهید، میتوانید اسکریپت بازپایهگذاری را از این حالت به این شکل تغییر دهید:
pick f7f3f6d Change my name a bit
pick 310154e Update README formatting and add blame
pick a5f4a0d Add cat-file
به این:
pick 310154e Update README formatting and add blame
pick f7f3f6d Change my name a bit
وقتی فایل را ذخیره و از ویرایشگر خارج میشوید، گیت شاخهی شما را به والد این کامیتها برمیگرداند، سپس 310154e
و بعد f7f3f6d
را اعمال میکند و متوقف میشود.
شما عملاً ترتیب این کامیتها را تغییر داده و کامیت “Add cat-file” را به طور کامل حذف کردهاید.
اسکواش کامیت ها (Squashing Commits)
با ابزار بازپایهگذاری تعاملی میتوانید چندین کامیت را به یک کامیت فشرده کنید. اسکریپت دستورالعملهای مفیدی در پیام بازپایهگذاری میگذارد:
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
اگر به جای “pick” یا “edit”، “squash” را مشخص کنید، گیت تغییر آن کامیت و کامیت مستقیم قبل از آن را اعمال میکند و از شما میخواهد پیامهای کامیتها را ادغام کنید. پس، اگر میخواهید از این سه کامیت یک کامیت بسازید، اسکریپت را به این شکل تنظیم میکنید:
pick f7f3f6d Change my name a bit
squash 310154e Update README formatting and add blame
squash a5f4a0d Add cat-file
وقتی ذخیره و از ویرایشگر خارج میشوید، گیت هر سه تغییر را اعمال میکند و سپس شما را دوباره به ویرایشگر میبرد تا پیامهای سه کامیت را با هم ادغام کنید:
# This is a combination of 3 commits.
# The first commit's message is:
Change my name a bit
# This is the 2nd commit message:
Update README formatting and add blame
# This is the 3rd commit message:
Add cat-file
وقتی پیام را ذخیره کنید، یک کامیت واحد دارید که تغییرات هر سه کامیت قبلی را معرفی میکند.
تقسیم یک کامیت (Splitting a Commit)
تقسیم یک کامیت یعنی بازگرداندن آن کامیت و سپس مرحلهبندی و کامیت کردن بخشهایی از آن به تعداد کامیتهایی که میخواهید داشته باشید.
مثلاً فرض کنید میخواهید کامیت وسط از سه کامیت را تقسیم کنید.
به جای “Update README formatting and add blame”، میخواهید آن را به دو کامیت تقسیم کنید: اولی “Update README formatting” و دومی “Add blame”.
میتوانید این کار را در اسکریپت rebase -i
با تغییر دستور روی کامیتی که میخواهید تقسیم کنید به “edit” انجام دهید:
pick f7f3f6d Change my name a bit
edit 310154e Update README formatting and add blame
pick a5f4a0d Add cat-file
سپس وقتی اسکریپت شما را به خط فرمان میرساند، آن کامیت را ریست میکنید، تغییرات ریست شده را میگیرید و چند کامیت جدید از آن میسازید.
وقتی ذخیره و از ویرایشگر خارج میشوید، گیت شاخه را به والد اولین کامیت در فهرست برمیگرداند، اولین کامیت (f7f3f6d
) را اعمال میکند، دومین را (310154e
) اعمال میکند و شما را به کنسول میبرد.
در آنجا میتوانید با دستور git reset HEAD^
ریست ترکیبی روی آن کامیت بزنید که عملاً آن کامیت را undo میکند و فایلهای تغییر یافته را unstaged باقی میگذارد.
حالا میتوانید فایلها را مرحلهبندی و کامیت کنید تا کامیتهای متعددی ایجاد شود، و وقتی تمام کردید، دستور git rebase --continue
را اجرا کنید:
$ git reset HEAD^
$ git add README
$ git commit -m 'Update README formatting'
$ git add lib/simplegit.rb
$ git commit -m 'Add blame'
$ git rebase --continue
گیت آخرین کامیت (a5f4a0d
) در اسکریپت را اعمال میکند و تاریخچه شما اینگونه خواهد بود:
$ git log -4 --pretty=format:"%h %s"
1c002dd Add cat-file
9b29157 Add blame
35cfb2b Update README formatting
f7f3f6d Change my name a bit
این کار باعث تغییر SHA-1 سه کامیت اخیر در لیست شما میشود، پس مطمئن شوید که هیچ کامیتی که تغییر کرده و قبلاً به مخزن مشترک ارسال کردهاید، در آن لیست ظاهر نشود. توجه داشته باشید که آخرین کامیت (`f7f3f6d`) در لیست بدون تغییر باقی مانده است. با وجود اینکه این کامیت در اسکریپت نشان داده شده است، چون با علامت "`pick`" مشخص شده و قبل از هر تغییر ریبیس اعمال شده، گیت آن کامیت را دستنخورده باقی میگذارد.
حذف یک کامیت (Deleting a commit)
اگر میخواهید یک کامیت را حذف کنید، میتوانید با استفاده از اسکریپت rebase -i
این کار را انجام دهید.
در لیست کامیتها، کلمه “drop” را قبل از کامیتی که میخواهید حذف کنید قرار دهید (یا به سادگی آن خط را از اسکریپت ریبیس حذف کنید):
pick 461cb2a This commit is OK
drop 5aecc10 This commit is broken
به دلیل نحوه ساخت اشیاء کامیت توسط گیت، حذف یا تغییر یک کامیت باعث بازنویسی تمام کامیتهای بعد از آن میشود. هرچه به عقبتر در تاریخچه مخزن خود بروید، تعداد بیشتری از کامیتها باید بازسازی شوند. این میتواند باعث ایجاد تعداد زیادی تضاد ادغام شود اگر کامیتهای زیادی بعد از آن کامیت وجود داشته باشند که به آن وابستهاند.
اگر در میانه انجام ریبیس چنین کاری تصمیم گرفتید که ادامه ندهید، همیشه میتوانید متوقف شوید.
دستور git rebase --abort
را وارد کنید تا مخزن شما به حالتی که قبل از شروع ریبیس بوده بازگردد.
اگر ریبیس را کامل کردید و بعد متوجه شدید که نتیجه مطلوب نیست، میتوانید با استفاده از git reflog
نسخه قبلی شاخه خود را بازیابی کنید.
برای اطلاعات بیشتر درباره دستور reflog
به بازیابی دادهها (Data Recovery) مراجعه کنید.
یادداشت
|
درو دیوالت یک راهنمای عملی و کاربردی همراه با تمرینها برای یادگیری استفاده از |
گزینه هستهای: filter-branch (The Nuclear Option: filter-branch)
گزینه دیگری برای بازنویسی تاریخچه وجود دارد که میتوانید وقتی نیاز به بازنویسی تعداد زیادی کامیت به صورت اسکریپتی دارید، از آن استفاده کنید — مثلاً تغییر آدرس ایمیل خود به صورت سراسری یا حذف یک فایل از هر کامیت.
این دستور filter-branch
است و میتواند بخشهای بسیار بزرگی از تاریخچه شما را بازنویسی کند، بنابراین احتمالاً نباید از آن استفاده کنید مگر اینکه پروژه شما هنوز عمومی نشده و افراد دیگری روی کامیتهایی که میخواهید بازنویسی کنید کار نکرده باشند.
با این حال، این ابزار میتواند بسیار مفید باشد.
شما چند کاربرد رایج آن را یاد خواهید گرفت تا با برخی از تواناییهای آن آشنا شوید.
گوشزد
|
|
حذف یک فایل از همه کامیتها (Removing a File from Every Commit)
این مورد نسبتاً رایج است.
کسی به اشتباه یک فایل باینری بزرگ را با دستور بیفکر git add .
کامیت کرده و شما میخواهید آن را از همه جا حذف کنید.
شاید به اشتباه فایلی که حاوی رمز عبور بوده را کامیت کردهاید و میخواهید پروژهتان را متنباز کنید.
filter-branch
ابزاری است که احتمالاً میخواهید برای پاکسازی کل تاریخچه خود استفاده کنید.
برای حذف فایلی به نام passwords.txt
از کل تاریخچه، میتوانید از گزینه --tree-filter
در filter-branch
استفاده کنید:
$ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD
Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21)
Ref 'refs/heads/master' was rewritten
گزینه --tree-filter
دستوری را پس از هر بار چکاوت پروژه اجرا کرده و سپس نتایج را دوباره کامیت میکند.
در این حالت، فایل passwords.txt
را از هر اسنپشات حذف میکند، چه وجود داشته باشد چه نه.
اگر بخواهید همه فایلهای پشتیبان تصادفی ویرایشگر را حذف کنید، میتوانید چیزی شبیه به git filter-branch --tree-filter 'rm -f *~' HEAD
را اجرا کنید.
میتوانید روند بازنویسی درختها و کامیتها را ببینید و سپس اشارهگر شاخه را در پایان حرکت دهید.
عموماً بهتر است این کار را روی یک شاخه آزمایشی انجام دهید و پس از اطمینان از نتیجه، شاخه master
خود را با hard-reset
بازنشانی کنید.
برای اجرای filter-branch
روی همه شاخهها، میتوانید گزینه --all
را به دستور اضافه کنید.
Making a Subdirectory the New Root (تبدیل یک زیرشاخه به ریشه جدید)
فرض کنید از یک سیستم کنترل نسخه دیگر وارد شدهاید و زیرشاخههایی دارید که معنایی ندارند (مانند trunk
، tags
و غیره).
اگر میخواهید زیرشاخه trunk
ریشه جدید پروژه در همه کامیتها باشد، filter-branch
میتواند به شما کمک کند:
$ git filter-branch --subdirectory-filter trunk HEAD
Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12)
Ref 'refs/heads/master' was rewritten
حالا ریشه جدید پروژه شما همان چیزی است که در هر بار زیرشاخه trunk
بوده است.
گیت همچنین به طور خودکار کامیتهایی را که روی آن زیرشاخه تأثیر نداشتهاند حذف میکند.
تغییر آدرس ایمیل به صورت سراسری (Changing Email Addresses Globally)
یک مورد رایج دیگر این است که فراموش کردهاید قبل از شروع کار، git config
را برای تنظیم نام و ایمیل خود اجرا کنید، یا شاید بخواهید پروژهای که در محل کار دارید را متنباز کنید و همه آدرسهای ایمیل کاری را به آدرس شخصی خود تغییر دهید.
در هر صورت، میتوانید آدرسهای ایمیل را در چندین کامیت به صورت دستهای با filter-branch
تغییر دهید.
باید مراقب باشید فقط آدرسهای ایمیل خود را تغییر دهید، بنابراین از گزینه --commit-filter
استفاده میکنید:
$ git filter-branch --commit-filter '
if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
then
GIT_AUTHOR_NAME="Scott Chacon";
GIT_AUTHOR_EMAIL="schacon@example.com";
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD
این دستور هر کامیت را بازنویسی میکند تا آدرس ایمیل جدید شما داشته باشد. چون کامیتها شامل مقادیر SHA-1 والدهای خود هستند، این دستور SHA-1 همه کامیتهای تاریخچه شما را تغییر میدهد، نه فقط آنهایی که آدرس ایمیلشان مطابقت دارد.